#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.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/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/dnsmgr.h"
#include "asterisk/devicestate.h"
#include "asterisk/linkedlists.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 call ---. More... | |
struct | ast_user_list |
The user list: Users and friends ---. More... | |
struct | cfalias |
Structure for conversion between compressed SIP and "normal" SIP. More... | |
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 |
struct | sip_auth |
sip_auth: Creadentials for authentication to other SIP services More... | |
struct | sip_dual |
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 |
struct | sip_pkt |
sip packet - read in sipsock_read, transmitted in send_request More... | |
struct | sip_pvt |
sip_pvt: PVT structures are used for each SIP conversation, ie. a call More... | |
struct | sip_registry |
sip_registry: Registrations with other SIP proxies More... | |
struct | sip_request |
sip_request: The data grabbed from the UDP socket More... | |
struct | sip_route |
struct | sip_user |
Structure for SIP user data. User's place calls to us. More... | |
Defines | |
#define | ALLOWED_METHODS "INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY" |
SIP Methods we support. | |
#define | CALLERID_UNKNOWN "Unknown" |
#define | DEBUG_READ 0 |
#define | DEBUG_SEND 1 |
#define | DEC_CALL_LIMIT 0 |
#define | DEFAULT_CALLERID "asterisk" |
#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_EXPIRY 3600 |
#define | DEFAULT_MAX_FORWARDS "70" |
#define | DEFAULT_MAXMS 2000 |
#define | DEFAULT_MWITIME 10 |
#define | DEFAULT_NOTIFYMIME "application/simple-message-summary" |
#define | DEFAULT_REALM "asterisk" |
#define | DEFAULT_REGISTRATION_TIMEOUT 20 |
#define | DEFAULT_RETRANS 1000 |
#define | DEFAULT_SIP_PORT 5060 |
#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 | 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\n" |
sip_show_domains: CLI command to list local domains | |
#define | FORMAT "%-30.30s %-12.12s %8d %-20.20s\n" |
sip_show_domains: CLI command to list local domains | |
#define | FORMAT "%-40.40s %-20.20s %-16.16s\n" |
sip_show_domains: CLI command to list local domains | |
#define | FORMAT "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8d %-10s\n" |
sip_show_domains: CLI command to list local domains | |
#define | FORMAT "%-25.25s %-15.15s %-15.15s %-15.15s %-5.5s%-10.10s\n" |
sip_show_domains: CLI command to list local domains | |
#define | FORMAT "%-25.25s %-15.15s %-15.15s \n" |
sip_show_domains: CLI command to list local domains | |
#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\n" |
#define | FORMAT2 "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8s %-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\n" |
#define | INC_CALL_LIMIT 1 |
#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 | REG_STATE_AUTHSENT 2 |
#define | REG_STATE_FAILED 7 |
#define | REG_STATE_NOAUTH 6 |
#define | REG_STATE_REGISTERED 3 |
#define | REG_STATE_REGSENT 1 |
#define | REG_STATE_REJECTED 4 |
#define | REG_STATE_TIMEOUT 5 |
#define | REG_STATE_UNREGISTERED 0 |
#define | RTP 1 |
#define | SIP_ALREADYGONE (1 << 0) |
#define | SIP_CALL_LIMIT (1 << 29) |
#define | SIP_CALL_ONHOLD (1 << 28) |
#define | SIP_CAN_REINVITE (1 << 20) |
#define | SIP_DEBUG_CONFIG 1 << 0 |
#define | SIP_DEBUG_CONSOLE 1 << 1 |
#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_DYNAMIC (1 << 15) |
#define | SIP_FLAGS_TO_COPY |
#define | SIP_GOTREFER (1 << 7) |
#define | SIP_INC_COUNT (1 << 31) |
#define | SIP_INSECURE_INVITE (1 << 23) |
#define | SIP_INSECURE_PORT (1 << 22) |
#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_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_JOIN (1 << 4) |
#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_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_OSPAUTH (3 << 26) |
#define | SIP_OSPAUTH_EXCLUSIVE (3 << 26) |
#define | SIP_OSPAUTH_GATEWAY (1 << 26) |
#define | SIP_OSPAUTH_NO (0 << 26) |
#define | SIP_OSPAUTH_PROXY (2 << 26) |
#define | SIP_OUTGOING (1 << 13) |
#define | SIP_PAGE2_IGNOREREGEXPIRE (1 << 3) |
#define | SIP_PAGE2_RT_FROMCONTACT (1 << 4) |
#define | SIP_PAGE2_RTAUTOCLEAR (1 << 2) |
#define | SIP_PAGE2_RTCACHEFRIENDS (1 << 0) |
#define | SIP_PAGE2_RTUPDATE (1 << 1) |
#define | SIP_PENDINGBYE (1 << 6) |
#define | SIP_PKT_DEBUG (1 << 0) |
#define | SIP_PKT_WITH_TOTAG (1 << 1) |
#define | SIP_PROG_INBAND (3 << 24) |
#define | SIP_PROG_INBAND_NEVER (0 << 24) |
#define | SIP_PROG_INBAND_NO (1 << 24) |
#define | SIP_PROG_INBAND_YES (2 << 24) |
#define | SIP_PROGRESS_SENT (1 << 4) |
#define | SIP_PROMISCREDIR (1 << 8) |
#define | SIP_REALTIME (1 << 11) |
#define | SIP_REINVITE (3 << 20) |
#define | SIP_REINVITE_UPDATE (2 << 20) |
#define | SIP_RINGING (1 << 3) |
#define | SIP_SELFDESTRUCT (1 << 14) |
#define | SIP_SENDRPID (1 << 30) |
#define | SIP_TRUSTRPID (1 << 9) |
#define | SIP_USECLIENTCODE (1 << 12) |
#define | SIP_USEREQPHONE (1 << 10) |
#define | SIPDUMPER |
#define | SUPPORTED 1 |
#define | SUPPORTED_EXTENSIONS "replaces" |
SIP Extensions we support. | |
#define | VIDEO_CODEC_MASK 0x1fc0000 |
Enumerations | |
enum | domain_mode { SIP_DOMAIN_AUTO, SIP_DOMAIN_CONFIG } |
enum | parse_register_result { PARSE_REGISTER_FAILED, PARSE_REGISTER_UPDATE, PARSE_REGISTER_QUERY } |
enum | sip_auth_type { PROXY_AUTH, WWW_AUTH } |
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 } |
enum | subscriptiontype { NONE = 0, TIMEOUT, XPIDF_XML, DIALOG_INFO_XML, CPIM_PIDF_XML, PIDF_XML } |
Functions | |
static char * | __get_header (struct sip_request *req, char *name, int *start) |
static int | __sip_ack (struct sip_pvt *p, int seqno, int resp, int sipmethod) |
__sip_ack: Acknowledges receipt of a packet and stops retransmission --- | |
static int | __sip_autodestruct (void *data) |
__sip_autodestruct: Kill a call (called by scheduler) --- | |
static void | __sip_destroy (struct sip_pvt *p, int lockowner) |
__sip_destroy: Execute destrucion of call structure, release memory--- | |
static int | __sip_do_register (struct sip_registry *r) |
__sip_do_register: Register with SIP proxy --- | |
static int | __sip_pretend_ack (struct sip_pvt *p) |
static int | __sip_reliable_xmit (struct sip_pvt *p, int seqno, int resp, char *data, int len, int fatal, int sipmethod) |
__sip_reliable_xmit: transmit packet with retransmits --- | |
static int | __sip_semi_ack (struct sip_pvt *p, int seqno, int resp, int sipmethod) |
__sip_semi_ack: Acks receipt of packet, keep it around (used for provisional responses) --- | |
static int | __sip_show_channels (int fd, int argc, char *argv[], int subscriptions) |
static int | __sip_xmit (struct sip_pvt *p, char *data, int len) |
__sip_xmit: Transmit SIP message --- | |
static int | __transmit_response (struct sip_pvt *p, char *msg, struct sip_request *req, int reliable) |
__transmit_response: Base transmit response function | |
static int | _sip_show_peer (int type, int fd, struct mansession *s, struct message *m, int argc, char *argv[]) |
static int | _sip_show_peers (int fd, int *total, struct mansession *s, struct message *m, int argc, char *argv[]) |
_sip_show_peers: Execute sip show peers command | |
static int | add_blank_header (struct sip_request *req) |
add_blank_header: Add blank header to SIP message | |
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) |
static int | add_digit (struct sip_request *req, char digit) |
add_digit: add DTMF INFO tone to sip message --- | |
static int | add_header (struct sip_request *req, const char *var, const char *value) |
add_header: Add header to SIP message | |
static int | add_header_contentLength (struct sip_request *req, int len) |
add_header_contentLen: Add 'Content-Length' header to SIP message | |
static int | add_line (struct sip_request *req, const char *line) |
add_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) |
static struct sip_auth * | add_realm_authentication (struct sip_auth *authlist, char *configuration, int lineno) |
add_realm_authentication: Add realm authentication in list --- | |
static void | add_route (struct sip_request *req, struct sip_route *route) |
add_route: Add route header into request per learned route --- | |
static int | add_sdp (struct sip_request *resp, struct sip_pvt *p) |
add_sdp: Add Session Description Protocol message --- | |
static int | add_sip_domain (const char *domain, const enum domain_mode mode, const char *context) |
add_sip_domain: Add SIP domain to list of domains we are responsible for | |
static int | add_text (struct sip_request *req, const char *text) |
add_text: Add text body to SIP message --- | |
static int | add_vidupdate (struct sip_request *req) |
add_vidupdate: add XML encoded media control with update --- | |
static void | append_date (struct sip_request *req) |
append_date: Append date to SIP message --- | |
static int | append_history (struct sip_pvt *p, const char *event, const char *data) |
append_history: Append to SIP dialog history | |
static | AST_LIST_HEAD_STATIC (domain_list, domain) |
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 interface list (of sip_pvt's). | |
AST_MUTEX_DEFINE_STATIC (rand_lock) | |
AST_MUTEX_DEFINE_STATIC (usecnt_lock) | |
static void | ast_quiet_chan (struct ast_channel *chan) |
ast_quiet_chan: Turn off generator data | |
static int | ast_sip_ouraddrfor (struct in_addr *them, struct in_addr *us) |
ast_sip_ouraddrfor: NAT fix - decide which IP address to use for ASterisk server? --- | |
static int | attempt_transfer (struct sip_pvt *p1, struct sip_pvt *p2) |
attempt_transfer: Attempt transfer of SIP call --- | |
static int | auto_congest (void *nothing) |
auto_congest: Scheduled congestion on a call --- | |
static void | build_callid (char *callid, int len, struct in_addr ourip, char *fromdomain) |
build_callid: Build SIP CALLID header --- | |
static void | build_contact (struct sip_pvt *p) |
build_contact: Build contact header - the contact header we send out --- | |
static struct sip_peer * | build_peer (const char *name, struct ast_variable *v, int realtime) |
build_peer: Build peer from config file --- | |
static int | build_reply_digest (struct sip_pvt *p, int method, char *digest, int digest_len) |
build_reply_digest: Build reply digest --- | |
static void | build_route (struct sip_pvt *p, struct sip_request *req, int backwards) |
build_route: Build route list from Record-Route header --- | |
static void | build_rpid (struct sip_pvt *p) |
build_rpid: Build the Remote Party-ID & From using callingpres options --- | |
static struct sip_user * | build_user (const char *name, struct ast_variable *v, int realtime) |
build_user: Initiate a SIP user structure from sip.conf --- | |
static void | build_via (struct sip_pvt *p, char *buf, int len) |
build_via: Build a Via header for a request --- | |
static int | cb_extensionstate (char *context, char *exten, int state, void *data) |
cb_extensionstate: Callback for the devicestate notification (SUBSCRIBE) support subsystem --- | |
static int | check_auth (struct sip_pvt *p, struct sip_request *req, char *randdata, int randlen, char *username, char *secret, char *md5secret, int sipmethod, char *uri, int reliable, int ignore) |
check_auth: Check user authorization from peer definition --- | |
static void | check_pendings (struct sip_pvt *p) |
check_pendings: 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, int reliable, struct sockaddr_in *sin, int ignore) |
check_user: Find user --- | |
static int | check_user_full (struct sip_pvt *p, struct sip_request *req, int sipmethod, char *uri, int reliable, struct sockaddr_in *sin, int ignore, char *mailbox, int mailboxlen) |
check_user_full: Check if matching user or peer is defined --- | |
static int | check_via (struct sip_pvt *p, struct sip_request *req) |
check Via: header for hostname, port and rport request/answer | |
static int | clear_realm_authentication (struct sip_auth *authlist) |
clear_realm_authentication: Clear realm authentication list (at reload) --- | |
static void | clear_sip_domains (void) |
clear_sip_domains: Clear our domain list (at reload) | |
static char * | complete_sip_debug_peer (char *line, char *word, int pos, int state) |
complete_sip_debug_peer: Support routine for 'sip debug peer' CLI --- | |
static char * | complete_sip_peer (char *word, int state, int flags2) |
complete_sip_peer: Do completion on peer name --- | |
static char * | complete_sip_prune_realtime_peer (char *line, char *word, int pos, int state) |
complete_sip_prune_realtime_peer: Support routine for 'sip prune realtime peer' CLI --- | |
static char * | complete_sip_prune_realtime_user (char *line, char *word, int pos, int state) |
complete_sip_prune_realtime_user: Support routine for 'sip prune realtime user' CLI --- | |
static char * | complete_sip_show_peer (char *line, char *word, int pos, int state) |
complete_sip_show_peer: Support routine for 'sip show peer' CLI --- | |
static char * | complete_sip_show_user (char *line, char *word, int pos, int state) |
complete_sip_show_user: Support routine for 'sip show user' CLI --- | |
static char * | complete_sip_user (char *word, int state, int flags2) |
complete_sip_user: Do completion on user name --- | |
static char * | complete_sipch (char *line, char *word, int pos, int state) |
complete_sipch: Support routine for 'sip show channel' CLI --- | |
static char * | complete_sipnotify (char *line, char *word, int pos, int state) |
complete_sipnotify: Support routine for 'sip notify' CLI --- | |
static int | copy_all_header (struct sip_request *req, struct sip_request *orig, char *field) |
copy_all_header: Copy all headers from one request to another --- | |
static int | copy_header (struct sip_request *req, struct sip_request *orig, char *field) |
copy_header: Copy one header field from one request to another | |
static void | copy_request (struct sip_request *dst, struct sip_request *src) |
copy_request: copy SIP request (mostly used to save request for responses) --- | |
static int | copy_via_headers (struct sip_pvt *p, struct sip_request *req, struct sip_request *orig, char *field) |
copy_via_headers: Copy SIP VIA Headers from the request to the response --- | |
static int | create_addr (struct sip_pvt *dialog, char *opeer) |
create_addr: 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 *r, struct sip_peer *peer) |
create_addr_from_peer: create address structure from peer reference --- | |
char * | description () |
Provides a description of the module. | |
static void | destroy_association (struct sip_peer *peer) |
static int | determine_firstline_parts (struct sip_request *req) |
determine_firstline_parts: parse first line of incoming SIP request | |
static void * | do_monitor (void *data) |
do_monitor: 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) |
do_proxy_auth: Add authentication on outbound SIP packet --- | |
static int | do_register_auth (struct sip_pvt *p, struct sip_request *req, char *header, char *respheader) |
do_register_auth: Authenticate for outbound registration --- | |
static const char * | domain_mode_to_text (const enum domain_mode mode) |
static const char * | dtmfmode2str (int mode) |
dtmfmode2str: Convert DTMF mode to printable string --- | |
static int | expire_register (void *data) |
expire_register: Expire registration of SIP peer --- | |
static void | extract_uri (struct sip_pvt *p, struct sip_request *req) |
extract_uri: Check Contact: URI of SIP message --- | |
static char * | find_alias (const char *name, char *_default) |
static struct sip_pvt * | find_call (struct sip_request *req, struct sockaddr_in *sin, const int intended_method) |
find_call: Connect incoming SIP message to current dialog or create new dialog structure | |
static struct sip_peer * | find_peer (const char *peer, struct sockaddr_in *sin, int realtime) |
find_peer: 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, char *realm) |
find_realm_authentication: Find authentication for a specific realm --- | |
int | find_sip_method (char *msg) |
find_sip_method: Find SIP method from header Strictly speaking, SIP methods are case SENSITIVE, but we don't check following Jon Postel's rule: Be gentle in what you accept, strict with what you send | |
static const struct cfsubscription_types * | find_subscription_type (enum subscriptiontype subtype) |
find_subscription_type: Find subscription type in array | |
static struct sip_user * | find_user (const char *name, int realtime) |
find_user: 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) |
free_old_route: Remove route from route list --- | |
static char * | func_check_sipdomain (struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) |
function_check_sipdomain: Dial plan function to check if domain is local | |
static char * | func_header_read (struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) |
func_header_read: Read SIP header (dialplan function) | |
static char * | function_sipchaninfo_read (struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) |
function_sipchaninfo_read: ${SIPCHANINFO()} Dialplan function - reads sip channel data | |
static char * | function_sippeer (struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) |
function_sippeer: ${SIPPEER()} Dialplan function - reads peer data | |
static int | get_also_info (struct sip_pvt *p, struct sip_request *oreq) |
get_also_info: Call transfer support (old way, depreciated)-- | |
static char * | get_calleridname (char *input, char *output, size_t outputsize) |
get_calleridname: Get caller id name from SIP headers --- | |
static int | get_destination (struct sip_pvt *p, struct sip_request *oreq) |
get_destination: Find out who the call is for -- | |
static char * | get_header (struct sip_request *req, char *name) |
get_header: Get header from SIP request --- | |
static char * | get_in_brackets (char *tmp) |
get_in_brackets: Pick out text in brackets from character string --- | |
static int | get_msg_text (char *buf, int len, struct sip_request *req) |
get_msg_text: Get text out of a SIP MESSAGE packet --- | |
static int | get_rdnis (struct sip_pvt *p, struct sip_request *oreq) |
get_rdnis: get referring dnis --- | |
static int | get_refer_info (struct sip_pvt *sip_pvt, struct sip_request *outgoing_req) |
get_refer_info: Call transfer support (the REFER method) --- | |
static int | get_rpid_num (char *input, char *output, int maxlen) |
get_rpid_num: 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 char * | get_sdp (struct sip_request *req, char *name) |
get_sdp: Gets all kind of SIP message bodies, including SDP, but the name wrongly applies _only_ sdp | |
static char * | get_sdp_by_line (char *line, char *name, int nameLen) |
get_sdp_by_line: Reads one line of SIP message body | |
static char * | get_sdp_iterate (int *iterator, struct sip_request *req, char *name) |
static struct sip_pvt * | get_sip_pvt_byid_locked (char *callid) |
get_sip_pvt_byid_locked: Lock interface lock and find matching pvt lock --- | |
static char * | gettag (struct sip_request *req, char *header, char *tagbuf, int tagbufsize) |
gettag: Get tag from packet | |
static int | handle_common_options (struct ast_flags *flags, struct ast_flags *mask, struct ast_variable *v) |
handle_common_options: Handle flag-type options common to users and peers --- | |
static int | handle_request (struct sip_pvt *p, struct sip_request *req, struct sockaddr_in *sin, int *recount, int *nounlock) |
handle_request: Handle SIP requests (methods) --- | |
static int | handle_request_bye (struct sip_pvt *p, struct sip_request *req, int debug, int ignore) |
handle_request_bye: Handle incoming BYE request --- | |
static int | handle_request_cancel (struct sip_pvt *p, struct sip_request *req, int debug, int ignore) |
handle_request_cancel: Handle incoming CANCEL request --- | |
static void | handle_request_info (struct sip_pvt *p, struct sip_request *req) |
handle_request_info: Receive SIP INFO Message --- | |
static int | handle_request_invite (struct sip_pvt *p, struct sip_request *req, int debug, int ignore, int seqno, struct sockaddr_in *sin, int *recount, char *e) |
handle_request_invite: Handle incoming INVITE request | |
static int | handle_request_message (struct sip_pvt *p, struct sip_request *req, int debug, int ignore) |
handle_request_message: Handle incoming MESSAGE request --- | |
static int | handle_request_options (struct sip_pvt *p, struct sip_request *req, int debug) |
handle_request_options: 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) |
handle_request_refer: Handle incoming REFER request --- | |
static int | handle_request_register (struct sip_pvt *p, struct sip_request *req, int debug, int ignore, struct sockaddr_in *sin, char *e) |
handle_request_register: Handle incoming REGISTER request --- | |
static int | handle_request_subscribe (struct sip_pvt *p, struct sip_request *req, int debug, int ignore, struct sockaddr_in *sin, int seqno, char *e) |
handle_request_subscribe: 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_response: Handle SIP response in dialogue --- | |
static void | handle_response_invite (struct sip_pvt *p, int resp, char *rest, struct sip_request *req, int ignore, int seqno) |
handle_response_invite: Handle SIP response in dialogue --- | |
static int | handle_response_peerpoke (struct sip_pvt *p, int resp, char *rest, struct sip_request *req, int ignore, int seqno, int sipmethod) |
handle_response_peerpoke: Handle qualification responses (OPTIONS) | |
static int | handle_response_register (struct sip_pvt *p, int resp, char *rest, struct sip_request *req, int ignore, int seqno) |
handle_response_register: Handle responses on REGISTER to services --- | |
static char * | hangup_cause2sip (int cause) |
hangup_cause2sip: Convert Asterisk hangup causes to SIP codes | |
static int | hangup_sip2cause (int cause) |
hangup_sip2cause: Convert SIP hangup causes to Asterisk hangup causes --- | |
static int | init_req (struct sip_request *req, int sipmethod, char *recip) |
init_req: Initialize SIP request --- | |
static int | init_resp (struct sip_request *req, char *resp, struct sip_request *orig) |
init_resp: Initialize SIP response, based on SIP request --- | |
static void | initreqprep (struct sip_request *req, struct sip_pvt *p, int sipmethod) |
initreqprep: Initiate new SIP request to peer/user --- | |
static const char * | insecure2str (int port, int invite) |
insecure2str: Convert Insecure setting to printable string --- | |
char * | key () |
Returns the ASTERISK_GPL_KEY. | |
static void | list_route (struct sip_route *route) |
list_route: List all routes - mostly for debugging --- | |
int | load_module () |
Initialize the module. | |
static int | lws2sws (char *msgbuf, int len) |
lws2sws: Parse multiline SIP headers into one header | |
static void | make_our_tag (char *tagbuf, size_t len) |
static int | manager_sip_show_peer (struct mansession *s, struct message *m) |
manager_sip_show_peer: Show SIP peers in the manager API --- | |
static int | manager_sip_show_peers (struct mansession *s, struct message *m) |
manager_sip_show_peers: Show SIP peers in the manager API --- | |
static char * | nat2str (int nat) |
nat2str: Convert NAT setting to text string | |
static void | parse_copy (struct sip_request *dst, struct sip_request *src) |
parse_copy: Copy SIP request, parse it | |
static void | parse_moved_contact (struct sip_pvt *p, struct sip_request *req) |
parse_moved_contact: Parse 302 Moved temporalily response | |
static int | parse_ok_contact (struct sip_pvt *pvt, struct sip_request *req) |
parse_ok_contact: Parse contact header for 200 OK on INVITE --- | |
static enum parse_register_result | parse_register_contact (struct sip_pvt *pvt, struct sip_peer *p, struct sip_request *req) |
parse_register_contact: Parse contact header and save registration --- | |
static void | parse_request (struct sip_request *req) |
parse_request: Parse a SIP message ---- | |
unsigned int | parse_sip_options (struct sip_pvt *pvt, char *supported) |
parse_sip_options: Parse supported header in incoming packet | |
static int | peer_status (struct sip_peer *peer, char *status, int statuslen) |
peer_status: Report Peer status in character string | |
static void | print_codec_to_cli (int fd, struct ast_codec_pref *pref) |
print_codec_to_cli: Print codec list from preference to CLI/manager | |
static void | print_group (int fd, unsigned int group, int crlf) |
print_group: Print call group and pickup group --- | |
static int | process_sdp (struct sip_pvt *p, struct sip_request *req) |
process_sdp: Process SIP SDP and activate RTP channels--- | |
static struct sip_peer * | realtime_peer (const char *peername, 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) |
realtime_update_peer: Update peer object in realtime storage --- | |
static struct sip_user * | realtime_user (const char *username) |
realtime_user: 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_message: Receive SIP MESSAGE method messages --- | |
static void | reg_source_db (struct sip_peer *peer) |
reg_source_db: Get registration details from Asterisk DB --- | |
static void | register_peer_exten (struct sip_peer *peer, int onoff) |
register_peer_exten: Automatically add peer extension to dial plan --- | |
static int | register_verify (struct sip_pvt *p, struct sockaddr_in *sin, struct sip_request *req, char *uri, int ignore) |
register_verify: Verify registration of user | |
static char * | regstate2str (int regstate) |
int | reload (void) |
Reload stuff. | |
static int | reload_config (void) |
reload_config: 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_digest: reply to authentication for outbound registrations --- | |
static int | reqprep (struct sip_request *req, struct sip_pvt *p, int sipmethod, int seqno, int newbranch) |
reqprep: Initialize a SIP request response packet --- | |
static int | respprep (struct sip_request *resp, struct sip_pvt *p, char *msg, struct sip_request *req) |
respprep: Prepare SIP response packet --- | |
static int | restart_monitor (void) |
restart_monitor: Start the channel monitor thread --- | |
static int | retrans_pkt (void *data) |
retrans_pkt: Retransmit SIP message if no answer --- | |
static void | sdpLineNum_iterator_init (int *iterator) |
static int | send_request (struct sip_pvt *p, struct sip_request *req, int reliable, int seqno) |
send_request: Send SIP Request to the other part of the dialogue --- | |
static int | send_response (struct sip_pvt *p, struct sip_request *req, int reliable, int seqno) |
send_response: Transmit response on SIP request--- | |
static void | set_destination (struct sip_pvt *p, char *uri) |
set_destination: Set destination from SIP URI --- | |
static int | sip_addheader (struct ast_channel *chan, void *data) |
sip_addheader: Add a SIP header --- | |
static int | sip_addrcmp (char *name, struct sockaddr_in *sin) |
sip_addrcmp: Support routine for find_peer --- | |
static struct sip_pvt * | sip_alloc (char *callid, struct sockaddr_in *sin, int useglobal_nat, const int intended_method) |
sip_alloc: Allocate SIP_PVT structure and set defaults --- | |
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) |
sip_call: Initiate SIP call from PBX used from the dial() application | |
static int | sip_cancel_destroy (struct sip_pvt *p) |
sip_cancel_destroy: Cancel destruction of SIP call --- | |
static int | sip_debug_test_addr (struct sockaddr_in *addr) |
sip_debug_test_addr: See if we pass debug IP filter | |
static int | sip_debug_test_pvt (struct sip_pvt *p) |
sip_debug_test_pvt: Test PVT for debugging output | |
static void | sip_destroy (struct sip_pvt *p) |
sip_destroy: Destroy SIP call structure --- | |
static void | sip_destroy_peer (struct sip_peer *peer) |
sip_destroy_peer: Destroy peer object from memory | |
static void | sip_destroy_user (struct sip_user *user) |
sip_destroy_user: Remove user object from in-memory storage --- | |
static int | sip_devicestate (void *data) |
sip_devicestate: Part of PBX channel interface --- | |
static int | sip_do_debug (int fd, int argc, char *argv[]) |
sip_do_debug: Turn on SIP debugging (CLI command) | |
static int | sip_do_debug_ip (int fd, int argc, char *argv[]) |
sip_do_debug: 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[]) |
sip_do_history: Enable SIP History logging (CLI) --- | |
static int | sip_do_reload (void) |
sip_do_reload: Reload module | |
static int | sip_dtmfmode (struct ast_channel *chan, void *data) |
sip_dtmfmode: change the DTMFmode for a SIP call (application) --- | |
static void | sip_dump_history (struct sip_pvt *dialog) |
dump_history: 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) |
sip_get_codec: Return SIP UA's codec (part of the RTP interface) --- | |
static struct ast_rtp * | sip_get_rtp_peer (struct ast_channel *chan) |
sip_get_rtp_peer: Returns null if we can't reinvite (part of RTP interface) | |
static struct ast_rtp * | sip_get_vrtp_peer (struct ast_channel *chan) |
sip_get_vrtp_peer: Returns null if we can't reinvite video (part of RTP interface) | |
static int | sip_getheader (struct ast_channel *chan, void *data) |
sip_getheader: Get a SIP header (dialplan app) --- | |
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) |
sip_indicate: 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 struct ast_channel * | sip_new (struct sip_pvt *i, int state, char *title) |
sip_new: Initiate a call in the SIP channel | |
static int | sip_no_debug (int fd, int argc, char *argv[]) |
sip_no_debug: Disable SIP Debugging in CLI --- | |
static int | sip_no_history (int fd, int argc, char *argv[]) |
sip_no_history: Disable SIP History logging (CLI) --- | |
static int | sip_notify (int fd, int argc, char *argv[]) |
sip_notify: Send SIP notify to peer | |
static int | sip_park (struct ast_channel *chan1, struct ast_channel *chan2, struct sip_request *req) |
sip_park: Park a call --- | |
static void * | sip_park_thread (void *stuff) |
sip_park_thread: Park SIP call support function | |
static void | sip_poke_all_peers (void) |
sip_poke_all_peers: Send a poke to all known peers | |
static int | sip_poke_noanswer (void *data) |
sip_poke_noanswer: No answer to Qualify poke --- | |
static int | sip_poke_peer (struct sip_peer *peer) |
sip_poke_peer: Check availability of peer, also keep NAT open --- | |
static int | sip_poke_peer_s (void *data) |
static int | sip_prune_realtime (int fd, int argc, char *argv[]) |
sip_prune_realtime: Remove temporary realtime objects from memory (CLI) --- | |
static struct ast_frame * | sip_read (struct ast_channel *ast) |
sip_read: Read SIP RTP from channel | |
static int | sip_reg_timeout (void *data) |
sip_reg_timeout: Registration timeout, register again | |
static int | sip_register (char *value, int lineno) |
sip_register: Parse register=> line in sip.conf and add to registry | |
static void | sip_registry_destroy (struct sip_registry *reg) |
sip_registry_destroy: Destroy registry object --- | |
static int | sip_reload (int fd, int argc, char *argv[]) |
sip_reload: Force reload of module from cli --- | |
static struct ast_channel * | sip_request_call (const char *type, int format, void *data, int *cause) |
sip_request: PBX interface function -build SIP pvt structure --- | |
static int | sip_reregister (void *data) |
sip_reregister: Update registration with SIP Proxy--- | |
static struct ast_frame * | sip_rtp_read (struct ast_channel *ast, struct sip_pvt *p) |
sip_rtp_read: Read RTP from network --- | |
static int | sip_scheddestroy (struct sip_pvt *p, int ms) |
sip_scheddestroy: Schedule destruction of SIP call --- | |
static void | sip_send_all_registers (void) |
sip_send_all_registers: Send all known registrations | |
static int | sip_send_mwi_to_peer (struct sip_peer *peer) |
sip_send_mwi_to_peer: Send message waiting indication --- | |
static int | sip_senddigit (struct ast_channel *ast, char digit) |
sip_senddigit: Send DTMF character on SIP channel | |
static int | sip_sendtext (struct ast_channel *ast, const char *text) |
sip_sendtext: Send SIP MESSAGE text within a call --- | |
static int | sip_set_rtp_peer (struct ast_channel *chan, struct ast_rtp *rtp, struct ast_rtp *vrtp, int codecs, int nat_active) |
sip_set_rtp_peer: Set the RTP peer for this call --- | |
static int | sip_show_channel (int fd, int argc, char *argv[]) |
sip_show_channel: Show details of one call --- | |
static int | sip_show_channels (int fd, int argc, char *argv[]) |
sip_show_channels: Show active SIP channels --- | |
static int | sip_show_domains (int fd, int argc, char *argv[]) |
static int | sip_show_history (int fd, int argc, char *argv[]) |
sip_show_history: Show history details of one call --- | |
static int | sip_show_inuse (int fd, int argc, char *argv[]) |
sip_show_inuse: CLI Command to show calls within limits set by call_limit --- | |
static int | sip_show_objects (int fd, int argc, char *argv[]) |
sip_show_objects: List all allocated SIP Objects --- | |
static int | sip_show_peer (int fd, int argc, char *argv[]) |
sip_show_peer: Show one peer in detail --- | |
static int | sip_show_peers (int fd, int argc, char *argv[]) |
sip_show_peers: CLI Show Peers command | |
static int | sip_show_registry (int fd, int argc, char *argv[]) |
sip_show_registry: Show SIP Registry (registrations with other SIP proxies --- | |
static int | sip_show_settings (int fd, int argc, char *argv[]) |
sip_show_settings: List global settings for the SIP channel --- | |
static int | sip_show_subscriptions (int fd, int argc, char *argv[]) |
sip_show_subscriptions: Show active SIP subscriptions --- | |
static int | sip_show_user (int fd, int argc, char *argv[]) |
sip_show_user: Show one user in detail --- | |
static int | sip_show_users (int fd, int argc, char *argv[]) |
sip_show_users: CLI Command 'SIP Show Users' --- | |
static int | sip_sipredirect (struct sip_pvt *p, const char *dest) |
sip_sipredirect: Transfer call before connect with a 302 redirect --- | |
static int | sip_transfer (struct ast_channel *ast, const char *dest) |
sip_transfer: Transfer SIP call | |
static int | sip_write (struct ast_channel *ast, struct ast_frame *frame) |
sip_write: Send frame to media channel (rtp) --- | |
static int | sipsock_read (int *id, int fd, short events, void *ignore) |
sipsock_read: Read data from SIP socket --- | |
static const char * | subscription_type2str (enum subscriptiontype subtype) |
subscription_type2str: Show subscription type in string format | |
static struct sip_peer * | temp_peer (const char *name) |
temp_peer: Create temporary peer (used in autocreatepeer mode) --- | |
static force_inline int | thread_safe_rand (void) |
Thread-safe random number generator. | |
static int | transmit_info_with_digit (struct sip_pvt *p, char digit) |
transmit_info_with_digit: Send SIP INFO dtmf message, see Cisco documentation on cisco.co m --- | |
static int | transmit_info_with_vidupdate (struct sip_pvt *p) |
transmit_info_with_vidupdate: Send SIP INFO with video update request --- | |
static int | transmit_invite (struct sip_pvt *p, int sipmethod, int sdp, int init) |
transmit_invite: Build REFER/INVITE/OPTIONS message and transmit it --- | |
static int | transmit_message_with_text (struct sip_pvt *p, const char *text) |
transmit_message_with_text: Transmit text with SIP MESSAGE method --- | |
static int | transmit_notify_with_mwi (struct sip_pvt *p, int newmsgs, int oldmsgs, char *vmexten) |
transmit_notify_with_mwi: Notify user of messages waiting in voicemail --- | |
static int | transmit_notify_with_sipfrag (struct sip_pvt *p, int cseq) |
transmit_notify_with_sipfrag: Notify a transferring party of the status of trasnfer --- | |
static int | transmit_refer (struct sip_pvt *p, const char *dest) |
transmit_refer: Transmit SIP REFER message --- | |
static int | transmit_register (struct sip_registry *r, int sipmethod, char *auth, char *authheader) |
transmit_register: Transmit register to SIP proxy or UA --- | |
static int | transmit_reinvite_with_sdp (struct sip_pvt *p) |
transmit_reinvite_with_sdp: Transmit reinvite with SDP :-) --- | |
static int | transmit_request (struct sip_pvt *p, int sipmethod, int seqno, int reliable, int newbranch) |
transmit_request: transmit generic SIP request --- | |
static int | transmit_request_with_auth (struct sip_pvt *p, int sipmethod, int seqno, int reliable, int newbranch) |
transmit_request_with_auth: Transmit SIP request, auth added --- | |
static int | transmit_response (struct sip_pvt *p, char *msg, struct sip_request *req) |
transmit_response: Transmit response, no retransmits | |
static int | transmit_response_reliable (struct sip_pvt *p, char *msg, struct sip_request *req, int fatal) |
transmit_response_reliable: Transmit response, Make sure you get a reply | |
static int | transmit_response_with_allow (struct sip_pvt *p, char *msg, struct sip_request *req, int reliable) |
transmit_response_with_allow: Append Accept header, content length before transmitting response --- | |
static int | transmit_response_with_auth (struct sip_pvt *p, char *msg, struct sip_request *req, char *rand, int reliable, char *header, int stale) |
static int | transmit_response_with_date (struct sip_pvt *p, char *msg, struct sip_request *req) |
transmit_response_with_date: Append date and content length before transmitting response --- | |
static int | transmit_response_with_sdp (struct sip_pvt *p, char *msg, struct sip_request *req, int retrans) |
transmit_response_with_sdp: Used for 200 OK and 183 early media --- | |
static int | transmit_response_with_unsupported (struct sip_pvt *p, char *msg, struct sip_request *req, char *unsupported) |
transmit_response_with_unsupported: Transmit response, no retransmits | |
static int | transmit_sip_request (struct sip_pvt *p, struct sip_request *req) |
transmit_sip_request: Transmit SIP request | |
static int | transmit_state_notify (struct sip_pvt *p, int state, int full, int substate) |
transmit_state_notify: 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. | |
int | unload_module () |
Cleanup all module structures, sockets, etc. | |
static int | update_call_counter (struct sip_pvt *fup, int event) |
update_call_counter: Handle call_limit for SIP users Note: This is going to be replaced by app_groupcount Thought: For realtime, we should propably update storage with inuse counter... | |
static void | update_peer (struct sip_peer *p, int expiry) |
update_peer: Update peer data in database (if used) --- | |
int | usecount () |
Provides a usecount. | |
Variables | |
static struct in_addr | __ourip |
static const struct cfalias | aliases [] |
Structure for conversion between compressed SIP and "normal" SIP. | |
int | allow_external_domains |
static int | apeerobjs = 0 |
static char * | app_dtmfmode = "SIPDtmfMode" |
static char * | app_sipaddheader = "SIPAddHeader" |
static char * | app_sipgetheader = "SIPGetHeader" |
static struct sip_auth * | authl |
static int | autocreatepeer = 0 |
static struct sockaddr_in | bindaddr = { 0, } |
static int | callevents = 0 |
static const char | channeltype [] = "SIP" |
static struct ast_custom_function | checksipdomain_function |
static int | compactheaders = 0 |
static const char | config [] = "sip.conf" |
static char | debug_usage [] |
static struct sockaddr_in | debugaddr |
static char | default_callerid [AST_MAX_EXTENSION] = DEFAULT_CALLERID |
static char | default_context [AST_MAX_CONTEXT] = DEFAULT_CONTEXT |
static int | default_expiry = DEFAULT_DEFAULT_EXPIRY |
static char | default_fromdomain [AST_MAX_EXTENSION] = "" |
static char | default_language [MAX_LANGUAGE] = "" |
static char | default_notifymime [AST_MAX_EXTENSION] = DEFAULT_NOTIFYMIME |
static int | default_qualify = 0 |
static char | default_subscribecontext [AST_MAX_CONTEXT] |
static char | default_useragent [AST_MAX_EXTENSION] = DEFAULT_USERAGENT |
static const char | desc [] = "Session Initiation Protocol (SIP)" |
static char * | descrip_dtmfmode = "SIPDtmfMode(inband|info|rfc2833): Changes the dtmfmode for a SIP call\n" |
static char * | descrip_sipaddheader |
static char * | descrip_sipgetheader |
static int | dumphistory = 0 |
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 = 1 |
static int | global_capability = AST_FORMAT_ULAW | AST_FORMAT_ALAW | AST_FORMAT_GSM | AST_FORMAT_H263 |
Codecs that we support by default:. | |
static struct ast_flags | global_flags = {0} |
static struct ast_flags | global_flags_page2 = {0} |
static char | global_musicclass [MAX_MUSICCLASS] = "" |
static int | global_mwitime = DEFAULT_MWITIME |
static int | global_notifyringing = 1 |
static char | global_realm [MAXHOSTNAMELEN] = DEFAULT_REALM |
static int | global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT |
static int | global_regattempts_max = 0 |
static int | global_rtautoclear |
static int | global_rtpholdtimeout = 0 |
static int | global_rtpkeepalive = 0 |
static int | global_rtptimeout = 0 |
static char | global_vmexten [AST_MAX_EXTENSION] = DEFAULT_VMEXTEN |
static char | history_usage [] |
static struct sip_pvt * | iflist |
sip_pvt: PVT structures are used for each SIP conversation, ie. a call | |
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 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 struct ast_cli_entry | my_clis [] |
static char | no_debug_usage [] |
static char | no_history_usage [] |
static int | noncodeccapability = AST_RTP_DTMF |
static const char | notify_config [] = "sip_notify.conf" |
ast_config * | notify_types |
static char | notify_usage [] |
static int | ourport |
static struct sockaddr_in | outboundproxyip |
static int | pedanticsipchecking = 0 |
static struct ast_peer_list | peerl |
The peer list: Peers and Friends ---. | |
static struct ast_codec_pref | prefs |
static char | prune_realtime_usage [] |
static int | recordhistory = 0 |
static char | regcontext [AST_MAX_CONTEXT] = "" |
static struct ast_register_list | regl |
The register list: Other SIP proxys we register with and call ---. | |
static int | regobjs = 0 |
static int | relaxdtmf = 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 |
enum sipmethod | sip_method_list |
static const struct cfsip_methods | sip_methods [] |
static const 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 = 0 |
static struct ast_rtp_protocol | sip_rtp |
sip_rtp: Interface structure with callbacks used to connect to rtp module -- | |
static const struct ast_channel_tech | sip_tech |
Definition of this channel for PBX channel registration. | |
static struct ast_custom_function | sipchaninfo_function |
static int | sipdebug = 0 |
ast_custom_function | sippeer_function |
static int | sipsock = -1 |
static int | speerobjs = 0 |
static int | srvlookup = 0 |
static const 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 char * | synopsis_sipgetheader = "Get a SIP header from an incoming call" |
static int | tos = 0 |
static int | usecnt = 0 |
static struct ast_user_list | userl |
The user list: Users and friends ---. | |
static int | videosupport = 0 |
Implementation of RFC 3261 - without S/MIME, TCP and TLS support Configuration file sip.conf
SIP over TLS
Better support of forking
Definition in file chan_sip.c.
|
SIP Methods we support.
Definition at line 321 of file chan_sip.c. Referenced by respprep(), transmit_invite(), and transmit_reinvite_with_sdp(). |
|
Definition at line 125 of file chan_sip.c. |
|
Definition at line 139 of file chan_sip.c. Referenced by ael_debug_read(), and ast_ael_compile(). |
|
Definition at line 140 of file chan_sip.c. |
|
Definition at line 441 of file chan_sip.c. Referenced by handle_request_invite(), handle_response(), sip_hangup(), and update_call_counter(). |
|
Definition at line 340 of file chan_sip.c. Referenced by reload_config(). |
|
Definition at line 331 of file chan_sip.c. Referenced by reload_config(). |
|
Definition at line 101 of file chan_sip.c. Referenced by reload_config(). |
|
Expire slowly Definition at line 432 of file chan_sip.c. |
|
Definition at line 131 of file chan_sip.c. |
|
Definition at line 130 of file chan_sip.c. |
|
Definition at line 102 of file chan_sip.c. Referenced by reload_config(). |
|
Definition at line 104 of file chan_sip.c. Referenced by reqprep(), and transmit_register(). |
|
Definition at line 129 of file chan_sip.c. |
|
Definition at line 382 of file chan_sip.c. Referenced by reload_config(). |
|
Definition at line 345 of file chan_sip.c. Referenced by reload_config(). |
|
Definition at line 428 of file chan_sip.c. Referenced by reload_config(). |
|
Definition at line 103 of file chan_sip.c. Referenced by reload_config(). |
|
Definition at line 133 of file chan_sip.c. |
|
From RFC 3261 (former 2543) Definition at line 326 of file chan_sip.c. Referenced by build_peer(), check_via(), create_addr(), parse_ok_contact(), parse_register_contact(), reload_config(), set_destination(), sip_show_registry(), and temp_peer(). |
|
Definition at line 90 of file chan_sip.c. Referenced by reload_config(). |
|
Definition at line 335 of file chan_sip.c. Referenced by reload_config(). |
|
Definition at line 109 of file chan_sip.c. |
|
Definition at line 111 of file chan_sip.c. |
|
Definition at line 115 of file chan_sip.c. |
|
Definition at line 108 of file chan_sip.c. |
|
Definition at line 696 of file chan_sip.c. Referenced by __sip_reliable_xmit(), and retrans_pkt(). |
|
Definition at line 695 of file chan_sip.c. Referenced by __sip_ack(), __sip_pretend_ack(), __sip_semi_ack(), handle_request(), and retrans_pkt(). |
|
sip_show_domains: CLI command to list local domains
Definition at line 7824 of file chan_sip.c. |
|
sip_show_domains: CLI command to list local domains
Definition at line 7824 of file chan_sip.c. |
|
sip_show_domains: CLI command to list local domains
Definition at line 7824 of file chan_sip.c. |
|
sip_show_domains: CLI command to list local domains
Definition at line 7824 of file chan_sip.c. |
|
sip_show_domains: CLI command to list local domains
Definition at line 7824 of file chan_sip.c. |
|
sip_show_domains: CLI command to list local domains
Definition at line 7824 of file chan_sip.c. |
|
|
|
|
|
|
|
|
|
Referenced by __sip_show_channels(). |
|
Definition at line 442 of file chan_sip.c. Referenced by handle_request_invite(), sip_call(), sip_hangup(), and update_call_counter(). |
|
Definition at line 95 of file chan_sip.c. |
|
Definition at line 122 of file chan_sip.c. |
|
Definition at line 136 of file chan_sip.c. Referenced by handle_response(), handle_response_invite(), and handle_response_register(). |
|
Definition at line 135 of file chan_sip.c. |
|
Definition at line 148 of file chan_sip.c. |
|
Definition at line 265 of file chan_sip.c. |
|
Definition at line 804 of file chan_sip.c. Referenced by registry_rerequest(), regstate2str(), and transmit_register(). |
|
Definition at line 809 of file chan_sip.c. Referenced by regstate2str(), and sip_reg_timeout(). |
|
Definition at line 808 of file chan_sip.c. Referenced by registry_rerequest(), and regstate2str(). |
|
Definition at line 805 of file chan_sip.c. Referenced by handle_response_register(), iax2_ack_registry(), and regstate2str(). |
|
Definition at line 803 of file chan_sip.c. Referenced by iax2_do_register(), regstate2str(), and transmit_register(). |
|
Definition at line 806 of file chan_sip.c. Referenced by regstate2str(), and socket_read(). |
|
Definition at line 807 of file chan_sip.c. Referenced by attempt_transmit(), and regstate2str(). |
|
Definition at line 802 of file chan_sip.c. Referenced by regstate2str(), and sip_reg_timeout(). |
|
Definition at line 147 of file chan_sip.c. |
|
Whether or not we've already been destroyed by our peer Definition at line 512 of file chan_sip.c. Referenced by handle_request(), handle_request_bye(), handle_request_cancel(), handle_request_invite(), handle_request_refer(), handle_response(), handle_response_invite(), retrans_pkt(), sip_hangup(), sip_indicate(), and sip_sipredirect(). |
|
Definition at line 560 of file chan_sip.c. Referenced by check_user_full(), create_addr_from_peer(), and update_call_counter(). |
|
Definition at line 559 of file chan_sip.c. Referenced by __sip_show_channels(), and process_sdp(). |
|
allow peers to be reinvited to send media directly p2p Definition at line 542 of file chan_sip.c. Referenced by _sip_show_peer(), handle_common_options(), reload_config(), sip_get_rtp_peer(), and sip_get_vrtp_peer(). |
|
Definition at line 413 of file chan_sip.c. Referenced by reload_config(). |
|
Definition at line 414 of file chan_sip.c. Referenced by sip_do_debug(), sip_do_debug_ip(), sip_do_debug_peer(), and sip_no_debug(). |
|
three settings, uses two bits Definition at line 529 of file chan_sip.c. Referenced by _sip_show_peer(), check_user_full(), create_addr_from_peer(), handle_common_options(), process_sdp(), sip_alloc(), sip_dtmfmode(), sip_new(), sip_rtp_read(), sip_senddigit(), sip_show_channel(), and sip_show_settings(). |
|
AUTO switch between rfc2833 and in-band DTMF Definition at line 533 of file chan_sip.c. Referenced by check_user_full(), create_addr_from_peer(), dtmfmode2str(), handle_common_options(), process_sdp(), and sip_alloc(). |
|
Inband audio, only for ULAW/ALAW Definition at line 531 of file chan_sip.c. Referenced by dtmfmode2str(), handle_common_options(), process_sdp(), sip_dtmfmode(), sip_new(), sip_rtp_read(), and sip_senddigit(). |
|
SIP Info messages Definition at line 532 of file chan_sip.c. Referenced by dtmfmode2str(), handle_common_options(), sip_dtmfmode(), and sip_senddigit(). |
|
RTP DTMF Definition at line 530 of file chan_sip.c. Referenced by check_user_full(), create_addr_from_peer(), dtmfmode2str(), handle_common_options(), process_sdp(), reload_config(), sip_alloc(), sip_dtmfmode(), sip_rtp_read(), and sip_senddigit(). |
|
Is this a dynamic peer? Definition at line 527 of file chan_sip.c. Referenced by _sip_show_peer(), _sip_show_peers(), build_peer(), function_sippeer(), register_verify(), and temp_peer(). |
|
Value: (SIP_PROMISCREDIR | SIP_TRUSTRPID | SIP_SENDRPID | SIP_DTMF | SIP_REINVITE | \ SIP_PROG_INBAND | SIP_OSPAUTH | SIP_USECLIENTCODE | SIP_NAT | \ SIP_USEREQPHONE | SIP_INSECURE_PORT | SIP_INSECURE_INVITE) Definition at line 566 of file chan_sip.c. Referenced by build_peer(), build_user(), check_user_full(), create_addr_from_peer(), sip_alloc(), sip_poke_peer(), and temp_peer(). |
|
Got a refer? Definition at line 519 of file chan_sip.c. Referenced by handle_request_refer(), and sip_set_rtp_peer(). |
|
Definition at line 564 of file chan_sip.c. Referenced by update_call_counter(). |
|
don't require authentication for incoming INVITEs Definition at line 546 of file chan_sip.c. Referenced by _sip_show_peer(), check_user_full(), and handle_common_options(). |
|
don't require matching port for incoming requests Definition at line 545 of file chan_sip.c. Referenced by _sip_show_peer(), handle_common_options(), and sip_addrcmp(). |
|
Max amount of SIP headers to read Definition at line 438 of file chan_sip.c. Referenced by add_blank_header(), add_header(), and parse_request(). |
|
Max amount of lines in SIP attachment (like SDP) Definition at line 439 of file chan_sip.c. Referenced by add_line(), and parse_request(). |
|
Also from RFC 3261 (2543), should sub headers tho Definition at line 327 of file chan_sip.c. |
|
four settings, uses two bits Definition at line 535 of file chan_sip.c. Referenced by __sip_xmit(), _sip_show_peer(), _sip_show_peers(), build_via(), check_user_full(), check_via(), copy_via_headers(), create_addr_from_peer(), handle_common_options(), parse_ok_contact(), parse_register_contact(), register_verify(), retrans_pkt(), send_request(), send_response(), sip_alloc(), sip_debug_test_pvt(), sip_show_channel(), and sip_show_settings(). |
|
Definition at line 539 of file chan_sip.c. Referenced by copy_via_headers(), handle_common_options(), and nat2str(). |
|
No nat support Definition at line 536 of file chan_sip.c. Referenced by handle_common_options(), and nat2str(). |
|
Definition at line 537 of file chan_sip.c. Referenced by build_via(), handle_common_options(), nat2str(), and reload_config(). |
|
Definition at line 538 of file chan_sip.c. Referenced by __sip_xmit(), _sip_show_peers(), check_user_full(), check_via(), create_addr_from_peer(), handle_common_options(), nat2str(), parse_ok_contact(), parse_register_contact(), retrans_pkt(), send_request(), send_response(), sip_alloc(), and sip_debug_test_pvt(). |
|
if we need to be destroyed Definition at line 513 of file chan_sip.c. Referenced by __sip_show_channels(), check_pendings(), do_monitor(), handle_request(), handle_request_bye(), handle_request_cancel(), handle_request_info(), handle_request_invite(), handle_request_options(), handle_request_subscribe(), handle_response(), handle_response_invite(), handle_response_peerpoke(), handle_response_register(), receive_message(), retrans_pkt(), sip_hangup(), sip_reg_timeout(), and sip_show_channel(). |
|
Do we need to send another reinvite? Definition at line 517 of file chan_sip.c. Referenced by check_pendings(), sip_hangup(), and sip_set_rtp_peer(). |
|
Didn't get video in invite, don't offer Definition at line 514 of file chan_sip.c. Referenced by process_sdp(), and sip_indicate(). |
|
Definition at line 268 of file chan_sip.c. |
|
Definition at line 270 of file chan_sip.c. |
|
Definition at line 278 of file chan_sip.c. |
|
Definition at line 279 of file chan_sip.c. |
|
Definition at line 271 of file chan_sip.c. |
|
Definition at line 272 of file chan_sip.c. |
|
Definition at line 274 of file chan_sip.c. |
|
Definition at line 273 of file chan_sip.c. |
|
Definition at line 275 of file chan_sip.c. |
|
Definition at line 267 of file chan_sip.c. |
|
Definition at line 276 of file chan_sip.c. |
|
Definition at line 277 of file chan_sip.c. |
|
Definition at line 280 of file chan_sip.c. |
|
Definition at line 269 of file chan_sip.c. |
|
four settings, uses two bits Definition at line 553 of file chan_sip.c. Referenced by check_auth(), check_user_full(), and handle_common_options(). |
|
Definition at line 557 of file chan_sip.c. Referenced by check_auth(), and handle_common_options(). |
|
Definition at line 555 of file chan_sip.c. Referenced by check_auth(), and handle_common_options(). |
|
Definition at line 554 of file chan_sip.c. Referenced by check_auth(). |
|
Definition at line 556 of file chan_sip.c. Referenced by check_auth(), and handle_common_options(). |
|
Is this an outgoing call? Definition at line 525 of file chan_sip.c. Referenced by handle_request_bye(), handle_request_invite(), handle_request_subscribe(), 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(), and update_call_counter(). |
|
Definition at line 575 of file chan_sip.c. Referenced by build_peer(), destroy_association(), reload_config(), and sip_show_settings(). |
|
Definition at line 576 of file chan_sip.c. Referenced by build_peer(), destroy_association(), parse_register_contact(), and reg_source_db(). |
|
Definition at line 574 of file chan_sip.c. Referenced by expire_register(), realtime_peer(), and reload_config(). |
|
Definition at line 572 of file chan_sip.c. Referenced by complete_sip_prune_realtime_peer(), complete_sip_prune_realtime_user(), realtime_peer(), realtime_user(), reload_config(), sip_prune_realtime(), sip_show_settings(), and update_peer(). |
|
Definition at line 573 of file chan_sip.c. Referenced by reload_config(), sip_show_settings(), and update_peer(). |
|
Need to send bye after we ack? Definition at line 518 of file chan_sip.c. Referenced by check_pendings(), handle_response_invite(), sip_hangup(), and sip_set_rtp_peer(). |
|
Debug this packet Definition at line 579 of file chan_sip.c. Referenced by sipsock_read(). |
|
This packet has a to-tag Definition at line 580 of file chan_sip.c. Referenced by find_call(), and handle_request(). |
|
three settings, uses two bits Definition at line 548 of file chan_sip.c. Referenced by handle_common_options(), sip_indicate(), and sip_show_settings(). |
|
Definition at line 549 of file chan_sip.c. Referenced by sip_indicate(), and sip_show_settings(). |
|
Definition at line 550 of file chan_sip.c. Referenced by handle_common_options(), and sip_show_settings(). |
|
Definition at line 551 of file chan_sip.c. Referenced by handle_common_options(), and sip_indicate(). |
|
Have sent 183 message progress Definition at line 516 of file chan_sip.c. Referenced by sip_indicate(), and sip_write(). |
|
Promiscuous redirection Definition at line 520 of file chan_sip.c. Referenced by _sip_show_peer(), handle_common_options(), parse_moved_contact(), sip_show_channel(), and sip_show_settings(). |
|
Flag for realtime users Definition at line 523 of file chan_sip.c. Referenced by build_peer(), parse_register_contact(), realtime_peer(), realtime_user(), sip_destroy_peer(), sip_destroy_user(), and update_peer(). |
|
two bits used Definition at line 541 of file chan_sip.c. Referenced by handle_common_options(). |
|
use UPDATE (RFC3311) when reinviting this peer Definition at line 543 of file chan_sip.c. Referenced by handle_common_options(), and transmit_reinvite_with_sdp(). |
|
Have sent 180 ringing Definition at line 515 of file chan_sip.c. Referenced by sip_indicate(). |
|
Definition at line 526 of file chan_sip.c. Referenced by expire_register(), sip_destroy_peer(), and temp_peer(). |
|
Definition at line 562 of file chan_sip.c. Referenced by _sip_show_peer(), and handle_common_options(). |
|
Trust RPID headers? Definition at line 521 of file chan_sip.c. Referenced by _sip_show_peer(), check_user_full(), and handle_common_options(). |
|
Trust X-ClientCode info message Definition at line 524 of file chan_sip.c. Referenced by handle_common_options(), handle_request_info(), and sip_show_settings(). |
|
Add user=phone to numeric URI. Default off Definition at line 522 of file chan_sip.c. Referenced by _sip_show_peer(), build_peer(), initreqprep(), reload_config(), and sip_show_settings(). |
|
Definition at line 100 of file chan_sip.c. |
|
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 264 of file chan_sip.c. |
|
SIP Extensions we support.
Definition at line 324 of file chan_sip.c. |
|
Definition at line 93 of file chan_sip.c. |
|
Definition at line 481 of file chan_sip.c. 00481 { 00482 SIP_DOMAIN_AUTO, /*!< This domain is auto-configured */ 00483 SIP_DOMAIN_CONFIG, /*!< This domain is from configuration */ 00484 };
|
|
Definition at line 5800 of file chan_sip.c. 05800 { 05801 PARSE_REGISTER_FAILED, 05802 PARSE_REGISTER_UPDATE, 05803 PARSE_REGISTER_QUERY, 05804 };
|
|
Definition at line 200 of file chan_sip.c. 00200 { 00201 PROXY_AUTH, 00202 WWW_AUTH, 00203 };
|
|
Definition at line 181 of file chan_sip.c. 00181 { 00182 SIP_UNKNOWN, 00183 SIP_RESPONSE, 00184 SIP_REGISTER, 00185 SIP_OPTIONS, 00186 SIP_NOTIFY, 00187 SIP_INVITE, 00188 SIP_ACK, 00189 SIP_PRACK, 00190 SIP_BYE, 00191 SIP_REFER, 00192 SIP_SUBSCRIBE, 00193 SIP_MESSAGE, 00194 SIP_UPDATE, 00195 SIP_INFO, 00196 SIP_CANCEL, 00197 SIP_PUBLISH, 00198 } sip_method_list;
|
|
Definition at line 158 of file chan_sip.c. 00158 { 00159 NONE = 0, 00160 TIMEOUT, 00161 XPIDF_XML, 00162 DIALOG_INFO_XML, 00163 CPIM_PIDF_XML, 00164 PIDF_XML 00165 };
|
|
Definition at line 2904 of file chan_sip.c. References sip_request::header, sip_request::headers, pass, and pedanticsipchecking. 02905 { 02906 int pass; 02907 02908 /* 02909 * Technically you can place arbitrary whitespace both before and after the ':' in 02910 * a header, although RFC3261 clearly says you shouldn't before, and place just 02911 * one afterwards. If you shouldn't do it, what absolute idiot decided it was 02912 * a good idea to say you can do it, and if you can do it, why in the hell would. 02913 * you say you shouldn't. 02914 * Anyways, pedanticsipchecking controls whether we allow spaces before ':', 02915 * and we always allow spaces after that for compatibility. 02916 */ 02917 for (pass = 0; name && pass < 2;pass++) { 02918 int x, len = strlen(name); 02919 for (x=*start; x<req->headers; x++) { 02920 if (!strncasecmp(req->header[x], name, len)) { 02921 char *r = req->header[x] + len; /* skip name */ 02922 if (pedanticsipchecking) 02923 r = ast_skip_blanks(r); 02924 02925 if (*r == ':') { 02926 *start = x+1; 02927 return ast_skip_blanks(r+1); 02928 } 02929 } 02930 } 02931 if (pass == 0) /* Try aliases */ 02932 name = find_alias(name, NULL); 02933 } 02934 02935 /* Don't return NULL, so get_header is always a valid pointer */ 02936 return ""; 02937 }
|
|
__sip_ack: Acknowledges receipt of a packet and stops retransmission ---
Definition at line 1355 of file chan_sip.c. References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_del(), ast_test_flag, sip_pvt::callid, sip_pkt::data, 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, and cfsip_methods::text. Referenced by __sip_pretend_ack(), handle_request(), and handle_response(). 01356 { 01357 struct sip_pkt *cur, *prev = NULL; 01358 int res = -1; 01359 int resetinvite = 0; 01360 /* Just in case... */ 01361 char *msg; 01362 01363 msg = sip_methods[sipmethod].text; 01364 01365 ast_mutex_lock(&p->lock); 01366 cur = p->packets; 01367 while(cur) { 01368 if ((cur->seqno == seqno) && ((ast_test_flag(cur, FLAG_RESPONSE)) == resp) && 01369 ((ast_test_flag(cur, FLAG_RESPONSE)) || 01370 (!strncasecmp(msg, cur->data, strlen(msg)) && (cur->data[strlen(msg)] < 33)))) { 01371 if (!resp && (seqno == p->pendinginvite)) { 01372 ast_log(LOG_DEBUG, "Acked pending invite %d\n", p->pendinginvite); 01373 p->pendinginvite = 0; 01374 resetinvite = 1; 01375 } 01376 /* this is our baby */ 01377 if (prev) 01378 prev->next = cur->next; 01379 else 01380 p->packets = cur->next; 01381 if (cur->retransid > -1) { 01382 if (sipdebug && option_debug > 3) 01383 ast_log(LOG_DEBUG, "** SIP TIMER: Cancelling retransmit of packet (reply received) Retransid #%d\n", cur->retransid); 01384 ast_sched_del(sched, cur->retransid); 01385 } 01386 free(cur); 01387 res = 0; 01388 break; 01389 } 01390 prev = cur; 01391 cur = cur->next; 01392 } 01393 ast_mutex_unlock(&p->lock); 01394 ast_log(LOG_DEBUG, "Stopping retransmission on '%s' of %s %d: Match %s\n", p->callid, resp ? "Response" : "Request", seqno, res ? "Not Found" : "Found"); 01395 return res; 01396 }
|
|
__sip_autodestruct: Kill a call (called by scheduler) ---
Definition at line 1299 of file chan_sip.c. References append_history(), AST_EXTENSION_DEACTIVATED, ast_log(), ast_queue_hangup(), sip_pvt::autokillid, sip_pvt::callid, LOG_DEBUG, LOG_WARNING, NONE, sip_pvt::owner, sip_destroy(), sip_pvt::subscribed, TIMEOUT, and transmit_state_notify(). Referenced by sip_scheddestroy(). 01300 { 01301 struct sip_pvt *p = data; 01302 01303 01304 /* If this is a subscription, tell the phone that we got a timeout */ 01305 if (p->subscribed) { 01306 p->subscribed = TIMEOUT; 01307 transmit_state_notify(p, AST_EXTENSION_DEACTIVATED, 1, 1); /* Send first notification */ 01308 p->subscribed = NONE; 01309 append_history(p, "Subscribestatus", "timeout"); 01310 return 10000; /* Reschedule this destruction so that we know that it's gone */ 01311 } 01312 01313 /* This scheduled event is now considered done. */ 01314 p->autokillid = -1; 01315 01316 ast_log(LOG_DEBUG, "Auto destroying call '%s'\n", p->callid); 01317 append_history(p, "AutoDestroy", ""); 01318 if (p->owner) { 01319 ast_log(LOG_WARNING, "Autodestruct on call '%s' with owner in place\n", p->callid); 01320 ast_queue_hangup(p->owner); 01321 } else { 01322 sip_destroy(p); 01323 } 01324 return 0; 01325 }
|
|
__sip_destroy: Execute destrucion of call structure, release memory---
Definition at line 2096 of file chan_sip.c. References ast_extension_state_del(), ast_log(), ast_mutex_destroy(), ast_mutex_lock(), ast_mutex_unlock(), ast_rtp_destroy(), ast_sched_del(), ast_variables_destroy(), ast_verbose(), ASTOBJ_UNREF, sip_pvt::callid, free, free_old_route(), iflist, LOG_DEBUG, LOG_WARNING, sip_pvt::next, oh323_pvt::next, sip_history::next, sip_pkt::retransid, sched, sip_debug_test_pvt(), sip_dump_history(), and sip_registry_destroy(). Referenced by do_monitor(), and sip_destroy(). 02097 { 02098 struct sip_pvt *cur, *prev = NULL; 02099 struct sip_pkt *cp; 02100 struct sip_history *hist; 02101 02102 if (sip_debug_test_pvt(p)) 02103 ast_verbose("Destroying call '%s'\n", p->callid); 02104 02105 if (dumphistory) 02106 sip_dump_history(p); 02107 02108 if (p->options) 02109 free(p->options); 02110 02111 if (p->stateid > -1) 02112 ast_extension_state_del(p->stateid, NULL); 02113 if (p->initid > -1) 02114 ast_sched_del(sched, p->initid); 02115 if (p->autokillid > -1) 02116 ast_sched_del(sched, p->autokillid); 02117 02118 if (p->rtp) { 02119 ast_rtp_destroy(p->rtp); 02120 } 02121 if (p->vrtp) { 02122 ast_rtp_destroy(p->vrtp); 02123 } 02124 if (p->route) { 02125 free_old_route(p->route); 02126 p->route = NULL; 02127 } 02128 if (p->registry) { 02129 if (p->registry->call == p) 02130 p->registry->call = NULL; 02131 ASTOBJ_UNREF(p->registry,sip_registry_destroy); 02132 } 02133 02134 if (p->rpid) 02135 free(p->rpid); 02136 02137 if (p->rpid_from) 02138 free(p->rpid_from); 02139 02140 /* Unlink us from the owner if we have one */ 02141 if (p->owner) { 02142 if (lockowner) 02143 ast_mutex_lock(&p->owner->lock); 02144 ast_log(LOG_DEBUG, "Detaching from %s\n", p->owner->name); 02145 p->owner->tech_pvt = NULL; 02146 if (lockowner) 02147 ast_mutex_unlock(&p->owner->lock); 02148 } 02149 /* Clear history */ 02150 while(p->history) { 02151 hist = p->history; 02152 p->history = p->history->next; 02153 free(hist); 02154 } 02155 02156 cur = iflist; 02157 while(cur) { 02158 if (cur == p) { 02159 if (prev) 02160 prev->next = cur->next; 02161 else 02162 iflist = cur->next; 02163 break; 02164 } 02165 prev = cur; 02166 cur = cur->next; 02167 } 02168 if (!cur) { 02169 ast_log(LOG_WARNING, "Trying to destroy \"%s\", not found in dialog list?!?! \n", p->callid); 02170 return; 02171 } 02172 if (p->initid > -1) 02173 ast_sched_del(sched, p->initid); 02174 02175 while((cp = p->packets)) { 02176 p->packets = p->packets->next; 02177 if (cp->retransid > -1) { 02178 ast_sched_del(sched, cp->retransid); 02179 } 02180 free(cp); 02181 } 02182 if (p->chanvars) { 02183 ast_variables_destroy(p->chanvars); 02184 p->chanvars = NULL; 02185 } 02186 ast_mutex_destroy(&p->lock); 02187 free(p); 02188 }
|
|
__sip_do_register: Register with SIP proxy ---
Definition at line 5270 of file chan_sip.c. References SIP_REGISTER, and transmit_register(). Referenced by sip_reregister(). 05271 { 05272 int res; 05273 05274 res = transmit_register(r, SIP_REGISTER, NULL, NULL); 05275 return res; 05276 }
|
|
Definition at line 1399 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, and sip_methods. Referenced by sip_hangup(), and sip_reg_timeout(). 01400 { 01401 struct sip_pkt *cur=NULL; 01402 01403 while(p->packets) { 01404 if (cur == p->packets) { 01405 ast_log(LOG_WARNING, "Have a packet that doesn't want to give up! %s\n", sip_methods[cur->method].text); 01406 return -1; 01407 } 01408 cur = p->packets; 01409 if (cur->method) 01410 __sip_ack(p, p->packets->seqno, (ast_test_flag(p->packets, FLAG_RESPONSE)), cur->method); 01411 else { /* Unknown packet type */ 01412 char *c; 01413 char method[128]; 01414 ast_copy_string(method, p->packets->data, sizeof(method)); 01415 c = ast_skip_blanks(method); /* XXX what ? */ 01416 *c = '\0'; 01417 __sip_ack(p, p->packets->seqno, (ast_test_flag(p->packets, FLAG_RESPONSE)), find_sip_method(method)); 01418 } 01419 } 01420 return 0; 01421 }
|
|
__sip_reliable_xmit: transmit packet with retransmits ---
Definition at line 1260 of file chan_sip.c. References __sip_xmit(), ast_log(), ast_sched_add_variable(), ast_set_flag, sip_pkt::data, DEFAULT_RETRANS, FLAG_FATAL, sip_pkt::flags, LOG_DEBUG, malloc, sip_pkt::method, sip_pkt::next, option_debug, sip_pkt::owner, sip_pkt::packetlen, sip_pvt::packets, sip_pvt::pendinginvite, retrans_pkt(), sched, sip_pkt::seqno, SIP_INVITE, sip_pvt::timer_t1, and sip_pkt::timer_t1. Referenced by send_request(), and send_response(). 01261 { 01262 struct sip_pkt *pkt; 01263 int siptimer_a = DEFAULT_RETRANS; 01264 01265 pkt = malloc(sizeof(struct sip_pkt) + len + 1); 01266 if (!pkt) 01267 return -1; 01268 memset(pkt, 0, sizeof(struct sip_pkt)); 01269 memcpy(pkt->data, data, len); 01270 pkt->method = sipmethod; 01271 pkt->packetlen = len; 01272 pkt->next = p->packets; 01273 pkt->owner = p; 01274 pkt->seqno = seqno; 01275 pkt->flags = resp; 01276 pkt->data[len] = '\0'; 01277 pkt->timer_t1 = p->timer_t1; /* Set SIP timer T1 */ 01278 if (fatal) 01279 ast_set_flag(pkt, FLAG_FATAL); 01280 if (pkt->timer_t1) 01281 siptimer_a = pkt->timer_t1 * 2; 01282 01283 /* Schedule retransmission */ 01284 pkt->retransid = ast_sched_add_variable(sched, siptimer_a, retrans_pkt, pkt, 1); 01285 if (option_debug > 3 && sipdebug) 01286 ast_log(LOG_DEBUG, "*** SIP TIMER: Initalizing retransmit timer on packet: Id #%d\n", pkt->retransid); 01287 pkt->next = p->packets; 01288 p->packets = pkt; 01289 01290 __sip_xmit(pkt->owner, pkt->data, pkt->packetlen); /* Send packet */ 01291 if (sipmethod == SIP_INVITE) { 01292 /* Note this is a pending invite */ 01293 p->pendinginvite = seqno; 01294 } 01295 return 0; 01296 }
|
|
__sip_semi_ack: Acks receipt of packet, keep it around (used for provisional responses) ---
Definition at line 1424 of file chan_sip.c. References ast_log(), ast_sched_del(), ast_test_flag, sip_pvt::callid, sip_pkt::data, FLAG_RESPONSE, LOG_DEBUG, sip_pkt::next, option_debug, sip_pvt::packets, sip_pkt::retransid, sched, sip_pkt::seqno, sip_methods, and cfsip_methods::text. Referenced by handle_response(). 01425 { 01426 struct sip_pkt *cur; 01427 int res = -1; 01428 char *msg = sip_methods[sipmethod].text; 01429 01430 cur = p->packets; 01431 while(cur) { 01432 if ((cur->seqno == seqno) && ((ast_test_flag(cur, FLAG_RESPONSE)) == resp) && 01433 ((ast_test_flag(cur, FLAG_RESPONSE)) || 01434 (!strncasecmp(msg, cur->data, strlen(msg)) && (cur->data[strlen(msg)] < 33)))) { 01435 /* this is our baby */ 01436 if (cur->retransid > -1) { 01437 if (option_debug > 3 && sipdebug) 01438 ast_log(LOG_DEBUG, "*** SIP TIMER: Cancelling retransmission #%d - %s (got response)\n", cur->retransid, msg); 01439 ast_sched_del(sched, cur->retransid); 01440 } 01441 cur->retransid = -1; 01442 res = 0; 01443 break; 01444 } 01445 cur = cur->next; 01446 } 01447 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"); 01448 return res; 01449 }
|
|
Definition at line 8280 of file chan_sip.c. References ast_cli(), ast_extension_state2str(), ast_getformatname(), ast_inet_ntoa(), ast_mutex_lock(), ast_mutex_unlock(), ast_strlen_zero(), ast_test_flag, sip_pvt::callid, sip_pvt::cid_num, sip_pvt::exten, FORMAT, FORMAT2, FORMAT3, sip_pvt::icseq, iflist, sip_pvt::lastmsg, sip_pvt::laststate, ast_channel::nativeformats, sip_pvt::next, NONE, sip_pvt::ocseq, sip_pvt::owner, RESULT_SHOWUSAGE, RESULT_SUCCESS, sip_pvt::sa, SIP_CALL_ONHOLD, SIP_NEEDDESTROY, sip_pvt::subscribed, subscription_type2str(), and sip_pvt::username. Referenced by sip_show_channels(), and sip_show_subscriptions(). 08281 { 08282 #define FORMAT3 "%-15.15s %-10.10s %-11.11s %-15.15s %-13.13s %-15.15s\n" 08283 #define FORMAT2 "%-15.15s %-10.10s %-11.11s %-11.11s %-4.4s %-7.7s %-15.15s\n" 08284 #define FORMAT "%-15.15s %-10.10s %-11.11s %5.5d/%5.5d %-4.4s %-3.3s %-3.3s %-15.15s\n" 08285 struct sip_pvt *cur; 08286 char iabuf[INET_ADDRSTRLEN]; 08287 int numchans = 0; 08288 if (argc != 3) 08289 return RESULT_SHOWUSAGE; 08290 ast_mutex_lock(&iflock); 08291 cur = iflist; 08292 if (!subscriptions) 08293 ast_cli(fd, FORMAT2, "Peer", "User/ANR", "Call ID", "Seq (Tx/Rx)", "Format", "Hold", "Last Message"); 08294 else 08295 ast_cli(fd, FORMAT3, "Peer", "User", "Call ID", "Extension", "Last state", "Type"); 08296 while (cur) { 08297 if (cur->subscribed == NONE && !subscriptions) { 08298 ast_cli(fd, FORMAT, ast_inet_ntoa(iabuf, sizeof(iabuf), cur->sa.sin_addr), 08299 ast_strlen_zero(cur->username) ? ( ast_strlen_zero(cur->cid_num) ? "(None)" : cur->cid_num ) : cur->username, 08300 cur->callid, 08301 cur->ocseq, cur->icseq, 08302 ast_getformatname(cur->owner ? cur->owner->nativeformats : 0), 08303 ast_test_flag(cur, SIP_CALL_ONHOLD) ? "Yes" : "No", 08304 ast_test_flag(cur, SIP_NEEDDESTROY) ? "(d)" : "", 08305 cur->lastmsg ); 08306 numchans++; 08307 } 08308 if (cur->subscribed != NONE && subscriptions) { 08309 ast_cli(fd, FORMAT3, ast_inet_ntoa(iabuf, sizeof(iabuf), cur->sa.sin_addr), 08310 ast_strlen_zero(cur->username) ? ( ast_strlen_zero(cur->cid_num) ? "(None)" : cur->cid_num ) : cur->username, 08311 cur->callid, cur->exten, ast_extension_state2str(cur->laststate), 08312 subscription_type2str(cur->subscribed)); 08313 numchans++; 08314 } 08315 cur = cur->next; 08316 } 08317 ast_mutex_unlock(&iflock); 08318 if (!subscriptions) 08319 ast_cli(fd, "%d active SIP channel%s\n", numchans, (numchans != 1) ? "s" : ""); 08320 else 08321 ast_cli(fd, "%d active SIP subscription%s\n", numchans, (numchans != 1) ? "s" : ""); 08322 return RESULT_SUCCESS; 08323 #undef FORMAT 08324 #undef FORMAT2 08325 #undef FORMAT3 08326 }
|
|
__sip_xmit: Transmit SIP message ---
Definition at line 1055 of file chan_sip.c. References ast_inet_ntoa(), ast_log(), ast_test_flag, LOG_WARNING, sip_pvt::recv, sip_pvt::sa, SIP_NAT, SIP_NAT_ROUTE, and sipsock. Referenced by __sip_reliable_xmit(), retrans_pkt(), send_request(), and send_response(). 01056 { 01057 int res; 01058 char iabuf[INET_ADDRSTRLEN]; 01059 01060 if (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE) 01061 res=sendto(sipsock, data, len, 0, (struct sockaddr *)&p->recv, sizeof(struct sockaddr_in)); 01062 else 01063 res=sendto(sipsock, data, len, 0, (struct sockaddr *)&p->sa, sizeof(struct sockaddr_in)); 01064 01065 if (res != len) { 01066 ast_log(LOG_WARNING, "sip_xmit of %p (len %d) to %s:%d returned %d: %s\n", data, len, ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr), ntohs(p->sa.sin_port), res, strerror(errno)); 01067 } 01068 return res; 01069 }
|
|
__transmit_response: Base transmit response function
Definition at line 4133 of file chan_sip.c. References add_blank_header(), add_header(), add_header_contentLength(), ast_cause2str(), ast_log(), get_header(), ast_channel::hangupcause, LOG_WARNING, sip_pvt::owner, respprep(), and send_response(). Referenced by transmit_response(), and transmit_response_reliable(). 04134 { 04135 struct sip_request resp; 04136 int seqno = 0; 04137 04138 if (reliable && (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1)) { 04139 ast_log(LOG_WARNING, "Unable to determine sequence number from '%s'\n", get_header(req, "CSeq")); 04140 return -1; 04141 } 04142 respprep(&resp, p, msg, req); 04143 add_header_contentLength(&resp, 0); 04144 /* If we are cancelling an incoming invite for some reason, add information 04145 about the reason why we are doing this in clear text */ 04146 if (msg[0] != '1' && p->owner && p->owner->hangupcause) { 04147 add_header(&resp, "X-Asterisk-HangupCause", ast_cause2str(p->owner->hangupcause)); 04148 } 04149 add_blank_header(&resp); 04150 return send_response(p, &resp, reliable, seqno); 04151 }
|
|
Definition at line 7887 of file chan_sip.c. References sip_peer::accountcode, sip_peer::addr, sip_peer::amaflags, ast_callerid_merge(), ast_cdr_flags2str(), ast_cli(), ast_describe_caller_presentation(), ast_getformatname_multiple(), ast_inet_ntoa(), ast_strlen_zero(), ast_test_flag, astman_send_error(), ASTOBJ_UNREF, sip_peer::auth, 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, find_peer(), 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_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, RESULT_SHOWUSAGE, s, sip_auth::secret, sip_peer::secret, SIP_CAN_REINVITE, sip_destroy_peer(), SIP_DTMF, SIP_DYNAMIC, SIP_INSECURE_INVITE, SIP_INSECURE_PORT, SIP_NAT, sip_options, SIP_PROMISCREDIR, SIP_SENDRPID, SIP_TRUSTRPID, SIP_USEREQPHONE, sip_peer::sipoptions, sip_peer::subscribecontext, text, sip_peer::tohost, 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(). 07888 { 07889 char status[30] = ""; 07890 char cbuf[256]; 07891 char iabuf[INET_ADDRSTRLEN]; 07892 struct sip_peer *peer; 07893 char codec_buf[512]; 07894 struct ast_codec_pref *pref; 07895 struct ast_variable *v; 07896 struct sip_auth *auth; 07897 int x = 0, codec = 0, load_realtime = 0; 07898 07899 if (argc < 4) 07900 return RESULT_SHOWUSAGE; 07901 07902 load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? 1 : 0; 07903 peer = find_peer(argv[3], NULL, load_realtime); 07904 if (s) { /* Manager */ 07905 if (peer) 07906 ast_cli(s->fd, "Response: Success\r\n"); 07907 else { 07908 snprintf (cbuf, sizeof(cbuf), "Peer %s not found.\n", argv[3]); 07909 astman_send_error(s, m, cbuf); 07910 return 0; 07911 } 07912 } 07913 if (peer && type==0 ) { /* Normal listing */ 07914 ast_cli(fd,"\n\n"); 07915 ast_cli(fd, " * Name : %s\n", peer->name); 07916 ast_cli(fd, " Secret : %s\n", ast_strlen_zero(peer->secret)?"<Not set>":"<Set>"); 07917 ast_cli(fd, " MD5Secret : %s\n", ast_strlen_zero(peer->md5secret)?"<Not set>":"<Set>"); 07918 auth = peer->auth; 07919 while(auth) { 07920 ast_cli(fd, " Realm-auth : Realm %-15.15s User %-10.20s ", auth->realm, auth->username); 07921 ast_cli(fd, "%s\n", !ast_strlen_zero(auth->secret)?"<Secret set>":(!ast_strlen_zero(auth->md5secret)?"<MD5secret set>" : "<Not set>")); 07922 auth = auth->next; 07923 } 07924 ast_cli(fd, " Context : %s\n", peer->context); 07925 ast_cli(fd, " Subscr.Cont. : %s\n", ast_strlen_zero(peer->subscribecontext)?"<Not set>":peer->subscribecontext); 07926 ast_cli(fd, " Language : %s\n", peer->language); 07927 if (!ast_strlen_zero(peer->accountcode)) 07928 ast_cli(fd, " Accountcode : %s\n", peer->accountcode); 07929 ast_cli(fd, " AMA flags : %s\n", ast_cdr_flags2str(peer->amaflags)); 07930 ast_cli(fd, " CallingPres : %s\n", ast_describe_caller_presentation(peer->callingpres)); 07931 if (!ast_strlen_zero(peer->fromuser)) 07932 ast_cli(fd, " FromUser : %s\n", peer->fromuser); 07933 if (!ast_strlen_zero(peer->fromdomain)) 07934 ast_cli(fd, " FromDomain : %s\n", peer->fromdomain); 07935 ast_cli(fd, " Callgroup : "); 07936 print_group(fd, peer->callgroup, 0); 07937 ast_cli(fd, " Pickupgroup : "); 07938 print_group(fd, peer->pickupgroup, 0); 07939 ast_cli(fd, " Mailbox : %s\n", peer->mailbox); 07940 ast_cli(fd, " VM Extension : %s\n", peer->vmexten); 07941 ast_cli(fd, " LastMsgsSent : %d\n", peer->lastmsgssent); 07942 ast_cli(fd, " Call limit : %d\n", peer->call_limit); 07943 ast_cli(fd, " Dynamic : %s\n", (ast_test_flag(peer, SIP_DYNAMIC)?"Yes":"No")); 07944 ast_cli(fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>")); 07945 ast_cli(fd, " Expire : %d\n", peer->expire); 07946 ast_cli(fd, " Insecure : %s\n", insecure2str(ast_test_flag(peer, SIP_INSECURE_PORT), ast_test_flag(peer, SIP_INSECURE_INVITE))); 07947 ast_cli(fd, " Nat : %s\n", nat2str(ast_test_flag(peer, SIP_NAT))); 07948 ast_cli(fd, " ACL : %s\n", (peer->ha?"Yes":"No")); 07949 ast_cli(fd, " CanReinvite : %s\n", (ast_test_flag(peer, SIP_CAN_REINVITE)?"Yes":"No")); 07950 ast_cli(fd, " PromiscRedir : %s\n", (ast_test_flag(peer, SIP_PROMISCREDIR)?"Yes":"No")); 07951 ast_cli(fd, " User=Phone : %s\n", (ast_test_flag(peer, SIP_USEREQPHONE)?"Yes":"No")); 07952 ast_cli(fd, " Trust RPID : %s\n", (ast_test_flag(peer, SIP_TRUSTRPID) ? "Yes" : "No")); 07953 ast_cli(fd, " Send RPID : %s\n", (ast_test_flag(peer, SIP_SENDRPID) ? "Yes" : "No")); 07954 07955 /* - is enumerated */ 07956 ast_cli(fd, " DTMFmode : %s\n", dtmfmode2str(ast_test_flag(peer, SIP_DTMF))); 07957 ast_cli(fd, " LastMsg : %d\n", peer->lastmsg); 07958 ast_cli(fd, " ToHost : %s\n", peer->tohost); 07959 ast_cli(fd, " Addr->IP : %s Port %d\n", peer->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), peer->addr.sin_addr) : "(Unspecified)", ntohs(peer->addr.sin_port)); 07960 ast_cli(fd, " Defaddr->IP : %s Port %d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port)); 07961 ast_cli(fd, " Def. Username: %s\n", peer->username); 07962 ast_cli(fd, " SIP Options : "); 07963 if (peer->sipoptions) { 07964 for (x=0 ; (x < (sizeof(sip_options) / sizeof(sip_options[0]))); x++) { 07965 if (peer->sipoptions & sip_options[x].id) 07966 ast_cli(fd, "%s ", sip_options[x].text); 07967 } 07968 } else 07969 ast_cli(fd, "(none)"); 07970 07971 ast_cli(fd, "\n"); 07972 ast_cli(fd, " Codecs : "); 07973 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability); 07974 ast_cli(fd, "%s\n", codec_buf); 07975 ast_cli(fd, " Codec Order : ("); 07976 print_codec_to_cli(fd, &peer->prefs); 07977 07978 ast_cli(fd, ")\n"); 07979 07980 ast_cli(fd, " Status : "); 07981 peer_status(peer, status, sizeof(status)); 07982 ast_cli(fd, "%s\n",status); 07983 ast_cli(fd, " Useragent : %s\n", peer->useragent); 07984 ast_cli(fd, " Reg. Contact : %s\n", peer->fullcontact); 07985 if (peer->chanvars) { 07986 ast_cli(fd, " Variables :\n"); 07987 for (v = peer->chanvars ; v ; v = v->next) 07988 ast_cli(fd, " %s = %s\n", v->name, v->value); 07989 } 07990 ast_cli(fd,"\n"); 07991 ASTOBJ_UNREF(peer,sip_destroy_peer); 07992 } else if (peer && type == 1) { /* manager listing */ 07993 ast_cli(fd, "Channeltype: SIP\r\n"); 07994 ast_cli(fd, "ObjectName: %s\r\n", peer->name); 07995 ast_cli(fd, "ChanObjectType: peer\r\n"); 07996 ast_cli(fd, "SecretExist: %s\r\n", ast_strlen_zero(peer->secret)?"N":"Y"); 07997 ast_cli(fd, "MD5SecretExist: %s\r\n", ast_strlen_zero(peer->md5secret)?"N":"Y"); 07998 ast_cli(fd, "Context: %s\r\n", peer->context); 07999 ast_cli(fd, "Language: %s\r\n", peer->language); 08000 if (!ast_strlen_zero(peer->accountcode)) 08001 ast_cli(fd, "Accountcode: %s\r\n", peer->accountcode); 08002 ast_cli(fd, "AMAflags: %s\r\n", ast_cdr_flags2str(peer->amaflags)); 08003 ast_cli(fd, "CID-CallingPres: %s\r\n", ast_describe_caller_presentation(peer->callingpres)); 08004 if (!ast_strlen_zero(peer->fromuser)) 08005 ast_cli(fd, "SIP-FromUser: %s\r\n", peer->fromuser); 08006 if (!ast_strlen_zero(peer->fromdomain)) 08007 ast_cli(fd, "SIP-FromDomain: %s\r\n", peer->fromdomain); 08008 ast_cli(fd, "Callgroup: "); 08009 print_group(fd, peer->callgroup, 1); 08010 ast_cli(fd, "Pickupgroup: "); 08011 print_group(fd, peer->pickupgroup, 1); 08012 ast_cli(fd, "VoiceMailbox: %s\r\n", peer->mailbox); 08013 ast_cli(fd, "LastMsgsSent: %d\r\n", peer->lastmsgssent); 08014 ast_cli(fd, "Call limit: %d\r\n", peer->call_limit); 08015 ast_cli(fd, "Dynamic: %s\r\n", (ast_test_flag(peer, SIP_DYNAMIC)?"Y":"N")); 08016 ast_cli(fd, "Callerid: %s\r\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "")); 08017 ast_cli(fd, "RegExpire: %ld seconds\r\n", ast_sched_when(sched,peer->expire)); 08018 ast_cli(fd, "SIP-AuthInsecure: %s\r\n", insecure2str(ast_test_flag(peer, SIP_INSECURE_PORT), ast_test_flag(peer, SIP_INSECURE_INVITE))); 08019 ast_cli(fd, "SIP-NatSupport: %s\r\n", nat2str(ast_test_flag(peer, SIP_NAT))); 08020 ast_cli(fd, "ACL: %s\r\n", (peer->ha?"Y":"N")); 08021 ast_cli(fd, "SIP-CanReinvite: %s\r\n", (ast_test_flag(peer, SIP_CAN_REINVITE)?"Y":"N")); 08022 ast_cli(fd, "SIP-PromiscRedir: %s\r\n", (ast_test_flag(peer, SIP_PROMISCREDIR)?"Y":"N")); 08023 ast_cli(fd, "SIP-UserPhone: %s\r\n", (ast_test_flag(peer, SIP_USEREQPHONE)?"Y":"N")); 08024 08025 /* - is enumerated */ 08026 ast_cli(fd, "SIP-DTMFmode: %s\r\n", dtmfmode2str(ast_test_flag(peer, SIP_DTMF))); 08027 ast_cli(fd, "SIPLastMsg: %d\r\n", peer->lastmsg); 08028 ast_cli(fd, "ToHost: %s\r\n", peer->tohost); 08029 ast_cli(fd, "Address-IP: %s\r\nAddress-Port: %d\r\n", peer->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), peer->addr.sin_addr) : "", ntohs(peer->addr.sin_port)); 08030 ast_cli(fd, "Default-addr-IP: %s\r\nDefault-addr-port: %d\r\n", ast_inet_ntoa(iabuf, sizeof(iabuf), peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port)); 08031 ast_cli(fd, "Default-Username: %s\r\n", peer->username); 08032 ast_cli(fd, "Codecs: "); 08033 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability); 08034 ast_cli(fd, "%s\r\n", codec_buf); 08035 ast_cli(fd, "CodecOrder: "); 08036 pref = &peer->prefs; 08037 for(x = 0; x < 32 ; x++) { 08038 codec = ast_codec_pref_index(pref,x); 08039 if (!codec) 08040 break; 08041 ast_cli(fd, "%s", ast_getformatname(codec)); 08042 if (x < 31 && ast_codec_pref_index(pref,x+1)) 08043 ast_cli(fd, ","); 08044 } 08045 08046 ast_cli(fd, "\r\n"); 08047 ast_cli(fd, "Status: "); 08048 peer_status(peer, status, sizeof(status)); 08049 ast_cli(fd, "%s\r\n", status); 08050 ast_cli(fd, "SIP-Useragent: %s\r\n", peer->useragent); 08051 ast_cli(fd, "Reg-Contact : %s\r\n", peer->fullcontact); 08052 if (peer->chanvars) { 08053 for (v = peer->chanvars ; v ; v = v->next) { 08054 ast_cli(fd, "ChanVariable:\n"); 08055 ast_cli(fd, " %s,%s\r\n", v->name, v->value); 08056 } 08057 } 08058 08059 ASTOBJ_UNREF(peer,sip_destroy_peer); 08060 08061 } else { 08062 ast_cli(fd,"Peer %s not found.\n", argv[3]); 08063 ast_cli(fd,"\n"); 08064 } 08065 08066 return RESULT_SUCCESS; 08067 }
|
|
_sip_show_peers: Execute sip show peers command
Definition at line 7465 of file chan_sip.c. References ast_cli(), ast_inet_ntoa(), ast_strlen_zero(), ast_test_flag, astman_get_header(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, FORMAT, FORMAT2, id, name, peer_status(), peerl, RESULT_SHOWUSAGE, s, SIP_DYNAMIC, SIP_NAT, and SIP_NAT_ROUTE. Referenced by manager_sip_show_peers(), and sip_show_peers(). 07466 { 07467 regex_t regexbuf; 07468 int havepattern = 0; 07469 07470 #define FORMAT2 "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8s %-10s\n" 07471 #define FORMAT "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8d %-10s\n" 07472 07473 char name[256]; 07474 char iabuf[INET_ADDRSTRLEN]; 07475 int total_peers = 0; 07476 int peers_online = 0; 07477 int peers_offline = 0; 07478 char *id; 07479 char idtext[256] = ""; 07480 07481 if (s) { /* Manager - get ActionID */ 07482 id = astman_get_header(m,"ActionID"); 07483 if (!ast_strlen_zero(id)) 07484 snprintf(idtext,256,"ActionID: %s\r\n",id); 07485 } 07486 07487 switch (argc) { 07488 case 5: 07489 if (!strcasecmp(argv[3], "like")) { 07490 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 07491 return RESULT_SHOWUSAGE; 07492 havepattern = 1; 07493 } else 07494 return RESULT_SHOWUSAGE; 07495 case 3: 07496 break; 07497 default: 07498 return RESULT_SHOWUSAGE; 07499 } 07500 07501 if (!s) { /* Normal list */ 07502 ast_cli(fd, FORMAT2, "Name/username", "Host", "Dyn", "Nat", "ACL", "Port", "Status"); 07503 } 07504 07505 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 07506 char status[20] = ""; 07507 char srch[2000]; 07508 char pstatus; 07509 07510 ASTOBJ_RDLOCK(iterator); 07511 07512 if (havepattern && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 07513 ASTOBJ_UNLOCK(iterator); 07514 continue; 07515 } 07516 07517 if (!ast_strlen_zero(iterator->username) && !s) 07518 snprintf(name, sizeof(name), "%s/%s", iterator->name, iterator->username); 07519 else 07520 ast_copy_string(name, iterator->name, sizeof(name)); 07521 07522 pstatus = peer_status(iterator, status, sizeof(status)); 07523 if (pstatus) 07524 peers_online++; 07525 else { 07526 if (pstatus == 0) 07527 peers_offline++; 07528 else { /* Unmonitored */ 07529 /* Checking if port is 0 */ 07530 if ( ntohs(iterator->addr.sin_port) == 0 ) { 07531 peers_offline++; 07532 } else { 07533 peers_online++; 07534 } 07535 } 07536 } 07537 07538 snprintf(srch, sizeof(srch), FORMAT, name, 07539 iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), iterator->addr.sin_addr) : "(Unspecified)", 07540 ast_test_flag(iterator, SIP_DYNAMIC) ? " D " : " ", /* Dynamic or not? */ 07541 (ast_test_flag(iterator, SIP_NAT) & SIP_NAT_ROUTE) ? " N " : " ", /* NAT=yes? */ 07542 iterator->ha ? " A " : " ", /* permit/deny */ 07543 ntohs(iterator->addr.sin_port), status); 07544 07545 if (!s) {/* Normal CLI list */ 07546 ast_cli(fd, FORMAT, name, 07547 iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), iterator->addr.sin_addr) : "(Unspecified)", 07548 ast_test_flag(iterator, SIP_DYNAMIC) ? " D " : " ", /* Dynamic or not? */ 07549 (ast_test_flag(iterator, SIP_NAT) & SIP_NAT_ROUTE) ? " N " : " ", /* NAT=yes? */ 07550 iterator->ha ? " A " : " ", /* permit/deny */ 07551 07552 ntohs(iterator->addr.sin_port), status); 07553 } else { /* Manager format */ 07554 /* The names here need to be the same as other channels */ 07555 ast_cli(fd, 07556 "Event: PeerEntry\r\n%s" 07557 "Channeltype: SIP\r\n" 07558 "ObjectName: %s\r\n" 07559 "ChanObjectType: peer\r\n" /* "peer" or "user" */ 07560 "IPaddress: %s\r\n" 07561 "IPport: %d\r\n" 07562 "Dynamic: %s\r\n" 07563 "Natsupport: %s\r\n" 07564 "ACL: %s\r\n" 07565 "Status: %s\r\n\r\n", 07566 idtext, 07567 iterator->name, 07568 iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), iterator->addr.sin_addr) : "-none-", 07569 ntohs(iterator->addr.sin_port), 07570 ast_test_flag(iterator, SIP_DYNAMIC) ? "yes" : "no", /* Dynamic or not? */ 07571 (ast_test_flag(iterator, SIP_NAT) & SIP_NAT_ROUTE) ? "yes" : "no", /* NAT=yes? */ 07572 iterator->ha ? "yes" : "no", /* permit/deny */ 07573 status); 07574 } 07575 07576 ASTOBJ_UNLOCK(iterator); 07577 07578 total_peers++; 07579 } while(0) ); 07580 07581 if (!s) { 07582 ast_cli(fd,"%d sip peers [%d online , %d offline]\n",total_peers,peers_online,peers_offline); 07583 } 07584 07585 if (havepattern) 07586 regfree(®exbuf); 07587 07588 if (total) 07589 *total = total_peers; 07590 07591 07592 return RESULT_SUCCESS; 07593 #undef FORMAT 07594 #undef FORMAT2 07595 }
|
|
add_blank_header: Add blank header to SIP message
Definition at line 3722 of file chan_sip.c. References ast_log(), sip_request::data, sip_request::header, sip_request::headers, sip_request::len, sip_request::lines, LOG_WARNING, and SIP_MAX_HEADERS. Referenced by __transmit_response(), sip_notify(), transmit_invite(), transmit_refer(), transmit_register(), transmit_request(), transmit_request_with_auth(), transmit_response_with_allow(), transmit_response_with_auth(), and transmit_response_with_date(). 03723 { 03724 if (req->headers == SIP_MAX_HEADERS) { 03725 ast_log(LOG_WARNING, "Out of SIP header space\n"); 03726 return -1; 03727 } 03728 if (req->lines) { 03729 ast_log(LOG_WARNING, "Can't add more headers when lines have been added\n"); 03730 return -1; 03731 } 03732 if (req->len >= sizeof(req->data) - 4) { 03733 ast_log(LOG_WARNING, "Out of space, can't add anymore\n"); 03734 return -1; 03735 } 03736 req->header[req->headers] = req->data + req->len; 03737 snprintf(req->header[req->headers], sizeof(req->data) - req->len, "\r\n"); 03738 req->len += strlen(req->header[req->headers]); 03739 req->headers++; 03740 return 0; 03741 }
|
|
Definition at line 4274 of file chan_sip.c. References ast_build_string(), AST_FORMAT_G729A, ast_getformatname(), ast_rtp_lookup_code(), ast_rtp_lookup_mime_subtype(), ast_verbose(), and sip_pvt::rtp. Referenced by add_sdp(). 04277 { 04278 int rtp_code; 04279 04280 if (debug) 04281 ast_verbose("Adding codec 0x%x (%s) to SDP\n", codec, ast_getformatname(codec)); 04282 if ((rtp_code = ast_rtp_lookup_code(p->rtp, 1, codec)) == -1) 04283 return; 04284 04285 ast_build_string(m_buf, m_size, " %d", rtp_code); 04286 ast_build_string(a_buf, a_size, "a=rtpmap:%d %s/%d\r\n", rtp_code, 04287 ast_rtp_lookup_mime_subtype(1, codec), 04288 sample_rate); 04289 if (codec == AST_FORMAT_G729A) 04290 /* Indicate that we don't support VAD (G.729 annex B) */ 04291 ast_build_string(a_buf, a_size, "a=fmtp:%d annexb=no\r\n", rtp_code); 04292 }
|
|
add_digit: add DTMF INFO tone to sip message ---
Definition at line 4243 of file chan_sip.c. References add_header(), add_header_contentLength(), and add_line(). Referenced by transmit_info_with_digit(). 04244 { 04245 char tmp[256]; 04246 04247 snprintf(tmp, sizeof(tmp), "Signal=%c\r\nDuration=250\r\n", digit); 04248 add_header(req, "Content-Type", "application/dtmf-relay"); 04249 add_header_contentLength(req, strlen(tmp)); 04250 add_line(req, tmp); 04251 return 0; 04252 }
|
|
add_header: Add header to SIP message
Definition at line 3678 of file chan_sip.c. References aliases, ast_log(), compactheaders, sip_request::data, sip_request::header, sip_request::headers, sip_request::len, sip_request::lines, LOG_WARNING, and SIP_MAX_HEADERS. 03679 { 03680 int x = 0; 03681 03682 if (req->headers == SIP_MAX_HEADERS) { 03683 ast_log(LOG_WARNING, "Out of SIP header space\n"); 03684 return -1; 03685 } 03686 03687 if (req->lines) { 03688 ast_log(LOG_WARNING, "Can't add more headers when lines have been added\n"); 03689 return -1; 03690 } 03691 03692 if (req->len >= sizeof(req->data) - 4) { 03693 ast_log(LOG_WARNING, "Out of space, can't add anymore (%s:%s)\n", var, value); 03694 return -1; 03695 } 03696 03697 req->header[req->headers] = req->data + req->len; 03698 03699 if (compactheaders) { 03700 for (x = 0; x < (sizeof(aliases) / sizeof(aliases[0])); x++) 03701 if (!strcasecmp(aliases[x].fullname, var)) 03702 var = aliases[x].shortname; 03703 } 03704 03705 snprintf(req->header[req->headers], sizeof(req->data) - req->len - 4, "%s: %s\r\n", var, value); 03706 req->len += strlen(req->header[req->headers]); 03707 req->headers++; 03708 03709 return 0; 03710 }
|
|
add_header_contentLen: Add 'Content-Length' header to SIP message
Definition at line 3713 of file chan_sip.c. References add_header(). Referenced by __transmit_response(), add_digit(), 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(), and transmit_state_notify(). 03714 { 03715 char clen[10]; 03716 03717 snprintf(clen, sizeof(clen), "%d", len); 03718 return add_header(req, "Content-Length", clen); 03719 }
|
|
add_line: Add content (not header) to SIP message
Definition at line 3744 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. 03745 { 03746 if (req->lines == SIP_MAX_LINES) { 03747 ast_log(LOG_WARNING, "Out of SIP line space\n"); 03748 return -1; 03749 } 03750 if (!req->lines) { 03751 /* Add extra empty return */ 03752 snprintf(req->data + req->len, sizeof(req->data) - req->len, "\r\n"); 03753 req->len += strlen(req->data + req->len); 03754 } 03755 if (req->len >= sizeof(req->data) - 4) { 03756 ast_log(LOG_WARNING, "Out of space, can't add anymore\n"); 03757 return -1; 03758 } 03759 req->line[req->lines] = req->data + req->len; 03760 snprintf(req->line[req->lines], sizeof(req->data) - req->len, "%s", line); 03761 req->len += strlen(req->line[req->lines]); 03762 req->lines++; 03763 return 0; 03764 }
|
|
Definition at line 4294 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. 04297 { 04298 int rtp_code; 04299 04300 if (debug) 04301 ast_verbose("Adding non-codec 0x%x (%s) to SDP\n", format, ast_rtp_lookup_mime_subtype(0, format)); 04302 if ((rtp_code = ast_rtp_lookup_code(p->rtp, 0, format)) == -1) 04303 return; 04304 04305 ast_build_string(m_buf, m_size, " %d", rtp_code); 04306 ast_build_string(a_buf, a_size, "a=rtpmap:%d %s/%d\r\n", rtp_code, 04307 ast_rtp_lookup_mime_subtype(0, format), 04308 sample_rate); 04309 if (format == AST_RTP_DTMF) 04310 /* Indicate we support DTMF and FLASH... */ 04311 ast_build_string(a_buf, a_size, "a=fmtp:%d 0-16\r\n", rtp_code); 04312 }
|
|
add_realm_authentication: Add realm authentication in list ---
Definition at line 11807 of file chan_sip.c. References ast_log(), ast_strlen_zero(), ast_verbose(), LOG_DEBUG, LOG_ERROR, LOG_WARNING, malloc, sip_auth::md5secret, sip_auth::next, option_verbose, sip_auth::realm, secret, strsep(), and username. Referenced by build_peer(), and reload_config(). 11808 { 11809 char authcopy[256]; 11810 char *username=NULL, *realm=NULL, *secret=NULL, *md5secret=NULL; 11811 char *stringp; 11812 struct sip_auth *auth; 11813 struct sip_auth *b = NULL, *a = authlist; 11814 11815 if (ast_strlen_zero(configuration)) 11816 return authlist; 11817 11818 ast_log(LOG_DEBUG, "Auth config :: %s\n", configuration); 11819 11820 ast_copy_string(authcopy, configuration, sizeof(authcopy)); 11821 stringp = authcopy; 11822 11823 username = stringp; 11824 realm = strrchr(stringp, '@'); 11825 if (realm) { 11826 *realm = '\0'; 11827 realm++; 11828 } 11829 if (ast_strlen_zero(username) || ast_strlen_zero(realm)) { 11830 ast_log(LOG_WARNING, "Format for authentication entry is user[:secret]@realm at line %d\n", lineno); 11831 return authlist; 11832 } 11833 stringp = username; 11834 username = strsep(&stringp, ":"); 11835 if (username) { 11836 secret = strsep(&stringp, ":"); 11837 if (!secret) { 11838 stringp = username; 11839 md5secret = strsep(&stringp,"#"); 11840 } 11841 } 11842 auth = malloc(sizeof(struct sip_auth)); 11843 if (auth) { 11844 memset(auth, 0, sizeof(struct sip_auth)); 11845 ast_copy_string(auth->realm, realm, sizeof(auth->realm)); 11846 ast_copy_string(auth->username, username, sizeof(auth->username)); 11847 if (secret) 11848 ast_copy_string(auth->secret, secret, sizeof(auth->secret)); 11849 if (md5secret) 11850 ast_copy_string(auth->md5secret, md5secret, sizeof(auth->md5secret)); 11851 } else { 11852 ast_log(LOG_ERROR, "Allocation of auth structure failed, Out of memory\n"); 11853 return authlist; 11854 } 11855 11856 /* Add authentication to authl */ 11857 if (!authlist) { /* No existing list */ 11858 return auth; 11859 } 11860 while(a) { 11861 b = a; 11862 a = a->next; 11863 } 11864 b->next = auth; /* Add structure add end of list */ 11865 11866 if (option_verbose > 2) 11867 ast_verbose("Added authentication for realm %s\n", realm); 11868 11869 return authlist; 11870 11871 }
|
|
add_route: Add route header into request per learned route ---
Definition at line 3862 of file chan_sip.c. References add_header(), sip_route::hop, n, and sip_route::next. Referenced by reqprep(). 03863 { 03864 char r[256], *p; 03865 int n, rem = sizeof(r); 03866 03867 if (!route) return; 03868 03869 p = r; 03870 while (route) { 03871 n = strlen(route->hop); 03872 if ((n+3)>rem) break; 03873 if (p != r) { 03874 *p++ = ','; 03875 --rem; 03876 } 03877 *p++ = '<'; 03878 ast_copy_string(p, route->hop, rem); p += n; 03879 *p++ = '>'; 03880 rem -= (n+2); 03881 route = route->next; 03882 } 03883 *p = '\0'; 03884 add_header(req, "Route", r); 03885 }
|
|
add_sdp: Add Session Description Protocol message ---
Definition at line 4315 of file chan_sip.c. References add_codec_to_sdp(), ast_build_string(), ast_codec_pref_index(), AST_FORMAT_MAX_AUDIO, ast_inet_ntoa(), ast_log(), ast_rtp_get_us(), ast_verbose(), capability, debug, sip_pvt::jointcapability, sip_request::len, LOG_WARNING, sip_pvt::ourip, sip_pvt::prefcodec, sip_pvt::prefs, sip_pvt::redircodecs, sip_pvt::redirip, sip_pvt::rtp, s, sip_pvt::sessionid, sip_pvt::sessionversion, sip_debug_test_pvt(), t, sip_pvt::vredirip, and sip_pvt::vrtp. 04316 { 04317 int len = 0; 04318 int pref_codec; 04319 int alreadysent = 0; 04320 struct sockaddr_in sin; 04321 struct sockaddr_in vsin; 04322 char v[256]; 04323 char s[256]; 04324 char o[256]; 04325 char c[256]; 04326 char t[256]; 04327 char m_audio[256]; 04328 char m_video[256]; 04329 char a_audio[1024]; 04330 char a_video[1024]; 04331 char *m_audio_next = m_audio; 04332 char *m_video_next = m_video; 04333 size_t m_audio_left = sizeof(m_audio); 04334 size_t m_video_left = sizeof(m_video); 04335 char *a_audio_next = a_audio; 04336 char *a_video_next = a_video; 04337 size_t a_audio_left = sizeof(a_audio); 04338 size_t a_video_left = sizeof(a_video); 04339 char iabuf[INET_ADDRSTRLEN]; 04340 int x; 04341 int capability; 04342 struct sockaddr_in dest; 04343 struct sockaddr_in vdest = { 0, }; 04344 int debug; 04345 04346 debug = sip_debug_test_pvt(p); 04347 04348 len = 0; 04349 if (!p->rtp) { 04350 ast_log(LOG_WARNING, "No way to add SDP without an RTP structure\n"); 04351 return -1; 04352 } 04353 capability = p->jointcapability; 04354 04355 if (!p->sessionid) { 04356 p->sessionid = getpid(); 04357 p->sessionversion = p->sessionid; 04358 } else 04359 p->sessionversion++; 04360 ast_rtp_get_us(p->rtp, &sin); 04361 if (p->vrtp) 04362 ast_rtp_get_us(p->vrtp, &vsin); 04363 04364 if (p->redirip.sin_addr.s_addr) { 04365 dest.sin_port = p->redirip.sin_port; 04366 dest.sin_addr = p->redirip.sin_addr; 04367 if (p->redircodecs) 04368 capability = p->redircodecs; 04369 } else { 04370 dest.sin_addr = p->ourip; 04371 dest.sin_port = sin.sin_port; 04372 } 04373 04374 /* Determine video destination */ 04375 if (p->vrtp) { 04376 if (p->vredirip.sin_addr.s_addr) { 04377 vdest.sin_port = p->vredirip.sin_port; 04378 vdest.sin_addr = p->vredirip.sin_addr; 04379 } else { 04380 vdest.sin_addr = p->ourip; 04381 vdest.sin_port = vsin.sin_port; 04382 } 04383 } 04384 if (debug){ 04385 ast_verbose("We're at %s port %d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip), ntohs(sin.sin_port)); 04386 if (p->vrtp) 04387 ast_verbose("Video is at %s port %d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip), ntohs(vsin.sin_port)); 04388 } 04389 04390 /* We break with the "recommendation" and send our IP, in order that our 04391 peer doesn't have to ast_gethostbyname() us */ 04392 04393 snprintf(v, sizeof(v), "v=0\r\n"); 04394 snprintf(o, sizeof(o), "o=root %d %d IN IP4 %s\r\n", p->sessionid, p->sessionversion, ast_inet_ntoa(iabuf, sizeof(iabuf), dest.sin_addr)); 04395 snprintf(s, sizeof(s), "s=session\r\n"); 04396 snprintf(c, sizeof(c), "c=IN IP4 %s\r\n", ast_inet_ntoa(iabuf, sizeof(iabuf), dest.sin_addr)); 04397 snprintf(t, sizeof(t), "t=0 0\r\n"); 04398 04399 ast_build_string(&m_audio_next, &m_audio_left, "m=audio %d RTP/AVP", ntohs(dest.sin_port)); 04400 ast_build_string(&m_video_next, &m_video_left, "m=video %d RTP/AVP", ntohs(vdest.sin_port)); 04401 04402 /* Prefer the codec we were requested to use, first, no matter what */ 04403 if (capability & p->prefcodec) { 04404 if (p->prefcodec <= AST_FORMAT_MAX_AUDIO) 04405 add_codec_to_sdp(p, p->prefcodec, 8000, 04406 &m_audio_next, &m_audio_left, 04407 &a_audio_next, &a_audio_left, 04408 debug); 04409 else 04410 add_codec_to_sdp(p, p->prefcodec, 90000, 04411 &m_video_next, &m_video_left, 04412 &a_video_next, &a_video_left, 04413 debug); 04414 alreadysent |= p->prefcodec; 04415 } 04416 04417 /* Start by sending our preferred codecs */ 04418 for (x = 0; x < 32; x++) { 04419 if (!(pref_codec = ast_codec_pref_index(&p->prefs, x))) 04420 break; 04421 04422 if (!(capability & pref_codec)) 04423 continue; 04424 04425 if (alreadysent & pref_codec) 04426 continue; 04427 04428 if (pref_codec <= AST_FORMAT_MAX_AUDIO) 04429 add_codec_to_sdp(p, pref_codec, 8000, 04430 &m_audio_next, &m_audio_left, 04431 &a_audio_next, &a_audio_left, 04432 debug); 04433 else 04434 add_codec_to_sdp(p, pref_codec, 90000, 04435 &m_video_next, &m_video_left, 04436 &a_video_next, &a_video_left, 04437 debug); 04438 alreadysent |= pref_codec; 04439 } 04440 04441 /* Now send any other common codecs, and non-codec formats: */ 04442 for (x = 1; x <= ((videosupport && p->vrtp) ? AST_FORMAT_MAX_VIDEO : AST_FORMAT_MAX_AUDIO); x <<= 1) { 04443 if (!(capability & x)) 04444 continue; 04445 04446 if (alreadysent & x) 04447 continue; 04448 04449 if (x <= AST_FORMAT_MAX_AUDIO) 04450 add_codec_to_sdp(p, x, 8000, 04451 &m_audio_next, &m_audio_left, 04452 &a_audio_next, &a_audio_left, 04453 debug); 04454 else 04455 add_codec_to_sdp(p, x, 90000, 04456 &m_video_next, &m_video_left, 04457 &a_video_next, &a_video_left, 04458 debug); 04459 } 04460 04461 for (x = 1; x <= AST_RTP_MAX; x <<= 1) { 04462 if (!(p->noncodeccapability & x)) 04463 continue; 04464 04465 add_noncodec_to_sdp(p, x, 8000, 04466 &m_audio_next, &m_audio_left, 04467 &a_audio_next, &a_audio_left, 04468 debug); 04469 } 04470 04471 ast_build_string(&a_audio_next, &a_audio_left, "a=silenceSupp:off - - - -\r\n"); 04472 04473 if ((m_audio_left < 2) || (m_video_left < 2) || (a_audio_left == 0) || (a_video_left == 0)) 04474 ast_log(LOG_WARNING, "SIP SDP may be truncated due to undersized buffer!!\n"); 04475 04476 ast_build_string(&m_audio_next, &m_audio_left, "\r\n"); 04477 ast_build_string(&m_video_next, &m_video_left, "\r\n"); 04478 04479 len = strlen(v) + strlen(s) + strlen(o) + strlen(c) + strlen(t) + strlen(m_audio) + strlen(a_audio); 04480 if ((p->vrtp) && (!ast_test_flag(p, SIP_NOVIDEO)) && (capability & VIDEO_CODEC_MASK)) /* only if video response is appropriate */ 04481 len += strlen(m_video) + strlen(a_video); 04482 04483 add_header(resp, "Content-Type", "application/sdp"); 04484 add_header_contentLength(resp, len); 04485 add_line(resp, v); 04486 add_line(resp, o); 04487 add_line(resp, s); 04488 add_line(resp, c); 04489 add_line(resp, t); 04490 add_line(resp, m_audio); 04491 add_line(resp, a_audio); 04492 if ((p->vrtp) && (!ast_test_flag(p, SIP_NOVIDEO)) && (capability & VIDEO_CODEC_MASK)) { /* only if video response is appropriate */ 04493 add_line(resp, m_video); 04494 add_line(resp, a_video); 04495 } 04496 04497 /* Update lastrtprx when we send our SDP */ 04498 time(&p->lastrtprx); 04499 time(&p->lastrtptx); 04500 04501 return 0; 04502 }
|
|
add_sip_domain: Add SIP domain to list of domains we are responsible for
Definition at line 11740 of file chan_sip.c. References AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), ast_strlen_zero(), calloc, list, LOG_DEBUG, LOG_ERROR, LOG_WARNING, and sipdebug. Referenced by reload_config(). 11741 { 11742 struct domain *d; 11743 11744 if (ast_strlen_zero(domain)) { 11745 ast_log(LOG_WARNING, "Zero length domain.\n"); 11746 return 1; 11747 } 11748 11749 d = calloc(1, sizeof(*d)); 11750 if (!d) { 11751 ast_log(LOG_ERROR, "Allocation of domain structure failed, Out of memory\n"); 11752 return 0; 11753 } 11754 11755 ast_copy_string(d->domain, domain, sizeof(d->domain)); 11756 11757 if (!ast_strlen_zero(context)) 11758 ast_copy_string(d->context, context, sizeof(d->context)); 11759 11760 d->mode = mode; 11761 11762 AST_LIST_LOCK(&domain_list); 11763 AST_LIST_INSERT_TAIL(&domain_list, d, list); 11764 AST_LIST_UNLOCK(&domain_list); 11765 11766 if (sipdebug) 11767 ast_log(LOG_DEBUG, "Added local SIP domain '%s'\n", domain); 11768 11769 return 1; 11770 }
|
|
add_text: Add text body to SIP message ---
Definition at line 4232 of file chan_sip.c. References add_header(), add_header_contentLength(), and add_line(). Referenced by transmit_message_with_text(). 04233 { 04234 /* XXX Convert \n's to \r\n's XXX */ 04235 add_header(req, "Content-Type", "text/plain"); 04236 add_header_contentLength(req, strlen(text)); 04237 add_line(req, text); 04238 return 0; 04239 }
|
|
add_vidupdate: add XML encoded media control with update ---
Definition at line 4256 of file chan_sip.c. References add_header(), add_header_contentLength(), and add_line(). Referenced by transmit_info_with_vidupdate(). 04257 { 04258 const char *xml_is_a_huge_waste_of_space = 04259 "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\r\n" 04260 " <media_control>\r\n" 04261 " <vc_primitive>\r\n" 04262 " <to_encoder>\r\n" 04263 " <picture_fast_update>\r\n" 04264 " </picture_fast_update>\r\n" 04265 " </to_encoder>\r\n" 04266 " </vc_primitive>\r\n" 04267 " </media_control>\r\n"; 04268 add_header(req, "Content-Type", "application/media_control+xml"); 04269 add_header_contentLength(req, strlen(xml_is_a_huge_waste_of_space)); 04270 add_line(req, xml_is_a_huge_waste_of_space); 04271 return 0; 04272 }
|
|
append_date: Append date to SIP message ---
Definition at line 4176 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(). 04177 { 04178 char tmpdat[256]; 04179 struct tm tm; 04180 time_t t; 04181 04182 time(&t); 04183 gmtime_r(&t, &tm); 04184 strftime(tmpdat, sizeof(tmpdat), "%a, %d %b %Y %T GMT", &tm); 04185 add_header(req, "Date", tmpdat); 04186 }
|
|
append_history: Append to SIP dialog history
Definition at line 1122 of file chan_sip.c. References ast_log(), sip_history::event, sip_pvt::history, LOG_WARNING, malloc, and sip_history::next. Referenced by __sip_autodestruct(), cb_extensionstate(), do_register_auth(), handle_request_subscribe(), process_sdp(), retrans_pkt(), send_request(), send_response(), sip_cancel_destroy(), sip_reregister(), sip_scheddestroy(), sipsock_read(), and transmit_register(). 01123 { 01124 struct sip_history *hist, *prev; 01125 char *c; 01126 01127 if (!recordhistory || !p) 01128 return 0; 01129 if(!(hist = malloc(sizeof(struct sip_history)))) { 01130 ast_log(LOG_WARNING, "Can't allocate memory for history"); 01131 return 0; 01132 } 01133 memset(hist, 0, sizeof(struct sip_history)); 01134 snprintf(hist->event, sizeof(hist->event), "%-15s %s", event, data); 01135 /* Trim up nicely */ 01136 c = hist->event; 01137 while(*c) { 01138 if ((*c == '\r') || (*c == '\n')) { 01139 *c = '\0'; 01140 break; 01141 } 01142 c++; 01143 } 01144 /* Enqueue into history */ 01145 prev = p->history; 01146 if (prev) { 01147 while(prev->next) 01148 prev = prev->next; 01149 prev->next = hist; 01150 } else { 01151 p->history = hist; 01152 } 01153 return 0; 01154 }
|
|
The SIP domain list |
|
|
|
|
|
Protect the monitoring thread, so only one process can kill or start it, and not when it's doing something critical.
|
|
Protect the interface list (of sip_pvt's).
|
|
|
|
|
|
ast_quiet_chan: Turn off generator data
Definition at line 10130 of file chan_sip.c. References ast_channel::_state, ast_deactivate_generator(), AST_STATE_UP, and ast_channel::generatordata. Referenced by attempt_transfer(). 10131 { 10132 if (chan && chan->_state == AST_STATE_UP) { 10133 if (chan->generatordata) 10134 ast_deactivate_generator(chan); 10135 } 10136 }
|
|
ast_sip_ouraddrfor: NAT fix - decide which IP address to use for ASterisk server? ---
Definition at line 1087 of file chan_sip.c. References ahp, ast_apply_ha(), ast_gethostbyname(), ast_inet_ntoa(), ast_log(), ast_ouraddrfor(), bindaddr, externexpire, externhost, externip, externrefresh, hp, localaddr, LOG_DEBUG, and LOG_NOTICE. Referenced by sip_alloc(), sip_notify(), sip_poke_peer(), sip_request_call(), sip_send_mwi_to_peer(), and transmit_register(). 01088 { 01089 /* 01090 * Using the localaddr structure built up with localnet statements 01091 * apply it to their address to see if we need to substitute our 01092 * externip or can get away with our internal bindaddr 01093 */ 01094 struct sockaddr_in theirs; 01095 theirs.sin_addr = *them; 01096 if (localaddr && externip.sin_addr.s_addr && 01097 ast_apply_ha(localaddr, &theirs)) { 01098 char iabuf[INET_ADDRSTRLEN]; 01099 if (externexpire && (time(NULL) >= externexpire)) { 01100 struct ast_hostent ahp; 01101 struct hostent *hp; 01102 time(&externexpire); 01103 externexpire += externrefresh; 01104 if ((hp = ast_gethostbyname(externhost, &ahp))) { 01105 memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr)); 01106 } else 01107 ast_log(LOG_NOTICE, "Warning: Re-lookup of '%s' failed!\n", externhost); 01108 } 01109 memcpy(us, &externip.sin_addr, sizeof(struct in_addr)); 01110 ast_inet_ntoa(iabuf, sizeof(iabuf), *(struct in_addr *)&them->s_addr); 01111 ast_log(LOG_DEBUG, "Target address %s is not local, substituting externip\n", iabuf); 01112 } 01113 else if (bindaddr.sin_addr.s_addr) 01114 memcpy(us, &bindaddr.sin_addr, sizeof(struct in_addr)); 01115 else 01116 return ast_ouraddrfor(them, us); 01117 return 0; 01118 }
|
|
attempt_transfer: Attempt transfer of SIP call ---
Definition at line 10139 of file chan_sip.c. References ast_bridged_channel(), ast_cdr_append(), ast_channel_masquerade(), ast_log(), ast_quiet_chan(), AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), LOG_NOTICE, LOG_WARNING, and sip_pvt::owner. 10140 { 10141 int res = 0; 10142 struct ast_channel 10143 *chana = NULL, 10144 *chanb = NULL, 10145 *bridgea = NULL, 10146 *bridgeb = NULL, 10147 *peera = NULL, 10148 *peerb = NULL, 10149 *peerc = NULL, 10150 *peerd = NULL; 10151 10152 if (!p1->owner || !p2->owner) { 10153 ast_log(LOG_WARNING, "Transfer attempted without dual ownership?\n"); 10154 return -1; 10155 } 10156 chana = p1->owner; 10157 chanb = p2->owner; 10158 bridgea = ast_bridged_channel(chana); 10159 bridgeb = ast_bridged_channel(chanb); 10160 10161 if (bridgea) { 10162 peera = chana; 10163 peerb = chanb; 10164 peerc = bridgea; 10165 peerd = bridgeb; 10166 } else if (bridgeb) { 10167 peera = chanb; 10168 peerb = chana; 10169 peerc = bridgeb; 10170 peerd = bridgea; 10171 } 10172 10173 if (peera && peerb && peerc && (peerb != peerc)) { 10174 ast_quiet_chan(peera); 10175 ast_quiet_chan(peerb); 10176 ast_quiet_chan(peerc); 10177 ast_quiet_chan(peerd); 10178 10179 if (peera->cdr && peerb->cdr) { 10180 peerb->cdr = ast_cdr_append(peerb->cdr, peera->cdr); 10181 } else if (peera->cdr) { 10182 peerb->cdr = peera->cdr; 10183 } 10184 peera->cdr = NULL; 10185 10186 if (peerb->cdr && peerc->cdr) { 10187 peerb->cdr = ast_cdr_append(peerb->cdr, peerc->cdr); 10188 } else if (peerc->cdr) { 10189 peerb->cdr = peerc->cdr; 10190 } 10191 peerc->cdr = NULL; 10192 10193 if (ast_channel_masquerade(peerb, peerc)) { 10194 ast_log(LOG_WARNING, "Failed to masquerade %s into %s\n", peerb->name, peerc->name); 10195 res = -1; 10196 } 10197 return res; 10198 } else { 10199 ast_log(LOG_NOTICE, "Transfer attempted with no appropriate bridged calls to transfer\n"); 10200 if (chana) 10201 ast_softhangup_nolock(chana, AST_SOFTHANGUP_DEV); 10202 if (chanb) 10203 ast_softhangup_nolock(chanb, AST_SOFTHANGUP_DEV); 10204 return -1; 10205 } 10206 return 0; 10207 }
|
|
auto_congest: Scheduled congestion on a call ---
Definition at line 1983 of file chan_sip.c. References AST_CONTROL_CONGESTION, ast_log(), ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_queue_control(), sip_pvt::initid, ast_channel::lock, sip_pvt::lock, LOG_NOTICE, ast_channel::name, and sip_pvt::owner. 01984 { 01985 struct sip_pvt *p = nothing; 01986 ast_mutex_lock(&p->lock); 01987 p->initid = -1; 01988 if (p->owner) { 01989 if (!ast_mutex_trylock(&p->owner->lock)) { 01990 ast_log(LOG_NOTICE, "Auto-congesting %s\n", p->owner->name); 01991 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 01992 ast_mutex_unlock(&p->owner->lock); 01993 } 01994 } 01995 ast_mutex_unlock(&p->lock); 01996 return 0; 01997 }
|
|
build_callid: Build SIP CALLID header ---
Definition at line 3009 of file chan_sip.c. References thread_safe_rand(). Referenced by sip_alloc(), sip_notify(), sip_poke_peer(), sip_request_call(), sip_send_mwi_to_peer(), and transmit_register(). 03010 { 03011 int res; 03012 int val; 03013 int x; 03014 char iabuf[INET_ADDRSTRLEN]; 03015 for (x=0; x<4; x++) { 03016 val = thread_safe_rand(); 03017 res = snprintf(callid, len, "%08x", val); 03018 len -= res; 03019 callid += res; 03020 } 03021 if (!ast_strlen_zero(fromdomain)) 03022 snprintf(callid, len, "@%s", fromdomain); 03023 else 03024 /* It's not important that we really use our right IP here... */ 03025 snprintf(callid, len, "@%s", ast_inet_ntoa(iabuf, sizeof(iabuf), ourip)); 03026 }
|
|
build_contact: Build contact header - the contact header we send out ---
Definition at line 4632 of file chan_sip.c. References ast_inet_ntoa(), ast_strlen_zero(), sip_pvt::exten, sip_pvt::our_contact, sip_pvt::ourip, and ourport. Referenced by check_user_full(), handle_request_invite(), handle_request_options(), handle_request_subscribe(), register_verify(), and transmit_register(). 04633 { 04634 char iabuf[INET_ADDRSTRLEN]; 04635 04636 /* Construct Contact: header */ 04637 if (ourport != 5060) /* Needs to be 5060, according to the RFC */ 04638 snprintf(p->our_contact, sizeof(p->our_contact), "<sip:%s%s%s:%d>", p->exten, ast_strlen_zero(p->exten) ? "" : "@", ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip), ourport); 04639 else 04640 snprintf(p->our_contact, sizeof(p->our_contact), "<sip:%s%s%s>", p->exten, ast_strlen_zero(p->exten) ? "" : "@", ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip)); 04641 }
|
|
build_peer: Build peer from config file ---
Definition at line 12037 of file chan_sip.c. References sip_peer::accountcode, add_realm_authentication(), sip_peer::addr, sip_peer::amaflags, ast_append_ha(), ast_callerid_split(), ast_cdr_amaflags2int(), ast_clear_flag, ast_copy_flags, ast_free_ha(), ast_get_group(), ast_get_ip(), ast_get_ip_or_srv(), 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_INIT, ASTOBJ_UNMARK, ASTOBJ_UNREF, sip_peer::auth, 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_context, default_language, DEFAULT_MAXMS, default_qualify, DEFAULT_SIP_PORT, default_subscribecontext, destroy_association(), sip_peer::expire, ast_flags::flags, sip_peer::flags_page2, sip_peer::fromdomain, sip_peer::fromuser, sip_peer::fullcontact, global_capability, global_flags, global_flags_page2, global_musicclass, global_rtpholdtimeout, global_rtpkeepalive, global_rtptimeout, global_vmexten, sip_peer::ha, handle_common_options(), sip_peer::language, sip_peer::lastmsgssent, ast_variable::lineno, LOG_DEBUG, LOG_WARNING, sip_peer::mailbox, malloc, sip_peer::maxms, sip_peer::md5secret, sip_peer::musicclass, ast_variable::name, ast_variable::next, option_debug, peerl, sip_peer::pickupgroup, prefs, sip_peer::prefs, reg_source_db(), sip_peer::regexten, rpeerobjs, sip_peer::rtpholdtimeout, sip_peer::rtpkeepalive, sip_peer::rtptimeout, sip_peer::secret, sip_destroy_peer(), SIP_DYNAMIC, SIP_FLAGS_TO_COPY, SIP_PAGE2_IGNOREREGEXPIRE, SIP_PAGE2_RT_FROMCONTACT, SIP_REALTIME, SIP_USEREQPHONE, speerobjs, sip_peer::subscribecontext, sip_peer::tohost, sip_peer::username, ast_variable::value, and sip_peer::vmexten. 12038 { 12039 struct sip_peer *peer = NULL; 12040 struct ast_ha *oldha = NULL; 12041 int obproxyfound=0; 12042 int found=0; 12043 int format=0; /* Ama flags */ 12044 time_t regseconds; 12045 char *varname = NULL, *varval = NULL; 12046 struct ast_variable *tmpvar = NULL; 12047 struct ast_flags peerflags = {(0)}; 12048 struct ast_flags mask = {(0)}; 12049 12050 12051 if (!realtime) 12052 /* Note we do NOT use find_peer here, to avoid realtime recursion */ 12053 /* We also use a case-sensitive comparison (unlike find_peer) so 12054 that case changes made to the peer name will be properly handled 12055 during reload 12056 */ 12057 peer = ASTOBJ_CONTAINER_FIND_UNLINK_FULL(&peerl, name, name, 0, 0, strcmp); 12058 12059 if (peer) { 12060 /* Already in the list, remove it and it will be added back (or FREE'd) */ 12061 found++; 12062 } else { 12063 peer = malloc(sizeof(*peer)); 12064 if (peer) { 12065 memset(peer, 0, sizeof(*peer)); 12066 if (realtime) 12067 rpeerobjs++; 12068 else 12069 speerobjs++; 12070 ASTOBJ_INIT(peer); 12071 peer->expire = -1; 12072 peer->pokeexpire = -1; 12073 } else { 12074 ast_log(LOG_WARNING, "Can't allocate SIP peer memory\n"); 12075 } 12076 } 12077 /* Note that our peer HAS had its reference count incrased */ 12078 if (!peer) 12079 return NULL; 12080 12081 peer->lastmsgssent = -1; 12082 if (!found) { 12083 if (name) 12084 ast_copy_string(peer->name, name, sizeof(peer->name)); 12085 peer->addr.sin_port = htons(DEFAULT_SIP_PORT); 12086 peer->addr.sin_family = AF_INET; 12087 peer->defaddr.sin_family = AF_INET; 12088 } 12089 /* If we have channel variables, remove them (reload) */ 12090 if (peer->chanvars) { 12091 ast_variables_destroy(peer->chanvars); 12092 peer->chanvars = NULL; 12093 } 12094 strcpy(peer->context, default_context); 12095 strcpy(peer->subscribecontext, default_subscribecontext); 12096 strcpy(peer->vmexten, global_vmexten); 12097 strcpy(peer->language, default_language); 12098 strcpy(peer->musicclass, global_musicclass); 12099 ast_copy_flags(peer, &global_flags, SIP_USEREQPHONE); 12100 peer->secret[0] = '\0'; 12101 peer->md5secret[0] = '\0'; 12102 peer->cid_num[0] = '\0'; 12103 peer->cid_name[0] = '\0'; 12104 peer->fromdomain[0] = '\0'; 12105 peer->fromuser[0] = '\0'; 12106 peer->regexten[0] = '\0'; 12107 peer->mailbox[0] = '\0'; 12108 peer->callgroup = 0; 12109 peer->pickupgroup = 0; 12110 peer->rtpkeepalive = global_rtpkeepalive; 12111 peer->maxms = default_qualify; 12112 peer->prefs = prefs; 12113 oldha = peer->ha; 12114 peer->ha = NULL; 12115 peer->addr.sin_family = AF_INET; 12116 ast_copy_flags(peer, &global_flags, SIP_FLAGS_TO_COPY); 12117 peer->capability = global_capability; 12118 peer->rtptimeout = global_rtptimeout; 12119 peer->rtpholdtimeout = global_rtpholdtimeout; 12120 while(v) { 12121 if (handle_common_options(&peerflags, &mask, v)) { 12122 v = v->next; 12123 continue; 12124 } 12125 12126 if (realtime && !strcasecmp(v->name, "regseconds")) { 12127 if (sscanf(v->value, "%ld", (time_t *)®seconds) != 1) 12128 regseconds = 0; 12129 } else if (realtime && !strcasecmp(v->name, "ipaddr") && !ast_strlen_zero(v->value) ) { 12130 inet_aton(v->value, &(peer->addr.sin_addr)); 12131 } else if (realtime && !strcasecmp(v->name, "name")) 12132 ast_copy_string(peer->name, v->value, sizeof(peer->name)); 12133 else if (realtime && !strcasecmp(v->name, "fullcontact")) { 12134 ast_copy_string(peer->fullcontact, v->value, sizeof(peer->fullcontact)); 12135 ast_set_flag((&peer->flags_page2), SIP_PAGE2_RT_FROMCONTACT); 12136 } else if (!strcasecmp(v->name, "secret")) 12137 ast_copy_string(peer->secret, v->value, sizeof(peer->secret)); 12138 else if (!strcasecmp(v->name, "md5secret")) 12139 ast_copy_string(peer->md5secret, v->value, sizeof(peer->md5secret)); 12140 else if (!strcasecmp(v->name, "auth")) 12141 peer->auth = add_realm_authentication(peer->auth, v->value, v->lineno); 12142 else if (!strcasecmp(v->name, "callerid")) { 12143 ast_callerid_split(v->value, peer->cid_name, sizeof(peer->cid_name), peer->cid_num, sizeof(peer->cid_num)); 12144 } else if (!strcasecmp(v->name, "context")) { 12145 ast_copy_string(peer->context, v->value, sizeof(peer->context)); 12146 } else if (!strcasecmp(v->name, "subscribecontext")) { 12147 ast_copy_string(peer->subscribecontext, v->value, sizeof(peer->subscribecontext)); 12148 } else if (!strcasecmp(v->name, "fromdomain")) 12149 ast_copy_string(peer->fromdomain, v->value, sizeof(peer->fromdomain)); 12150 else if (!strcasecmp(v->name, "usereqphone")) 12151 ast_set2_flag(peer, ast_true(v->value), SIP_USEREQPHONE); 12152 else if (!strcasecmp(v->name, "fromuser")) 12153 ast_copy_string(peer->fromuser, v->value, sizeof(peer->fromuser)); 12154 else if (!strcasecmp(v->name, "host") || !strcasecmp(v->name, "outboundproxy")) { 12155 if (!strcasecmp(v->value, "dynamic")) { 12156 if (!strcasecmp(v->name, "outboundproxy") || obproxyfound) { 12157 ast_log(LOG_WARNING, "You can't have a dynamic outbound proxy, you big silly head at line %d.\n", v->lineno); 12158 } else { 12159 /* They'll register with us */ 12160 ast_set_flag(peer, SIP_DYNAMIC); 12161 if (!found) { 12162 /* Initialize stuff iff we're not found, otherwise 12163 we keep going with what we had */ 12164 memset(&peer->addr.sin_addr, 0, 4); 12165 if (peer->addr.sin_port) { 12166 /* If we've already got a port, make it the default rather than absolute */ 12167 peer->defaddr.sin_port = peer->addr.sin_port; 12168 peer->addr.sin_port = 0; 12169 } 12170 } 12171 } 12172 } else { 12173 /* Non-dynamic. Make sure we become that way if we're not */ 12174 if (peer->expire > -1) 12175 ast_sched_del(sched, peer->expire); 12176 peer->expire = -1; 12177 ast_clear_flag(peer, SIP_DYNAMIC); 12178 if (!obproxyfound || !strcasecmp(v->name, "outboundproxy")) { 12179 if (ast_get_ip_or_srv(&peer->addr, v->value, "_sip._udp")) { 12180 ASTOBJ_UNREF(peer, sip_destroy_peer); 12181 return NULL; 12182 } 12183 } 12184 if (!strcasecmp(v->name, "outboundproxy")) 12185 obproxyfound=1; 12186 else { 12187 ast_copy_string(peer->tohost, v->value, sizeof(peer->tohost)); 12188 if (!peer->addr.sin_port) 12189 peer->addr.sin_port = htons(DEFAULT_SIP_PORT); 12190 } 12191 } 12192 } else if (!strcasecmp(v->name, "defaultip")) { 12193 if (ast_get_ip(&peer->defaddr, v->value)) { 12194 ASTOBJ_UNREF(peer, sip_destroy_peer); 12195 return NULL; 12196 } 12197 } else if (!strcasecmp(v->name, "permit") || !strcasecmp(v->name, "deny")) { 12198 peer->ha = ast_append_ha(v->name, v->value, peer->ha); 12199 } else if (!strcasecmp(v->name, "port")) { 12200 if (!realtime && ast_test_flag(peer, SIP_DYNAMIC)) 12201 peer->defaddr.sin_port = htons(atoi(v->value)); 12202 else 12203 peer->addr.sin_port = htons(atoi(v->value)); 12204 } else if (!strcasecmp(v->name, "callingpres")) { 12205 peer->callingpres = ast_parse_caller_presentation(v->value); 12206 if (peer->callingpres == -1) 12207 peer->callingpres = atoi(v->value); 12208 } else if (!strcasecmp(v->name, "username")) { 12209 ast_copy_string(peer->username, v->value, sizeof(peer->username)); 12210 } else if (!strcasecmp(v->name, "language")) { 12211 ast_copy_string(peer->language, v->value, sizeof(peer->language)); 12212 } else if (!strcasecmp(v->name, "regexten")) { 12213 ast_copy_string(peer->regexten, v->value, sizeof(peer->regexten)); 12214 } else if (!strcasecmp(v->name, "call-limit") || !strcasecmp(v->name, "incominglimit")) { 12215 peer->call_limit = atoi(v->value); 12216 if (peer->call_limit < 0) 12217 peer->call_limit = 0; 12218 } else if (!strcasecmp(v->name, "amaflags")) { 12219 format = ast_cdr_amaflags2int(v->value); 12220 if (format < 0) { 12221 ast_log(LOG_WARNING, "Invalid AMA Flags for peer: %s at line %d\n", v->value, v->lineno); 12222 } else { 12223 peer->amaflags = format; 12224 } 12225 } else if (!strcasecmp(v->name, "accountcode")) { 12226 ast_copy_string(peer->accountcode, v->value, sizeof(peer->accountcode)); 12227 } else if (!strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) { 12228 ast_copy_string(peer->musicclass, v->value, sizeof(peer->musicclass)); 12229 } else if (!strcasecmp(v->name, "mailbox")) { 12230 ast_copy_string(peer->mailbox, v->value, sizeof(peer->mailbox)); 12231 } else if (!strcasecmp(v->name, "vmexten")) { 12232 ast_copy_string(peer->vmexten, v->value, sizeof(peer->vmexten)); 12233 } else if (!strcasecmp(v->name, "callgroup")) { 12234 peer->callgroup = ast_get_group(v->value); 12235 } else if (!strcasecmp(v->name, "pickupgroup")) { 12236 peer->pickupgroup = ast_get_group(v->value); 12237 } else if (!strcasecmp(v->name, "allow")) { 12238 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1); 12239 } else if (!strcasecmp(v->name, "disallow")) { 12240 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0); 12241 } else if (!strcasecmp(v->name, "rtptimeout")) { 12242 if ((sscanf(v->value, "%d", &peer->rtptimeout) != 1) || (peer->rtptimeout < 0)) { 12243 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 12244 peer->rtptimeout = global_rtptimeout; 12245 } 12246 } else if (!strcasecmp(v->name, "rtpholdtimeout")) { 12247 if ((sscanf(v->value, "%d", &peer->rtpholdtimeout) != 1) || (peer->rtpholdtimeout < 0)) { 12248 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 12249 peer->rtpholdtimeout = global_rtpholdtimeout; 12250 } 12251 } else if (!strcasecmp(v->name, "rtpkeepalive")) { 12252 if ((sscanf(v->value, "%d", &peer->rtpkeepalive) != 1) || (peer->rtpkeepalive < 0)) { 12253 ast_log(LOG_WARNING, "'%s' is not a valid RTP keepalive time at line %d. Using default.\n", v->value, v->lineno); 12254 peer->rtpkeepalive = global_rtpkeepalive; 12255 } 12256 } else if (!strcasecmp(v->name, "setvar")) { 12257 /* Set peer channel variable */ 12258 varname = ast_strdupa(v->value); 12259 if (varname && (varval = strchr(varname,'='))) { 12260 *varval = '\0'; 12261 varval++; 12262 if ((tmpvar = ast_variable_new(varname, varval))) { 12263 tmpvar->next = peer->chanvars; 12264 peer->chanvars = tmpvar; 12265 } 12266 } 12267 } else if (!strcasecmp(v->name, "qualify")) { 12268 if (!strcasecmp(v->value, "no")) { 12269 peer->maxms = 0; 12270 } else if (!strcasecmp(v->value, "yes")) { 12271 peer->maxms = DEFAULT_MAXMS; 12272 } else if (sscanf(v->value, "%d", &peer->maxms) != 1) { 12273 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); 12274 peer->maxms = 0; 12275 } 12276 } 12277 /* else if (strcasecmp(v->name,"type")) 12278 * ast_log(LOG_WARNING, "Ignoring %s\n", v->name); 12279 */ 12280 v=v->next; 12281 } 12282 if (!ast_test_flag((&global_flags_page2), SIP_PAGE2_IGNOREREGEXPIRE) && ast_test_flag(peer, SIP_DYNAMIC) && realtime) { 12283 time_t nowtime; 12284 12285 time(&nowtime); 12286 if ((nowtime - regseconds) > 0) { 12287 destroy_association(peer); 12288 memset(&peer->addr, 0, sizeof(peer->addr)); 12289 if (option_debug) 12290 ast_log(LOG_DEBUG, "Bah, we're expired (%d/%d/%d)!\n", (int)(nowtime - regseconds), (int)regseconds, (int)nowtime); 12291 } 12292 } 12293 ast_copy_flags(peer, &peerflags, mask.flags); 12294 if (!found && ast_test_flag(peer, SIP_DYNAMIC) && !ast_test_flag(peer, SIP_REALTIME)) 12295 reg_source_db(peer); 12296 ASTOBJ_UNMARK(peer); 12297 ast_free_ha(oldha); 12298 return peer; 12299 }
|
|
build_reply_digest: Build reply digest ---
Definition at line 8998 of file chan_sip.c. References ast_inet_ntoa(), ast_log(), ast_md5_hash(), ast_strlen_zero(), authl, sip_pvt::authname, sip_pvt::callid, sip_pvt::domain, find_realm_authentication(), LOG_DEBUG, sip_auth::md5secret, sip_registry::md5secret, sip_pvt::nonce, sip_pvt::noncecount, sip_pvt::opaque, sip_pvt::peermd5secret, sip_pvt::peersecret, sip_pvt::qop, sip_pvt::realm, sip_pvt::sa, sip_auth::secret, secret, sip_methods, sipdebug, text, thread_safe_rand(), sip_pvt::uri, sip_auth::username, sip_pvt::username, and username. Referenced by transmit_register(), and transmit_request_with_auth(). 08999 { 09000 char a1[256]; 09001 char a2[256]; 09002 char a1_hash[256]; 09003 char a2_hash[256]; 09004 char resp[256]; 09005 char resp_hash[256]; 09006 char uri[256]; 09007 char cnonce[80]; 09008 char iabuf[INET_ADDRSTRLEN]; 09009 char *username; 09010 char *secret; 09011 char *md5secret; 09012 struct sip_auth *auth = (struct sip_auth *) NULL; /* Realm authentication */ 09013 09014 if (!ast_strlen_zero(p->domain)) 09015 ast_copy_string(uri, p->domain, sizeof(uri)); 09016 else if (!ast_strlen_zero(p->uri)) 09017 ast_copy_string(uri, p->uri, sizeof(uri)); 09018 else 09019 snprintf(uri, sizeof(uri), "sip:%s@%s",p->username, ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr)); 09020 09021 snprintf(cnonce, sizeof(cnonce), "%08x", thread_safe_rand()); 09022 09023 /* Check if we have separate auth credentials */ 09024 if ((auth = find_realm_authentication(authl, p->realm))) { 09025 username = auth->username; 09026 secret = auth->secret; 09027 md5secret = auth->md5secret; 09028 if (sipdebug) 09029 ast_log(LOG_DEBUG,"Using realm %s authentication for call %s\n", p->realm, p->callid); 09030 } else { 09031 /* No authentication, use peer or register= config */ 09032 username = p->authname; 09033 secret = p->peersecret; 09034 md5secret = p->peermd5secret; 09035 } 09036 if (ast_strlen_zero(username)) /* We have no authentication */ 09037 return -1; 09038 09039 09040 /* Calculate SIP digest response */ 09041 snprintf(a1,sizeof(a1),"%s:%s:%s", username, p->realm, secret); 09042 snprintf(a2,sizeof(a2),"%s:%s", sip_methods[method].text, uri); 09043 if (!ast_strlen_zero(md5secret)) 09044 ast_copy_string(a1_hash, md5secret, sizeof(a1_hash)); 09045 else 09046 ast_md5_hash(a1_hash,a1); 09047 ast_md5_hash(a2_hash,a2); 09048 09049 p->noncecount++; 09050 if (!ast_strlen_zero(p->qop)) 09051 snprintf(resp,sizeof(resp),"%s:%s:%08x:%s:%s:%s", a1_hash, p->nonce, p->noncecount, cnonce, "auth", a2_hash); 09052 else 09053 snprintf(resp,sizeof(resp),"%s:%s:%s", a1_hash, p->nonce, a2_hash); 09054 ast_md5_hash(resp_hash, resp); 09055 /* XXX We hard code our qop to "auth" for now. XXX */ 09056 if (!ast_strlen_zero(p->qop)) 09057 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); 09058 else 09059 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); 09060 09061 return 0; 09062 }
|
|
build_route: Build route list from Record-Route header ---
Definition at line 5983 of file chan_sip.c. References __get_header(), ast_log(), free_old_route(), sip_route::hop, LOG_DEBUG, malloc, sip_route::next, sip_pvt::route, and sip_pvt::route_persistant. Referenced by handle_request_invite(), and handle_response_invite(). 05984 { 05985 struct sip_route *thishop, *head, *tail; 05986 int start = 0; 05987 int len; 05988 char *rr, *contact, *c; 05989 05990 /* Once a persistant route is set, don't fool with it */ 05991 if (p->route && p->route_persistant) { 05992 ast_log(LOG_DEBUG, "build_route: Retaining previous route: <%s>\n", p->route->hop); 05993 return; 05994 } 05995 05996 if (p->route) { 05997 free_old_route(p->route); 05998 p->route = NULL; 05999 } 06000 06001 p->route_persistant = backwards; 06002 06003 /* We build up head, then assign it to p->route when we're done */ 06004 head = NULL; tail = head; 06005 /* 1st we pass through all the hops in any Record-Route headers */ 06006 for (;;) { 06007 /* Each Record-Route header */ 06008 rr = __get_header(req, "Record-Route", &start); 06009 if (*rr == '\0') break; 06010 for (;;) { 06011 /* Each route entry */ 06012 /* Find < */ 06013 rr = strchr(rr, '<'); 06014 if (!rr) break; /* No more hops */ 06015 ++rr; 06016 len = strcspn(rr, ">") + 1; 06017 /* Make a struct route */ 06018 thishop = malloc(sizeof(*thishop) + len); 06019 if (thishop) { 06020 ast_copy_string(thishop->hop, rr, len); 06021 ast_log(LOG_DEBUG, "build_route: Record-Route hop: <%s>\n", thishop->hop); 06022 /* Link in */ 06023 if (backwards) { 06024 /* Link in at head so they end up in reverse order */ 06025 thishop->next = head; 06026 head = thishop; 06027 /* If this was the first then it'll be the tail */ 06028 if (!tail) tail = thishop; 06029 } else { 06030 thishop->next = NULL; 06031 /* Link in at the end */ 06032 if (tail) 06033 tail->next = thishop; 06034 else 06035 head = thishop; 06036 tail = thishop; 06037 } 06038 } 06039 rr += len; 06040 } 06041 } 06042 06043 /* Only append the contact if we are dealing with a strict router */ 06044 if (!head || (!ast_strlen_zero(head->hop) && strstr(head->hop,";lr") == NULL) ) { 06045 /* 2nd append the Contact: if there is one */ 06046 /* Can be multiple Contact headers, comma separated values - we just take the first */ 06047 contact = get_header(req, "Contact"); 06048 if (!ast_strlen_zero(contact)) { 06049 ast_log(LOG_DEBUG, "build_route: Contact hop: %s\n", contact); 06050 /* Look for <: delimited address */ 06051 c = strchr(contact, '<'); 06052 if (c) { 06053 /* Take to > */ 06054 ++c; 06055 len = strcspn(c, ">") + 1; 06056 } else { 06057 /* No <> - just take the lot */ 06058 c = contact; 06059 len = strlen(contact) + 1; 06060 } 06061 thishop = malloc(sizeof(*thishop) + len); 06062 if (thishop) { 06063 ast_copy_string(thishop->hop, c, len); 06064 thishop->next = NULL; 06065 /* Goes at the end */ 06066 if (tail) 06067 tail->next = thishop; 06068 else 06069 head = thishop; 06070 } 06071 } 06072 } 06073 06074 /* Store as new route */ 06075 p->route = head; 06076 06077 /* For debugging dump what we ended up with */ 06078 if (sip_debug_test_pvt(p)) 06079 list_route(p->route); 06080 }
|
|
build_rpid: Build the Remote Party-ID & From using callingpres options ---
Definition at line 4644 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_strlen_zero(), sip_pvt::callingpres, ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, default_callerid, sip_pvt::fromdomain, sip_pvt::fromuser, LOG_WARNING, sip_pvt::ourip, sip_pvt::owner, sip_pvt::rpid, sip_pvt::rpid_from, strdup, and sip_pvt::tag. 04645 { 04646 int send_pres_tags = 1; 04647 const char *privacy=NULL; 04648 const char *screen=NULL; 04649 char buf[256]; 04650 const char *clid = default_callerid; 04651 const char *clin = NULL; 04652 char iabuf[INET_ADDRSTRLEN]; 04653 const char *fromdomain; 04654 04655 if (p->rpid || p->rpid_from) 04656 return; 04657 04658 if (p->owner && p->owner->cid.cid_num) 04659 clid = p->owner->cid.cid_num; 04660 if (p->owner && p->owner->cid.cid_name) 04661 clin = p->owner->cid.cid_name; 04662 if (ast_strlen_zero(clin)) 04663 clin = clid; 04664 04665 switch (p->callingpres) { 04666 case AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED: 04667 privacy = "off"; 04668 screen = "no"; 04669 break; 04670 case AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN: 04671 privacy = "off"; 04672 screen = "pass"; 04673 break; 04674 case AST_PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN: 04675 privacy = "off"; 04676 screen = "fail"; 04677 break; 04678 case AST_PRES_ALLOWED_NETWORK_NUMBER: 04679 privacy = "off"; 04680 screen = "yes"; 04681 break; 04682 case AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED: 04683 privacy = "full"; 04684 screen = "no"; 04685 break; 04686 case AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN: 04687 privacy = "full"; 04688 screen = "pass"; 04689 break; 04690 case AST_PRES_PROHIB_USER_NUMBER_FAILED_SCREEN: 04691 privacy = "full"; 04692 screen = "fail"; 04693 break; 04694 case AST_PRES_PROHIB_NETWORK_NUMBER: 04695 privacy = "full"; 04696 screen = "pass"; 04697 break; 04698 case AST_PRES_NUMBER_NOT_AVAILABLE: 04699 send_pres_tags = 0; 04700 break; 04701 default: 04702 ast_log(LOG_WARNING, "Unsupported callingpres (%d)\n", p->callingpres); 04703 if ((p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED) 04704 privacy = "full"; 04705 else 04706 privacy = "off"; 04707 screen = "no"; 04708 break; 04709 } 04710 04711 fromdomain = ast_strlen_zero(p->fromdomain) ? ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip) : p->fromdomain; 04712 04713 snprintf(buf, sizeof(buf), "\"%s\" <sip:%s@%s>", clin, clid, fromdomain); 04714 if (send_pres_tags) 04715 snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), ";privacy=%s;screen=%s", privacy, screen); 04716 p->rpid = strdup(buf); 04717 04718 snprintf(buf, sizeof(buf), "\"%s\" <sip:%s@%s>;tag=%s", clin, 04719 ast_strlen_zero(p->fromuser) ? clid : p->fromuser, 04720 fromdomain, p->tag); 04721 p->rpid_from = strdup(buf); 04722 }
|
|
build_user: Initiate a SIP user structure from sip.conf ---
Definition at line 11904 of file chan_sip.c. References ast_append_ha(), ast_callerid_split(), ast_cdr_amaflags2int(), ast_copy_flags, ast_free_ha(), ast_get_group(), ast_log(), ast_parse_allow_disallow(), ast_parse_caller_presentation(), ast_strdupa, ast_variable_new(), ASTOBJ_INIT, default_context, default_language, ast_flags::flags, format, global_capability, global_flags, global_musicclass, handle_common_options(), ast_variable::lineno, LOG_WARNING, malloc, ast_variable::name, ast_variable::next, prefs, SIP_FLAGS_TO_COPY, suserobjs, user, and ast_variable::value. 11905 { 11906 struct sip_user *user; 11907 int format; 11908 struct ast_ha *oldha = NULL; 11909 char *varname = NULL, *varval = NULL; 11910 struct ast_variable *tmpvar = NULL; 11911 struct ast_flags userflags = {(0)}; 11912 struct ast_flags mask = {(0)}; 11913 11914 11915 user = (struct sip_user *)malloc(sizeof(struct sip_user)); 11916 if (!user) { 11917 return NULL; 11918 } 11919 memset(user, 0, sizeof(struct sip_user)); 11920 suserobjs++; 11921 ASTOBJ_INIT(user); 11922 ast_copy_string(user->name, name, sizeof(user->name)); 11923 oldha = user->ha; 11924 user->ha = NULL; 11925 ast_copy_flags(user, &global_flags, SIP_FLAGS_TO_COPY); 11926 user->capability = global_capability; 11927 user->prefs = prefs; 11928 /* set default context */ 11929 strcpy(user->context, default_context); 11930 strcpy(user->language, default_language); 11931 strcpy(user->musicclass, global_musicclass); 11932 while(v) { 11933 if (handle_common_options(&userflags, &mask, v)) { 11934 v = v->next; 11935 continue; 11936 } 11937 11938 if (!strcasecmp(v->name, "context")) { 11939 ast_copy_string(user->context, v->value, sizeof(user->context)); 11940 } else if (!strcasecmp(v->name, "subscribecontext")) { 11941 ast_copy_string(user->subscribecontext, v->value, sizeof(user->subscribecontext)); 11942 } else if (!strcasecmp(v->name, "setvar")) { 11943 varname = ast_strdupa(v->value); 11944 if (varname && (varval = strchr(varname,'='))) { 11945 *varval = '\0'; 11946 varval++; 11947 if ((tmpvar = ast_variable_new(varname, varval))) { 11948 tmpvar->next = user->chanvars; 11949 user->chanvars = tmpvar; 11950 } 11951 } 11952 } else if (!strcasecmp(v->name, "permit") || 11953 !strcasecmp(v->name, "deny")) { 11954 user->ha = ast_append_ha(v->name, v->value, user->ha); 11955 } else if (!strcasecmp(v->name, "secret")) { 11956 ast_copy_string(user->secret, v->value, sizeof(user->secret)); 11957 } else if (!strcasecmp(v->name, "md5secret")) { 11958 ast_copy_string(user->md5secret, v->value, sizeof(user->md5secret)); 11959 } else if (!strcasecmp(v->name, "callerid")) { 11960 ast_callerid_split(v->value, user->cid_name, sizeof(user->cid_name), user->cid_num, sizeof(user->cid_num)); 11961 } else if (!strcasecmp(v->name, "callgroup")) { 11962 user->callgroup = ast_get_group(v->value); 11963 } else if (!strcasecmp(v->name, "pickupgroup")) { 11964 user->pickupgroup = ast_get_group(v->value); 11965 } else if (!strcasecmp(v->name, "language")) { 11966 ast_copy_string(user->language, v->value, sizeof(user->language)); 11967 } else if (!strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) { 11968 ast_copy_string(user->musicclass, v->value, sizeof(user->musicclass)); 11969 } else if (!strcasecmp(v->name, "accountcode")) { 11970 ast_copy_string(user->accountcode, v->value, sizeof(user->accountcode)); 11971 } else if (!strcasecmp(v->name, "call-limit") || !strcasecmp(v->name, "incominglimit")) { 11972 user->call_limit = atoi(v->value); 11973 if (user->call_limit < 0) 11974 user->call_limit = 0; 11975 } else if (!strcasecmp(v->name, "amaflags")) { 11976 format = ast_cdr_amaflags2int(v->value); 11977 if (format < 0) { 11978 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno); 11979 } else { 11980 user->amaflags = format; 11981 } 11982 } else if (!strcasecmp(v->name, "allow")) { 11983 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1); 11984 } else if (!strcasecmp(v->name, "disallow")) { 11985 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 0); 11986 } else if (!strcasecmp(v->name, "callingpres")) { 11987 user->callingpres = ast_parse_caller_presentation(v->value); 11988 if (user->callingpres == -1) 11989 user->callingpres = atoi(v->value); 11990 } 11991 /*else if (strcasecmp(v->name,"type")) 11992 * ast_log(LOG_WARNING, "Ignoring %s\n", v->name); 11993 */ 11994 v = v->next; 11995 } 11996 ast_copy_flags(user, &userflags, mask.flags); 11997 ast_free_ha(oldha); 11998 return user; 11999 }
|
|
build_via: Build a Via header for a request ---
Definition at line 1074 of file chan_sip.c. References ast_inet_ntoa(), ast_test_flag, sip_pvt::branch, sip_pvt::ourip, 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(), and transmit_register(). 01075 { 01076 char iabuf[INET_ADDRSTRLEN]; 01077 01078 /* z9hG4bK is a magic cookie. See RFC 3261 section 8.1.1.7 */ 01079 if (ast_test_flag(p, SIP_NAT) & SIP_NAT_RFC3581) 01080 snprintf(buf, len, "SIP/2.0/UDP %s:%d;branch=z9hG4bK%08x;rport", ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip), ourport, p->branch); 01081 else /* Work around buggy UNIDEN UIP200 firmware */ 01082 snprintf(buf, len, "SIP/2.0/UDP %s:%d;branch=z9hG4bK%08x", ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip), ourport, p->branch); 01083 }
|
|
cb_extensionstate: Callback for the devicestate notification (SUBSCRIBE) support subsystem ---
Definition at line 6326 of file chan_sip.c. References append_history(), AST_EXTENSION_DEACTIVATED, AST_EXTENSION_REMOVED, ast_extension_state2str(), ast_verbose(), sip_pvt::autokillid, sip_pvt::laststate, NONE, option_debug, sip_cancel_destroy(), sip_scheddestroy(), sip_pvt::stateid, sip_pvt::subscribed, transmit_state_notify(), sip_pvt::username, VERBOSE_PREFIX_1, and VERBOSE_PREFIX_2. Referenced by handle_request_subscribe(). 06327 { 06328 struct sip_pvt *p = data; 06329 06330 switch(state) { 06331 case AST_EXTENSION_DEACTIVATED: /* Retry after a while */ 06332 case AST_EXTENSION_REMOVED: /* Extension is gone */ 06333 if (p->autokillid > -1) 06334 sip_cancel_destroy(p); /* Remove subscription expiry for renewals */ 06335 sip_scheddestroy(p, 15000); /* Delete subscription in 15 secs */ 06336 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); 06337 p->stateid = -1; 06338 p->subscribed = NONE; 06339 append_history(p, "Subscribestatus", state == AST_EXTENSION_REMOVED ? "HintRemoved" : "Deactivated"); 06340 break; 06341 default: /* Tell user */ 06342 p->laststate = state; 06343 break; 06344 } 06345 transmit_state_notify(p, state, 1, 1); 06346 06347 if (option_debug > 1) 06348 ast_verbose(VERBOSE_PREFIX_1 "Extension Changed %s new state %s for Notify User %s\n", exten, ast_extension_state2str(state), p->username); 06349 return 0; 06350 }
|
|
check_auth: Check user authorization from peer definition ---
Definition at line 6101 of file chan_sip.c. References ast_log(), ast_md5_hash(), ast_strlen_zero(), ast_test_flag, get_header(), global_allowguest, global_realm, LOG_DEBUG, LOG_NOTICE, sip_methods, SIP_OSPAUTH, SIP_OSPAUTH_EXCLUSIVE, SIP_OSPAUTH_GATEWAY, SIP_OSPAUTH_NO, SIP_OSPAUTH_PROXY, SIP_REGISTER, sip_scheddestroy(), SIP_SUBSCRIBE, sipdebug, text, thread_safe_rand(), and transmit_response_with_auth(). Referenced by check_user_full(), and register_verify(). 06102 { 06103 int res = -1; 06104 char *response = "407 Proxy Authentication Required"; 06105 char *reqheader = "Proxy-Authorization"; 06106 char *respheader = "Proxy-Authenticate"; 06107 char *authtoken; 06108 #ifdef OSP_SUPPORT 06109 char *osptoken; 06110 #endif 06111 /* Always OK if no secret */ 06112 if (ast_strlen_zero(secret) && ast_strlen_zero(md5secret) 06113 #ifdef OSP_SUPPORT 06114 && !ast_test_flag(p, SIP_OSPAUTH) 06115 && global_allowguest != 2 06116 #endif 06117 ) 06118 return 0; 06119 if (sipmethod == SIP_REGISTER || sipmethod == SIP_SUBSCRIBE) { 06120 /* On a REGISTER, we have to use 401 and its family of headers instead of 407 and its family 06121 of headers -- GO SIP! Whoo hoo! Two things that do the same thing but are used in 06122 different circumstances! What a surprise. */ 06123 response = "401 Unauthorized"; 06124 reqheader = "Authorization"; 06125 respheader = "WWW-Authenticate"; 06126 } 06127 #ifdef OSP_SUPPORT 06128 else { 06129 ast_log (LOG_DEBUG, "Checking OSP Authentication!\n"); 06130 osptoken = get_header (req, "P-OSP-Auth-Token"); 06131 switch (ast_test_flag (p, SIP_OSPAUTH)) { 06132 case SIP_OSPAUTH_NO: 06133 break; 06134 case SIP_OSPAUTH_GATEWAY: 06135 if (ast_strlen_zero (osptoken)) { 06136 if (ast_strlen_zero (secret) && ast_strlen_zero (md5secret)) { 06137 return (0); 06138 } 06139 } 06140 else { 06141 return (check_osptoken (p, osptoken)); 06142 } 06143 break; 06144 case SIP_OSPAUTH_PROXY: 06145 if (ast_strlen_zero (osptoken)) { 06146 return (0); 06147 } 06148 else { 06149 return (check_osptoken (p, osptoken)); 06150 } 06151 break; 06152 case SIP_OSPAUTH_EXCLUSIVE: 06153 if (ast_strlen_zero (osptoken)) { 06154 return (-1); 06155 } 06156 else { 06157 return (check_osptoken (p, osptoken)); 06158 } 06159 break; 06160 default: 06161 return (-1); 06162 } 06163 } 06164 #endif 06165 authtoken = get_header(req, reqheader); 06166 if (ignore && !ast_strlen_zero(randdata) && ast_strlen_zero(authtoken)) { 06167 /* This is a retransmitted invite/register/etc, don't reconstruct authentication 06168 information */ 06169 if (!ast_strlen_zero(randdata)) { 06170 if (!reliable) { 06171 /* Resend message if this was NOT a reliable delivery. Otherwise the 06172 retransmission should get it */ 06173 transmit_response_with_auth(p, response, req, randdata, reliable, respheader, 0); 06174 /* Schedule auto destroy in 15 seconds */ 06175 sip_scheddestroy(p, 15000); 06176 } 06177 res = 1; 06178 } 06179 } else if (ast_strlen_zero(randdata) || ast_strlen_zero(authtoken)) { 06180 snprintf(randdata, randlen, "%08x", thread_safe_rand()); 06181 transmit_response_with_auth(p, response, req, randdata, reliable, respheader, 0); 06182 /* Schedule auto destroy in 15 seconds */ 06183 sip_scheddestroy(p, 15000); 06184 res = 1; 06185 } else { 06186 /* Whoever came up with the authentication section of SIP can suck my %&#$&* for not putting 06187 an example in the spec of just what it is you're doing a hash on. */ 06188 char a1[256]; 06189 char a2[256]; 06190 char a1_hash[256]; 06191 char a2_hash[256]; 06192 char resp[256]; 06193 char resp_hash[256]=""; 06194 char tmp[256]; 06195 char *c; 06196 char *z; 06197 char *ua_hash =""; 06198 char *resp_uri =""; 06199 char *nonce = ""; 06200 char *digestusername = ""; 06201 int wrongnonce = 0; 06202 char *usednonce = randdata; 06203 06204 /* Find their response among the mess that we'r sent for comparison */ 06205 ast_copy_string(tmp, authtoken, sizeof(tmp)); 06206 c = tmp; 06207 06208 while(c) { 06209 c = ast_skip_blanks(c); 06210 if (!*c) 06211 break; 06212 if (!strncasecmp(c, "response=", strlen("response="))) { 06213 c+= strlen("response="); 06214 if ((*c == '\"')) { 06215 ua_hash=++c; 06216 if ((c = strchr(c,'\"'))) 06217 *c = '\0'; 06218 06219 } else { 06220 ua_hash=c; 06221 if ((c = strchr(c,','))) 06222 *c = '\0'; 06223 } 06224 06225 } else if (!strncasecmp(c, "uri=", strlen("uri="))) { 06226 c+= strlen("uri="); 06227 if ((*c == '\"')) { 06228 resp_uri=++c; 06229 if ((c = strchr(c,'\"'))) 06230 *c = '\0'; 06231 } else { 06232 resp_uri=c; 06233 if ((c = strchr(c,','))) 06234 *c = '\0'; 06235 } 06236 06237 } else if (!strncasecmp(c, "username=", strlen("username="))) { 06238 c+= strlen("username="); 06239 if ((*c == '\"')) { 06240 digestusername=++c; 06241 if((c = strchr(c,'\"'))) 06242 *c = '\0'; 06243 } else { 06244 digestusername=c; 06245 if((c = strchr(c,','))) 06246 *c = '\0'; 06247 } 06248 } else if (!strncasecmp(c, "nonce=", strlen("nonce="))) { 06249 c+= strlen("nonce="); 06250 if ((*c == '\"')) { 06251 nonce=++c; 06252 if ((c = strchr(c,'\"'))) 06253 *c = '\0'; 06254 } else { 06255 nonce=c; 06256 if ((c = strchr(c,','))) 06257 *c = '\0'; 06258 } 06259 06260 } else 06261 if ((z = strchr(c,' ')) || (z = strchr(c,','))) c=z; 06262 if (c) 06263 c++; 06264 } 06265 /* Verify that digest username matches the username we auth as */ 06266 if (strcmp(username, digestusername)) { 06267 /* Oops, we're trying something here */ 06268 return -2; 06269 } 06270 06271 /* Verify nonce from request matches our nonce. If not, send 401 with new nonce */ 06272 if (strncasecmp(randdata, nonce, randlen)) { 06273 wrongnonce = 1; 06274 usednonce = nonce; 06275 } 06276 06277 snprintf(a1, sizeof(a1), "%s:%s:%s", username, global_realm, secret); 06278 06279 if (!ast_strlen_zero(resp_uri)) 06280 snprintf(a2, sizeof(a2), "%s:%s", sip_methods[sipmethod].text, resp_uri); 06281 else 06282 snprintf(a2, sizeof(a2), "%s:%s", sip_methods[sipmethod].text, uri); 06283 06284 if (!ast_strlen_zero(md5secret)) 06285 snprintf(a1_hash, sizeof(a1_hash), "%s", md5secret); 06286 else 06287 ast_md5_hash(a1_hash, a1); 06288 06289 ast_md5_hash(a2_hash, a2); 06290 06291 snprintf(resp, sizeof(resp), "%s:%s:%s", a1_hash, usednonce, a2_hash); 06292 ast_md5_hash(resp_hash, resp); 06293 06294 if (wrongnonce) { 06295 06296 snprintf(randdata, randlen, "%08x", thread_safe_rand()); 06297 if (ua_hash && !strncasecmp(ua_hash, resp_hash, strlen(resp_hash))) { 06298 if (sipdebug) 06299 ast_log(LOG_NOTICE, "stale nonce received from '%s'\n", get_header(req, "To")); 06300 /* We got working auth token, based on stale nonce . */ 06301 transmit_response_with_auth(p, response, req, randdata, reliable, respheader, 1); 06302 } else { 06303 /* Everything was wrong, so give the device one more try with a new challenge */ 06304 if (sipdebug) 06305 ast_log(LOG_NOTICE, "Bad authentication received from '%s'\n", get_header(req, "To")); 06306 transmit_response_with_auth(p, response, req, randdata, reliable, respheader, 0); 06307 } 06308 06309 /* Schedule auto destroy in 15 seconds */ 06310 sip_scheddestroy(p, 15000); 06311 return 1; 06312 } 06313 /* resp_hash now has the expected response, compare the two */ 06314 if (ua_hash && !strncasecmp(ua_hash, resp_hash, strlen(resp_hash))) { 06315 /* Auth is OK */ 06316 res = 0; 06317 } 06318 } 06319 /* Failure */ 06320 return res; 06321 }
|
|
check_pendings: Check pending actions on SIP call ---
Definition at line 9436 of file chan_sip.c. References ast_clear_flag, ast_log(), ast_set_flag, ast_test_flag, sip_pvt::callid, LOG_DEBUG, SIP_BYE, SIP_NEEDDESTROY, SIP_NEEDREINVITE, SIP_PENDINGBYE, transmit_reinvite_with_sdp(), and transmit_request_with_auth(). Referenced by handle_request(), and handle_response_invite(). 09437 { 09438 /* Go ahead and send bye at this point */ 09439 if (ast_test_flag(p, SIP_PENDINGBYE)) { 09440 transmit_request_with_auth(p, SIP_BYE, 0, 1, 1); 09441 ast_set_flag(p, SIP_NEEDDESTROY); 09442 ast_clear_flag(p, SIP_NEEDREINVITE); 09443 } else if (ast_test_flag(p, SIP_NEEDREINVITE)) { 09444 ast_log(LOG_DEBUG, "Sending pending reinvite on '%s'\n", p->callid); 09445 /* Didn't get to reinvite yet, so do it now */ 09446 transmit_reinvite_with_sdp(p); 09447 ast_clear_flag(p, SIP_NEEDREINVITE); 09448 } 09449 }
|
|
check_sip_domain: Check if domain part of uri is local to our server
Definition at line 11773 of file chan_sip.c. References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_strlen_zero(), domain::context, domain::domain, list, and result. Referenced by func_check_sipdomain(), get_destination(), and register_verify(). 11774 { 11775 struct domain *d; 11776 int result = 0; 11777 11778 AST_LIST_LOCK(&domain_list); 11779 AST_LIST_TRAVERSE(&domain_list, d, list) { 11780 if (strcasecmp(d->domain, domain)) 11781 continue; 11782 11783 if (len && !ast_strlen_zero(d->context)) 11784 ast_copy_string(context, d->context, len); 11785 11786 result = 1; 11787 break; 11788 } 11789 AST_LIST_UNLOCK(&domain_list); 11790 11791 return result; 11792 }
|
|
check_user: Find user ---
Definition at line 7221 of file chan_sip.c. References check_user_full(). Referenced by handle_request_invite(). 07222 { 07223 return check_user_full(p, req, sipmethod, uri, reliable, sin, ignore, NULL, 0); 07224 }
|
|
check_user_full: Check if matching user or peer is defined ---
Definition at line 6958 of file chan_sip.c. References sip_peer::accountcode, sip_peer::amaflags, ast_apply_ha(), ast_copy_flags, ast_inet_ntoa(), ast_log(), AST_RTP_DTMF, ast_rtp_setnat(), ast_set_flag, ast_shrink_phone_number(), ast_strlen_zero(), ast_test_flag, ast_uri_decode(), ast_variable_new(), ast_verbose(), ASTOBJ_UNREF, build_contact(), sip_peer::call_limit, sip_peer::callgroup, sip_peer::callingpres, sip_pvt::callingpres, sip_peer::capability, sip_peer::chanvars, check_auth(), sip_peer::cid_name, sip_pvt::cid_name, sip_peer::cid_num, sip_pvt::cid_num, sip_peer::context, debug, sip_pvt::exten, find_peer(), find_user(), sip_pvt::from, sip_peer::fullcontact, get_calleridname(), get_header(), get_in_brackets(), get_rpid_num(), global_allowguest, global_flags, sip_peer::language, sip_peer::lastms, LOG_DEBUG, LOG_NOTICE, sip_peer::mailbox, sip_peer::maxms, sip_peer::md5secret, ast_variable::next, sip_pvt::our_contact, pedanticsipchecking, sip_pvt::peermd5secret, sip_pvt::peersecret, sip_peer::pickupgroup, sip_peer::prefs, sip_pvt::randdata, sip_pvt::recv, sip_pvt::rtp, sip_peer::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, SIP_NAT_ROUTE, SIP_OSPAUTH, SIP_SUBSCRIBE, SIP_TRUSTRPID, sip_peer::sipoptions, sip_pvt::sipoptions, sip_peer::subscribecontext, sip_pvt::subscribecontext, t, sip_pvt::timer_t1, user, sip_peer::username, and sip_pvt::vrtp. Referenced by check_user(), and handle_request_subscribe(). 06959 { 06960 struct sip_user *user = NULL; 06961 struct sip_peer *peer; 06962 char *of, from[256], *c; 06963 char *rpid,rpid_num[50]; 06964 char iabuf[INET_ADDRSTRLEN]; 06965 int res = 0; 06966 char *t; 06967 char calleridname[50]; 06968 int debug=sip_debug_test_addr(sin); 06969 struct ast_variable *tmpvar = NULL, *v = NULL; 06970 06971 /* Terminate URI */ 06972 t = uri; 06973 while(*t && (*t > 32) && (*t != ';')) 06974 t++; 06975 *t = '\0'; 06976 of = get_header(req, "From"); 06977 if (pedanticsipchecking) 06978 ast_uri_decode(of); 06979 06980 ast_copy_string(from, of, sizeof(from)); 06981 06982 memset(calleridname,0,sizeof(calleridname)); 06983 get_calleridname(from, calleridname, sizeof(calleridname)); 06984 if (calleridname[0]) 06985 ast_copy_string(p->cid_name, calleridname, sizeof(p->cid_name)); 06986 06987 rpid = get_header(req, "Remote-Party-ID"); 06988 memset(rpid_num,0,sizeof(rpid_num)); 06989 if (!ast_strlen_zero(rpid)) 06990 p->callingpres = get_rpid_num(rpid,rpid_num, sizeof(rpid_num)); 06991 06992 of = get_in_brackets(from); 06993 if (ast_strlen_zero(p->exten)) { 06994 t = uri; 06995 if (!strncmp(t, "sip:", 4)) 06996 t+= 4; 06997 ast_copy_string(p->exten, t, sizeof(p->exten)); 06998 t = strchr(p->exten, '@'); 06999 if (t) 07000 *t = '\0'; 07001 if (ast_strlen_zero(p->our_contact)) 07002 build_contact(p); 07003 } 07004 /* save the URI part of the From header */ 07005 ast_copy_string(p->from, of, sizeof(p->from)); 07006 if (strncmp(of, "sip:", 4)) { 07007 ast_log(LOG_NOTICE, "From address missing 'sip:', using it anyway\n"); 07008 } else 07009 of += 4; 07010 /* Get just the username part */ 07011 if ((c = strchr(of, '@'))) { 07012 *c = '\0'; 07013 if ((c = strchr(of, ':'))) 07014 *c = '\0'; 07015 ast_copy_string(p->cid_num, of, sizeof(p->cid_num)); 07016 ast_shrink_phone_number(p->cid_num); 07017 } 07018 if (ast_strlen_zero(of)) 07019 return 0; 07020 07021 if (!mailbox) /* If it's a mailbox SUBSCRIBE, don't check users */ 07022 user = find_user(of, 1); 07023 07024 /* Find user based on user name in the from header */ 07025 if (user && ast_apply_ha(user->ha, sin)) { 07026 ast_copy_flags(p, user, SIP_FLAGS_TO_COPY); 07027 /* copy channel vars */ 07028 for (v = user->chanvars ; v ; v = v->next) { 07029 if ((tmpvar = ast_variable_new(v->name, v->value))) { 07030 tmpvar->next = p->chanvars; 07031 p->chanvars = tmpvar; 07032 } 07033 } 07034 p->prefs = user->prefs; 07035 /* replace callerid if rpid found, and not restricted */ 07036 if (!ast_strlen_zero(rpid_num) && ast_test_flag(p, SIP_TRUSTRPID)) { 07037 if (*calleridname) 07038 ast_copy_string(p->cid_name, calleridname, sizeof(p->cid_name)); 07039 ast_copy_string(p->cid_num, rpid_num, sizeof(p->cid_num)); 07040 ast_shrink_phone_number(p->cid_num); 07041 } 07042 07043 if (p->rtp) { 07044 ast_log(LOG_DEBUG, "Setting NAT on RTP to %d\n", (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE)); 07045 ast_rtp_setnat(p->rtp, (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE)); 07046 } 07047 if (p->vrtp) { 07048 ast_log(LOG_DEBUG, "Setting NAT on VRTP to %d\n", (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE)); 07049 ast_rtp_setnat(p->vrtp, (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE)); 07050 } 07051 if (!(res = check_auth(p, req, p->randdata, sizeof(p->randdata), user->name, user->secret, user->md5secret, sipmethod, uri, reliable, ignore))) { 07052 sip_cancel_destroy(p); 07053 ast_copy_flags(p, user, SIP_FLAGS_TO_COPY); 07054 /* Copy SIP extensions profile from INVITE */ 07055 if (p->sipoptions) 07056 user->sipoptions = p->sipoptions; 07057 07058 /* If we have a call limit, set flag */ 07059 if (user->call_limit) 07060 ast_set_flag(p, SIP_CALL_LIMIT); 07061 if (!ast_strlen_zero(user->context)) 07062 ast_copy_string(p->context, user->context, sizeof(p->context)); 07063 if (!ast_strlen_zero(user->cid_num) && !ast_strlen_zero(p->cid_num)) { 07064 ast_copy_string(p->cid_num, user->cid_num, sizeof(p->cid_num)); 07065 ast_shrink_phone_number(p->cid_num); 07066 } 07067 if (!ast_strlen_zero(user->cid_name) && !ast_strlen_zero(p->cid_num)) 07068 ast_copy_string(p->cid_name, user->cid_name, sizeof(p->cid_name)); 07069 ast_copy_string(p->username, user->name, sizeof(p->username)); 07070 ast_copy_string(p->peersecret, user->secret, sizeof(p->peersecret)); 07071 ast_copy_string(p->subscribecontext, user->subscribecontext, sizeof(p->subscribecontext)); 07072 ast_copy_string(p->peermd5secret, user->md5secret, sizeof(p->peermd5secret)); 07073 ast_copy_string(p->accountcode, user->accountcode, sizeof(p->accountcode)); 07074 ast_copy_string(p->language, user->language, sizeof(p->language)); 07075 ast_copy_string(p->musicclass, user->musicclass, sizeof(p->musicclass)); 07076 p->amaflags = user->amaflags; 07077 p->callgroup = user->callgroup; 07078 p->pickupgroup = user->pickupgroup; 07079 p->callingpres = user->callingpres; 07080 p->capability = user->capability; 07081 p->jointcapability = user->capability; 07082 if (p->peercapability) 07083 p->jointcapability &= p->peercapability; 07084 if ((ast_test_flag(p, SIP_DTMF) == SIP_DTMF_RFC2833) || (ast_test_flag(p, SIP_DTMF) == SIP_DTMF_AUTO)) 07085 p->noncodeccapability |= AST_RTP_DTMF; 07086 else 07087 p->noncodeccapability &= ~AST_RTP_DTMF; 07088 } 07089 if (user && debug) 07090 ast_verbose("Found user '%s'\n", user->name); 07091 } else { 07092 if (user) { 07093 if (!mailbox && debug) 07094 ast_verbose("Found user '%s', but fails host access\n", user->name); 07095 ASTOBJ_UNREF(user,sip_destroy_user); 07096 } 07097 user = NULL; 07098 } 07099 07100 if (!user) { 07101 /* If we didn't find a user match, check for peers */ 07102 if (sipmethod == SIP_SUBSCRIBE) 07103 /* For subscribes, match on peer name only */ 07104 peer = find_peer(of, NULL, 1); 07105 else 07106 /* Look for peer based on the IP address we received data from */ 07107 /* If peer is registered from this IP address or have this as a default 07108 IP address, this call is from the peer 07109 */ 07110 peer = find_peer(NULL, &p->recv, 1); 07111 07112 if (peer) { 07113 if (debug) 07114 ast_verbose("Found peer '%s'\n", peer->name); 07115 /* Take the peer */ 07116 ast_copy_flags(p, peer, SIP_FLAGS_TO_COPY); 07117 07118 /* Copy SIP extensions profile to peer */ 07119 if (p->sipoptions) 07120 peer->sipoptions = p->sipoptions; 07121 07122 /* replace callerid if rpid found, and not restricted */ 07123 if (!ast_strlen_zero(rpid_num) && ast_test_flag(p, SIP_TRUSTRPID)) { 07124 if (*calleridname) 07125 ast_copy_string(p->cid_name, calleridname, sizeof(p->cid_name)); 07126 ast_copy_string(p->cid_num, rpid_num, sizeof(p->cid_num)); 07127 ast_shrink_phone_number(p->cid_num); 07128 } 07129 if (p->rtp) { 07130 ast_log(LOG_DEBUG, "Setting NAT on RTP to %d\n", (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE)); 07131 ast_rtp_setnat(p->rtp, (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE)); 07132 } 07133 if (p->vrtp) { 07134 ast_log(LOG_DEBUG, "Setting NAT on VRTP to %d\n", (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE)); 07135 ast_rtp_setnat(p->vrtp, (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE)); 07136 } 07137 ast_copy_string(p->peersecret, peer->secret, sizeof(p->peersecret)); 07138 p->peersecret[sizeof(p->peersecret)-1] = '\0'; 07139 ast_copy_string(p->subscribecontext, peer->subscribecontext, sizeof(p->subscribecontext)); 07140 ast_copy_string(p->peermd5secret, peer->md5secret, sizeof(p->peermd5secret)); 07141 p->peermd5secret[sizeof(p->peermd5secret)-1] = '\0'; 07142 p->callingpres = peer->callingpres; 07143 if (peer->maxms && peer->lastms) 07144 p->timer_t1 = peer->lastms; 07145 if (ast_test_flag(peer, SIP_INSECURE_INVITE)) { 07146 /* Pretend there is no required authentication */ 07147 p->peersecret[0] = '\0'; 07148 p->peermd5secret[0] = '\0'; 07149 } 07150 if (!(res = check_auth(p, req, p->randdata, sizeof(p->randdata), peer->name, p->peersecret, p->peermd5secret, sipmethod, uri, reliable, ignore))) { 07151 ast_copy_flags(p, peer, SIP_FLAGS_TO_COPY); 07152 /* If we have a call limit, set flag */ 07153 if (peer->call_limit) 07154 ast_set_flag(p, SIP_CALL_LIMIT); 07155 ast_copy_string(p->peername, peer->name, sizeof(p->peername)); 07156 ast_copy_string(p->authname, peer->name, sizeof(p->authname)); 07157 /* copy channel vars */ 07158 for (v = peer->chanvars ; v ; v = v->next) { 07159 if ((tmpvar = ast_variable_new(v->name, v->value))) { 07160 tmpvar->next = p->chanvars; 07161 p->chanvars = tmpvar; 07162 } 07163 } 07164 if (mailbox) 07165 snprintf(mailbox, mailboxlen, ",%s,", peer->mailbox); 07166 if (!ast_strlen_zero(peer->username)) { 07167 ast_copy_string(p->username, peer->username, sizeof(p->username)); 07168 /* Use the default username for authentication on outbound calls */ 07169 ast_copy_string(p->authname, peer->username, sizeof(p->authname)); 07170 } 07171 if (!ast_strlen_zero(peer->cid_num) && !ast_strlen_zero(p->cid_num)) { 07172 ast_copy_string(p->cid_num, peer->cid_num, sizeof(p->cid_num)); 07173 ast_shrink_phone_number(p->cid_num); 07174 } 07175 if (!ast_strlen_zero(peer->cid_name) && !ast_strlen_zero(p->cid_name)) 07176 ast_copy_string(p->cid_name, peer->cid_name, sizeof(p->cid_name)); 07177 ast_copy_string(p->fullcontact, peer->fullcontact, sizeof(p->fullcontact)); 07178 if (!ast_strlen_zero(peer->context)) 07179 ast_copy_string(p->context, peer->context, sizeof(p->context)); 07180 ast_copy_string(p->peersecret, peer->secret, sizeof(p->peersecret)); 07181 ast_copy_string(p->peermd5secret, peer->md5secret, sizeof(p->peermd5secret)); 07182 ast_copy_string(p->language, peer->language, sizeof(p->language)); 07183 ast_copy_string(p->accountcode, peer->accountcode, sizeof(p->accountcode)); 07184 p->amaflags = peer->amaflags; 07185 p->callgroup = peer->callgroup; 07186 p->pickupgroup = peer->pickupgroup; 07187 p->capability = peer->capability; 07188 p->prefs = peer->prefs; 07189 p->jointcapability = peer->capability; 07190 if (p->peercapability) 07191 p->jointcapability &= p->peercapability; 07192 if ((ast_test_flag(p, SIP_DTMF) == SIP_DTMF_RFC2833) || (ast_test_flag(p, SIP_DTMF) == SIP_DTMF_AUTO)) 07193 p->noncodeccapability |= AST_RTP_DTMF; 07194 else 07195 p->noncodeccapability &= ~AST_RTP_DTMF; 07196 } 07197 ASTOBJ_UNREF(peer,sip_destroy_peer); 07198 } else { 07199 if (debug) 07200 ast_verbose("Found no matching peer or user for '%s:%d'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), p->recv.sin_addr), ntohs(p->recv.sin_port)); 07201 07202 /* do we allow guests? */ 07203 if (!global_allowguest) 07204 res = -1; /* we don't want any guests, authentication will fail */ 07205 #ifdef OSP_SUPPORT 07206 else if (global_allowguest == 2) { 07207 ast_copy_flags(p, &global_flags, SIP_OSPAUTH); 07208 res = check_auth(p, req, p->randdata, sizeof(p->randdata), "", "", "", sipmethod, uri, reliable, ignore); 07209 } 07210 #endif 07211 } 07212 07213 } 07214 07215 if (user) 07216 ASTOBJ_UNREF(user,sip_destroy_user); 07217 return res; 07218 }
|
|
check Via: header for hostname, port and rport request/answer
Definition at line 6834 of file chan_sip.c. References ahp, ast_gethostbyname(), ast_inet_ntoa(), ast_log(), ast_set_flag, ast_test_flag, ast_verbose(), DEFAULT_SIP_PORT, get_header(), hp, LOG_WARNING, sip_pvt::sa, sip_debug_test_pvt(), SIP_NAT, and SIP_NAT_ROUTE. Referenced by handle_request_bye(), handle_request_cancel(), handle_request_invite(), handle_request_register(), and handle_request_subscribe(). 06835 { 06836 char via[256]; 06837 char iabuf[INET_ADDRSTRLEN]; 06838 char *c, *pt; 06839 struct hostent *hp; 06840 struct ast_hostent ahp; 06841 06842 ast_copy_string(via, get_header(req, "Via"), sizeof(via)); 06843 06844 /* Check for rport */ 06845 c = strstr(via, ";rport"); 06846 if (c && (c[6] != '=')) /* rport query, not answer */ 06847 ast_set_flag(p, SIP_NAT_ROUTE); 06848 06849 c = strchr(via, ';'); 06850 if (c) 06851 *c = '\0'; 06852 06853 c = strchr(via, ' '); 06854 if (c) { 06855 *c = '\0'; 06856 c = ast_skip_blanks(c+1); 06857 if (strcasecmp(via, "SIP/2.0/UDP")) { 06858 ast_log(LOG_WARNING, "Don't know how to respond via '%s'\n", via); 06859 return -1; 06860 } 06861 pt = strchr(c, ':'); 06862 if (pt) 06863 *pt++ = '\0'; /* remember port pointer */ 06864 hp = ast_gethostbyname(c, &ahp); 06865 if (!hp) { 06866 ast_log(LOG_WARNING, "'%s' is not a valid host\n", c); 06867 return -1; 06868 } 06869 memset(&p->sa, 0, sizeof(p->sa)); 06870 p->sa.sin_family = AF_INET; 06871 memcpy(&p->sa.sin_addr, hp->h_addr, sizeof(p->sa.sin_addr)); 06872 p->sa.sin_port = htons(pt ? atoi(pt) : DEFAULT_SIP_PORT); 06873 06874 if (sip_debug_test_pvt(p)) { 06875 c = (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE) ? "NAT" : "non-NAT"; 06876 ast_verbose("Sending to %s : %d (%s)\n", ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr), ntohs(p->sa.sin_port), c); 06877 } 06878 } 06879 return 0; 06880 }
|
|
clear_realm_authentication: Clear realm authentication list (at reload) ---
Definition at line 11874 of file chan_sip.c. References free, and sip_auth::next. Referenced by sip_destroy_peer(), sip_do_reload(), and unload_module(). 11875 { 11876 struct sip_auth *a = authlist; 11877 struct sip_auth *b; 11878 11879 while (a) { 11880 b = a; 11881 a = a->next; 11882 free(b); 11883 } 11884 11885 return 1; 11886 }
|
|
clear_sip_domains: Clear our domain list (at reload)
Definition at line 11795 of file chan_sip.c. References AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, free, and list. Referenced by sip_do_reload(), and unload_module(). 11796 { 11797 struct domain *d; 11798 11799 AST_LIST_LOCK(&domain_list); 11800 while ((d = AST_LIST_REMOVE_HEAD(&domain_list, list))) 11801 free(d); 11802 AST_LIST_UNLOCK(&domain_list); 11803 }
|
|
complete_sip_debug_peer: Support routine for 'sip debug peer' CLI ---
Definition at line 8380 of file chan_sip.c. References complete_sip_peer(). 08381 { 08382 if (pos == 3) 08383 return complete_sip_peer(word, state, 0); 08384 08385 return NULL; 08386 }
|
|
complete_sip_peer: Do completion on peer name ---
Definition at line 8351 of file chan_sip.c. References ast_test_flag, ASTOBJ_CONTAINER_TRAVERSE, peerl, result, and strdup. Referenced by complete_sip_debug_peer(), complete_sip_prune_realtime_peer(), complete_sip_show_peer(), and complete_sipnotify(). 08352 { 08353 char *result = NULL; 08354 int wordlen = strlen(word); 08355 int which = 0; 08356 08357 ASTOBJ_CONTAINER_TRAVERSE(&peerl, !result, do { 08358 /* locking of the object is not required because only the name and flags are being compared */ 08359 if (!strncasecmp(word, iterator->name, wordlen)) { 08360 if (flags2 && !ast_test_flag((&iterator->flags_page2), flags2)) 08361 continue; 08362 if (++which > state) { 08363 result = strdup(iterator->name); 08364 } 08365 } 08366 } while(0) ); 08367 return result; 08368 }
|
|
complete_sip_prune_realtime_peer: Support routine for 'sip prune realtime peer' CLI ---
Definition at line 8451 of file chan_sip.c. References complete_sip_peer(), and SIP_PAGE2_RTCACHEFRIENDS. 08452 { 08453 if (pos == 4) 08454 return complete_sip_peer(word, state, SIP_PAGE2_RTCACHEFRIENDS); 08455 return NULL; 08456 }
|
|
complete_sip_prune_realtime_user: Support routine for 'sip prune realtime user' CLI ---
Definition at line 8459 of file chan_sip.c. References complete_sip_user(), and SIP_PAGE2_RTCACHEFRIENDS. 08460 { 08461 if (pos == 4) 08462 return complete_sip_user(word, state, SIP_PAGE2_RTCACHEFRIENDS); 08463 08464 return NULL; 08465 }
|
|
complete_sip_show_peer: Support routine for 'sip show peer' CLI ---
Definition at line 8371 of file chan_sip.c. References complete_sip_peer(). 08372 { 08373 if (pos == 3) 08374 return complete_sip_peer(word, state, 0); 08375 08376 return NULL; 08377 }
|
|
complete_sip_show_user: Support routine for 'sip show user' CLI ---
Definition at line 8409 of file chan_sip.c. References complete_sip_user(). 08410 { 08411 if (pos == 3) 08412 return complete_sip_user(word, state, 0); 08413 08414 return NULL; 08415 }
|
|
complete_sip_user: Do completion on user name ---
Definition at line 8389 of file chan_sip.c. References ast_test_flag, ASTOBJ_CONTAINER_TRAVERSE, result, strdup, and userl. Referenced by complete_sip_prune_realtime_user(), and complete_sip_show_user(). 08390 { 08391 char *result = NULL; 08392 int wordlen = strlen(word); 08393 int which = 0; 08394 08395 ASTOBJ_CONTAINER_TRAVERSE(&userl, !result, do { 08396 /* locking of the object is not required because only the name and flags are being compared */ 08397 if (!strncasecmp(word, iterator->name, wordlen)) { 08398 if (flags2 && !ast_test_flag(&(iterator->flags_page2), flags2)) 08399 continue; 08400 if (++which > state) { 08401 result = strdup(iterator->name); 08402 } 08403 } 08404 } while(0) ); 08405 return result; 08406 }
|
|
complete_sipch: Support routine for 'sip show channel' CLI ---
Definition at line 8329 of file chan_sip.c. References ast_mutex_lock(), ast_mutex_unlock(), sip_pvt::callid, iflist, sip_pvt::next, and strdup. 08330 { 08331 int which=0; 08332 struct sip_pvt *cur; 08333 char *c = NULL; 08334 08335 ast_mutex_lock(&iflock); 08336 cur = iflist; 08337 while(cur) { 08338 if (!strncasecmp(word, cur->callid, strlen(word))) { 08339 if (++which > state) { 08340 c = strdup(cur->callid); 08341 break; 08342 } 08343 } 08344 cur = cur->next; 08345 } 08346 ast_mutex_unlock(&iflock); 08347 return c; 08348 }
|
|
complete_sipnotify: Support routine for 'sip notify' CLI ---
Definition at line 8418 of file chan_sip.c. References ast_category_browse(), complete_sip_peer(), notify_types, and strdup. 08419 { 08420 char *c = NULL; 08421 08422 if (pos == 2) { 08423 int which = 0; 08424 char *cat; 08425 08426 /* do completion for notify type */ 08427 08428 if (!notify_types) 08429 return NULL; 08430 08431 cat = ast_category_browse(notify_types, NULL); 08432 while(cat) { 08433 if (!strncasecmp(word, cat, strlen(word))) { 08434 if (++which > state) { 08435 c = strdup(cat); 08436 break; 08437 } 08438 } 08439 cat = ast_category_browse(notify_types, cat); 08440 } 08441 return c; 08442 } 08443 08444 if (pos > 2) 08445 return complete_sip_peer(word, state, 0); 08446 08447 return NULL; 08448 }
|
|
copy_all_header: Copy all headers from one request to another ---
Definition at line 3780 of file chan_sip.c. References __get_header(), add_header(), and ast_strlen_zero(). Referenced by respprep(). 03781 { 03782 char *tmp; 03783 int start = 0; 03784 int copied = 0; 03785 for (;;) { 03786 tmp = __get_header(orig, field, &start); 03787 if (!ast_strlen_zero(tmp)) { 03788 /* Add what we're responding to */ 03789 add_header(req, field, tmp); 03790 copied++; 03791 } else 03792 break; 03793 } 03794 return copied ? 0 : -1; 03795 }
|
|
copy_header: Copy one header field from one request to another
Definition at line 3767 of file chan_sip.c. References add_header(), ast_log(), ast_strlen_zero(), get_header(), and LOG_NOTICE. Referenced by reqprep(), and respprep(). 03768 { 03769 char *tmp; 03770 tmp = get_header(orig, field); 03771 if (!ast_strlen_zero(tmp)) { 03772 /* Add what we're responding to */ 03773 return add_header(req, field, tmp); 03774 } 03775 ast_log(LOG_NOTICE, "No field '%s' present to copy\n", field); 03776 return -1; 03777 }
|
|
copy_request: copy SIP request (mostly used to save request for responses) ---
Definition at line 4505 of file chan_sip.c. References offset. Referenced by handle_request_bye(), handle_request_invite(), handle_request_register(), handle_request_subscribe(), sip_park(), sip_park_thread(), transmit_invite(), transmit_notify_with_mwi(), transmit_notify_with_sipfrag(), transmit_register(), transmit_reinvite_with_sdp(), and transmit_sip_request(). 04506 { 04507 long offset; 04508 int x; 04509 offset = ((void *)dst) - ((void *)src); 04510 /* First copy stuff */ 04511 memcpy(dst, src, sizeof(*dst)); 04512 /* Now fix pointer arithmetic */ 04513 for (x=0; x < src->headers; x++) 04514 dst->header[x] += offset; 04515 for (x=0; x < src->lines; x++) 04516 dst->line[x] += offset; 04517 }
|
|
copy_via_headers: Copy SIP VIA Headers from the request to the response ---
Definition at line 3803 of file chan_sip.c. References __get_header(), add_header(), ast_inet_ntoa(), ast_strlen_zero(), ast_test_flag, sip_pvt::recv, SIP_NAT, and SIP_NAT_ALWAYS. Referenced by respprep(). 03804 { 03805 char tmp[256], *oh, *end; 03806 int start = 0; 03807 int copied = 0; 03808 char iabuf[INET_ADDRSTRLEN]; 03809 03810 for (;;) { 03811 oh = __get_header(orig, field, &start); 03812 if (!ast_strlen_zero(oh)) { 03813 if (!copied) { /* Only check for empty rport in topmost via header */ 03814 char *rport; 03815 char new[256]; 03816 03817 /* Find ;rport; (empty request) */ 03818 rport = strstr(oh, ";rport"); 03819 if (rport && *(rport+6) == '=') 03820 rport = NULL; /* We already have a parameter to rport */ 03821 03822 if (rport && (ast_test_flag(p, SIP_NAT) == SIP_NAT_ALWAYS)) { 03823 /* We need to add received port - rport */ 03824 ast_copy_string(tmp, oh, sizeof(tmp)); 03825 03826 rport = strstr(tmp, ";rport"); 03827 03828 if (rport) { 03829 end = strchr(rport + 1, ';'); 03830 if (end) 03831 memmove(rport, end, strlen(end) + 1); 03832 else 03833 *rport = '\0'; 03834 } 03835 03836 /* Add rport to first VIA header if requested */ 03837 /* Whoo hoo! Now we can indicate port address translation too! Just 03838 another RFC (RFC3581). I'll leave the original comments in for 03839 posterity. */ 03840 snprintf(new, sizeof(new), "%s;received=%s;rport=%d", tmp, ast_inet_ntoa(iabuf, sizeof(iabuf), p->recv.sin_addr), ntohs(p->recv.sin_port)); 03841 } else { 03842 /* We should *always* add a received to the topmost via */ 03843 snprintf(new, sizeof(new), "%s;received=%s", oh, ast_inet_ntoa(iabuf, sizeof(iabuf), p->recv.sin_addr)); 03844 } 03845 add_header(req, field, new); 03846 } else { 03847 /* Add the following via headers untouched */ 03848 add_header(req, field, oh); 03849 } 03850 copied++; 03851 } else 03852 break; 03853 } 03854 if (!copied) { 03855 ast_log(LOG_NOTICE, "No header field '%s' present to copy\n", field); 03856 return -1; 03857 } 03858 return 0; 03859 }
|
|
create_addr: 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 1919 of file chan_sip.c. References ahp, ast_get_srv(), ast_gethostbyname(), ast_log(), ASTOBJ_UNREF, create_addr_from_peer(), DEFAULT_SIP_PORT, find_peer(), host, hp, LOG_WARNING, portno, sip_pvt::recv, sip_pvt::sa, sip_destroy_peer(), sip_pvt::timer_t1, and sip_pvt::tohost. 01920 { 01921 struct hostent *hp; 01922 struct ast_hostent ahp; 01923 struct sip_peer *p; 01924 int found=0; 01925 char *port; 01926 int portno; 01927 char host[MAXHOSTNAMELEN], *hostn; 01928 char peer[256]; 01929 01930 ast_copy_string(peer, opeer, sizeof(peer)); 01931 port = strchr(peer, ':'); 01932 if (port) { 01933 *port = '\0'; 01934 port++; 01935 } 01936 dialog->sa.sin_family = AF_INET; 01937 dialog->timer_t1 = 500; /* Default SIP retransmission timer T1 (RFC 3261) */ 01938 p = find_peer(peer, NULL, 1); 01939 01940 if (p) { 01941 found++; 01942 if (create_addr_from_peer(dialog, p)) 01943 ASTOBJ_UNREF(p, sip_destroy_peer); 01944 } 01945 if (!p) { 01946 if (found) 01947 return -1; 01948 01949 hostn = peer; 01950 if (port) 01951 portno = atoi(port); 01952 else 01953 portno = DEFAULT_SIP_PORT; 01954 if (srvlookup) { 01955 char service[MAXHOSTNAMELEN]; 01956 int tportno; 01957 int ret; 01958 snprintf(service, sizeof(service), "_sip._udp.%s", peer); 01959 ret = ast_get_srv(NULL, host, sizeof(host), &tportno, service); 01960 if (ret > 0) { 01961 hostn = host; 01962 portno = tportno; 01963 } 01964 } 01965 hp = ast_gethostbyname(hostn, &ahp); 01966 if (hp) { 01967 ast_copy_string(dialog->tohost, peer, sizeof(dialog->tohost)); 01968 memcpy(&dialog->sa.sin_addr, hp->h_addr, sizeof(dialog->sa.sin_addr)); 01969 dialog->sa.sin_port = htons(portno); 01970 memcpy(&dialog->recv, &dialog->sa, sizeof(dialog->recv)); 01971 return 0; 01972 } else { 01973 ast_log(LOG_WARNING, "No such host: %s\n", peer); 01974 return -1; 01975 } 01976 } else { 01977 ASTOBJ_UNREF(p, sip_destroy_peer); 01978 return 0; 01979 } 01980 }
|
|
create_addr_from_peer: create address structure from peer reference ---
Definition at line 1843 of file chan_sip.c. References sip_peer::addr, ast_copy_flags, ast_inet_ntoa(), ast_log(), AST_RTP_DTMF, ast_rtp_setnat(), ast_set_flag, ast_strlen_zero(), ast_test_flag, sip_pvt::authname, sip_peer::call_limit, sip_peer::callgroup, sip_pvt::callgroup, sip_pvt::callid, sip_peer::capability, sip_pvt::capability, sip_peer::context, sip_pvt::context, sip_peer::defaddr, sip_pvt::fromdomain, sip_peer::fromdomain, sip_pvt::fromuser, sip_peer::fromuser, sip_peer::fullcontact, sip_pvt::fullcontact, sip_request::headers, sip_pvt::initreq, sip_peer::lastms, LOG_DEBUG, sip_peer::maxms, sip_pvt::maxtime, sip_peer::md5secret, sip_pvt::noncodeccapability, sip_pvt::peermd5secret, sip_pvt::peername, sip_pvt::peersecret, sip_peer::pickupgroup, sip_pvt::pickupgroup, sip_peer::prefs, sip_pvt::prefs, sip_pvt::recv, sip_pvt::rtp, sip_peer::rtpholdtimeout, sip_pvt::rtpholdtimeout, sip_peer::rtpkeepalive, sip_pvt::rtpkeepalive, sip_peer::rtptimeout, sip_pvt::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_pvt::timer_t1, sip_peer::tohost, sip_pvt::tohost, sip_pvt::username, sip_peer::username, and sip_pvt::vrtp. Referenced by create_addr(), and sip_send_mwi_to_peer(). 01844 { 01845 char *callhost; 01846 01847 if ((peer->addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr) && 01848 (!peer->maxms || ((peer->lastms >= 0) && (peer->lastms <= peer->maxms)))) { 01849 if (peer->addr.sin_addr.s_addr) { 01850 r->sa.sin_family = peer->addr.sin_family; 01851 r->sa.sin_addr = peer->addr.sin_addr; 01852 r->sa.sin_port = peer->addr.sin_port; 01853 } else { 01854 r->sa.sin_family = peer->defaddr.sin_family; 01855 r->sa.sin_addr = peer->defaddr.sin_addr; 01856 r->sa.sin_port = peer->defaddr.sin_port; 01857 } 01858 memcpy(&r->recv, &r->sa, sizeof(r->recv)); 01859 } else { 01860 return -1; 01861 } 01862 01863 ast_copy_flags(r, peer, SIP_FLAGS_TO_COPY); 01864 r->capability = peer->capability; 01865 r->prefs = peer->prefs; 01866 if (r->rtp) { 01867 ast_log(LOG_DEBUG, "Setting NAT on RTP to %d\n", (ast_test_flag(r, SIP_NAT) & SIP_NAT_ROUTE)); 01868 ast_rtp_setnat(r->rtp, (ast_test_flag(r, SIP_NAT) & SIP_NAT_ROUTE)); 01869 } 01870 if (r->vrtp) { 01871 ast_log(LOG_DEBUG, "Setting NAT on VRTP to %d\n", (ast_test_flag(r, SIP_NAT) & SIP_NAT_ROUTE)); 01872 ast_rtp_setnat(r->vrtp, (ast_test_flag(r, SIP_NAT) & SIP_NAT_ROUTE)); 01873 } 01874 ast_copy_string(r->peername, peer->username, sizeof(r->peername)); 01875 ast_copy_string(r->authname, peer->username, sizeof(r->authname)); 01876 ast_copy_string(r->username, peer->username, sizeof(r->username)); 01877 ast_copy_string(r->peersecret, peer->secret, sizeof(r->peersecret)); 01878 ast_copy_string(r->peermd5secret, peer->md5secret, sizeof(r->peermd5secret)); 01879 ast_copy_string(r->tohost, peer->tohost, sizeof(r->tohost)); 01880 ast_copy_string(r->fullcontact, peer->fullcontact, sizeof(r->fullcontact)); 01881 if (!r->initreq.headers && !ast_strlen_zero(peer->fromdomain)) { 01882 if ((callhost = strchr(r->callid, '@'))) { 01883 strncpy(callhost + 1, peer->fromdomain, sizeof(r->callid) - (callhost - r->callid) - 2); 01884 } 01885 } 01886 if (ast_strlen_zero(r->tohost)) { 01887 if (peer->addr.sin_addr.s_addr) 01888 ast_inet_ntoa(r->tohost, sizeof(r->tohost), peer->addr.sin_addr); 01889 else 01890 ast_inet_ntoa(r->tohost, sizeof(r->tohost), peer->defaddr.sin_addr); 01891 } 01892 if (!ast_strlen_zero(peer->fromdomain)) 01893 ast_copy_string(r->fromdomain, peer->fromdomain, sizeof(r->fromdomain)); 01894 if (!ast_strlen_zero(peer->fromuser)) 01895 ast_copy_string(r->fromuser, peer->fromuser, sizeof(r->fromuser)); 01896 r->maxtime = peer->maxms; 01897 r->callgroup = peer->callgroup; 01898 r->pickupgroup = peer->pickupgroup; 01899 /* Set timer T1 to RTT for this peer (if known by qualify=) */ 01900 if (peer->maxms && peer->lastms) 01901 r->timer_t1 = peer->lastms; 01902 if ((ast_test_flag(r, SIP_DTMF) == SIP_DTMF_RFC2833) || (ast_test_flag(r, SIP_DTMF) == SIP_DTMF_AUTO)) 01903 r->noncodeccapability |= AST_RTP_DTMF; 01904 else 01905 r->noncodeccapability &= ~AST_RTP_DTMF; 01906 ast_copy_string(r->context, peer->context,sizeof(r->context)); 01907 r->rtptimeout = peer->rtptimeout; 01908 r->rtpholdtimeout = peer->rtpholdtimeout; 01909 r->rtpkeepalive = peer->rtpkeepalive; 01910 if (peer->call_limit) 01911 ast_set_flag(r, SIP_CALL_LIMIT); 01912 01913 return 0; 01914 }
|
|
Provides a description of the module.
Definition at line 13287 of file chan_sip.c. References desc. 13288 { 13289 return (char *) desc; 13290 }
|
|
Definition at line 5627 of file chan_sip.c. References ast_db_del(), ast_test_flag, ast_update_realtime(), sip_peer::flags_page2, global_flags_page2, SIP_PAGE2_IGNOREREGEXPIRE, and SIP_PAGE2_RT_FROMCONTACT. Referenced by build_peer(), expire_register(), and parse_register_contact(). 05628 { 05629 if (!ast_test_flag((&global_flags_page2), SIP_PAGE2_IGNOREREGEXPIRE)) { 05630 if (ast_test_flag(&(peer->flags_page2), SIP_PAGE2_RT_FROMCONTACT)) { 05631 ast_update_realtime("sippeers", "name", peer->name, "fullcontact", "", "ipaddr", "", "port", "", "regseconds", "0", "username", "", NULL); 05632 } else { 05633 ast_db_del("SIP/Registry", peer->name); 05634 } 05635 } 05636 }
|
|
determine_firstline_parts: parse first line of incoming SIP request
Definition at line 4540 of file chan_sip.c. References sip_request::header, sip_request::len, sip_request::rlPart1, and sip_request::rlPart2. Referenced by parse_request(), transmit_notify_with_mwi(), transmit_notify_with_sipfrag(), transmit_register(), and transmit_sip_request(). 04541 { 04542 char *e, *cmd; 04543 int len; 04544 04545 cmd = ast_skip_blanks(req->header[0]); 04546 if (!*cmd) 04547 return -1; 04548 req->rlPart1 = cmd; 04549 e = ast_skip_nonblanks(cmd); 04550 /* Get the command */ 04551 if (*e) 04552 *e++ = '\0'; 04553 e = ast_skip_blanks(e); 04554 if ( !*e ) 04555 return -1; 04556 04557 if ( !strcasecmp(cmd, "SIP/2.0") ) { 04558 /* We have a response */ 04559 req->rlPart2 = e; 04560 len = strlen( req->rlPart2 ); 04561 if ( len < 2 ) { 04562 return -1; 04563 } 04564 ast_trim_blanks(e); 04565 } else { 04566 /* We have a request */ 04567 if ( *e == '<' ) { 04568 e++; 04569 if ( !*e ) { 04570 return -1; 04571 } 04572 } 04573 req->rlPart2 = e; /* URI */ 04574 if ( ( e= strrchr( req->rlPart2, 'S' ) ) == NULL ) { 04575 return -1; 04576 } 04577 /* XXX maybe trim_blanks() ? */ 04578 while( isspace( *(--e) ) ) {} 04579 if ( *e == '>' ) { 04580 *e = '\0'; 04581 } else { 04582 *(++e)= '\0'; 04583 } 04584 } 04585 return 1; 04586 }
|
|
do_monitor: The SIP monitoring thread ---
Definition at line 11235 of file chan_sip.c. References __sip_destroy(), ast_channel::_state, ast_io_add(), AST_IO_IN, ast_io_wait(), ast_log(), ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_rtp_get_peer(), ast_rtp_sendcng(), ast_sched_runq(), ast_sched_wait(), ast_softhangup(), AST_SOFTHANGUP_DEV, AST_STATE_UP, ast_strlen_zero(), ast_test_flag, ast_verbose(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_REF, global_mwitime, iflist, io, sip_pvt::lastrtprx, sip_pvt::lastrtptx, ast_channel::lock, sip_pvt::lock, LOG_DEBUG, LOG_NOTICE, ast_channel::name, sip_pvt::next, option_verbose, sip_pvt::owner, sip_pvt::packets, peerl, sip_pvt::redirip, sip_pvt::rtp, sip_pvt::rtpholdtimeout, sip_pvt::rtpkeepalive, sip_pvt::rtptimeout, sip_do_reload(), SIP_NEEDDESTROY, sip_reloading, sipsock, sipsock_read(), t, and VERBOSE_PREFIX_1. 11236 { 11237 int res; 11238 struct sip_pvt *sip; 11239 struct sip_peer *peer = NULL; 11240 time_t t; 11241 int fastrestart =0; 11242 int lastpeernum = -1; 11243 int curpeernum; 11244 int reloading; 11245 11246 /* Add an I/O event to our UDP socket */ 11247 if (sipsock > -1) 11248 ast_io_add(io, sipsock, sipsock_read, AST_IO_IN, NULL); 11249 11250 /* This thread monitors all the frame relay interfaces which are not yet in use 11251 (and thus do not have a separate thread) indefinitely */ 11252 /* From here on out, we die whenever asked */ 11253 for(;;) { 11254 /* Check for a reload request */ 11255 ast_mutex_lock(&sip_reload_lock); 11256 reloading = sip_reloading; 11257 sip_reloading = 0; 11258 ast_mutex_unlock(&sip_reload_lock); 11259 if (reloading) { 11260 if (option_verbose > 0) 11261 ast_verbose(VERBOSE_PREFIX_1 "Reloading SIP\n"); 11262 sip_do_reload(); 11263 } 11264 /* Check for interfaces needing to be killed */ 11265 ast_mutex_lock(&iflock); 11266 restartsearch: 11267 time(&t); 11268 sip = iflist; 11269 while(sip) { 11270 ast_mutex_lock(&sip->lock); 11271 if (sip->rtp && sip->owner && (sip->owner->_state == AST_STATE_UP) && !sip->redirip.sin_addr.s_addr) { 11272 if (sip->lastrtptx && sip->rtpkeepalive && t > sip->lastrtptx + sip->rtpkeepalive) { 11273 /* Need to send an empty RTP packet */ 11274 time(&sip->lastrtptx); 11275 ast_rtp_sendcng(sip->rtp, 0); 11276 } 11277 if (sip->lastrtprx && (sip->rtptimeout || sip->rtpholdtimeout) && t > sip->lastrtprx + sip->rtptimeout) { 11278 /* Might be a timeout now -- see if we're on hold */ 11279 struct sockaddr_in sin; 11280 ast_rtp_get_peer(sip->rtp, &sin); 11281 if (sin.sin_addr.s_addr || 11282 (sip->rtpholdtimeout && 11283 (t > sip->lastrtprx + sip->rtpholdtimeout))) { 11284 /* Needs a hangup */ 11285 if (sip->rtptimeout) { 11286 while(sip->owner && ast_mutex_trylock(&sip->owner->lock)) { 11287 ast_mutex_unlock(&sip->lock); 11288 usleep(1); 11289 ast_mutex_lock(&sip->lock); 11290 } 11291 if (sip->owner) { 11292 ast_log(LOG_NOTICE, "Disconnecting call '%s' for lack of RTP activity in %ld seconds\n", sip->owner->name, (long)(t - sip->lastrtprx)); 11293 /* Issue a softhangup */ 11294 ast_softhangup(sip->owner, AST_SOFTHANGUP_DEV); 11295 ast_mutex_unlock(&sip->owner->lock); 11296 } 11297 } 11298 } 11299 } 11300 } 11301 if (ast_test_flag(sip, SIP_NEEDDESTROY) && !sip->packets && !sip->owner) { 11302 ast_mutex_unlock(&sip->lock); 11303 __sip_destroy(sip, 1); 11304 goto restartsearch; 11305 } 11306 ast_mutex_unlock(&sip->lock); 11307 sip = sip->next; 11308 } 11309 ast_mutex_unlock(&iflock); 11310 /* Don't let anybody kill us right away. Nobody should lock the interface list 11311 and wait for the monitor list, but the other way around is okay. */ 11312 ast_mutex_lock(&monlock); 11313 /* Lock the network interface */ 11314 ast_mutex_lock(&netlock); 11315 /* Okay, now that we know what to do, release the network lock */ 11316 ast_mutex_unlock(&netlock); 11317 /* And from now on, we're okay to be killed, so release the monitor lock as well */ 11318 ast_mutex_unlock(&monlock); 11319 pthread_testcancel(); 11320 /* Wait for sched or io */ 11321 res = ast_sched_wait(sched); 11322 if ((res < 0) || (res > 1000)) 11323 res = 1000; 11324 /* If we might need to send more mailboxes, don't wait long at all.*/ 11325 if (fastrestart) 11326 res = 1; 11327 res = ast_io_wait(io, res); 11328 if (res > 20) 11329 ast_log(LOG_DEBUG, "chan_sip: ast_io_wait ran %d all at once\n", res); 11330 ast_mutex_lock(&monlock); 11331 if (res >= 0) { 11332 res = ast_sched_runq(sched); 11333 if (res >= 20) 11334 ast_log(LOG_DEBUG, "chan_sip: ast_sched_runq ran %d all at once\n", res); 11335 } 11336 11337 /* needs work to send mwi to realtime peers */ 11338 time(&t); 11339 fastrestart = 0; 11340 curpeernum = 0; 11341 peer = NULL; 11342 ASTOBJ_CONTAINER_TRAVERSE(&peerl, !peer, do { 11343 if ((curpeernum > lastpeernum) && !ast_strlen_zero(iterator->mailbox) && ((t - iterator->lastmsgcheck) > global_mwitime)) { 11344 fastrestart = 1; 11345 lastpeernum = curpeernum; 11346 peer = ASTOBJ_REF(iterator); 11347 }; 11348 curpeernum++; 11349 } while (0) 11350 ); 11351 if (peer) { 11352 ASTOBJ_WRLOCK(peer); 11353 sip_send_mwi_to_peer(peer); 11354 ASTOBJ_UNLOCK(peer); 11355 ASTOBJ_UNREF(peer,sip_destroy_peer); 11356 } else { 11357 /* Reset where we come from */ 11358 lastpeernum = -1; 11359 } 11360 ast_mutex_unlock(&monlock); 11361 } 11362 /* Never reached */ 11363 return NULL; 11364 11365 }
|
|
do_proxy_auth: Add authentication on outbound SIP packet ---
Definition at line 8891 of file chan_sip.c. References ast_log(), sip_invite_param::auth, sip_invite_param::authheader, sip_pvt::authtries, calloc, LOG_DEBUG, LOG_ERROR, option_debug, sip_pvt::options, reply_digest(), SIP_INVITE, sip_methods, cfsip_methods::text, and transmit_invite(). Referenced by handle_response(), and handle_response_invite(). 08892 { 08893 char digest[1024]; 08894 08895 if (!p->options) { 08896 p->options = calloc(1, sizeof(*p->options)); 08897 if (!p->options) { 08898 ast_log(LOG_ERROR, "Out of memory\n"); 08899 return -2; 08900 } 08901 } 08902 08903 p->authtries++; 08904 if (option_debug > 1) 08905 ast_log(LOG_DEBUG, "Auth attempt %d on %s\n", p->authtries, sip_methods[sipmethod].text); 08906 memset(digest, 0, sizeof(digest)); 08907 if (reply_digest(p, req, header, sipmethod, digest, sizeof(digest) )) { 08908 /* No way to authenticate */ 08909 return -1; 08910 } 08911 /* Now we have a reply digest */ 08912 p->options->auth = digest; 08913 p->options->authheader = respheader; 08914 return transmit_invite(p, sipmethod, sipmethod == SIP_INVITE, init); 08915 }
|
|
do_register_auth: Authenticate for outbound registration ---
Definition at line 8867 of file chan_sip.c. References append_history(), ast_verbose(), sip_pvt::authtries, sip_registry::hostname, recordhistory, sip_pvt::registry, reply_digest(), sip_debug_test_pvt(), SIP_REGISTER, and transmit_register(). Referenced by handle_response_register(). 08868 { 08869 char digest[1024]; 08870 p->authtries++; 08871 memset(digest,0,sizeof(digest)); 08872 if (reply_digest(p, req, header, SIP_REGISTER, digest, sizeof(digest))) { 08873 /* There's nothing to use for authentication */ 08874 /* No digest challenge in request */ 08875 if (sip_debug_test_pvt(p) && p->registry) 08876 ast_verbose("No authentication challenge, sending blank registration to domain/host name %s\n", p->registry->hostname); 08877 /* No old challenge */ 08878 return -1; 08879 } 08880 if (recordhistory) { 08881 char tmp[80]; 08882 snprintf(tmp, sizeof(tmp), "Try: %d", p->authtries); 08883 append_history(p, "RegistryAuth", tmp); 08884 } 08885 if (sip_debug_test_pvt(p) && p->registry) 08886 ast_verbose("Responding to challenge, registration to domain/host name %s\n", p->registry->hostname); 08887 return transmit_register(p->registry, SIP_REGISTER, digest, respheader); 08888 }
|
|
Definition at line 7811 of file chan_sip.c. References SIP_DOMAIN_AUTO, and SIP_DOMAIN_CONFIG. Referenced by sip_show_domains(). 07812 { 07813 switch (mode) { 07814 case SIP_DOMAIN_AUTO: 07815 return "[Automatic]"; 07816 case SIP_DOMAIN_CONFIG: 07817 return "[Configured]"; 07818 } 07819 07820 return ""; 07821 }
|
|
dtmfmode2str: Convert DTMF mode to printable string ---
Definition at line 7619 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(). 07620 { 07621 switch (mode) { 07622 case SIP_DTMF_RFC2833: 07623 return "rfc2833"; 07624 case SIP_DTMF_INFO: 07625 return "info"; 07626 case SIP_DTMF_INBAND: 07627 return "inband"; 07628 case SIP_DTMF_AUTO: 07629 return "auto"; 07630 } 07631 return "<error>"; 07632 }
|
|
|
extract_uri: Check Contact: URI of SIP message ---
Definition at line 4618 of file chan_sip.c. References ast_strlen_zero(), get_header(), get_in_brackets(), n, and sip_pvt::uri. Referenced by handle_request(), and handle_request_invite(). 04619 { 04620 char stripped[256]; 04621 char *c, *n; 04622 ast_copy_string(stripped, get_header(req, "Contact"), sizeof(stripped)); 04623 c = get_in_brackets(stripped); 04624 n = strchr(c, ';'); 04625 if (n) 04626 *n = '\0'; 04627 if (!ast_strlen_zero(c)) 04628 ast_copy_string(p->uri, c, sizeof(p->uri)); 04629 }
|
|
Definition at line 2895 of file chan_sip.c. References aliases. 02896 { 02897 int x; 02898 for (x=0;x<sizeof(aliases) / sizeof(aliases[0]); x++) 02899 if (!strcasecmp(aliases[x].fullname, name)) 02900 return aliases[x].shortname; 02901 return _default; 02902 }
|
|
find_call: Connect incoming SIP message to current dialog or create new dialog structure
Definition at line 3127 of file chan_sip.c. References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_strlen_zero(), sip_pvt::callid, get_header(), gettag(), iflist, sip_pvt::lock, LOG_DEBUG, sip_request::method, sip_pvt::next, option_debug, pedanticsipchecking, sip_alloc(), sip_methods, SIP_PKT_WITH_TOTAG, SIP_REGISTER, SIP_RESPONSE, sip_pvt::tag, and sip_pvt::theirtag. Referenced by sipsock_read(). 03128 { 03129 struct sip_pvt *p; 03130 char *callid; 03131 char *tag = ""; 03132 char totag[128]; 03133 char fromtag[128]; 03134 03135 callid = get_header(req, "Call-ID"); 03136 03137 if (pedanticsipchecking) { 03138 /* In principle Call-ID's uniquely identify a call, but with a forking SIP proxy 03139 we need more to identify a branch - so we have to check branch, from 03140 and to tags to identify a call leg. 03141 For Asterisk to behave correctly, you need to turn on pedanticsipchecking 03142 in sip.conf 03143 */ 03144 if (gettag(req, "To", totag, sizeof(totag))) 03145 ast_set_flag(req, SIP_PKT_WITH_TOTAG); /* Used in handle_request/response */ 03146 gettag(req, "From", fromtag, sizeof(fromtag)); 03147 03148 if (req->method == SIP_RESPONSE) 03149 tag = totag; 03150 else 03151 tag = fromtag; 03152 03153 03154 if (option_debug > 4 ) 03155 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); 03156 } 03157 03158 ast_mutex_lock(&iflock); 03159 p = iflist; 03160 while(p) { /* In pedantic, we do not want packets with bad syntax to be connected to a PVT */ 03161 int found = 0; 03162 if (req->method == SIP_REGISTER) 03163 found = (!strcmp(p->callid, callid)); 03164 else 03165 found = (!strcmp(p->callid, callid) && 03166 (!pedanticsipchecking || !tag || ast_strlen_zero(p->theirtag) || !strcmp(p->theirtag, tag))) ; 03167 03168 if (option_debug > 4) 03169 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); 03170 03171 /* If we get a new request within an existing to-tag - check the to tag as well */ 03172 if (pedanticsipchecking && found && req->method != SIP_RESPONSE) { /* SIP Request */ 03173 if (p->tag[0] == '\0' && totag[0]) { 03174 /* We have no to tag, but they have. Wrong dialog */ 03175 found = 0; 03176 } else if (totag[0]) { /* Both have tags, compare them */ 03177 if (strcmp(totag, p->tag)) { 03178 found = 0; /* This is not our packet */ 03179 } 03180 } 03181 if (!found && option_debug > 4) 03182 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); 03183 } 03184 03185 03186 if (found) { 03187 /* Found the call */ 03188 ast_mutex_lock(&p->lock); 03189 ast_mutex_unlock(&iflock); 03190 return p; 03191 } 03192 p = p->next; 03193 } 03194 ast_mutex_unlock(&iflock); 03195 p = sip_alloc(callid, sin, 1, intended_method); 03196 if (p) 03197 ast_mutex_lock(&p->lock); 03198 return p; 03199 }
|
|
find_peer: 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 1750 of file chan_sip.c. References ASTOBJ_CONTAINER_FIND, ASTOBJ_CONTAINER_FIND_FULL, name, peerl, realtime_peer(), and sip_addrcmp(). 01751 { 01752 struct sip_peer *p = NULL; 01753 01754 if (peer) 01755 p = ASTOBJ_CONTAINER_FIND(&peerl,peer); 01756 else 01757 p = ASTOBJ_CONTAINER_FIND_FULL(&peerl,sin,name,sip_addr_hashfunc,1,sip_addrcmp); 01758 01759 if (!p && realtime) { 01760 p = realtime_peer(peer, sin); 01761 } 01762 01763 return p; 01764 }
|
|
find_realm_authentication: Find authentication for a specific realm ---
Definition at line 11889 of file chan_sip.c. References sip_auth::next, and sip_auth::realm. Referenced by build_reply_digest(). 11890 { 11891 struct sip_auth *a = authlist; /* First entry in auth list */ 11892 11893 while (a) { 11894 if (!strcasecmp(a->realm, realm)){ 11895 break; 11896 } 11897 a = a->next; 11898 } 11899 11900 return a; 11901 }
|
|
find_sip_method: Find SIP method from header Strictly speaking, SIP methods are case SENSITIVE, but we don't check following Jon Postel's rule: Be gentle in what you accept, strict with what you send
Definition at line 970 of file chan_sip.c. References ast_strlen_zero(), sip_methods, and text. Referenced by __sip_pretend_ack(), handle_response(), and sipsock_read(). 00971 { 00972 int i, res = 0; 00973 00974 if (ast_strlen_zero(msg)) 00975 return 0; 00976 00977 for (i = 1; (i < (sizeof(sip_methods) / sizeof(sip_methods[0]))) && !res; i++) { 00978 if (!strcasecmp(sip_methods[i].text, msg)) 00979 res = sip_methods[i].id; 00980 } 00981 return res; 00982 }
|
|
find_subscription_type: Find subscription type in array
Definition at line 8254 of file chan_sip.c. References subscription_types, and type. Referenced by transmit_state_notify(). 08254 { 08255 int i; 08256 08257 for (i = 1; (i < (sizeof(subscription_types) / sizeof(subscription_types[0]))); i++) { 08258 if (subscription_types[i].type == subtype) { 08259 return &subscription_types[i]; 08260 } 08261 } 08262 return &subscription_types[0]; 08263 }
|
|
find_user: 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 1832 of file chan_sip.c. References ASTOBJ_CONTAINER_FIND, realtime_user(), and userl. 01833 { 01834 struct sip_user *u = NULL; 01835 u = ASTOBJ_CONTAINER_FIND(&userl,name); 01836 if (!u && realtime) { 01837 u = realtime_user(name); 01838 } 01839 return u; 01840 }
|
|
free_old_route: Remove route from route list ---
Definition at line 5959 of file chan_sip.c. References free, and sip_route::next. Referenced by __sip_destroy(), and build_route(). 05960 { 05961 struct sip_route *next; 05962 while (route) { 05963 next = route->next; 05964 free(route); 05965 route = next; 05966 } 05967 }
|
|
function_check_sipdomain: Dial plan function to check if domain is local
Definition at line 9208 of file chan_sip.c. References ast_log(), ast_strlen_zero(), check_sip_domain(), and LOG_WARNING. 09209 { 09210 if (ast_strlen_zero(data)) { 09211 ast_log(LOG_WARNING, "CHECKSIPDOMAIN requires an argument - A domain name\n"); 09212 return buf; 09213 } 09214 if (check_sip_domain(data, NULL, 0)) 09215 ast_copy_string(buf, data, len); 09216 else 09217 buf[0] = '\0'; 09218 return buf; 09219 }
|
|
func_header_read: Read SIP header (dialplan function)
Definition at line 9161 of file chan_sip.c. References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_strlen_zero(), channeltype, get_header(), sip_pvt::initreq, ast_channel::lock, LOG_WARNING, ast_channel::tech_pvt, and ast_channel::type. 09162 { 09163 struct sip_pvt *p; 09164 char *content; 09165 09166 if (!data) { 09167 ast_log(LOG_WARNING, "This function requires a header name.\n"); 09168 return NULL; 09169 } 09170 09171 ast_mutex_lock(&chan->lock); 09172 if (chan->type != channeltype) { 09173 ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n"); 09174 ast_mutex_unlock(&chan->lock); 09175 return NULL; 09176 } 09177 09178 p = chan->tech_pvt; 09179 09180 /* If there is no private structure, this channel is no longer alive */ 09181 if (!p) { 09182 ast_mutex_unlock(&chan->lock); 09183 return NULL; 09184 } 09185 09186 content = get_header(&p->initreq, data); 09187 09188 if (ast_strlen_zero(content)) { 09189 ast_mutex_unlock(&chan->lock); 09190 return NULL; 09191 } 09192 09193 ast_copy_string(buf, content, len); 09194 ast_mutex_unlock(&chan->lock); 09195 09196 return buf; 09197 }
|
|
function_sipchaninfo_read: ${SIPCHANINFO()} Dialplan function - reads sip channel data
Definition at line 9335 of file chan_sip.c. References ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), channeltype, sip_pvt::from, ast_channel::lock, LOG_WARNING, sip_pvt::peername, sip_pvt::recv, sip_pvt::sa, ast_channel::tech_pvt, ast_channel::type, sip_pvt::uri, and sip_pvt::useragent. 09336 { 09337 struct sip_pvt *p; 09338 char iabuf[INET_ADDRSTRLEN]; 09339 09340 *buf = 0; 09341 09342 if (!data) { 09343 ast_log(LOG_WARNING, "This function requires a parameter name.\n"); 09344 return NULL; 09345 } 09346 09347 ast_mutex_lock(&chan->lock); 09348 if (chan->type != channeltype) { 09349 ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n"); 09350 ast_mutex_unlock(&chan->lock); 09351 return NULL; 09352 } 09353 09354 /* ast_verbose("function_sipchaninfo_read: %s\n", data); */ 09355 p = chan->tech_pvt; 09356 09357 /* If there is no private structure, this channel is no longer alive */ 09358 if (!p) { 09359 ast_mutex_unlock(&chan->lock); 09360 return NULL; 09361 } 09362 09363 if (!strcasecmp(data, "peerip")) { 09364 ast_copy_string(buf, p->sa.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr) : "", len); 09365 } else if (!strcasecmp(data, "recvip")) { 09366 ast_copy_string(buf, p->recv.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), p->recv.sin_addr) : "", len); 09367 } else if (!strcasecmp(data, "from")) { 09368 ast_copy_string(buf, p->from, len); 09369 } else if (!strcasecmp(data, "uri")) { 09370 ast_copy_string(buf, p->uri, len); 09371 } else if (!strcasecmp(data, "useragent")) { 09372 ast_copy_string(buf, p->useragent, len); 09373 } else if (!strcasecmp(data, "peername")) { 09374 ast_copy_string(buf, p->peername, len); 09375 } else { 09376 ast_mutex_unlock(&chan->lock); 09377 return NULL; 09378 } 09379 ast_mutex_unlock(&chan->lock); 09380 09381 return buf; 09382 }
|
|
function_sippeer: ${SIPPEER()} Dialplan function - reads peer data
Definition at line 9234 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_log(), ast_strdupa, 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::inUse, sip_peer::language, LOG_ERROR, sip_peer::mailbox, peer_status(), sip_peer::prefs, sip_peer::regexten, sip_destroy_peer(), SIP_DYNAMIC, and sip_peer::useragent. 09235 { 09236 char *ret = NULL; 09237 struct sip_peer *peer; 09238 char *peername, *colname; 09239 char iabuf[INET_ADDRSTRLEN]; 09240 09241 if (!(peername = ast_strdupa(data))) { 09242 ast_log(LOG_ERROR, "Memory Error!\n"); 09243 return ret; 09244 } 09245 09246 if ((colname = strchr(peername, ':'))) { 09247 *colname = '\0'; 09248 colname++; 09249 } else { 09250 colname = "ip"; 09251 } 09252 if (!(peer = find_peer(peername, NULL, 1))) 09253 return ret; 09254 09255 if (!strcasecmp(colname, "ip")) { 09256 ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), peer->addr.sin_addr) : "", len); 09257 } else if (!strcasecmp(colname, "status")) { 09258 peer_status(peer, buf, sizeof(buf)); 09259 } else if (!strcasecmp(colname, "language")) { 09260 ast_copy_string(buf, peer->language, len); 09261 } else if (!strcasecmp(colname, "regexten")) { 09262 ast_copy_string(buf, peer->regexten, len); 09263 } else if (!strcasecmp(colname, "limit")) { 09264 snprintf(buf, len, "%d", peer->call_limit); 09265 } else if (!strcasecmp(colname, "curcalls")) { 09266 snprintf(buf, len, "%d", peer->inUse); 09267 } else if (!strcasecmp(colname, "accountcode")) { 09268 ast_copy_string(buf, peer->accountcode, len); 09269 } else if (!strcasecmp(colname, "useragent")) { 09270 ast_copy_string(buf, peer->useragent, len); 09271 } else if (!strcasecmp(colname, "mailbox")) { 09272 ast_copy_string(buf, peer->mailbox, len); 09273 } else if (!strcasecmp(colname, "context")) { 09274 ast_copy_string(buf, peer->context, len); 09275 } else if (!strcasecmp(colname, "expire")) { 09276 snprintf(buf, len, "%d", peer->expire); 09277 } else if (!strcasecmp(colname, "dynamic")) { 09278 ast_copy_string(buf, (ast_test_flag(peer, SIP_DYNAMIC) ? "yes" : "no"), len); 09279 } else if (!strcasecmp(colname, "callerid_name")) { 09280 ast_copy_string(buf, peer->cid_name, len); 09281 } else if (!strcasecmp(colname, "callerid_num")) { 09282 ast_copy_string(buf, peer->cid_num, len); 09283 } else if (!strcasecmp(colname, "codecs")) { 09284 ast_getformatname_multiple(buf, len -1, peer->capability); 09285 } else if (!strncasecmp(colname, "codec[", 6)) { 09286 char *codecnum, *ptr; 09287 int index = 0, codec = 0; 09288 09289 codecnum = strchr(colname, '['); 09290 *codecnum = '\0'; 09291 codecnum++; 09292 if ((ptr = strchr(codecnum, ']'))) { 09293 *ptr = '\0'; 09294 } 09295 index = atoi(codecnum); 09296 if((codec = ast_codec_pref_index(&peer->prefs, index))) { 09297 ast_copy_string(buf, ast_getformatname(codec), len); 09298 } 09299 } 09300 ret = buf; 09301 09302 ASTOBJ_UNREF(peer, sip_destroy_peer); 09303 09304 return ret; 09305 }
|
|
get_also_info: Call transfer support (old way, depreciated)--
Definition at line 6792 of file chan_sip.c. References ast_canmatch_extension(), ast_exists_extension(), ast_log(), ast_verbose(), sip_pvt::context, get_header(), get_in_brackets(), sip_pvt::initreq, LOG_DEBUG, LOG_WARNING, sip_pvt::refer_call, sip_pvt::refer_contact, sip_pvt::refer_to, sip_pvt::referred_by, and sip_debug_test_pvt(). Referenced by handle_request_bye(). 06793 { 06794 char tmp[256], *c, *a; 06795 struct sip_request *req; 06796 06797 req = oreq; 06798 if (!req) 06799 req = &p->initreq; 06800 ast_copy_string(tmp, get_header(req, "Also"), sizeof(tmp)); 06801 06802 c = get_in_brackets(tmp); 06803 06804 06805 if (strncmp(c, "sip:", 4)) { 06806 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", c); 06807 return -1; 06808 } 06809 c += 4; 06810 if ((a = strchr(c, '@'))) 06811 *a = '\0'; 06812 if ((a = strchr(c, ';'))) 06813 *a = '\0'; 06814 06815 if (sip_debug_test_pvt(p)) { 06816 ast_verbose("Looking for %s in %s\n", c, p->context); 06817 } 06818 if (ast_exists_extension(NULL, p->context, c, 1, NULL)) { 06819 /* This is an unsupervised transfer */ 06820 ast_log(LOG_DEBUG,"Assigning Extension %s to REFER-TO\n", c); 06821 ast_copy_string(p->refer_to, c, sizeof(p->refer_to)); 06822 ast_copy_string(p->referred_by, "", sizeof(p->referred_by)); 06823 ast_copy_string(p->refer_contact, "", sizeof(p->refer_contact)); 06824 p->refer_call = NULL; 06825 return 0; 06826 } else if (ast_canmatch_extension(NULL, p->context, c, 1, NULL)) { 06827 return 1; 06828 } 06829 06830 return -1; 06831 }
|
|
get_calleridname: Get caller id name from SIP headers ---
Definition at line 6883 of file chan_sip.c. Referenced by check_user_full(). 06884 { 06885 char *end = strchr(input,'<'); 06886 char *tmp = strchr(input,'\"'); 06887 int bytes = 0; 06888 int maxbytes = outputsize - 1; 06889 06890 if (!end || (end == input)) return NULL; 06891 /* move away from "<" */ 06892 end--; 06893 /* we found "name" */ 06894 if (tmp && tmp < end) { 06895 end = strchr(tmp+1, '\"'); 06896 if (!end) return NULL; 06897 bytes = (int) (end - tmp); 06898 /* protect the output buffer */ 06899 if (bytes > maxbytes) 06900 bytes = maxbytes; 06901 ast_copy_string(output, tmp + 1, bytes); 06902 } else { 06903 /* we didn't find "name" */ 06904 /* clear the empty characters in the begining*/ 06905 input = ast_skip_blanks(input); 06906 /* clear the empty characters in the end */ 06907 while(*end && (*end < 33) && end > input) 06908 end--; 06909 if (end >= input) { 06910 bytes = (int) (end - input) + 2; 06911 /* protect the output buffer */ 06912 if (bytes > maxbytes) { 06913 bytes = maxbytes; 06914 } 06915 ast_copy_string(output, input, bytes); 06916 } 06917 else 06918 return NULL; 06919 } 06920 return output; 06921 }
|
|
get_destination: Find out who the call is for --
Definition at line 6525 of file chan_sip.c. References allow_external_domains, ast_canmatch_extension(), ast_exists_extension(), AST_LIST_EMPTY, ast_log(), AST_MAX_EXTENSION, ast_pickup_ext(), ast_strlen_zero(), ast_uri_decode(), ast_verbose(), check_sip_domain(), sip_pvt::context, sip_pvt::domain, sip_pvt::exten, sip_pvt::fromdomain, get_header(), get_in_brackets(), sip_pvt::initreq, LOG_DEBUG, LOG_WARNING, sip_request::method, pedanticsipchecking, sip_request::rlPart2, sip_debug_test_pvt(), SIP_INVITE, sip_methods, and SIP_REFER. Referenced by handle_request_invite(), handle_request_options(), and handle_request_subscribe(). 06526 { 06527 char tmp[256] = "", *uri, *a; 06528 char tmpf[256], *from; 06529 struct sip_request *req; 06530 char *colon; 06531 06532 req = oreq; 06533 if (!req) 06534 req = &p->initreq; 06535 if (req->rlPart2) 06536 ast_copy_string(tmp, req->rlPart2, sizeof(tmp)); 06537 uri = get_in_brackets(tmp); 06538 06539 ast_copy_string(tmpf, get_header(req, "From"), sizeof(tmpf)); 06540 06541 from = get_in_brackets(tmpf); 06542 06543 if (strncmp(uri, "sip:", 4)) { 06544 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", uri); 06545 return -1; 06546 } 06547 uri += 4; 06548 if (!ast_strlen_zero(from)) { 06549 if (strncmp(from, "sip:", 4)) { 06550 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", from); 06551 return -1; 06552 } 06553 from += 4; 06554 } else 06555 from = NULL; 06556 06557 if (pedanticsipchecking) { 06558 ast_uri_decode(uri); 06559 ast_uri_decode(from); 06560 } 06561 06562 /* Skip any options */ 06563 if ((a = strchr(uri, ';'))) { 06564 *a = '\0'; 06565 } 06566 06567 /* Get the target domain */ 06568 if ((a = strchr(uri, '@'))) { 06569 *a = '\0'; 06570 a++; 06571 } else { /* No username part */ 06572 a = uri; 06573 uri = "s"; /* Set extension to "s" */ 06574 } 06575 colon = strchr(a, ':'); /* Remove :port */ 06576 if (colon) 06577 *colon = '\0'; 06578 06579 ast_copy_string(p->domain, a, sizeof(p->domain)); 06580 06581 if (!AST_LIST_EMPTY(&domain_list)) { 06582 char domain_context[AST_MAX_EXTENSION]; 06583 06584 domain_context[0] = '\0'; 06585 if (!check_sip_domain(p->domain, domain_context, sizeof(domain_context))) { 06586 if (!allow_external_domains && (req->method == SIP_INVITE || req->method == SIP_REFER)) { 06587 ast_log(LOG_DEBUG, "Got SIP %s to non-local domain '%s'; refusing request.\n", sip_methods[req->method].text, p->domain); 06588 return -2; 06589 } 06590 } 06591 /* If we have a context defined, overwrite the original context */ 06592 if (!ast_strlen_zero(domain_context)) 06593 ast_copy_string(p->context, domain_context, sizeof(p->context)); 06594 } 06595 06596 if (from) { 06597 if ((a = strchr(from, ';'))) 06598 *a = '\0'; 06599 if ((a = strchr(from, '@'))) { 06600 *a = '\0'; 06601 ast_copy_string(p->fromdomain, a + 1, sizeof(p->fromdomain)); 06602 } else 06603 ast_copy_string(p->fromdomain, from, sizeof(p->fromdomain)); 06604 } 06605 if (sip_debug_test_pvt(p)) 06606 ast_verbose("Looking for %s in %s (domain %s)\n", uri, p->context, p->domain); 06607 06608 /* Return 0 if we have a matching extension */ 06609 if (ast_exists_extension(NULL, p->context, uri, 1, from) || 06610 !strcmp(uri, ast_pickup_ext())) { 06611 if (!oreq) 06612 ast_copy_string(p->exten, uri, sizeof(p->exten)); 06613 return 0; 06614 } 06615 06616 /* Return 1 for overlap dialling support */ 06617 if (ast_canmatch_extension(NULL, p->context, uri, 1, from) || 06618 !strncmp(uri, ast_pickup_ext(),strlen(uri))) { 06619 return 1; 06620 } 06621 06622 return -1; 06623 }
|
|
get_header: Get header from SIP request ---
Definition at line 2940 of file chan_sip.c. References __get_header(). 02941 { 02942 int start = 0; 02943 return __get_header(req, name, &start); 02944 }
|
|
get_in_brackets: Pick out text in brackets from character string ---
Definition at line 1532 of file chan_sip.c. References ast_log(), 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(). 01533 { 01534 char *parse; 01535 char *first_quote; 01536 char *first_bracket; 01537 char *second_bracket; 01538 char last_char; 01539 01540 parse = tmp; 01541 while (1) { 01542 first_quote = strchr(parse, '"'); 01543 first_bracket = strchr(parse, '<'); 01544 if (first_quote && first_bracket && (first_quote < first_bracket)) { 01545 last_char = '\0'; 01546 for (parse = first_quote + 1; *parse; parse++) { 01547 if ((*parse == '"') && (last_char != '\\')) 01548 break; 01549 last_char = *parse; 01550 } 01551 if (!*parse) { 01552 ast_log(LOG_WARNING, "No closing quote found in '%s'\n", tmp); 01553 return tmp; 01554 } 01555 parse++; 01556 continue; 01557 } 01558 if (first_bracket) { 01559 second_bracket = strchr(first_bracket + 1, '>'); 01560 if (second_bracket) { 01561 *second_bracket = '\0'; 01562 return first_bracket + 1; 01563 } else { 01564 ast_log(LOG_WARNING, "No closing bracket found in '%s'\n", tmp); 01565 return tmp; 01566 } 01567 } 01568 return tmp; 01569 } 01570 }
|
|
get_msg_text: Get text out of a SIP MESSAGE packet ---
Definition at line 7227 of file chan_sip.c. References sip_request::line, and sip_request::lines. Referenced by receive_message(). 07228 { 07229 int x; 07230 int y; 07231 07232 buf[0] = '\0'; 07233 y = len - strlen(buf) - 5; 07234 if (y < 0) 07235 y = 0; 07236 for (x=0;x<req->lines;x++) { 07237 strncat(buf, req->line[x], y); /* safe */ 07238 y -= strlen(req->line[x]) + 1; 07239 if (y < 0) 07240 y = 0; 07241 if (y != 0) 07242 strcat(buf, "\n"); /* safe */ 07243 } 07244 return 0; 07245 }
|
|
get_rdnis: get referring dnis ---
Definition at line 6497 of file chan_sip.c. References ast_log(), ast_strlen_zero(), ast_verbose(), get_header(), get_in_brackets(), sip_pvt::initreq, LOG_WARNING, sip_pvt::rdnis, and sip_debug_test_pvt(). Referenced by handle_request_invite(). 06498 { 06499 char tmp[256], *c, *a; 06500 struct sip_request *req; 06501 06502 req = oreq; 06503 if (!req) 06504 req = &p->initreq; 06505 ast_copy_string(tmp, get_header(req, "Diversion"), sizeof(tmp)); 06506 if (ast_strlen_zero(tmp)) 06507 return 0; 06508 c = get_in_brackets(tmp); 06509 if (strncmp(c, "sip:", 4)) { 06510 ast_log(LOG_WARNING, "Huh? Not an RDNIS SIP header (%s)?\n", c); 06511 return -1; 06512 } 06513 c += 4; 06514 if ((a = strchr(c, '@')) || (a = strchr(c, ';'))) { 06515 *a = '\0'; 06516 } 06517 if (sip_debug_test_pvt(p)) 06518 ast_verbose("RDNIS is %s\n", c); 06519 ast_copy_string(p->rdnis, c, sizeof(p->rdnis)); 06520 06521 return 0; 06522 }
|
|
get_refer_info: Call transfer support (the REFER method) ---
Definition at line 6655 of file chan_sip.c. References ast_bridged_channel(), ast_canmatch_extension(), ast_exists_extension(), ast_log(), ast_parking_ext(), ast_strdupa, ast_strlen_zero(), ast_uri_decode(), ast_verbose(), sip_pvt::callid, sip_pvt::context, get_header(), get_in_brackets(), get_sip_pvt_byid_locked(), sip_pvt::initreq, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, ast_channel::name, sip_pvt::owner, pbx_builtin_setvar_helper(), pedanticsipchecking, sip_pvt::refer_call, sip_pvt::refer_contact, sip_pvt::refer_to, sip_pvt::referred_by, and sip_debug_test_pvt(). Referenced by handle_request_refer(). 06656 { 06657 06658 char *p_refer_to = NULL, *p_referred_by = NULL, *h_refer_to = NULL, *h_referred_by = NULL, *h_contact = NULL; 06659 char *replace_callid = "", *refer_to = NULL, *referred_by = NULL, *ptr = NULL; 06660 struct sip_request *req = NULL; 06661 struct sip_pvt *sip_pvt_ptr = NULL; 06662 struct ast_channel *chan = NULL, *peer = NULL; 06663 06664 req = outgoing_req; 06665 06666 if (!req) { 06667 req = &sip_pvt->initreq; 06668 } 06669 06670 if (!( (p_refer_to = get_header(req, "Refer-To")) && (h_refer_to = ast_strdupa(p_refer_to)) )) { 06671 ast_log(LOG_WARNING, "No Refer-To Header That's illegal\n"); 06672 return -1; 06673 } 06674 06675 refer_to = get_in_brackets(h_refer_to); 06676 06677 if (!( (p_referred_by = get_header(req, "Referred-By")) && (h_referred_by = ast_strdupa(p_referred_by)) )) { 06678 ast_log(LOG_WARNING, "No Referrred-By Header That's not illegal\n"); 06679 return -1; 06680 } else { 06681 if (pedanticsipchecking) { 06682 ast_uri_decode(h_referred_by); 06683 } 06684 referred_by = get_in_brackets(h_referred_by); 06685 } 06686 h_contact = get_header(req, "Contact"); 06687 06688 if (strncmp(refer_to, "sip:", 4)) { 06689 ast_log(LOG_WARNING, "Refer-to: Huh? Not a SIP header (%s)?\n", refer_to); 06690 return -1; 06691 } 06692 06693 if (strncmp(referred_by, "sip:", 4)) { 06694 ast_log(LOG_WARNING, "Referred-by: Huh? Not a SIP header (%s) Ignoring?\n", referred_by); 06695 referred_by = NULL; 06696 } 06697 06698 if (refer_to) 06699 refer_to += 4; 06700 06701 if (referred_by) 06702 referred_by += 4; 06703 06704 if ((ptr = strchr(refer_to, '?'))) { 06705 /* Search for arguments */ 06706 *ptr = '\0'; 06707 ptr++; 06708 if (!strncasecmp(ptr, "REPLACES=", 9)) { 06709 char *p; 06710 replace_callid = ast_strdupa(ptr + 9); 06711 /* someday soon to support invite/replaces properly! 06712 replaces_header = ast_strdupa(replace_callid); 06713 -anthm 06714 */ 06715 ast_uri_decode(replace_callid); 06716 if ((ptr = strchr(replace_callid, '%'))) 06717 *ptr = '\0'; 06718 if ((ptr = strchr(replace_callid, ';'))) 06719 *ptr = '\0'; 06720 /* Skip leading whitespace XXX memmove behaviour with overlaps ? */ 06721 p = ast_skip_blanks(replace_callid); 06722 if (p != replace_callid) 06723 memmove(replace_callid, p, strlen(p)); 06724 } 06725 } 06726 06727 if ((ptr = strchr(refer_to, '@'))) /* Skip domain (should be saved in SIPDOMAIN) */ 06728 *ptr = '\0'; 06729 if ((ptr = strchr(refer_to, ';'))) 06730 *ptr = '\0'; 06731 06732 if (referred_by) { 06733 if ((ptr = strchr(referred_by, '@'))) 06734 *ptr = '\0'; 06735 if ((ptr = strchr(referred_by, ';'))) 06736 *ptr = '\0'; 06737 } 06738 06739 if (sip_debug_test_pvt(sip_pvt)) { 06740 ast_verbose("Transfer to %s in %s\n", refer_to, sip_pvt->context); 06741 if (referred_by) 06742 ast_verbose("Transfer from %s in %s\n", referred_by, sip_pvt->context); 06743 } 06744 if (!ast_strlen_zero(replace_callid)) { 06745 /* This is a supervised transfer */ 06746 ast_log(LOG_DEBUG,"Assigning Replace-Call-ID Info %s to REPLACE_CALL_ID\n",replace_callid); 06747 06748 ast_copy_string(sip_pvt->refer_to, "", sizeof(sip_pvt->refer_to)); 06749 ast_copy_string(sip_pvt->referred_by, "", sizeof(sip_pvt->referred_by)); 06750 ast_copy_string(sip_pvt->refer_contact, "", sizeof(sip_pvt->refer_contact)); 06751 sip_pvt->refer_call = NULL; 06752 if ((sip_pvt_ptr = get_sip_pvt_byid_locked(replace_callid))) { 06753 sip_pvt->refer_call = sip_pvt_ptr; 06754 if (sip_pvt->refer_call == sip_pvt) { 06755 ast_log(LOG_NOTICE, "Supervised transfer attempted to transfer into same call id (%s == %s)!\n", replace_callid, sip_pvt->callid); 06756 sip_pvt->refer_call = NULL; 06757 } else 06758 return 0; 06759 } else { 06760 ast_log(LOG_NOTICE, "Supervised transfer requested, but unable to find callid '%s'. Both legs must reside on Asterisk box to transfer at this time.\n", replace_callid); 06761 /* XXX The refer_to could contain a call on an entirely different machine, requiring an 06762 INVITE with a replaces header -anthm XXX */ 06763 /* The only way to find out is to use the dialplan - oej */ 06764 } 06765 } else if (ast_exists_extension(NULL, sip_pvt->context, refer_to, 1, NULL) || !strcmp(refer_to, ast_parking_ext())) { 06766 /* This is an unsupervised transfer (blind transfer) */ 06767 06768 ast_log(LOG_DEBUG,"Unsupervised transfer to (Refer-To): %s\n", refer_to); 06769 if (referred_by) 06770 ast_log(LOG_DEBUG,"Transferred by (Referred-by: ) %s \n", referred_by); 06771 ast_log(LOG_DEBUG,"Transfer Contact Info %s (REFER_CONTACT)\n", h_contact); 06772 ast_copy_string(sip_pvt->refer_to, refer_to, sizeof(sip_pvt->refer_to)); 06773 if (referred_by) 06774 ast_copy_string(sip_pvt->referred_by, referred_by, sizeof(sip_pvt->referred_by)); 06775 if (h_contact) { 06776 ast_copy_string(sip_pvt->refer_contact, h_contact, sizeof(sip_pvt->refer_contact)); 06777 } 06778 sip_pvt->refer_call = NULL; 06779 if ((chan = sip_pvt->owner) && (peer = ast_bridged_channel(sip_pvt->owner))) { 06780 pbx_builtin_setvar_helper(chan, "BLINDTRANSFER", peer->name); 06781 pbx_builtin_setvar_helper(peer, "BLINDTRANSFER", chan->name); 06782 } 06783 return 0; 06784 } else if (ast_canmatch_extension(NULL, sip_pvt->context, refer_to, 1, NULL)) { 06785 return 1; 06786 } 06787 06788 return -1; 06789 }
|
|
get_rpid_num: 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 6927 of file chan_sip.c. References AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED. Referenced by check_user_full(). 06928 { 06929 char *start; 06930 char *end; 06931 06932 start = strchr(input,':'); 06933 if (!start) { 06934 output[0] = '\0'; 06935 return 0; 06936 } 06937 start++; 06938 06939 /* we found "number" */ 06940 ast_copy_string(output,start,maxlen); 06941 output[maxlen-1] = '\0'; 06942 06943 end = strchr(output,'@'); 06944 if (end) 06945 *end = '\0'; 06946 else 06947 output[0] = '\0'; 06948 if (strstr(input,"privacy=full") || strstr(input,"privacy=uri")) 06949 return AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED; 06950 06951 return 0; 06952 }
|
|
get_sdp: Gets all kind of SIP message bodies, including SDP, but the name wrongly applies _only_ sdp
Definition at line 2861 of file chan_sip.c. References get_sdp_by_line(), sip_request::line, and sip_request::lines. 02862 { 02863 int x; 02864 int len = strlen(name); 02865 char *r; 02866 02867 for (x=0; x<req->lines; x++) { 02868 r = get_sdp_by_line(req->line[x], name, len); 02869 if (r[0] != '\0') 02870 return r; 02871 } 02872 return ""; 02873 }
|
|
get_sdp_by_line: Reads one line of SIP message body
Definition at line 2851 of file chan_sip.c. 02852 { 02853 if (strncasecmp(line, name, nameLen) == 0 && line[nameLen] == '=') { 02854 return ast_skip_blanks(line + nameLen + 1); 02855 } 02856 return ""; 02857 }
|
|
Definition at line 2881 of file chan_sip.c. References get_sdp_by_line(), and sip_request::line. 02883 { 02884 int len = strlen(name); 02885 char *r; 02886 02887 while (*iterator < req->lines) { 02888 r = get_sdp_by_line(req->line[(*iterator)++], name, len); 02889 if (r[0] != '\0') 02890 return r; 02891 } 02892 return ""; 02893 }
|
|
get_sip_pvt_byid_locked: Lock interface lock and find matching pvt lock ---
Definition at line 6626 of file chan_sip.c. References ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), sip_pvt::callid, iflist, ast_channel::lock, sip_pvt::lock, sip_pvt::next, and sip_pvt::owner. Referenced by get_refer_info(). 06627 { 06628 struct sip_pvt *sip_pvt_ptr = NULL; 06629 06630 /* Search interfaces and find the match */ 06631 ast_mutex_lock(&iflock); 06632 sip_pvt_ptr = iflist; 06633 while(sip_pvt_ptr) { 06634 if (!strcmp(sip_pvt_ptr->callid, callid)) { 06635 /* Go ahead and lock it (and its owner) before returning */ 06636 ast_mutex_lock(&sip_pvt_ptr->lock); 06637 if (sip_pvt_ptr->owner) { 06638 while(ast_mutex_trylock(&sip_pvt_ptr->owner->lock)) { 06639 ast_mutex_unlock(&sip_pvt_ptr->lock); 06640 usleep(1); 06641 ast_mutex_lock(&sip_pvt_ptr->lock); 06642 if (!sip_pvt_ptr->owner) 06643 break; 06644 } 06645 } 06646 break; 06647 } 06648 sip_pvt_ptr = sip_pvt_ptr->next; 06649 } 06650 ast_mutex_unlock(&iflock); 06651 return sip_pvt_ptr; 06652 }
|
|
gettag: Get tag from packet
Definition at line 10210 of file chan_sip.c. References get_header(), and strcasestr(). Referenced by find_call(), handle_request(), and handle_response(). 10211 { 10212 10213 char *thetag, *sep; 10214 10215 10216 if (!tagbuf) 10217 return NULL; 10218 tagbuf[0] = '\0'; /* reset the buffer */ 10219 thetag = get_header(req, header); 10220 thetag = strcasestr(thetag, ";tag="); 10221 if (thetag) { 10222 thetag += 5; 10223 ast_copy_string(tagbuf, thetag, tagbufsize); 10224 sep = strchr(tagbuf, ';'); 10225 if (sep) 10226 *sep = '\0'; 10227 } 10228 return thetag; 10229 }
|
|
handle_common_options: Handle flag-type options common to users and peers ---
Definition at line 11631 of file chan_sip.c. References ast_clear_flag, ast_false(), ast_log(), ast_set2_flag, ast_set_flag, ast_true(), ast_channel::flags, global_allowguest, ast_variable::lineno, LOG_WARNING, ast_variable::name, ast_channel::next, SIP_CAN_REINVITE, SIP_DTMF, SIP_DTMF_AUTO, SIP_DTMF_INBAND, SIP_DTMF_INFO, SIP_DTMF_RFC2833, SIP_INSECURE_INVITE, SIP_INSECURE_PORT, SIP_NAT, SIP_NAT_ALWAYS, SIP_NAT_NEVER, SIP_NAT_RFC3581, SIP_NAT_ROUTE, SIP_OSPAUTH, SIP_OSPAUTH_EXCLUSIVE, SIP_OSPAUTH_GATEWAY, SIP_OSPAUTH_PROXY, 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(). 11632 { 11633 int res = 0; 11634 11635 if (!strcasecmp(v->name, "trustrpid")) { 11636 ast_set_flag(mask, SIP_TRUSTRPID); 11637 ast_set2_flag(flags, ast_true(v->value), SIP_TRUSTRPID); 11638 res = 1; 11639 } else if (!strcasecmp(v->name, "sendrpid")) { 11640 ast_set_flag(mask, SIP_SENDRPID); 11641 ast_set2_flag(flags, ast_true(v->value), SIP_SENDRPID); 11642 res = 1; 11643 } else if (!strcasecmp(v->name, "useclientcode")) { 11644 ast_set_flag(mask, SIP_USECLIENTCODE); 11645 ast_set2_flag(flags, ast_true(v->value), SIP_USECLIENTCODE); 11646 res = 1; 11647 } else if (!strcasecmp(v->name, "dtmfmode")) { 11648 ast_set_flag(mask, SIP_DTMF); 11649 ast_clear_flag(flags, SIP_DTMF); 11650 if (!strcasecmp(v->value, "inband")) 11651 ast_set_flag(flags, SIP_DTMF_INBAND); 11652 else if (!strcasecmp(v->value, "rfc2833")) 11653 ast_set_flag(flags, SIP_DTMF_RFC2833); 11654 else if (!strcasecmp(v->value, "info")) 11655 ast_set_flag(flags, SIP_DTMF_INFO); 11656 else if (!strcasecmp(v->value, "auto")) 11657 ast_set_flag(flags, SIP_DTMF_AUTO); 11658 else { 11659 ast_log(LOG_WARNING, "Unknown dtmf mode '%s' on line %d, using rfc2833\n", v->value, v->lineno); 11660 ast_set_flag(flags, SIP_DTMF_RFC2833); 11661 } 11662 } else if (!strcasecmp(v->name, "nat")) { 11663 ast_set_flag(mask, SIP_NAT); 11664 ast_clear_flag(flags, SIP_NAT); 11665 if (!strcasecmp(v->value, "never")) 11666 ast_set_flag(flags, SIP_NAT_NEVER); 11667 else if (!strcasecmp(v->value, "route")) 11668 ast_set_flag(flags, SIP_NAT_ROUTE); 11669 else if (ast_true(v->value)) 11670 ast_set_flag(flags, SIP_NAT_ALWAYS); 11671 else 11672 ast_set_flag(flags, SIP_NAT_RFC3581); 11673 } else if (!strcasecmp(v->name, "canreinvite")) { 11674 ast_set_flag(mask, SIP_REINVITE); 11675 ast_clear_flag(flags, SIP_REINVITE); 11676 if (!strcasecmp(v->value, "update")) 11677 ast_set_flag(flags, SIP_REINVITE_UPDATE | SIP_CAN_REINVITE); 11678 else 11679 ast_set2_flag(flags, ast_true(v->value), SIP_CAN_REINVITE); 11680 } else if (!strcasecmp(v->name, "insecure")) { 11681 ast_set_flag(mask, SIP_INSECURE_PORT | SIP_INSECURE_INVITE); 11682 ast_clear_flag(flags, SIP_INSECURE_PORT | SIP_INSECURE_INVITE); 11683 if (!strcasecmp(v->value, "very")) 11684 ast_set_flag(flags, SIP_INSECURE_PORT | SIP_INSECURE_INVITE); 11685 else if (ast_true(v->value)) 11686 ast_set_flag(flags, SIP_INSECURE_PORT); 11687 else if (!ast_false(v->value)) { 11688 char buf[64]; 11689 char *word, *next; 11690 11691 ast_copy_string(buf, v->value, sizeof(buf)); 11692 next = buf; 11693 while ((word = strsep(&next, ","))) { 11694 if (!strcasecmp(word, "port")) 11695 ast_set_flag(flags, SIP_INSECURE_PORT); 11696 else if (!strcasecmp(word, "invite")) 11697 ast_set_flag(flags, SIP_INSECURE_INVITE); 11698 else 11699 ast_log(LOG_WARNING, "Unknown insecure mode '%s' on line %d\n", v->value, v->lineno); 11700 } 11701 } 11702 } else if (!strcasecmp(v->name, "progressinband")) { 11703 ast_set_flag(mask, SIP_PROG_INBAND); 11704 ast_clear_flag(flags, SIP_PROG_INBAND); 11705 if (ast_true(v->value)) 11706 ast_set_flag(flags, SIP_PROG_INBAND_YES); 11707 else if (strcasecmp(v->value, "never")) 11708 ast_set_flag(flags, SIP_PROG_INBAND_NO); 11709 } else if (!strcasecmp(v->name, "allowguest")) { 11710 #ifdef OSP_SUPPORT 11711 if (!strcasecmp(v->value, "osp")) 11712 global_allowguest = 2; 11713 else 11714 #endif 11715 if (ast_true(v->value)) 11716 global_allowguest = 1; 11717 else 11718 global_allowguest = 0; 11719 #ifdef OSP_SUPPORT 11720 } else if (!strcasecmp(v->name, "ospauth")) { 11721 ast_set_flag(mask, SIP_OSPAUTH); 11722 ast_clear_flag(flags, SIP_OSPAUTH); 11723 if (!strcasecmp(v->value, "proxy")) 11724 ast_set_flag(flags, SIP_OSPAUTH_PROXY); 11725 else if (!strcasecmp(v->value, "gateway")) 11726 ast_set_flag(flags, SIP_OSPAUTH_GATEWAY); 11727 else if(!strcasecmp (v->value, "exclusive")) 11728 ast_set_flag(flags, SIP_OSPAUTH_EXCLUSIVE); 11729 #endif 11730 } else if (!strcasecmp(v->name, "promiscredir")) { 11731 ast_set_flag(mask, SIP_PROMISCREDIR); 11732 ast_set2_flag(flags, ast_true(v->value), SIP_PROMISCREDIR); 11733 res = 1; 11734 } 11735 11736 return res; 11737 }
|
|
handle_request: Handle SIP requests (methods) ---
Definition at line 10899 of file chan_sip.c. References __sip_ack(), ast_inet_ntoa(), ast_log(), ast_set_flag, ast_strlen_zero(), ast_test_flag, ast_verbose(), check_pendings(), debug, error(), extract_uri(), FLAG_RESPONSE, get_header(), gettag(), handle_request_bye(), handle_request_cancel(), handle_request_info(), handle_request_invite(), handle_request_message(), handle_request_options(), handle_request_refer(), handle_request_register(), handle_request_subscribe(), handle_response(), sip_request::header, sip_request::headers, sip_pvt::icseq, sip_pvt::initreq, sip_pvt::lastinvite, sip_pvt::lastmsg, sip_request::len, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, LOG_WARNING, sip_pvt::method, sip_request::method, sip_pvt::ocseq, option_debug, pedanticsipchecking, sip_pvt::pendinginvite, process_sdp(), sip_pvt::randdata, sip_request::rlPart1, sip_request::rlPart2, sip_pvt::sa, 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_WITH_TOTAG, SIP_REFER, SIP_REGISTER, SIP_RESPONSE, SIP_SUBSCRIBE, sip_pvt::theirtag, transmit_response(), transmit_response_reliable(), transmit_response_with_allow(), and sip_pvt::useragent. 10900 { 10901 /* Called with p->lock held, as well as p->owner->lock if appropriate, keeping things 10902 relatively static */ 10903 struct sip_request resp; 10904 char *cmd; 10905 char *cseq; 10906 char *useragent; 10907 int seqno; 10908 int len; 10909 int ignore=0; 10910 int respid; 10911 int res = 0; 10912 char iabuf[INET_ADDRSTRLEN]; 10913 int debug = sip_debug_test_pvt(p); 10914 char *e; 10915 int error = 0; 10916 10917 /* Clear out potential response */ 10918 memset(&resp, 0, sizeof(resp)); 10919 10920 /* Get Method and Cseq */ 10921 cseq = get_header(req, "Cseq"); 10922 cmd = req->header[0]; 10923 10924 /* Must have Cseq */ 10925 if (ast_strlen_zero(cmd) || ast_strlen_zero(cseq)) { 10926 ast_log(LOG_ERROR, "Missing Cseq. Dropping this SIP message, it's incomplete.\n"); 10927 error = 1; 10928 } 10929 if (!error && sscanf(cseq, "%d%n", &seqno, &len) != 1) { 10930 ast_log(LOG_ERROR, "No seqno in '%s'. Dropping incomplete message.\n", cmd); 10931 error = 1; 10932 } 10933 if (error) { 10934 if (!p->initreq.header) /* New call */ 10935 ast_set_flag(p, SIP_NEEDDESTROY); /* Make sure we destroy this dialog */ 10936 return -1; 10937 } 10938 /* Get the command XXX */ 10939 10940 cmd = req->rlPart1; 10941 e = req->rlPart2; 10942 10943 /* Save useragent of the client */ 10944 useragent = get_header(req, "User-Agent"); 10945 if (!ast_strlen_zero(useragent)) 10946 ast_copy_string(p->useragent, useragent, sizeof(p->useragent)); 10947 10948 /* Find out SIP method for incoming request */ 10949 if (req->method == SIP_RESPONSE) { /* Response to our request */ 10950 /* Response to our request -- Do some sanity checks */ 10951 if (!p->initreq.headers) { 10952 ast_log(LOG_DEBUG, "That's odd... Got a response on a call we dont know about. Cseq %d Cmd %s\n", seqno, cmd); 10953 ast_set_flag(p, SIP_NEEDDESTROY); 10954 return 0; 10955 } else if (p->ocseq && (p->ocseq < seqno)) { 10956 ast_log(LOG_DEBUG, "Ignoring out of order response %d (expecting %d)\n", seqno, p->ocseq); 10957 return -1; 10958 } else if (p->ocseq && (p->ocseq != seqno)) { 10959 /* ignore means "don't do anything with it" but still have to 10960 respond appropriately */ 10961 ignore=1; 10962 } 10963 10964 e = ast_skip_blanks(e); 10965 if (sscanf(e, "%d %n", &respid, &len) != 1) { 10966 ast_log(LOG_WARNING, "Invalid response: '%s'\n", e); 10967 } else { 10968 /* More SIP ridiculousness, we have to ignore bogus contacts in 100 etc responses */ 10969 if ((respid == 200) || ((respid >= 300) && (respid <= 399))) 10970 extract_uri(p, req); 10971 handle_response(p, respid, e + len, req, ignore, seqno); 10972 } 10973 return 0; 10974 } 10975 10976 /* New SIP request coming in 10977 (could be new request in existing SIP dialog as well...) 10978 */ 10979 10980 p->method = req->method; /* Find out which SIP method they are using */ 10981 if (option_debug > 2) 10982 ast_log(LOG_DEBUG, "**** Received %s (%d) - Command in SIP %s\n", sip_methods[p->method].text, sip_methods[p->method].id, cmd); 10983 10984 if (p->icseq && (p->icseq > seqno)) { 10985 if (option_debug) 10986 ast_log(LOG_DEBUG, "Ignoring too old SIP packet packet %d (expecting >= %d)\n", seqno, p->icseq); 10987 if (req->method != SIP_ACK) 10988 transmit_response(p, "503 Server error", req); /* We must respond according to RFC 3261 sec 12.2 */ 10989 return -1; 10990 } else if (p->icseq && (p->icseq == seqno) && req->method != SIP_ACK &&(p->method != SIP_CANCEL|| ast_test_flag(p, SIP_ALREADYGONE))) { 10991 /* ignore means "don't do anything with it" but still have to 10992 respond appropriately. We do this if we receive a repeat of 10993 the last sequence number */ 10994 ignore=2; 10995 if (option_debug > 2) 10996 ast_log(LOG_DEBUG, "Ignoring SIP message because of retransmit (%s Seqno %d, ours %d)\n", sip_methods[p->method].text, p->icseq, seqno); 10997 } 10998 10999 if (seqno >= p->icseq) 11000 /* Next should follow monotonically (but not necessarily 11001 incrementally -- thanks again to the genius authors of SIP -- 11002 increasing */ 11003 p->icseq = seqno; 11004 11005 /* Find their tag if we haven't got it */ 11006 if (ast_strlen_zero(p->theirtag)) { 11007 gettag(req, "From", p->theirtag, sizeof(p->theirtag)); 11008 } 11009 snprintf(p->lastmsg, sizeof(p->lastmsg), "Rx: %s", cmd); 11010 11011 if (pedanticsipchecking) { 11012 /* If this is a request packet without a from tag, it's not 11013 correct according to RFC 3261 */ 11014 /* Check if this a new request in a new dialog with a totag already attached to it, 11015 RFC 3261 - section 12.2 - and we don't want to mess with recovery */ 11016 if (!p->initreq.headers && ast_test_flag(req, SIP_PKT_WITH_TOTAG)) { 11017 /* If this is a first request and it got a to-tag, it is not for us */ 11018 if (!ignore && req->method == SIP_INVITE) { 11019 transmit_response_reliable(p, "481 Call/Transaction Does Not Exist", req, 1); 11020 /* Will cease to exist after ACK */ 11021 } else { 11022 transmit_response(p, "481 Call/Transaction Does Not Exist", req); 11023 ast_set_flag(p, SIP_NEEDDESTROY); 11024 } 11025 return res; 11026 } 11027 } 11028 11029 if (!e && (p->method == SIP_INVITE || p->method == SIP_SUBSCRIBE || p->method == SIP_REGISTER)) { 11030 transmit_response(p, "503 Server error", req); 11031 ast_set_flag(p, SIP_NEEDDESTROY); 11032 return -1; 11033 } 11034 11035 /* Handle various incoming SIP methods in requests */ 11036 switch (p->method) { 11037 case SIP_OPTIONS: 11038 res = handle_request_options(p, req, debug); 11039 break; 11040 case SIP_INVITE: 11041 res = handle_request_invite(p, req, debug, ignore, seqno, sin, recount, e); 11042 break; 11043 case SIP_REFER: 11044 res = handle_request_refer(p, req, debug, ignore, seqno, nounlock); 11045 break; 11046 case SIP_CANCEL: 11047 res = handle_request_cancel(p, req, debug, ignore); 11048 break; 11049 case SIP_BYE: 11050 res = handle_request_bye(p, req, debug, ignore); 11051 break; 11052 case SIP_MESSAGE: 11053 res = handle_request_message(p, req, debug, ignore); 11054 break; 11055 case SIP_SUBSCRIBE: 11056 res = handle_request_subscribe(p, req, debug, ignore, sin, seqno, e); 11057 break; 11058 case SIP_REGISTER: 11059 res = handle_request_register(p, req, debug, ignore, sin, e); 11060 break; 11061 case SIP_INFO: 11062 if (!ignore) { 11063 if (debug) 11064 ast_verbose("Receiving INFO!\n"); 11065 handle_request_info(p, req); 11066 } else { /* if ignoring, transmit response */ 11067 transmit_response(p, "200 OK", req); 11068 } 11069 break; 11070 case SIP_NOTIFY: 11071 /* XXX we get NOTIFY's from some servers. WHY?? Maybe we should 11072 look into this someday XXX */ 11073 transmit_response(p, "200 OK", req); 11074 if (!p->lastinvite) 11075 ast_set_flag(p, SIP_NEEDDESTROY); 11076 break; 11077 case SIP_ACK: 11078 /* Make sure we don't ignore this */ 11079 if (seqno == p->pendinginvite) { 11080 p->pendinginvite = 0; 11081 __sip_ack(p, seqno, FLAG_RESPONSE, 0); 11082 if (!ast_strlen_zero(get_header(req, "Content-Type"))) { 11083 if (process_sdp(p, req)) 11084 return -1; 11085 } 11086 check_pendings(p); 11087 } 11088 if (!p->lastinvite && ast_strlen_zero(p->randdata)) 11089 ast_set_flag(p, SIP_NEEDDESTROY); 11090 break; 11091 default: 11092 transmit_response_with_allow(p, "501 Method Not Implemented", req, 0); 11093 ast_log(LOG_NOTICE, "Unknown SIP command '%s' from '%s'\n", 11094 cmd, ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr)); 11095 /* If this is some new method, and we don't have a call, destroy it now */ 11096 if (!p->initreq.headers) 11097 ast_set_flag(p, SIP_NEEDDESTROY); 11098 break; 11099 } 11100 return res; 11101 }
|
|
handle_request_bye: Handle incoming BYE request ---
Definition at line 10611 of file chan_sip.c. References ast_async_goto(), ast_bridged_channel(), ast_inet_ntoa(), ast_log(), ast_moh_stop(), ast_queue_hangup(), ast_rtp_stop(), ast_set_flag, ast_strlen_zero(), ast_test_flag, check_via(), copy_request(), default_context, get_also_info(), get_header(), sip_pvt::initreq, LOG_NOTICE, LOG_WARNING, sip_pvt::pendinginvite, SIP_ALREADYGONE, SIP_NEEDDESTROY, SIP_OUTGOING, transmit_response(), and transmit_response_reliable(). Referenced by handle_request(). 10612 { 10613 struct ast_channel *c=NULL; 10614 int res; 10615 struct ast_channel *bridged_to; 10616 char iabuf[INET_ADDRSTRLEN]; 10617 10618 if (p->pendinginvite && !ast_test_flag(p, SIP_OUTGOING) && !ignore) 10619 transmit_response_reliable(p, "487 Request Terminated", &p->initreq, 1); 10620 10621 copy_request(&p->initreq, req); 10622 check_via(p, req); 10623 ast_set_flag(p, SIP_ALREADYGONE); 10624 if (p->rtp) { 10625 /* Immediately stop RTP */ 10626 ast_rtp_stop(p->rtp); 10627 } 10628 if (p->vrtp) { 10629 /* Immediately stop VRTP */ 10630 ast_rtp_stop(p->vrtp); 10631 } 10632 if (!ast_strlen_zero(get_header(req, "Also"))) { 10633 ast_log(LOG_NOTICE, "Client '%s' using deprecated BYE/Also transfer method. Ask vendor to support REFER instead\n", 10634 ast_inet_ntoa(iabuf, sizeof(iabuf), p->recv.sin_addr)); 10635 if (ast_strlen_zero(p->context)) 10636 strcpy(p->context, default_context); 10637 res = get_also_info(p, req); 10638 if (!res) { 10639 c = p->owner; 10640 if (c) { 10641 bridged_to = ast_bridged_channel(c); 10642 if (bridged_to) { 10643 /* Don't actually hangup here... */ 10644 ast_moh_stop(bridged_to); 10645 ast_async_goto(bridged_to, p->context, p->refer_to,1); 10646 } else 10647 ast_queue_hangup(p->owner); 10648 } 10649 } else { 10650 ast_log(LOG_WARNING, "Invalid transfer information from '%s'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), p->recv.sin_addr)); 10651 if (p->owner) 10652 ast_queue_hangup(p->owner); 10653 } 10654 } else if (p->owner) 10655 ast_queue_hangup(p->owner); 10656 else 10657 ast_set_flag(p, SIP_NEEDDESTROY); 10658 transmit_response(p, "200 OK", req); 10659 10660 return 1; 10661 }
|
|
handle_request_cancel: Handle incoming CANCEL request ---
Definition at line 10582 of file chan_sip.c. References ast_queue_hangup(), ast_rtp_stop(), ast_set_flag, check_via(), sip_pvt::initreq, sip_request::len, sip_pvt::owner, sip_pvt::rtp, SIP_ALREADYGONE, SIP_NEEDDESTROY, transmit_response(), transmit_response_reliable(), and sip_pvt::vrtp. Referenced by handle_request(). 10583 { 10584 10585 check_via(p, req); 10586 ast_set_flag(p, SIP_ALREADYGONE); 10587 if (p->rtp) { 10588 /* Immediately stop RTP */ 10589 ast_rtp_stop(p->rtp); 10590 } 10591 if (p->vrtp) { 10592 /* Immediately stop VRTP */ 10593 ast_rtp_stop(p->vrtp); 10594 } 10595 if (p->owner) 10596 ast_queue_hangup(p->owner); 10597 else 10598 ast_set_flag(p, SIP_NEEDDESTROY); 10599 if (p->initreq.len > 0) { 10600 if (!ignore) 10601 transmit_response_reliable(p, "487 Request Terminated", &p->initreq, 1); 10602 transmit_response(p, "200 OK", req); 10603 return 1; 10604 } else { 10605 transmit_response(p, "481 Call Leg Does Not Exist", req); 10606 return 0; 10607 } 10608 }
|
|
handle_request_info: Receive SIP INFO Message ---
Definition at line 8607 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_set_flag, ast_strlen_zero(), ast_test_flag, ast_verbose(), sip_pvt::callid, ast_channel::cdr, sip_history::event, get_header(), get_sdp(), LOG_WARNING, sip_pvt::owner, SIP_NEEDDESTROY, SIP_USECLIENTCODE, sipdebug, ast_frame::subclass, and transmit_response(). Referenced by handle_request(). 08608 { 08609 char buf[1024]; 08610 unsigned int event; 08611 char *c; 08612 08613 /* Need to check the media/type */ 08614 if (!strcasecmp(get_header(req, "Content-Type"), "application/dtmf-relay") || 08615 !strcasecmp(get_header(req, "Content-Type"), "application/vnd.nortelnetworks.digits")) { 08616 08617 /* Try getting the "signal=" part */ 08618 if (ast_strlen_zero(c = get_sdp(req, "Signal")) && ast_strlen_zero(c = get_sdp(req, "d"))) { 08619 ast_log(LOG_WARNING, "Unable to retrieve DTMF signal from INFO message from %s\n", p->callid); 08620 transmit_response(p, "200 OK", req); /* Should return error */ 08621 return; 08622 } else { 08623 ast_copy_string(buf, c, sizeof(buf)); 08624 } 08625 08626 if (!p->owner) { /* not a PBX call */ 08627 transmit_response(p, "481 Call leg/transaction does not exist", req); 08628 ast_set_flag(p, SIP_NEEDDESTROY); 08629 return; 08630 } 08631 08632 if (ast_strlen_zero(buf)) { 08633 transmit_response(p, "200 OK", req); 08634 return; 08635 } 08636 08637 if (buf[0] == '*') 08638 event = 10; 08639 else if (buf[0] == '#') 08640 event = 11; 08641 else if ((buf[0] >= 'A') && (buf[0] <= 'D')) 08642 event = 12 + buf[0] - 'A'; 08643 else 08644 event = atoi(buf); 08645 if (event == 16) { 08646 /* send a FLASH event */ 08647 struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_FLASH, }; 08648 ast_queue_frame(p->owner, &f); 08649 if (sipdebug) 08650 ast_verbose("* DTMF-relay event received: FLASH\n"); 08651 } else { 08652 /* send a DTMF event */ 08653 struct ast_frame f = { AST_FRAME_DTMF, }; 08654 if (event < 10) { 08655 f.subclass = '0' + event; 08656 } else if (event < 11) { 08657 f.subclass = '*'; 08658 } else if (event < 12) { 08659 f.subclass = '#'; 08660 } else if (event < 16) { 08661 f.subclass = 'A' + (event - 12); 08662 } 08663 ast_queue_frame(p->owner, &f); 08664 if (sipdebug) 08665 ast_verbose("* DTMF-relay event received: %c\n", f.subclass); 08666 } 08667 transmit_response(p, "200 OK", req); 08668 return; 08669 } else if (!strcasecmp(get_header(req, "Content-Type"), "application/media_control+xml")) { 08670 /* Eh, we'll just assume it's a fast picture update for now */ 08671 if (p->owner) 08672 ast_queue_control(p->owner, AST_CONTROL_VIDUPDATE); 08673 transmit_response(p, "200 OK", req); 08674 return; 08675 } else if ((c = get_header(req, "X-ClientCode"))) { 08676 /* Client code (from SNOM phone) */ 08677 if (ast_test_flag(p, SIP_USECLIENTCODE)) { 08678 if (p->owner && p->owner->cdr) 08679 ast_cdr_setuserfield(p->owner, c); 08680 if (p->owner && ast_bridged_channel(p->owner) && ast_bridged_channel(p->owner)->cdr) 08681 ast_cdr_setuserfield(ast_bridged_channel(p->owner), c); 08682 transmit_response(p, "200 OK", req); 08683 } else { 08684 transmit_response(p, "403 Unauthorized", req); 08685 } 08686 return; 08687 } 08688 /* Other type of INFO message, not really understood by Asterisk */ 08689 /* if (get_msg_text(buf, sizeof(buf), req)) { */ 08690 08691 ast_log(LOG_WARNING, "Unable to parse INFO message from %s. Content %s\n", p->callid, buf); 08692 transmit_response(p, "415 Unsupported media type", req); 08693 return; 08694 }
|
|
handle_request_invite: Handle incoming INVITE request
Definition at line 10256 of file chan_sip.c. References ast_channel::_state, ast_channel_setwhentohangup(), ast_clear_flag, AST_FRAME_NULL, ast_hangup(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_PBX_CALL_LIMIT, AST_PBX_FAILED, ast_pbx_start(), AST_PBX_SUCCESS, ast_pickup_call(), ast_pickup_ext(), ast_queue_frame(), ast_set_flag, ast_setstate(), AST_STATE_DOWN, AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, ast_strlen_zero(), ast_test_flag, ast_verbose(), build_contact(), build_route(), sip_pvt::callid, sip_pvt::capability, check_user(), check_via(), sip_pvt::context, copy_request(), DEC_CALL_LIMIT, default_context, sip_pvt::exten, extract_uri(), get_destination(), get_header(), get_rdnis(), INC_CALL_LIMIT, sip_pvt::initreq, 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_sip_options(), sip_pvt::pendinginvite, process_sdp(), SIP_ALREADYGONE, sip_cancel_destroy(), SIP_INVITE, SIP_NEEDDESTROY, sip_new(), SIP_OUTGOING, sipdebug, sip_pvt::sipoptions, sip_pvt::tag, transmit_response(), transmit_response_reliable(), transmit_response_with_sdp(), transmit_response_with_unsupported(), update_call_counter(), and sip_pvt::username. Referenced by handle_request(). 10257 { 10258 int res = 1; 10259 struct ast_channel *c=NULL; 10260 int gotdest; 10261 struct ast_frame af = { AST_FRAME_NULL, }; 10262 char *supported; 10263 char *required; 10264 unsigned int required_profile = 0; 10265 10266 /* Find out what they support */ 10267 if (!p->sipoptions) { 10268 supported = get_header(req, "Supported"); 10269 if (supported) 10270 parse_sip_options(p, supported); 10271 } 10272 required = get_header(req, "Required"); 10273 if (!ast_strlen_zero(required)) { 10274 required_profile = parse_sip_options(NULL, required); 10275 if (required_profile) { /* They require something */ 10276 /* At this point we support no extensions, so fail */ 10277 transmit_response_with_unsupported(p, "420 Bad extension", req, required); 10278 if (!p->lastinvite) 10279 ast_set_flag(p, SIP_NEEDDESTROY); 10280 return -1; 10281 10282 } 10283 } 10284 10285 /* Check if this is a loop */ 10286 /* This happens since we do not properly support SIP domain 10287 handling yet... -oej */ 10288 if (ast_test_flag(p, SIP_OUTGOING) && p->owner && (p->owner->_state != AST_STATE_UP)) { 10289 /* This is a call to ourself. Send ourselves an error code and stop 10290 processing immediately, as SIP really has no good mechanism for 10291 being able to call yourself */ 10292 transmit_response(p, "482 Loop Detected", req); 10293 /* We do NOT destroy p here, so that our response will be accepted */ 10294 return 0; 10295 } 10296 if (!ignore) { 10297 /* Use this as the basis */ 10298 if (debug) 10299 ast_verbose("Using INVITE request as basis request - %s\n", p->callid); 10300 sip_cancel_destroy(p); 10301 /* This call is no longer outgoing if it ever was */ 10302 ast_clear_flag(p, SIP_OUTGOING); 10303 /* This also counts as a pending invite */ 10304 p->pendinginvite = seqno; 10305 copy_request(&p->initreq, req); 10306 check_via(p, req); 10307 if (p->owner) { 10308 /* Handle SDP here if we already have an owner */ 10309 if (!strcasecmp(get_header(req, "Content-Type"), "application/sdp")) { 10310 if (process_sdp(p, req)) { 10311 transmit_response(p, "488 Not acceptable here", req); 10312 if (!p->lastinvite) 10313 ast_set_flag(p, SIP_NEEDDESTROY); 10314 return -1; 10315 } 10316 } else { 10317 p->jointcapability = p->capability; 10318 ast_log(LOG_DEBUG, "Hm.... No sdp for the moment\n"); 10319 } 10320 } 10321 } else if (debug) 10322 ast_verbose("Ignoring this INVITE request\n"); 10323 if (!p->lastinvite && !ignore && !p->owner) { 10324 /* Handle authentication if this is our first invite */ 10325 res = check_user(p, req, SIP_INVITE, e, 1, sin, ignore); 10326 if (res) { 10327 if (res < 0) { 10328 ast_log(LOG_NOTICE, "Failed to authenticate user %s\n", get_header(req, "From")); 10329 if (ignore) 10330 transmit_response(p, "403 Forbidden", req); 10331 else 10332 transmit_response_reliable(p, "403 Forbidden", req, 1); 10333 ast_set_flag(p, SIP_NEEDDESTROY); 10334 p->theirtag[0] = '\0'; /* Forget their to-tag, we'll get a new one */ 10335 } 10336 return 0; 10337 } 10338 /* Process the SDP portion */ 10339 if (!ast_strlen_zero(get_header(req, "Content-Type"))) { 10340 if (process_sdp(p, req)) { 10341 transmit_response(p, "488 Not acceptable here", req); 10342 ast_set_flag(p, SIP_NEEDDESTROY); 10343 return -1; 10344 } 10345 } else { 10346 p->jointcapability = p->capability; 10347 ast_log(LOG_DEBUG, "Hm.... No sdp for the moment\n"); 10348 } 10349 /* Queue NULL frame to prod ast_rtp_bridge if appropriate */ 10350 if (p->owner) 10351 ast_queue_frame(p->owner, &af); 10352 /* Initialize the context if it hasn't been already */ 10353 if (ast_strlen_zero(p->context)) 10354 strcpy(p->context, default_context); 10355 /* Check number of concurrent calls -vs- incoming limit HERE */ 10356 ast_log(LOG_DEBUG, "Checking SIP call limits for device %s\n", p->username); 10357 res = update_call_counter(p, INC_CALL_LIMIT); 10358 if (res) { 10359 if (res < 0) { 10360 ast_log(LOG_NOTICE, "Failed to place call for user %s, too many calls\n", p->username); 10361 if (ignore) 10362 transmit_response(p, "480 Temporarily Unavailable (Call limit)", req); 10363 else 10364 transmit_response_reliable(p, "480 Temporarily Unavailable (Call limit) ", req, 1); 10365 ast_set_flag(p, SIP_NEEDDESTROY); 10366 } 10367 return 0; 10368 } 10369 /* Get destination right away */ 10370 gotdest = get_destination(p, NULL); 10371 10372 get_rdnis(p, NULL); 10373 extract_uri(p, req); 10374 build_contact(p); 10375 10376 if (gotdest) { 10377 if (gotdest < 0) { 10378 if (ignore) 10379 transmit_response(p, "404 Not Found", req); 10380 else 10381 transmit_response_reliable(p, "404 Not Found", req, 1); 10382 update_call_counter(p, DEC_CALL_LIMIT); 10383 } else { 10384 if (ignore) 10385 transmit_response(p, "484 Address Incomplete", req); 10386 else 10387 transmit_response_reliable(p, "484 Address Incomplete", req, 1); 10388 update_call_counter(p, DEC_CALL_LIMIT); 10389 } 10390 ast_set_flag(p, SIP_NEEDDESTROY); 10391 } else { 10392 /* If no extension was specified, use the s one */ 10393 if (ast_strlen_zero(p->exten)) 10394 ast_copy_string(p->exten, "s", sizeof(p->exten)); 10395 /* Initialize tag */ 10396 make_our_tag(p->tag, sizeof(p->tag)); 10397 /* First invitation */ 10398 c = sip_new(p, AST_STATE_DOWN, ast_strlen_zero(p->username) ? NULL : p->username ); 10399 *recount = 1; 10400 /* Save Record-Route for any later requests we make on this dialogue */ 10401 build_route(p, req, 0); 10402 if (c) { 10403 /* Pre-lock the call */ 10404 ast_mutex_lock(&c->lock); 10405 } 10406 } 10407 10408 } else { 10409 if (option_debug > 1 && sipdebug) 10410 ast_log(LOG_DEBUG, "Got a SIP re-invite for call %s\n", p->callid); 10411 c = p->owner; 10412 } 10413 if (!ignore && p) 10414 p->lastinvite = seqno; 10415 if (c) { 10416 #ifdef OSP_SUPPORT 10417 ast_channel_setwhentohangup (c, p->osptimelimit); 10418 #endif 10419 switch(c->_state) { 10420 case AST_STATE_DOWN: 10421 transmit_response(p, "100 Trying", req); 10422 ast_setstate(c, AST_STATE_RING); 10423 if (strcmp(p->exten, ast_pickup_ext())) { 10424 enum ast_pbx_result res; 10425 10426 res = ast_pbx_start(c); 10427 10428 switch (res) { 10429 case AST_PBX_FAILED: 10430 ast_log(LOG_WARNING, "Failed to start PBX :(\n"); 10431 if (ignore) 10432 transmit_response(p, "503 Unavailable", req); 10433 else 10434 transmit_response_reliable(p, "503 Unavailable", req, 1); 10435 break; 10436 case AST_PBX_CALL_LIMIT: 10437 ast_log(LOG_WARNING, "Failed to start PBX (call limit reached) \n"); 10438 if (ignore) 10439 transmit_response(p, "480 Temporarily Unavailable", req); 10440 else 10441 transmit_response_reliable(p, "480 Temporarily Unavailable", req, 1); 10442 break; 10443 case AST_PBX_SUCCESS: 10444 /* nothing to do */ 10445 break; 10446 } 10447 10448 if (res) { 10449 ast_log(LOG_WARNING, "Failed to start PBX :(\n"); 10450 /* Unlock locks so ast_hangup can do its magic */ 10451 ast_mutex_unlock(&c->lock); 10452 ast_mutex_unlock(&p->lock); 10453 ast_hangup(c); 10454 ast_mutex_lock(&p->lock); 10455 c = NULL; 10456 } 10457 } else { 10458 ast_mutex_unlock(&c->lock); 10459 if (ast_pickup_call(c)) { 10460 ast_log(LOG_NOTICE, "Nothing to pick up\n"); 10461 if (ignore) 10462 transmit_response(p, "503 Unavailable", req); 10463 else 10464 transmit_response_reliable(p, "503 Unavailable", req, 1); 10465 ast_set_flag(p, SIP_ALREADYGONE); 10466 /* Unlock locks so ast_hangup can do its magic */ 10467 ast_mutex_unlock(&p->lock); 10468 ast_hangup(c); 10469 ast_mutex_lock(&p->lock); 10470 c = NULL; 10471 } else { 10472 ast_mutex_unlock(&p->lock); 10473 ast_setstate(c, AST_STATE_DOWN); 10474 ast_hangup(c); 10475 ast_mutex_lock(&p->lock); 10476 c = NULL; 10477 } 10478 } 10479 break; 10480 case AST_STATE_RING: 10481 transmit_response(p, "100 Trying", req); 10482 break; 10483 case AST_STATE_RINGING: 10484 transmit_response(p, "180 Ringing", req); 10485 break; 10486 case AST_STATE_UP: 10487 transmit_response_with_sdp(p, "200 OK", req, 1); 10488 break; 10489 default: 10490 ast_log(LOG_WARNING, "Don't know how to handle INVITE in state %d\n", c->_state); 10491 transmit_response(p, "100 Trying", req); 10492 } 10493 } else { 10494 if (p && !ast_test_flag(p, SIP_NEEDDESTROY) && !ignore) { 10495 if (!p->jointcapability) { 10496 if (ignore) 10497 transmit_response(p, "488 Not Acceptable Here (codec error)", req); 10498 else 10499 transmit_response_reliable(p, "488 Not Acceptable Here (codec error)", req, 1); 10500 ast_set_flag(p, SIP_NEEDDESTROY); 10501 } else { 10502 ast_log(LOG_NOTICE, "Unable to create/find channel\n"); 10503 if (ignore) 10504 transmit_response(p, "503 Unavailable", req); 10505 else 10506 transmit_response_reliable(p, "503 Unavailable", req, 1); 10507 ast_set_flag(p, SIP_NEEDDESTROY); 10508 } 10509 } 10510 } 10511 return res; 10512 }
|
|
handle_request_message: Handle incoming MESSAGE request ---
Definition at line 10664 of file chan_sip.c. References ast_verbose(), receive_message(), and transmit_response(). Referenced by handle_request(). 10665 { 10666 if (!ignore) { 10667 if (debug) 10668 ast_verbose("Receiving message!\n"); 10669 receive_message(p, req); 10670 } else { 10671 transmit_response(p, "202 Accepted", req); 10672 } 10673 return 1; 10674 }
|
|
handle_request_options: Handle incoming OPTIONS request
Definition at line 10232 of file chan_sip.c. References ast_set_flag, ast_strlen_zero(), build_contact(), sip_pvt::context, default_context, get_destination(), sip_pvt::lastinvite, SIP_NEEDDESTROY, and transmit_response_with_allow(). Referenced by handle_request(). 10233 { 10234 int res; 10235 10236 res = get_destination(p, req); 10237 build_contact(p); 10238 /* XXX Should we authenticate OPTIONS? XXX */ 10239 if (ast_strlen_zero(p->context)) 10240 strcpy(p->context, default_context); 10241 if (res < 0) 10242 transmit_response_with_allow(p, "404 Not Found", req, 0); 10243 else if (res > 0) 10244 transmit_response_with_allow(p, "484 Address Incomplete", req, 0); 10245 else 10246 transmit_response_with_allow(p, "200 OK", req, 0); 10247 /* Destroy if this OPTIONS was the opening request, but not if 10248 it's in the middle of a normal call flow. */ 10249 if (!p->lastinvite) 10250 ast_set_flag(p, SIP_NEEDDESTROY); 10251 10252 return res; 10253 }
|
|
handle_request_refer: Handle incoming REFER request ---
Definition at line 10515 of file chan_sip.c. References ast_async_goto(), ast_bridged_channel(), ast_log(), ast_moh_stop(), ast_mutex_unlock(), ast_parking_ext(), ast_queue_hangup(), ast_set_flag, ast_strlen_zero(), attempt_transfer(), sip_pvt::callid, sip_pvt::context, default_context, get_refer_info(), sip_pvt::lock, ast_channel::lock, LOG_DEBUG, ast_channel::name, option_debug, sip_pvt::owner, sip_pvt::refer_call, sip_pvt::refer_to, SIP_ALREADYGONE, SIP_BYE, SIP_GOTREFER, sip_park(), transmit_notify_with_sipfrag(), transmit_request_with_auth(), transmit_response(), and transmit_response_with_allow(). Referenced by handle_request(). 10516 { 10517 struct ast_channel *c=NULL; 10518 int res; 10519 struct ast_channel *transfer_to; 10520 10521 if (option_debug > 2) 10522 ast_log(LOG_DEBUG, "SIP call transfer received for call %s (REFER)!\n", p->callid); 10523 if (ast_strlen_zero(p->context)) 10524 strcpy(p->context, default_context); 10525 res = get_refer_info(p, req); 10526 if (res < 0) 10527 transmit_response_with_allow(p, "404 Not Found", req, 1); 10528 else if (res > 0) 10529 transmit_response_with_allow(p, "484 Address Incomplete", req, 1); 10530 else { 10531 int nobye = 0; 10532 if (!ignore) { 10533 if (p->refer_call) { 10534 ast_log(LOG_DEBUG,"202 Accepted (supervised)\n"); 10535 attempt_transfer(p, p->refer_call); 10536 if (p->refer_call->owner) 10537 ast_mutex_unlock(&p->refer_call->owner->lock); 10538 ast_mutex_unlock(&p->refer_call->lock); 10539 p->refer_call = NULL; 10540 ast_set_flag(p, SIP_GOTREFER); 10541 } else { 10542 ast_log(LOG_DEBUG,"202 Accepted (blind)\n"); 10543 c = p->owner; 10544 if (c) { 10545 transfer_to = ast_bridged_channel(c); 10546 if (transfer_to) { 10547 ast_log(LOG_DEBUG, "Got SIP blind transfer, applying to '%s'\n", transfer_to->name); 10548 ast_moh_stop(transfer_to); 10549 if (!strcmp(p->refer_to, ast_parking_ext())) { 10550 /* Must release c's lock now, because it will not longer 10551 be accessible after the transfer! */ 10552 *nounlock = 1; 10553 ast_mutex_unlock(&c->lock); 10554 sip_park(transfer_to, c, req); 10555 nobye = 1; 10556 } else { 10557 /* Must release c's lock now, because it will not longer 10558 be accessible after the transfer! */ 10559 *nounlock = 1; 10560 ast_mutex_unlock(&c->lock); 10561 ast_async_goto(transfer_to,p->context, p->refer_to,1); 10562 } 10563 } else { 10564 ast_log(LOG_DEBUG, "Got SIP blind transfer but nothing to transfer to.\n"); 10565 ast_queue_hangup(p->owner); 10566 } 10567 } 10568 ast_set_flag(p, SIP_GOTREFER); 10569 } 10570 transmit_response(p, "202 Accepted", req); 10571 transmit_notify_with_sipfrag(p, seqno); 10572 /* Always increment on a BYE */ 10573 if (!nobye) { 10574 transmit_request_with_auth(p, SIP_BYE, 0, 1, 1); 10575 ast_set_flag(p, SIP_ALREADYGONE); 10576 } 10577 } 10578 } 10579 return res; 10580 }
|
|
handle_request_register: Handle incoming REGISTER request ---
Definition at line 10877 of file chan_sip.c. References ast_inet_ntoa(), ast_log(), ast_verbose(), check_via(), copy_request(), get_header(), sip_pvt::initreq, LOG_NOTICE, register_verify(), and sip_scheddestroy(). Referenced by handle_request(). 10878 { 10879 int res = 0; 10880 char iabuf[INET_ADDRSTRLEN]; 10881 10882 /* Use this as the basis */ 10883 if (debug) 10884 ast_verbose("Using latest REGISTER request as basis request\n"); 10885 copy_request(&p->initreq, req); 10886 check_via(p, req); 10887 if ((res = register_verify(p, sin, req, e, ignore)) < 0) 10888 ast_log(LOG_NOTICE, "Registration from '%s' failed for '%s' - %s\n", get_header(req, "To"), ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr), (res == -1) ? "Wrong password" : (res == -2 ? "Username/auth name mismatch" : "Not a local SIP domain")); 10889 if (res < 1) { 10890 /* Destroy the session, but keep us around for just a bit in case they don't 10891 get our 200 OK */ 10892 sip_scheddestroy(p, 15*1000); 10893 } 10894 return res; 10895 }
|
|
handle_request_subscribe: Handle incoming SUBSCRIBE request ---
Definition at line 10676 of file chan_sip.c. References append_history(), ast_clear_flag, AST_EXTENSION_REMOVED, ast_extension_state(), ast_extension_state2str(), ast_extension_state_add(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_strlen_zero(), ast_test_flag, ast_verbose(), sip_pvt::autokillid, build_contact(), sip_pvt::callid, cb_extensionstate(), check_user_full(), check_via(), sip_pvt::context, copy_request(), CPIM_PIDF_XML, default_context, DIALOG_INFO_XML, sip_pvt::expiry, sip_pvt::exten, get_destination(), get_header(), sip_request::headers, iflist, sip_pvt::initreq, sip_pvt::lastinvite, sip_pvt::lock, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, mailbox, make_our_tag(), max_expiry, sip_request::method, sip_pvt::next, NONE, option_debug, PIDF_XML, sip_cancel_destroy(), sip_methods, SIP_NEEDDESTROY, SIP_OUTGOING, sip_scheddestroy(), SIP_SUBSCRIBE, sipdebug, sip_pvt::stateid, sip_pvt::subscribecontext, sip_pvt::subscribed, sip_pvt::tag, cfsip_methods::text, transmit_response(), transmit_state_notify(), sip_pvt::useragent, sip_pvt::username, and XPIDF_XML. Referenced by handle_request(). 10677 { 10678 int gotdest; 10679 int res = 0; 10680 int firststate = AST_EXTENSION_REMOVED; 10681 10682 if (p->initreq.headers) { 10683 /* We already have a dialog */ 10684 if (p->initreq.method != SIP_SUBSCRIBE) { 10685 /* This is a SUBSCRIBE within another SIP dialog, which we do not support */ 10686 /* For transfers, this could happen, but since we haven't seen it happening, let us just refuse this */ 10687 transmit_response(p, "403 Forbidden (within dialog)", req); 10688 /* Do not destroy session, since we will break the call if we do */ 10689 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); 10690 return 0; 10691 } else { 10692 if (debug) 10693 ast_log(LOG_DEBUG, "Got a re-subscribe on existing subscription %s\n", p->callid); 10694 } 10695 } 10696 if (!ignore && !p->initreq.headers) { 10697 /* Use this as the basis */ 10698 if (debug) 10699 ast_verbose("Using latest SUBSCRIBE request as basis request\n"); 10700 /* This call is no longer outgoing if it ever was */ 10701 ast_clear_flag(p, SIP_OUTGOING); 10702 copy_request(&p->initreq, req); 10703 check_via(p, req); 10704 } else if (debug && ignore) 10705 ast_verbose("Ignoring this SUBSCRIBE request\n"); 10706 10707 if (!p->lastinvite) { 10708 char mailboxbuf[256]=""; 10709 int found = 0; 10710 char *mailbox = NULL; 10711 int mailboxsize = 0; 10712 char *eventparam; 10713 10714 char *event = get_header(req, "Event"); /* Get Event package name */ 10715 char *accept = get_header(req, "Accept"); 10716 10717 /* Find parameters to Event: header value and remove them for now */ 10718 eventparam = strchr(event, ';'); 10719 if (eventparam) { 10720 *eventparam = '\0'; 10721 eventparam++; 10722 } 10723 10724 if (!strcmp(event, "message-summary") && !strcmp(accept, "application/simple-message-summary")) { 10725 mailbox = mailboxbuf; 10726 mailboxsize = sizeof(mailboxbuf); 10727 } 10728 /* Handle authentication if this is our first subscribe */ 10729 res = check_user_full(p, req, SIP_SUBSCRIBE, e, 0, sin, ignore, mailbox, mailboxsize); 10730 if (res) { 10731 if (res < 0) { 10732 ast_log(LOG_NOTICE, "Failed to authenticate user %s for SUBSCRIBE\n", get_header(req, "From")); 10733 ast_set_flag(p, SIP_NEEDDESTROY); 10734 } 10735 return 0; 10736 } 10737 /* Initialize the context if it hasn't been already */ 10738 if (!ast_strlen_zero(p->subscribecontext)) 10739 ast_copy_string(p->context, p->subscribecontext, sizeof(p->context)); 10740 else if (ast_strlen_zero(p->context)) 10741 strcpy(p->context, default_context); 10742 /* Get destination right away */ 10743 gotdest = get_destination(p, NULL); 10744 build_contact(p); 10745 if (gotdest) { 10746 if (gotdest < 0) 10747 transmit_response(p, "404 Not Found", req); 10748 else 10749 transmit_response(p, "484 Address Incomplete", req); /* Overlap dialing on SUBSCRIBE?? */ 10750 ast_set_flag(p, SIP_NEEDDESTROY); 10751 } else { 10752 10753 /* Initialize tag for new subscriptions */ 10754 if (ast_strlen_zero(p->tag)) 10755 make_our_tag(p->tag, sizeof(p->tag)); 10756 10757 if (!strcmp(event, "presence") || !strcmp(event, "dialog")) { /* Presence, RFC 3842 */ 10758 10759 /* Header from Xten Eye-beam Accept: multipart/related, application/rlmi+xml, application/pidf+xml, application/xpidf+xml */ 10760 if (strstr(accept, "application/pidf+xml")) { 10761 p->subscribed = PIDF_XML; /* RFC 3863 format */ 10762 } else if (strstr(accept, "application/dialog-info+xml")) { 10763 p->subscribed = DIALOG_INFO_XML; 10764 /* IETF draft: draft-ietf-sipping-dialog-package-05.txt */ 10765 } else if (strstr(accept, "application/cpim-pidf+xml")) { 10766 p->subscribed = CPIM_PIDF_XML; /* RFC 3863 format */ 10767 } else if (strstr(accept, "application/xpidf+xml")) { 10768 p->subscribed = XPIDF_XML; /* Early pre-RFC 3863 format with MSN additions (Microsoft Messenger) */ 10769 } else if (strstr(p->useragent, "Polycom")) { 10770 p->subscribed = XPIDF_XML; /* Polycoms subscribe for "event: dialog" but don't include an "accept:" header */ 10771 } else { 10772 /* Can't find a format for events that we know about */ 10773 transmit_response(p, "489 Bad Event", req); 10774 ast_set_flag(p, SIP_NEEDDESTROY); 10775 return 0; 10776 } 10777 } else if (!strcmp(event, "message-summary") && !strcmp(accept, "application/simple-message-summary")) { 10778 /* Looks like they actually want a mailbox status */ 10779 10780 /* At this point, we should check if they subscribe to a mailbox that 10781 has the same extension as the peer or the mailbox id. If we configure 10782 the context to be the same as a SIP domain, we could check mailbox 10783 context as well. To be able to securely accept subscribes on mailbox 10784 IDs, not extensions, we need to check the digest auth user to make 10785 sure that the user has access to the mailbox. 10786 10787 Since we do not act on this subscribe anyway, we might as well 10788 accept any authenticated peer with a mailbox definition in their 10789 config section. 10790 10791 */ 10792 if (!ast_strlen_zero(mailbox)) { 10793 found++; 10794 } 10795 10796 if (found){ 10797 transmit_response(p, "200 OK", req); 10798 ast_set_flag(p, SIP_NEEDDESTROY); 10799 } else { 10800 transmit_response(p, "404 Not found", req); 10801 ast_set_flag(p, SIP_NEEDDESTROY); 10802 } 10803 return 0; 10804 } else { /* At this point, Asterisk does not understand the specified event */ 10805 transmit_response(p, "489 Bad Event", req); 10806 if (option_debug > 1) 10807 ast_log(LOG_DEBUG, "Received SIP subscribe for unknown event package: %s\n", event); 10808 ast_set_flag(p, SIP_NEEDDESTROY); 10809 return 0; 10810 } 10811 if (p->subscribed != NONE) 10812 p->stateid = ast_extension_state_add(p->context, p->exten, cb_extensionstate, p); 10813 } 10814 } 10815 10816 if (!ignore && p) 10817 p->lastinvite = seqno; 10818 if (p && !ast_test_flag(p, SIP_NEEDDESTROY)) { 10819 p->expiry = atoi(get_header(req, "Expires")); 10820 10821 /* The next 4 lines can be removed if the SNOM Expires bug is fixed */ 10822 if (p->subscribed == DIALOG_INFO_XML) { 10823 if (p->expiry > max_expiry) 10824 p->expiry = max_expiry; 10825 } 10826 if (sipdebug || option_debug > 1) 10827 ast_log(LOG_DEBUG, "Adding subscription for extension %s context %s for peer %s\n", p->exten, p->context, p->username); 10828 if (p->autokillid > -1) 10829 sip_cancel_destroy(p); /* Remove subscription expiry for renewals */ 10830 sip_scheddestroy(p, (p->expiry + 10) * 1000); /* Set timer for destruction of call at expiration */ 10831 10832 if ((firststate = ast_extension_state(NULL, p->context, p->exten)) < 0) { 10833 ast_log(LOG_ERROR, "Got SUBSCRIBE for extensions without hint. Please add hint to %s in context %s\n", p->exten, p->context); 10834 transmit_response(p, "404 Not found", req); 10835 ast_set_flag(p, SIP_NEEDDESTROY); 10836 return 0; 10837 } else { 10838 struct sip_pvt *p_old; 10839 10840 transmit_response(p, "200 OK", req); 10841 transmit_state_notify(p, firststate, 1, 1); /* Send first notification */ 10842 append_history(p, "Subscribestatus", ast_extension_state2str(firststate)); 10843 10844 /* remove any old subscription from this peer for the same exten/context, 10845 as the peer has obviously forgotten about it and it's wasteful to wait 10846 for it to expire and send NOTIFY messages to the peer only to have them 10847 ignored (or generate errors) 10848 */ 10849 ast_mutex_lock(&iflock); 10850 for (p_old = iflist; p_old; p_old = p_old->next) { 10851 if (p_old == p) 10852 continue; 10853 if (p_old->initreq.method != SIP_SUBSCRIBE) 10854 continue; 10855 if (p_old->subscribed == NONE) 10856 continue; 10857 ast_mutex_lock(&p_old->lock); 10858 if (!strcmp(p_old->username, p->username)) { 10859 if (!strcmp(p_old->exten, p->exten) && 10860 !strcmp(p_old->context, p->context)) { 10861 ast_set_flag(p_old, SIP_NEEDDESTROY); 10862 ast_mutex_unlock(&p_old->lock); 10863 break; 10864 } 10865 } 10866 ast_mutex_unlock(&p_old->lock); 10867 } 10868 ast_mutex_unlock(&iflock); 10869 } 10870 if (!p->expiry) 10871 ast_set_flag(p, SIP_NEEDDESTROY); 10872 } 10873 return 1; 10874 }
|
|
handle_response: Handle SIP response in dialogue ---
Definition at line 9763 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_rtp_stop(), ast_sched_del(), ast_set_flag, ast_strlen_zero(), ast_test_flag, ast_verbose(), sip_request::debug, DEC_CALL_LIMIT, do_proxy_auth(), find_sip_method(), get_header(), gettag(), handle_response_invite(), handle_response_peerpoke(), handle_response_register(), hangup_sip2cause(), ast_channel::hangupcause, sip_pvt::initid, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, MAX_AUTHTRIES, NONE, option_verbose, sip_pvt::owner, parse_moved_contact(), sip_pvt::peerpoke, process_sdp(), SIP_ACK, SIP_ALREADYGONE, SIP_BYE, SIP_CANCEL, sip_cancel_destroy(), SIP_INVITE, SIP_MESSAGE, sip_methods, SIP_NEEDDESTROY, SIP_NOTIFY, SIP_OUTGOING, SIP_REFER, SIP_REGISTER, text, sip_pvt::theirtag, transmit_request(), update_call_counter(), and VERBOSE_PREFIX_3. 09764 { 09765 char *msg, *c; 09766 struct ast_channel *owner; 09767 char iabuf[INET_ADDRSTRLEN]; 09768 int sipmethod; 09769 int res = 1; 09770 09771 c = get_header(req, "Cseq"); 09772 msg = strchr(c, ' '); 09773 if (!msg) 09774 msg = ""; 09775 else 09776 msg++; 09777 sipmethod = find_sip_method(msg); 09778 09779 owner = p->owner; 09780 if (owner) 09781 owner->hangupcause = hangup_sip2cause(resp); 09782 09783 /* Acknowledge whatever it is destined for */ 09784 if ((resp >= 100) && (resp <= 199)) 09785 __sip_semi_ack(p, seqno, 0, sipmethod); 09786 else 09787 __sip_ack(p, seqno, 0, sipmethod); 09788 09789 /* Get their tag if we haven't already */ 09790 if (ast_strlen_zero(p->theirtag) || (resp >= 200)) { 09791 gettag(req, "To", p->theirtag, sizeof(p->theirtag)); 09792 } 09793 if (p->peerpoke) { 09794 /* We don't really care what the response is, just that it replied back. 09795 Well, as long as it's not a 100 response... since we might 09796 need to hang around for something more "definitive" */ 09797 09798 res = handle_response_peerpoke(p, resp, rest, req, ignore, seqno, sipmethod); 09799 } else if (ast_test_flag(p, SIP_OUTGOING)) { 09800 /* Acknowledge sequence number */ 09801 if (p->initid > -1) { 09802 /* Don't auto congest anymore since we've gotten something useful back */ 09803 ast_sched_del(sched, p->initid); 09804 p->initid = -1; 09805 } 09806 switch(resp) { 09807 case 100: /* 100 Trying */ 09808 if (sipmethod == SIP_INVITE) 09809 handle_response_invite(p, resp, rest, req, ignore, seqno); 09810 break; 09811 case 183: /* 183 Session Progress */ 09812 if (sipmethod == SIP_INVITE) 09813 handle_response_invite(p, resp, rest, req, ignore, seqno); 09814 break; 09815 case 180: /* 180 Ringing */ 09816 if (sipmethod == SIP_INVITE) 09817 handle_response_invite(p, resp, rest, req, ignore, seqno); 09818 break; 09819 case 200: /* 200 OK */ 09820 p->authtries = 0; /* Reset authentication counter */ 09821 if (sipmethod == SIP_MESSAGE) { 09822 /* We successfully transmitted a message */ 09823 ast_set_flag(p, SIP_NEEDDESTROY); 09824 } else if (sipmethod == SIP_NOTIFY) { 09825 /* They got the notify, this is the end */ 09826 if (p->owner) { 09827 ast_log(LOG_WARNING, "Notify answer on an owned channel?\n"); 09828 ast_queue_hangup(p->owner); 09829 } else { 09830 if (p->subscribed == NONE) { 09831 ast_set_flag(p, SIP_NEEDDESTROY); 09832 } 09833 } 09834 } else if (sipmethod == SIP_INVITE) { 09835 handle_response_invite(p, resp, rest, req, ignore, seqno); 09836 } else if (sipmethod == SIP_REGISTER) { 09837 res = handle_response_register(p, resp, rest, req, ignore, seqno); 09838 } 09839 break; 09840 case 401: /* Not www-authorized on SIP method */ 09841 if (sipmethod == SIP_INVITE) { 09842 handle_response_invite(p, resp, rest, req, ignore, seqno); 09843 } else if (p->registry && sipmethod == SIP_REGISTER) { 09844 res = handle_response_register(p, resp, rest, req, ignore, seqno); 09845 } else { 09846 ast_log(LOG_WARNING, "Got authentication request (401) on unknown %s to '%s'\n", sip_methods[sipmethod].text, get_header(req, "To")); 09847 ast_set_flag(p, SIP_NEEDDESTROY); 09848 } 09849 break; 09850 case 403: /* Forbidden - we failed authentication */ 09851 if (sipmethod == SIP_INVITE) { 09852 handle_response_invite(p, resp, rest, req, ignore, seqno); 09853 } else if (p->registry && sipmethod == SIP_REGISTER) { 09854 res = handle_response_register(p, resp, rest, req, ignore, seqno); 09855 } else { 09856 ast_log(LOG_WARNING, "Forbidden - wrong password on authentication for %s\n", msg); 09857 } 09858 break; 09859 case 404: /* Not found */ 09860 if (p->registry && sipmethod == SIP_REGISTER) { 09861 res = handle_response_register(p, resp, rest, req, ignore, seqno); 09862 } else if (sipmethod == SIP_INVITE) { 09863 handle_response_invite(p, resp, rest, req, ignore, seqno); 09864 } else if (owner) 09865 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 09866 break; 09867 case 407: /* Proxy auth required */ 09868 if (sipmethod == SIP_INVITE) { 09869 handle_response_invite(p, resp, rest, req, ignore, seqno); 09870 } else if (sipmethod == SIP_BYE || sipmethod == SIP_REFER) { 09871 if (ast_strlen_zero(p->authname)) 09872 ast_log(LOG_WARNING, "Asked to authenticate %s, to %s:%d but we have no matching peer!\n", 09873 msg, ast_inet_ntoa(iabuf, sizeof(iabuf), p->recv.sin_addr), ntohs(p->recv.sin_port)); 09874 ast_set_flag(p, SIP_NEEDDESTROY); 09875 if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, "Proxy-Authenticate", "Proxy-Authorization", sipmethod, 0)) { 09876 ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From")); 09877 ast_set_flag(p, SIP_NEEDDESTROY); 09878 } 09879 } else if (p->registry && sipmethod == SIP_REGISTER) { 09880 res = handle_response_register(p, resp, rest, req, ignore, seqno); 09881 } else /* We can't handle this, giving up in a bad way */ 09882 ast_set_flag(p, SIP_NEEDDESTROY); 09883 09884 break; 09885 case 491: /* Pending */ 09886 if (sipmethod == SIP_INVITE) { 09887 handle_response_invite(p, resp, rest, req, ignore, seqno); 09888 } 09889 case 501: /* Not Implemented */ 09890 if (sipmethod == SIP_INVITE) { 09891 handle_response_invite(p, resp, rest, req, ignore, seqno); 09892 } else 09893 ast_log(LOG_WARNING, "Host '%s' does not implement '%s'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr), msg); 09894 break; 09895 default: 09896 if ((resp >= 300) && (resp < 700)) { 09897 if ((option_verbose > 2) && (resp != 487)) 09898 ast_verbose(VERBOSE_PREFIX_3 "Got SIP response %d \"%s\" back from %s\n", resp, rest, ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr)); 09899 ast_set_flag(p, SIP_ALREADYGONE); 09900 if (p->rtp) { 09901 /* Immediately stop RTP */ 09902 ast_rtp_stop(p->rtp); 09903 } 09904 if (p->vrtp) { 09905 /* Immediately stop VRTP */ 09906 ast_rtp_stop(p->vrtp); 09907 } 09908 /* XXX Locking issues?? XXX */ 09909 switch(resp) { 09910 case 300: /* Multiple Choices */ 09911 case 301: /* Moved permenantly */ 09912 case 302: /* Moved temporarily */ 09913 case 305: /* Use Proxy */ 09914 parse_moved_contact(p, req); 09915 /* Fall through */ 09916 case 486: /* Busy here */ 09917 case 600: /* Busy everywhere */ 09918 case 603: /* Decline */ 09919 if (p->owner) 09920 ast_queue_control(p->owner, AST_CONTROL_BUSY); 09921 break; 09922 case 487: 09923 /* channel now destroyed - dec the inUse counter */ 09924 update_call_counter(p, DEC_CALL_LIMIT); 09925 break; 09926 case 482: /* SIP is incapable of performing a hairpin call, which 09927 is yet another failure of not having a layer 2 (again, YAY 09928 IETF for thinking ahead). So we treat this as a call 09929 forward and hope we end up at the right place... */ 09930 ast_log(LOG_DEBUG, "Hairpin detected, setting up call forward for what it's worth\n"); 09931 if (p->owner) 09932 snprintf(p->owner->call_forward, sizeof(p->owner->call_forward), "Local/%s@%s", p->username, p->context); 09933 /* Fall through */ 09934 case 488: /* Not acceptable here - codec error */ 09935 case 480: /* Temporarily Unavailable */ 09936 case 404: /* Not Found */ 09937 case 410: /* Gone */ 09938 case 400: /* Bad Request */ 09939 case 500: /* Server error */ 09940 case 503: /* Service Unavailable */ 09941 if (owner) 09942 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 09943 break; 09944 default: 09945 /* Send hangup */ 09946 if (owner) 09947 ast_queue_hangup(p->owner); 09948 break; 09949 } 09950 /* ACK on invite */ 09951 if (sipmethod == SIP_INVITE) 09952 transmit_request(p, SIP_ACK, seqno, 0, 0); 09953 ast_set_flag(p, SIP_ALREADYGONE); 09954 if (!p->owner) 09955 ast_set_flag(p, SIP_NEEDDESTROY); 09956 } else if ((resp >= 100) && (resp < 200)) { 09957 if (sipmethod == SIP_INVITE) { 09958 sip_cancel_destroy(p); 09959 if (!ast_strlen_zero(get_header(req, "Content-Type"))) 09960 process_sdp(p, req); 09961 if (p->owner) { 09962 /* Queue a progress frame */ 09963 ast_queue_control(p->owner, AST_CONTROL_PROGRESS); 09964 } 09965 } 09966 } else 09967 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(iabuf, sizeof(iabuf), p->sa.sin_addr)); 09968 } 09969 } else { 09970 /* Responses to OUTGOING SIP requests on INCOMING calls 09971 get handled here. As well as out-of-call message responses */ 09972 if (req->debug) 09973 ast_verbose("SIP Response message for INCOMING dialog %s arrived\n", msg); 09974 if (resp == 200) { 09975 /* Tags in early session is replaced by the tag in 200 OK, which is 09976 the final reply to our INVITE */ 09977 gettag(req, "To", p->theirtag, sizeof(p->theirtag)); 09978 } 09979 09980 switch(resp) { 09981 case 200: 09982 if (sipmethod == SIP_INVITE) { 09983 handle_response_invite(p, resp, rest, req, ignore, seqno); 09984 } else if (sipmethod == SIP_CANCEL) { 09985 ast_log(LOG_DEBUG, "Got 200 OK on CANCEL\n"); 09986 } else if (sipmethod == SIP_MESSAGE) 09987 /* We successfully transmitted a message */ 09988 ast_set_flag(p, SIP_NEEDDESTROY); 09989 break; 09990 case 401: /* www-auth */ 09991 case 407: 09992 if (sipmethod == SIP_BYE || sipmethod == SIP_REFER) { 09993 char *auth, *auth2; 09994 09995 if (resp == 407) { 09996 auth = "Proxy-Authenticate"; 09997 auth2 = "Proxy-Authorization"; 09998 } else { 09999 auth = "WWW-Authenticate"; 10000 auth2 = "Authorization"; 10001 } 10002 if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, auth, auth2, sipmethod, 0)) { 10003 ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From")); 10004 ast_set_flag(p, SIP_NEEDDESTROY); 10005 } 10006 } else if (sipmethod == SIP_INVITE) { 10007 handle_response_invite(p, resp, rest, req, ignore, seqno); 10008 } 10009 break; 10010 case 481: /* Call leg does not exist */ 10011 if (sipmethod == SIP_INVITE) { 10012 /* Re-invite failed */ 10013 handle_response_invite(p, resp, rest, req, ignore, seqno); 10014 } 10015 break; 10016 default: /* Errors without handlers */ 10017 if ((resp >= 100) && (resp < 200)) { 10018 if (sipmethod == SIP_INVITE) { /* re-invite */ 10019 sip_cancel_destroy(p); 10020 } 10021 } 10022 if ((resp >= 300) && (resp < 700)) { 10023 if ((option_verbose > 2) && (resp != 487)) 10024 ast_verbose(VERBOSE_PREFIX_3 "Incoming call: Got SIP response %d \"%s\" back from %s\n", resp, rest, ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr)); 10025 switch(resp) { 10026 case 488: /* Not acceptable here - codec error */ 10027 case 603: /* Decline */ 10028 case 500: /* Server error */ 10029 case 503: /* Service Unavailable */ 10030 10031 if (sipmethod == SIP_INVITE) { /* re-invite failed */ 10032 sip_cancel_destroy(p); 10033 } 10034 break; 10035 } 10036 } 10037 break; 10038 } 10039 } 10040 }
|
|
handle_response_invite: Handle SIP response in dialogue ---
Definition at line 9452 of file chan_sip.c. References ast_channel::_state, AST_CONTROL_ANSWER, AST_CONTROL_CONGESTION, AST_CONTROL_PROGRESS, AST_CONTROL_RINGING, AST_FRAME_NULL, ast_log(), ast_queue_control(), ast_queue_frame(), ast_set_flag, ast_setstate(), AST_STATE_RINGING, AST_STATE_UP, ast_test_flag, authenticate(), build_route(), sip_pvt::callid, check_pendings(), do_proxy_auth(), get_header(), LOG_DEBUG, LOG_NOTICE, LOG_WARNING, MAX_AUTHTRIES, option_debug, sip_pvt::owner, parse_ok_contact(), process_sdp(), PROXY_AUTH, SIP_ACK, SIP_ALREADYGONE, sip_cancel_destroy(), SIP_INVITE, SIP_NEEDDESTROY, SIP_OUTGOING, SIP_PENDINGBYE, transmit_request(), and WWW_AUTH. Referenced by handle_response(). 09453 { 09454 int outgoing = ast_test_flag(p, SIP_OUTGOING); 09455 09456 if (option_debug > 3) { 09457 int reinvite = (p->owner && p->owner->_state == AST_STATE_UP); 09458 if (reinvite) 09459 ast_log(LOG_DEBUG, "SIP response %d to RE-invite on %s call %s\n", resp, outgoing ? "outgoing" : "incoming", p->callid); 09460 else 09461 ast_log(LOG_DEBUG, "SIP response %d to standard invite\n", resp); 09462 } 09463 09464 if (ast_test_flag(p, SIP_ALREADYGONE)) { /* This call is already gone */ 09465 ast_log(LOG_DEBUG, "Got response on call that is already terminated: %s (ignoring)\n", p->callid); 09466 return; 09467 } 09468 09469 switch (resp) { 09470 case 100: /* Trying */ 09471 sip_cancel_destroy(p); 09472 break; 09473 case 180: /* 180 Ringing */ 09474 sip_cancel_destroy(p); 09475 if (!ignore && p->owner) { 09476 ast_queue_control(p->owner, AST_CONTROL_RINGING); 09477 if (p->owner->_state != AST_STATE_UP) 09478 ast_setstate(p->owner, AST_STATE_RINGING); 09479 } 09480 if (!strcasecmp(get_header(req, "Content-Type"), "application/sdp")) { 09481 process_sdp(p, req); 09482 if (!ignore && p->owner) { 09483 /* Queue a progress frame only if we have SDP in 180 */ 09484 ast_queue_control(p->owner, AST_CONTROL_PROGRESS); 09485 } 09486 } 09487 break; 09488 case 183: /* Session progress */ 09489 sip_cancel_destroy(p); 09490 /* Ignore 183 Session progress without SDP */ 09491 if (!strcasecmp(get_header(req, "Content-Type"), "application/sdp")) { 09492 process_sdp(p, req); 09493 if (!ignore && p->owner) { 09494 /* Queue a progress frame */ 09495 ast_queue_control(p->owner, AST_CONTROL_PROGRESS); 09496 } 09497 } 09498 break; 09499 case 200: /* 200 OK on invite - someone's answering our call */ 09500 sip_cancel_destroy(p); 09501 p->authtries = 0; 09502 if (!strcasecmp(get_header(req, "Content-Type"), "application/sdp")) { 09503 process_sdp(p, req); 09504 } 09505 09506 /* Parse contact header for continued conversation */ 09507 /* When we get 200 OK, we know which device (and IP) to contact for this call */ 09508 /* This is important when we have a SIP proxy between us and the phone */ 09509 if (outgoing) { 09510 parse_ok_contact(p, req); 09511 09512 /* Save Record-Route for any later requests we make on this dialogue */ 09513 build_route(p, req, 1); 09514 } 09515 09516 if (!ignore && p->owner) { 09517 if (p->owner->_state != AST_STATE_UP) { 09518 #ifdef OSP_SUPPORT 09519 time(&p->ospstart); 09520 #endif 09521 ast_queue_control(p->owner, AST_CONTROL_ANSWER); 09522 } else { /* RE-invite */ 09523 struct ast_frame af = { AST_FRAME_NULL, }; 09524 ast_queue_frame(p->owner, &af); 09525 } 09526 } else { 09527 /* It's possible we're getting an ACK after we've tried to disconnect 09528 by sending CANCEL */ 09529 /* THIS NEEDS TO BE CHECKED: OEJ */ 09530 if (!ignore) 09531 ast_set_flag(p, SIP_PENDINGBYE); 09532 } 09533 /* If I understand this right, the branch is different for a non-200 ACK only */ 09534 transmit_request(p, SIP_ACK, seqno, 0, 1); 09535 check_pendings(p); 09536 break; 09537 case 407: /* Proxy authentication */ 09538 case 401: /* Www auth */ 09539 /* First we ACK */ 09540 transmit_request(p, SIP_ACK, seqno, 0, 0); 09541 if (p->options) 09542 p->options->auth_type = (resp == 401 ? WWW_AUTH : PROXY_AUTH); 09543 09544 /* Then we AUTH */ 09545 p->theirtag[0]='\0'; /* forget their old tag, so we don't match tags when getting response */ 09546 if (!ignore) { 09547 char *authenticate = (resp == 401 ? "WWW-Authenticate" : "Proxy-Authenticate"); 09548 char *authorization = (resp == 401 ? "Authorization" : "Proxy-Authorization"); 09549 if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, authenticate, authorization, SIP_INVITE, 1)) { 09550 ast_log(LOG_NOTICE, "Failed to authenticate on INVITE to '%s'\n", get_header(&p->initreq, "From")); 09551 ast_set_flag(p, SIP_NEEDDESTROY); 09552 ast_set_flag(p, SIP_ALREADYGONE); 09553 if (p->owner) 09554 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 09555 } 09556 } 09557 break; 09558 case 403: /* Forbidden */ 09559 /* First we ACK */ 09560 transmit_request(p, SIP_ACK, seqno, 0, 0); 09561 ast_log(LOG_WARNING, "Forbidden - wrong password on authentication for INVITE to '%s'\n", get_header(&p->initreq, "From")); 09562 if (!ignore && p->owner) 09563 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 09564 ast_set_flag(p, SIP_NEEDDESTROY); 09565 ast_set_flag(p, SIP_ALREADYGONE); 09566 break; 09567 case 404: /* Not found */ 09568 transmit_request(p, SIP_ACK, seqno, 0, 0); 09569 if (p->owner && !ignore) 09570 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 09571 ast_set_flag(p, SIP_ALREADYGONE); 09572 break; 09573 case 481: /* Call leg does not exist */ 09574 /* Could be REFER or INVITE */ 09575 ast_log(LOG_WARNING, "Re-invite to non-existing call leg on other UA. SIP dialog '%s'. Giving up.\n", p->callid); 09576 transmit_request(p, SIP_ACK, seqno, 0, 0); 09577 break; 09578 case 491: /* Pending */ 09579 /* we have to wait a while, then retransmit */ 09580 /* Transmission is rescheduled, so everything should be taken care of. 09581 We should support the retry-after at some point */ 09582 break; 09583 case 501: /* Not implemented */ 09584 if (p->owner) 09585 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 09586 break; 09587 } 09588 }
|
|
handle_response_peerpoke: Handle qualification responses (OPTIONS)
Definition at line 9707 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_peer::lastms, LOG_NOTICE, manager_event(), sip_peer::maxms, sip_pvt::peerpoke, sip_peer::pokeexpire, sip_peer::ps, SIP_ACK, SIP_INVITE, SIP_NEEDDESTROY, sip_poke_peer_s(), and transmit_request(). Referenced by handle_response(). 09708 { 09709 struct sip_peer *peer; 09710 int pingtime; 09711 struct timeval tv; 09712 09713 if (resp != 100) { 09714 int statechanged = 0; 09715 int newstate = 0; 09716 peer = p->peerpoke; 09717 gettimeofday(&tv, NULL); 09718 pingtime = ast_tvdiff_ms(tv, peer->ps); 09719 if (pingtime < 1) 09720 pingtime = 1; 09721 if ((peer->lastms < 0) || (peer->lastms > peer->maxms)) { 09722 if (pingtime <= peer->maxms) { 09723 ast_log(LOG_NOTICE, "Peer '%s' is now REACHABLE! (%dms / %dms)\n", peer->name, pingtime, peer->maxms); 09724 statechanged = 1; 09725 newstate = 1; 09726 } 09727 } else if ((peer->lastms > 0) && (peer->lastms <= peer->maxms)) { 09728 if (pingtime > peer->maxms) { 09729 ast_log(LOG_NOTICE, "Peer '%s' is now TOO LAGGED! (%dms / %dms)\n", peer->name, pingtime, peer->maxms); 09730 statechanged = 1; 09731 newstate = 2; 09732 } 09733 } 09734 if (!peer->lastms) 09735 statechanged = 1; 09736 peer->lastms = pingtime; 09737 peer->call = NULL; 09738 if (statechanged) { 09739 ast_device_state_changed("SIP/%s", peer->name); 09740 if (newstate == 2) { 09741 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Lagged\r\nTime: %d\r\n", peer->name, pingtime); 09742 } else { 09743 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Reachable\r\nTime: %d\r\n", peer->name, pingtime); 09744 } 09745 } 09746 09747 if (peer->pokeexpire > -1) 09748 ast_sched_del(sched, peer->pokeexpire); 09749 if (sipmethod == SIP_INVITE) /* Does this really happen? */ 09750 transmit_request(p, SIP_ACK, seqno, 0, 0); 09751 ast_set_flag(p, SIP_NEEDDESTROY); 09752 09753 /* Try again eventually */ 09754 if ((peer->lastms < 0) || (peer->lastms > peer->maxms)) 09755 peer->pokeexpire = ast_sched_add(sched, DEFAULT_FREQ_NOTOK, sip_poke_peer_s, peer); 09756 else 09757 peer->pokeexpire = ast_sched_add(sched, DEFAULT_FREQ_OK, sip_poke_peer_s, peer); 09758 } 09759 return 1; 09760 }
|
|
handle_response_register: Handle responses on REGISTER to services ---
Definition at line 9591 of file chan_sip.c. References __get_header(), ast_log(), ast_sched_del(), ast_set_flag, ast_strlen_zero(), sip_pvt::authtries, sip_registry::call, sip_registry::contact, do_register_auth(), EVENT_FLAG_SYSTEM, sip_registry::expire, get_header(), global_regattempts_max, sip_registry::hostname, sip_pvt::initreq, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, manager_event(), MAX_AUTHTRIES, sip_pvt::our_contact, REG_STATE_REGISTERED, sip_registry::regattempts, sip_pvt::registry, sip_registry::regstate, regstate2str(), SIP_NEEDDESTROY, sip_scheddestroy(), sip_registry::timeout, and sip_registry::username. Referenced by handle_response(). 09592 { 09593 int expires, expires_ms; 09594 struct sip_registry *r; 09595 r=p->registry; 09596 09597 switch (resp) { 09598 case 401: /* Unauthorized */ 09599 if ((p->authtries == MAX_AUTHTRIES) || do_register_auth(p, req, "WWW-Authenticate", "Authorization")) { 09600 ast_log(LOG_NOTICE, "Failed to authenticate on REGISTER to '%s@%s' (Tries %d)\n", p->registry->username, p->registry->hostname, p->authtries); 09601 ast_set_flag(p, SIP_NEEDDESTROY); 09602 } 09603 break; 09604 case 403: /* Forbidden */ 09605 ast_log(LOG_WARNING, "Forbidden - wrong password on authentication for REGISTER for '%s' to '%s'\n", p->registry->username, p->registry->hostname); 09606 if (global_regattempts_max) 09607 p->registry->regattempts = global_regattempts_max+1; 09608 ast_sched_del(sched, r->timeout); 09609 ast_set_flag(p, SIP_NEEDDESTROY); 09610 break; 09611 case 404: /* Not found */ 09612 ast_log(LOG_WARNING, "Got 404 Not found on SIP register to service %s@%s, giving up\n", p->registry->username,p->registry->hostname); 09613 if (global_regattempts_max) 09614 p->registry->regattempts = global_regattempts_max+1; 09615 ast_set_flag(p, SIP_NEEDDESTROY); 09616 r->call = NULL; 09617 ast_sched_del(sched, r->timeout); 09618 break; 09619 case 407: /* Proxy auth */ 09620 if ((p->authtries == MAX_AUTHTRIES) || do_register_auth(p, req, "Proxy-Authenticate", "Proxy-Authorization")) { 09621 ast_log(LOG_NOTICE, "Failed to authenticate on REGISTER to '%s' (tries '%d')\n", get_header(&p->initreq, "From"), p->authtries); 09622 ast_set_flag(p, SIP_NEEDDESTROY); 09623 } 09624 break; 09625 case 479: /* SER: Not able to process the URI - address is wrong in register*/ 09626 ast_log(LOG_WARNING, "Got error 479 on register to %s@%s, giving up (check config)\n", p->registry->username,p->registry->hostname); 09627 if (global_regattempts_max) 09628 p->registry->regattempts = global_regattempts_max+1; 09629 ast_set_flag(p, SIP_NEEDDESTROY); 09630 r->call = NULL; 09631 ast_sched_del(sched, r->timeout); 09632 break; 09633 case 200: /* 200 OK */ 09634 if (!r) { 09635 ast_log(LOG_WARNING, "Got 200 OK on REGISTER that isn't a register\n"); 09636 ast_set_flag(p, SIP_NEEDDESTROY); 09637 return 0; 09638 } 09639 09640 r->regstate=REG_STATE_REGISTERED; 09641 manager_event(EVENT_FLAG_SYSTEM, "Registry", "Channel: SIP\r\nDomain: %s\r\nStatus: %s\r\n", r->hostname, regstate2str(r->regstate)); 09642 r->regattempts = 0; 09643 ast_log(LOG_DEBUG, "Registration successful\n"); 09644 if (r->timeout > -1) { 09645 ast_log(LOG_DEBUG, "Cancelling timeout %d\n", r->timeout); 09646 ast_sched_del(sched, r->timeout); 09647 } 09648 r->timeout=-1; 09649 r->call = NULL; 09650 p->registry = NULL; 09651 /* Let this one hang around until we have all the responses */ 09652 sip_scheddestroy(p, 32000); 09653 /* ast_set_flag(p, SIP_NEEDDESTROY); */ 09654 09655 /* set us up for re-registering */ 09656 /* figure out how long we got registered for */ 09657 if (r->expire > -1) 09658 ast_sched_del(sched, r->expire); 09659 /* according to section 6.13 of RFC, contact headers override 09660 expires headers, so check those first */ 09661 expires = 0; 09662 if (!ast_strlen_zero(get_header(req, "Contact"))) { 09663 char *contact = NULL; 09664 char *tmptmp = NULL; 09665 int start = 0; 09666 for(;;) { 09667 contact = __get_header(req, "Contact", &start); 09668 /* this loop ensures we get a contact header about our register request */ 09669 if(!ast_strlen_zero(contact)) { 09670 if( (tmptmp=strstr(contact, p->our_contact))) { 09671 contact=tmptmp; 09672 break; 09673 } 09674 } else 09675 break; 09676 } 09677 tmptmp = strcasestr(contact, "expires="); 09678 if (tmptmp) { 09679 if (sscanf(tmptmp + 8, "%d;", &expires) != 1) 09680 expires = 0; 09681 } 09682 09683 } 09684 if (!expires) 09685 expires=atoi(get_header(req, "expires")); 09686 if (!expires) 09687 expires=default_expiry; 09688 09689 expires_ms = expires * 1000; 09690 if (expires <= EXPIRY_GUARD_LIMIT) 09691 expires_ms -= MAX((expires_ms * EXPIRY_GUARD_PCT),EXPIRY_GUARD_MIN); 09692 else 09693 expires_ms -= EXPIRY_GUARD_SECS * 1000; 09694 if (sipdebug) 09695 ast_log(LOG_NOTICE, "Outbound Registration: Expiry for %s is %d sec (Scheduling reregistration in %d s)\n", r->hostname, expires, expires_ms/1000); 09696 09697 r->refresh= (int) expires_ms / 1000; 09698 09699 /* Schedule re-registration before we expire */ 09700 r->expire=ast_sched_add(sched, expires_ms, sip_reregister, r); 09701 ASTOBJ_UNREF(r, sip_registry_destroy); 09702 } 09703 return 1; 09704 }
|
|
hangup_cause2sip: 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 2350 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(), and LOG_DEBUG. Referenced by sip_hangup(). 02351 { 02352 switch(cause) 02353 { 02354 case AST_CAUSE_UNALLOCATED: /* 1 */ 02355 case AST_CAUSE_NO_ROUTE_DESTINATION: /* 3 IAX2: Can't find extension in context */ 02356 case AST_CAUSE_NO_ROUTE_TRANSIT_NET: /* 2 */ 02357 return "404 Not Found"; 02358 case AST_CAUSE_CONGESTION: /* 34 */ 02359 case AST_CAUSE_SWITCH_CONGESTION: /* 42 */ 02360 return "503 Service Unavailable"; 02361 case AST_CAUSE_NO_USER_RESPONSE: /* 18 */ 02362 return "408 Request Timeout"; 02363 case AST_CAUSE_NO_ANSWER: /* 19 */ 02364 return "480 Temporarily unavailable"; 02365 case AST_CAUSE_CALL_REJECTED: /* 21 */ 02366 return "403 Forbidden"; 02367 case AST_CAUSE_NUMBER_CHANGED: /* 22 */ 02368 return "410 Gone"; 02369 case AST_CAUSE_NORMAL_UNSPECIFIED: /* 31 */ 02370 return "480 Temporarily unavailable"; 02371 case AST_CAUSE_INVALID_NUMBER_FORMAT: 02372 return "484 Address incomplete"; 02373 case AST_CAUSE_USER_BUSY: 02374 return "486 Busy here"; 02375 case AST_CAUSE_FAILURE: 02376 return "500 Server internal failure"; 02377 case AST_CAUSE_FACILITY_REJECTED: /* 29 */ 02378 return "501 Not Implemented"; 02379 case AST_CAUSE_CHAN_NOT_IMPLEMENTED: 02380 return "503 Service Unavailable"; 02381 /* Used in chan_iax2 */ 02382 case AST_CAUSE_DESTINATION_OUT_OF_ORDER: 02383 return "502 Bad Gateway"; 02384 case AST_CAUSE_BEARERCAPABILITY_NOTAVAIL: /* Can't find codec to connect to host */ 02385 return "488 Not Acceptable Here"; 02386 02387 case AST_CAUSE_NOTDEFINED: 02388 default: 02389 ast_log(LOG_DEBUG, "AST hangup cause %d (no match found in SIP)\n", cause); 02390 return NULL; 02391 } 02392 02393 /* Never reached */ 02394 return 0; 02395 }
|
|
hangup_sip2cause: Convert SIP hangup causes to Asterisk hangup causes ---
Definition at line 2282 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_NO_ANSWER, AST_CAUSE_NO_USER_RESPONSE, AST_CAUSE_NORMAL, and AST_CAUSE_UNALLOCATED. Referenced by handle_response(). 02283 { 02284 /* Possible values taken from causes.h */ 02285 02286 switch(cause) { 02287 case 603: /* Declined */ 02288 case 403: /* Not found */ 02289 return AST_CAUSE_CALL_REJECTED; 02290 case 404: /* Not found */ 02291 return AST_CAUSE_UNALLOCATED; 02292 case 408: /* No reaction */ 02293 return AST_CAUSE_NO_USER_RESPONSE; 02294 case 480: /* No answer */ 02295 return AST_CAUSE_FAILURE; 02296 case 483: /* Too many hops */ 02297 return AST_CAUSE_NO_ANSWER; 02298 case 486: /* Busy everywhere */ 02299 return AST_CAUSE_BUSY; 02300 case 488: /* No codecs approved */ 02301 return AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; 02302 case 500: /* Server internal failure */ 02303 return AST_CAUSE_FAILURE; 02304 case 501: /* Call rejected */ 02305 return AST_CAUSE_FACILITY_REJECTED; 02306 case 502: 02307 return AST_CAUSE_DESTINATION_OUT_OF_ORDER; 02308 case 503: /* Service unavailable */ 02309 return AST_CAUSE_CONGESTION; 02310 default: 02311 return AST_CAUSE_NORMAL; 02312 } 02313 /* Never reached */ 02314 return 0; 02315 }
|
|
init_req: Initialize SIP request ---
Definition at line 3967 of file chan_sip.c. References ast_log(), sip_request::data, sip_request::header, sip_request::headers, sip_request::len, LOG_WARNING, sip_request::method, sip_methods, and cfsip_methods::text. 03968 { 03969 /* Initialize a response */ 03970 if (req->headers || req->len) { 03971 ast_log(LOG_WARNING, "Request already initialized?!?\n"); 03972 return -1; 03973 } 03974 req->header[req->headers] = req->data + req->len; 03975 snprintf(req->header[req->headers], sizeof(req->data) - req->len, "%s %s SIP/2.0\r\n", sip_methods[sipmethod].text, recip); 03976 req->len += strlen(req->header[req->headers]); 03977 req->headers++; 03978 req->method = sipmethod; 03979 return 0; 03980 }
|
|
init_resp: Initialize SIP response, based on SIP request ---
Definition at line 3951 of file chan_sip.c. References ast_log(), sip_request::data, sip_request::header, sip_request::headers, sip_request::len, LOG_WARNING, sip_request::method, and SIP_RESPONSE. 03952 { 03953 /* Initialize a response */ 03954 if (req->headers || req->len) { 03955 ast_log(LOG_WARNING, "Request already initialized?!?\n"); 03956 return -1; 03957 } 03958 req->method = SIP_RESPONSE; 03959 req->header[req->headers] = req->data + req->len; 03960 snprintf(req->header[req->headers], sizeof(req->data) - req->len, "SIP/2.0 %s\r\n", resp); 03961 req->len += strlen(req->header[req->headers]); 03962 req->headers++; 03963 return 0; 03964 }
|
|
initreqprep: Initiate new SIP request to peer/user ---
Definition at line 4725 of file chan_sip.c. References AST_DIGIT_ANYNUM, ast_test_flag, n, SIP_USEREQPHONE, and sip_pvt::username. Referenced by sip_notify(), transmit_invite(), and transmit_notify_with_mwi(). 04726 { 04727 char invite_buf[256] = ""; 04728 char *invite = invite_buf; 04729 size_t invite_max = sizeof(invite_buf); 04730 char from[256]; 04731 char to[256]; 04732 char tmp[BUFSIZ/2]; 04733 char tmp2[BUFSIZ/2]; 04734 char iabuf[INET_ADDRSTRLEN]; 04735 char *l = NULL, *n = NULL; 04736 int x; 04737 char urioptions[256]=""; 04738 04739 if (ast_test_flag(p, SIP_USEREQPHONE)) { 04740 char onlydigits = 1; 04741 x=0; 04742 04743 /* Test p->username against allowed characters in AST_DIGIT_ANY 04744 If it matches the allowed characters list, then sipuser = ";user=phone" 04745 If not, then sipuser = "" 04746 */ 04747 /* + is allowed in first position in a tel: uri */ 04748 if (p->username && p->username[0] == '+') 04749 x=1; 04750 04751 for (; x < strlen(p->username); x++) { 04752 if (!strchr(AST_DIGIT_ANYNUM, p->username[x])) { 04753 onlydigits = 0; 04754 break; 04755 } 04756 } 04757 04758 /* If we have only digits, add ;user=phone to the uri */ 04759 if (onlydigits) 04760 strcpy(urioptions, ";user=phone"); 04761 } 04762 04763 04764 snprintf(p->lastmsg, sizeof(p->lastmsg), "Init: %s", sip_methods[sipmethod].text); 04765 04766 if (p->owner) { 04767 l = p->owner->cid.cid_num; 04768 n = p->owner->cid.cid_name; 04769 } 04770 /* if we are not sending RPID and user wants his callerid restricted */ 04771 if (!ast_test_flag(p, SIP_SENDRPID) && ((p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED)) { 04772 l = CALLERID_UNKNOWN; 04773 n = l; 04774 } 04775 if (!l) 04776 l = default_callerid; 04777 if (ast_strlen_zero(n)) 04778 n = l; 04779 /* Allow user to be overridden */ 04780 if (!ast_strlen_zero(p->fromuser)) 04781 l = p->fromuser; 04782 else /* Save for any further attempts */ 04783 ast_copy_string(p->fromuser, l, sizeof(p->fromuser)); 04784 04785 /* Allow user to be overridden */ 04786 if (!ast_strlen_zero(p->fromname)) 04787 n = p->fromname; 04788 else /* Save for any further attempts */ 04789 ast_copy_string(p->fromname, n, sizeof(p->fromname)); 04790 04791 if (pedanticsipchecking) { 04792 ast_uri_encode(n, tmp, sizeof(tmp), 0); 04793 n = tmp; 04794 ast_uri_encode(l, tmp2, sizeof(tmp2), 0); 04795 l = tmp2; 04796 } 04797 04798 if ((ourport != 5060) && ast_strlen_zero(p->fromdomain)) /* Needs to be 5060 */ 04799 snprintf(from, sizeof(from), "\"%s\" <sip:%s@%s:%d>;tag=%s", n, l, ast_strlen_zero(p->fromdomain) ? ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip) : p->fromdomain, ourport, p->tag); 04800 else 04801 snprintf(from, sizeof(from), "\"%s\" <sip:%s@%s>;tag=%s", n, l, ast_strlen_zero(p->fromdomain) ? ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip) : p->fromdomain, p->tag); 04802 04803 /* If we're calling a registered SIP peer, use the fullcontact to dial to the peer */ 04804 if (!ast_strlen_zero(p->fullcontact)) { 04805 /* If we have full contact, trust it */ 04806 ast_build_string(&invite, &invite_max, "%s", p->fullcontact); 04807 } else { 04808 /* Otherwise, use the username while waiting for registration */ 04809 ast_build_string(&invite, &invite_max, "sip:"); 04810 if (!ast_strlen_zero(p->username)) { 04811 n = p->username; 04812 if (pedanticsipchecking) { 04813 ast_uri_encode(n, tmp, sizeof(tmp), 0); 04814 n = tmp; 04815 } 04816 ast_build_string(&invite, &invite_max, "%s@", n); 04817 } 04818 ast_build_string(&invite, &invite_max, "%s", p->tohost); 04819 if (ntohs(p->sa.sin_port) != 5060) /* Needs to be 5060 */ 04820 ast_build_string(&invite, &invite_max, ":%d", ntohs(p->sa.sin_port)); 04821 ast_build_string(&invite, &invite_max, "%s", urioptions); 04822 } 04823 04824 /* If custom URI options have been provided, append them */ 04825 if (p->options && p->options->uri_options) 04826 ast_build_string(&invite, &invite_max, ";%s", p->options->uri_options); 04827 04828 ast_copy_string(p->uri, invite_buf, sizeof(p->uri)); 04829 04830 if (sipmethod == SIP_NOTIFY && !ast_strlen_zero(p->theirtag)) { 04831 /* If this is a NOTIFY, use the From: tag in the subscribe (RFC 3265) */ 04832 snprintf(to, sizeof(to), "<sip:%s>;tag=%s", p->uri, p->theirtag); 04833 } else if (p->options && p->options->vxml_url) { 04834 /* If there is a VXML URL append it to the SIP URL */ 04835 snprintf(to, sizeof(to), "<%s>;%s", p->uri, p->options->vxml_url); 04836 } else { 04837 snprintf(to, sizeof(to), "<%s>", p->uri); 04838 } 04839 04840 memset(req, 0, sizeof(struct sip_request)); 04841 init_req(req, sipmethod, p->uri); 04842 snprintf(tmp, sizeof(tmp), "%d %s", ++p->ocseq, sip_methods[sipmethod].text); 04843 04844 add_header(req, "Via", p->via); 04845 /* SLD: FIXME?: do Route: here too? I think not cos this is the first request. 04846 * OTOH, then we won't have anything in p->route anyway */ 04847 /* Build Remote Party-ID and From */ 04848 if (ast_test_flag(p, SIP_SENDRPID) && (sipmethod == SIP_INVITE)) { 04849 build_rpid(p); 04850 add_header(req, "From", p->rpid_from); 04851 } else { 04852 add_header(req, "From", from); 04853 } 04854 add_header(req, "To", to); 04855 ast_copy_string(p->exten, l, sizeof(p->exten)); 04856 build_contact(p); 04857 add_header(req, "Contact", p->our_contact); 04858 add_header(req, "Call-ID", p->callid); 04859 add_header(req, "CSeq", tmp); 04860 add_header(req, "User-Agent", default_useragent); 04861 add_header(req, "Max-Forwards", DEFAULT_MAX_FORWARDS); 04862 if (p->rpid) 04863 add_header(req, "Remote-Party-ID", p->rpid); 04864 }
|
|
insecure2str: Convert Insecure setting to printable string ---
Definition at line 7635 of file chan_sip.c. Referenced by _sip_show_peer(). 07636 { 07637 if (port && invite) 07638 return "port,invite"; 07639 else if (port) 07640 return "port"; 07641 else if (invite) 07642 return "invite"; 07643 else 07644 return "no"; 07645 }
|
|
Returns the ASTERISK_GPL_KEY. This returns the ASTERISK_GPL_KEY, signifiying that you agree to the terms of the GPL stated in the ASTERISK_GPL_KEY. Your module will not load if it does not return the EXACT message:
char *key(void) { return ASTERISK_GPL_KEY; }
Definition at line 13282 of file chan_sip.c. References ASTERISK_GPL_KEY. 13283 { 13284 return ASTERISK_GPL_KEY; 13285 }
|
|
list_route: List all routes - mostly for debugging ---
Definition at line 5970 of file chan_sip.c. References ast_verbose(), sip_route::hop, and sip_route::next. 05971 { 05972 if (!route) { 05973 ast_verbose("list_route: no route\n"); 05974 return; 05975 } 05976 while (route) { 05977 ast_verbose("list_route: hop: <%s>\n", route->hop); 05978 route = route->next; 05979 } 05980 }
|
|
|
lws2sws: Parse multiline SIP headers into one header
Definition at line 3276 of file chan_sip.c. References t. Referenced by sipsock_read(). 03277 { 03278 int h = 0, t = 0; 03279 int lws = 0; 03280 03281 for (; h < len;) { 03282 /* Eliminate all CRs */ 03283 if (msgbuf[h] == '\r') { 03284 h++; 03285 continue; 03286 } 03287 /* Check for end-of-line */ 03288 if (msgbuf[h] == '\n') { 03289 /* Check for end-of-message */ 03290 if (h + 1 == len) 03291 break; 03292 /* Check for a continuation line */ 03293 if (msgbuf[h + 1] == ' ' || msgbuf[h + 1] == '\t') { 03294 /* Merge continuation line */ 03295 h++; 03296 continue; 03297 } 03298 /* Propagate LF and start new line */ 03299 msgbuf[t++] = msgbuf[h++]; 03300 lws = 0; 03301 continue; 03302 } 03303 if (msgbuf[h] == ' ' || msgbuf[h] == '\t') { 03304 if (lws) { 03305 h++; 03306 continue; 03307 } 03308 msgbuf[t++] = msgbuf[h++]; 03309 lws = 1; 03310 continue; 03311 } 03312 msgbuf[t++] = msgbuf[h++]; 03313 if (lws) 03314 lws = 0; 03315 } 03316 msgbuf[t] = '\0'; 03317 return t; 03318 }
|
|
Definition at line 3028 of file chan_sip.c. References thread_safe_rand(). Referenced by handle_request_invite(), handle_request_subscribe(), sip_alloc(), and transmit_register(). 03029 { 03030 snprintf(tagbuf, len, "as%08x", thread_safe_rand()); 03031 }
|
|
manager_sip_show_peer: Show SIP peers in the manager API ---
Definition at line 7855 of file chan_sip.c. References _sip_show_peer(), ast_cli(), ast_strlen_zero(), astman_get_header(), astman_send_error(), and s. Referenced by load_module(). 07856 { 07857 char *id = astman_get_header(m,"ActionID"); 07858 char *a[4]; 07859 char *peer; 07860 int ret; 07861 07862 peer = astman_get_header(m,"Peer"); 07863 if (ast_strlen_zero(peer)) { 07864 astman_send_error(s, m, "Peer: <name> missing.\n"); 07865 return 0; 07866 } 07867 a[0] = "sip"; 07868 a[1] = "show"; 07869 a[2] = "peer"; 07870 a[3] = peer; 07871 07872 if (!ast_strlen_zero(id)) 07873 ast_cli(s->fd, "ActionID: %s\r\n",id); 07874 ret = _sip_show_peer(1, s->fd, s, m, 4, a ); 07875 ast_cli( s->fd, "\r\n\r\n" ); 07876 return ret; 07877 }
|
|
manager_sip_show_peers: Show SIP peers in the manager API ---
Definition at line 7436 of file chan_sip.c. References _sip_show_peers(), ast_cli(), ast_strlen_zero(), astman_get_header(), astman_send_ack(), s, and total. Referenced by load_module(). 07437 { 07438 char *id = astman_get_header(m,"ActionID"); 07439 char *a[] = { "sip", "show", "peers" }; 07440 char idtext[256] = ""; 07441 int total = 0; 07442 07443 if (!ast_strlen_zero(id)) 07444 snprintf(idtext,256,"ActionID: %s\r\n",id); 07445 07446 astman_send_ack(s, m, "Peer status list will follow"); 07447 /* List the peers in separate manager events */ 07448 _sip_show_peers(s->fd, &total, s, m, 3, a); 07449 /* Send final confirmation */ 07450 ast_cli(s->fd, 07451 "Event: PeerlistComplete\r\n" 07452 "ListItems: %d\r\n" 07453 "%s" 07454 "\r\n", total, idtext); 07455 return 0; 07456 }
|
|
nat2str: Convert NAT setting to text string
Definition at line 7338 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(), and sip_show_settings(). 07339 { 07340 switch(nat) { 07341 case SIP_NAT_NEVER: 07342 return "No"; 07343 case SIP_NAT_ROUTE: 07344 return "Route"; 07345 case SIP_NAT_ALWAYS: 07346 return "Always"; 07347 case SIP_NAT_RFC3581: 07348 return "RFC3581"; 07349 default: 07350 return "Unknown"; 07351 } 07352 }
|
|
parse_copy: Copy SIP request, parse it
Definition at line 1456 of file chan_sip.c. References sip_request::data, sip_request::len, and parse_request(). Referenced by send_request(), and send_response(). 01457 { 01458 memset(dst, 0, sizeof(*dst)); 01459 memcpy(dst->data, src->data, sizeof(dst->data)); 01460 dst->len = src->len; 01461 parse_request(dst); 01462 }
|
|
parse_moved_contact: Parse 302 Moved temporalily response
Definition at line 9402 of file chan_sip.c. References ast_log(), ast_test_flag, ast_channel::call_forward, get_header(), get_in_brackets(), LOG_DEBUG, sip_pvt::owner, s, and SIP_PROMISCREDIR. Referenced by handle_response(). 09403 { 09404 char tmp[256]; 09405 char *s, *e; 09406 ast_copy_string(tmp, get_header(req, "Contact"), sizeof(tmp)); 09407 s = get_in_brackets(tmp); 09408 e = strchr(s, ';'); 09409 if (e) 09410 *e = '\0'; 09411 if (ast_test_flag(p, SIP_PROMISCREDIR)) { 09412 if (!strncasecmp(s, "sip:", 4)) 09413 s += 4; 09414 e = strchr(s, '/'); 09415 if (e) 09416 *e = '\0'; 09417 ast_log(LOG_DEBUG, "Found promiscuous redirection to 'SIP/%s'\n", s); 09418 if (p->owner) 09419 snprintf(p->owner->call_forward, sizeof(p->owner->call_forward), "SIP/%s", s); 09420 } else { 09421 e = strchr(tmp, '@'); 09422 if (e) 09423 *e = '\0'; 09424 e = strchr(tmp, '/'); 09425 if (e) 09426 *e = '\0'; 09427 if (!strncasecmp(s, "sip:", 4)) 09428 s += 4; 09429 ast_log(LOG_DEBUG, "Found 302 Redirect to extension '%s'\n", s); 09430 if (p->owner) 09431 ast_copy_string(p->owner->call_forward, s, sizeof(p->owner->call_forward)); 09432 } 09433 }
|
|
parse_ok_contact: Parse contact header for 200 OK on INVITE ---
Definition at line 5731 of file chan_sip.c. References ahp, ast_gethostbyname(), ast_log(), ast_test_flag, DEFAULT_SIP_PORT, sip_pvt::fullcontact, get_header(), get_in_brackets(), hp, LOG_NOTICE, LOG_WARNING, sip_pvt::okcontacturi, sip_pvt::recv, sip_pvt::sa, SIP_NAT, and SIP_NAT_ROUTE. Referenced by handle_response_invite(). 05732 { 05733 char contact[250]; 05734 char *c, *n, *pt; 05735 int port; 05736 struct hostent *hp; 05737 struct ast_hostent ahp; 05738 struct sockaddr_in oldsin; 05739 05740 /* Look for brackets */ 05741 ast_copy_string(contact, get_header(req, "Contact"), sizeof(contact)); 05742 c = get_in_brackets(contact); 05743 05744 /* Save full contact to call pvt for later bye or re-invite */ 05745 ast_copy_string(pvt->fullcontact, c, sizeof(pvt->fullcontact)); 05746 05747 /* Save URI for later ACKs, BYE or RE-invites */ 05748 ast_copy_string(pvt->okcontacturi, c, sizeof(pvt->okcontacturi)); 05749 05750 /* Make sure it's a SIP URL */ 05751 if (strncasecmp(c, "sip:", 4)) { 05752 ast_log(LOG_NOTICE, "'%s' is not a valid SIP contact (missing sip:) trying to use anyway\n", c); 05753 } else 05754 c += 4; 05755 05756 /* Ditch arguments */ 05757 n = strchr(c, ';'); 05758 if (n) 05759 *n = '\0'; 05760 05761 /* Grab host */ 05762 n = strchr(c, '@'); 05763 if (!n) { 05764 n = c; 05765 c = NULL; 05766 } else { 05767 *n = '\0'; 05768 n++; 05769 } 05770 pt = strchr(n, ':'); 05771 if (pt) { 05772 *pt = '\0'; 05773 pt++; 05774 port = atoi(pt); 05775 } else 05776 port = DEFAULT_SIP_PORT; 05777 05778 memcpy(&oldsin, &pvt->sa, sizeof(oldsin)); 05779 05780 if (!(ast_test_flag(pvt, SIP_NAT) & SIP_NAT_ROUTE)) { 05781 /* XXX This could block for a long time XXX */ 05782 /* We should only do this if it's a name, not an IP */ 05783 hp = ast_gethostbyname(n, &ahp); 05784 if (!hp) { 05785 ast_log(LOG_WARNING, "Invalid host '%s'\n", n); 05786 return -1; 05787 } 05788 pvt->sa.sin_family = AF_INET; 05789 memcpy(&pvt->sa.sin_addr, hp->h_addr, sizeof(pvt->sa.sin_addr)); 05790 pvt->sa.sin_port = htons(port); 05791 } else { 05792 /* Don't trust the contact field. Just use what they came to us 05793 with. */ 05794 memcpy(&pvt->sa, &pvt->recv, sizeof(pvt->sa)); 05795 } 05796 return 0; 05797 }
|
|
parse_register_contact: Parse contact header and save registration ---
Definition at line 5807 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_strlen_zero(), ast_test_flag, ast_verbose(), default_expiry, DEFAULT_SIP_PORT, destroy_association(), EVENT_FLAG_SYSTEM, sip_peer::expire, expire_register(), sip_pvt::expiry, expiry, sip_peer::flags_page2, sip_peer::fullcontact, get_header(), get_in_brackets(), hp, inaddrcmp(), sip_peer::lastms, LOG_NOTICE, LOG_WARNING, manager_event(), max_expiry, option_verbose, sip_pvt::our_contact, PARSE_REGISTER_FAILED, PARSE_REGISTER_QUERY, PARSE_REGISTER_UPDATE, sip_pvt::recv, register_peer_exten(), SIP_NAT, SIP_NAT_ROUTE, SIP_PAGE2_RT_FROMCONTACT, sip_poke_peer(), SIP_REALTIME, sip_pvt::sipoptions, sip_peer::sipoptions, strcasestr(), sip_peer::useragent, sip_peer::username, and VERBOSE_PREFIX_3. Referenced by register_verify(). 05808 { 05809 char contact[80]; 05810 char data[256]; 05811 char iabuf[INET_ADDRSTRLEN]; 05812 char *expires = get_header(req, "Expires"); 05813 int expiry = atoi(expires); 05814 char *c, *n, *pt; 05815 int port; 05816 char *useragent; 05817 struct hostent *hp; 05818 struct ast_hostent ahp; 05819 struct sockaddr_in oldsin; 05820 05821 if (ast_strlen_zero(expires)) { /* No expires header */ 05822 expires = strcasestr(get_header(req, "Contact"), ";expires="); 05823 if (expires) { 05824 char *ptr; 05825 if ((ptr = strchr(expires, ';'))) 05826 *ptr = '\0'; 05827 if (sscanf(expires + 9, "%d", &expiry) != 1) 05828 expiry = default_expiry; 05829 } else { 05830 /* Nothing has been specified */ 05831 expiry = default_expiry; 05832 } 05833 } 05834 /* Look for brackets */ 05835 ast_copy_string(contact, get_header(req, "Contact"), sizeof(contact)); 05836 if (strchr(contact, '<') == NULL) { /* No <, check for ; and strip it */ 05837 char *ptr = strchr(contact, ';'); /* This is Header options, not URI options */ 05838 if (ptr) 05839 *ptr = '\0'; 05840 } 05841 c = get_in_brackets(contact); 05842 05843 /* if they did not specify Contact: or Expires:, they are querying 05844 what we currently have stored as their contact address, so return 05845 it 05846 */ 05847 if (ast_strlen_zero(c) && ast_strlen_zero(expires)) { 05848 /* If we have an active registration, tell them when the registration is going to expire */ 05849 if ((p->expire > -1) && !ast_strlen_zero(p->fullcontact)) { 05850 pvt->expiry = ast_sched_when(sched, p->expire); 05851 } 05852 return PARSE_REGISTER_QUERY; 05853 } else if (!strcasecmp(c, "*") || !expiry) { /* Unregister this peer */ 05854 /* This means remove all registrations and return OK */ 05855 memset(&p->addr, 0, sizeof(p->addr)); 05856 if (p->expire > -1) 05857 ast_sched_del(sched, p->expire); 05858 p->expire = -1; 05859 05860 destroy_association(p); 05861 05862 register_peer_exten(p, 0); 05863 p->fullcontact[0] = '\0'; 05864 p->useragent[0] = '\0'; 05865 p->sipoptions = 0; 05866 p->lastms = 0; 05867 05868 if (option_verbose > 2) 05869 ast_verbose(VERBOSE_PREFIX_3 "Unregistered SIP '%s'\n", p->name); 05870 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unregistered\r\n", p->name); 05871 return PARSE_REGISTER_UPDATE; 05872 } 05873 ast_copy_string(p->fullcontact, c, sizeof(p->fullcontact)); 05874 /* For the 200 OK, we should use the received contact */ 05875 snprintf(pvt->our_contact, sizeof(pvt->our_contact) - 1, "<%s>", c); 05876 /* Make sure it's a SIP URL */ 05877 if (strncasecmp(c, "sip:", 4)) { 05878 ast_log(LOG_NOTICE, "'%s' is not a valid SIP contact (missing sip:) trying to use anyway\n", c); 05879 } else 05880 c += 4; 05881 /* Ditch q */ 05882 n = strchr(c, ';'); 05883 if (n) { 05884 *n = '\0'; 05885 } 05886 /* Grab host */ 05887 n = strchr(c, '@'); 05888 if (!n) { 05889 n = c; 05890 c = NULL; 05891 } else { 05892 *n = '\0'; 05893 n++; 05894 } 05895 pt = strchr(n, ':'); 05896 if (pt) { 05897 *pt = '\0'; 05898 pt++; 05899 port = atoi(pt); 05900 } else 05901 port = DEFAULT_SIP_PORT; 05902 memcpy(&oldsin, &p->addr, sizeof(oldsin)); 05903 if (!(ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE)) { 05904 /* XXX This could block for a long time XXX */ 05905 hp = ast_gethostbyname(n, &ahp); 05906 if (!hp) { 05907 ast_log(LOG_WARNING, "Invalid host '%s'\n", n); 05908 return PARSE_REGISTER_FAILED; 05909 } 05910 p->addr.sin_family = AF_INET; 05911 memcpy(&p->addr.sin_addr, hp->h_addr, sizeof(p->addr.sin_addr)); 05912 p->addr.sin_port = htons(port); 05913 } else { 05914 /* Don't trust the contact field. Just use what they came to us 05915 with */ 05916 memcpy(&p->addr, &pvt->recv, sizeof(p->addr)); 05917 } 05918 05919 if (c) /* Overwrite the default username from config at registration */ 05920 ast_copy_string(p->username, c, sizeof(p->username)); 05921 else 05922 p->username[0] = '\0'; 05923 05924 if (p->expire > -1) 05925 ast_sched_del(sched, p->expire); 05926 if ((expiry < 1) || (expiry > max_expiry)) 05927 expiry = max_expiry; 05928 if (!ast_test_flag(p, SIP_REALTIME)) 05929 p->expire = ast_sched_add(sched, (expiry + 10) * 1000, expire_register, p); 05930 else 05931 p->expire = -1; 05932 pvt->expiry = expiry; 05933 snprintf(data, sizeof(data), "%s:%d:%d:%s:%s", ast_inet_ntoa(iabuf, sizeof(iabuf), p->addr.sin_addr), ntohs(p->addr.sin_port), expiry, p->username, p->fullcontact); 05934 if (!ast_test_flag((&p->flags_page2), SIP_PAGE2_RT_FROMCONTACT)) 05935 ast_db_put("SIP/Registry", p->name, data); 05936 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Registered\r\n", p->name); 05937 if (inaddrcmp(&p->addr, &oldsin)) { 05938 sip_poke_peer(p); 05939 if (option_verbose > 2) 05940 ast_verbose(VERBOSE_PREFIX_3 "Registered SIP '%s' at %s port %d expires %d\n", p->name, ast_inet_ntoa(iabuf, sizeof(iabuf), p->addr.sin_addr), ntohs(p->addr.sin_port), expiry); 05941 register_peer_exten(p, 1); 05942 } 05943 05944 /* Save SIP options profile */ 05945 p->sipoptions = pvt->sipoptions; 05946 05947 /* Save User agent */ 05948 useragent = get_header(req, "User-Agent"); 05949 if (useragent && strcasecmp(useragent, p->useragent)) { 05950 ast_copy_string(p->useragent, useragent, sizeof(p->useragent)); 05951 if (option_verbose > 3) { 05952 ast_verbose(VERBOSE_PREFIX_3 "Saved useragent \"%s\" for peer %s\n",p->useragent,p->name); 05953 } 05954 } 05955 return PARSE_REGISTER_UPDATE; 05956 }
|
|
parse_request: Parse a SIP message ----
Definition at line 3321 of file chan_sip.c. References ast_log(), ast_strlen_zero(), sip_request::data, determine_firstline_parts(), 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 parse_copy(), sipsock_read(), transmit_invite(), transmit_notify_with_mwi(), transmit_notify_with_sipfrag(), transmit_register(), transmit_reinvite_with_sdp(), and transmit_sip_request(). 03322 { 03323 /* Divide fields by NULL's */ 03324 char *c; 03325 int f = 0; 03326 03327 c = req->data; 03328 03329 /* First header starts immediately */ 03330 req->header[f] = c; 03331 while(*c) { 03332 if (*c == '\n') { 03333 /* We've got a new header */ 03334 *c = 0; 03335 03336 if (sipdebug && option_debug > 3) 03337 ast_log(LOG_DEBUG, "Header %d: %s (%d)\n", f, req->header[f], (int) strlen(req->header[f])); 03338 if (ast_strlen_zero(req->header[f])) { 03339 /* Line by itself means we're now in content */ 03340 c++; 03341 break; 03342 } 03343 if (f >= SIP_MAX_HEADERS - 1) { 03344 ast_log(LOG_WARNING, "Too many SIP headers. Ignoring.\n"); 03345 } else 03346 f++; 03347 req->header[f] = c + 1; 03348 } else if (*c == '\r') { 03349 /* Ignore but eliminate \r's */ 03350 *c = 0; 03351 } 03352 c++; 03353 } 03354 /* Check for last header */ 03355 if (!ast_strlen_zero(req->header[f])) { 03356 if (sipdebug && option_debug > 3) 03357 ast_log(LOG_DEBUG, "Header %d: %s (%d)\n", f, req->header[f], (int) strlen(req->header[f])); 03358 f++; 03359 } 03360 req->headers = f; 03361 /* Now we process any mime content */ 03362 f = 0; 03363 req->line[f] = c; 03364 while(*c) { 03365 if (*c == '\n') { 03366 /* We've got a new line */ 03367 *c = 0; 03368 if (sipdebug && option_debug > 3) 03369 ast_log(LOG_DEBUG, "Line: %s (%d)\n", req->line[f], (int) strlen(req->line[f])); 03370 if (f >= SIP_MAX_LINES - 1) { 03371 ast_log(LOG_WARNING, "Too many SDP lines. Ignoring.\n"); 03372 } else 03373 f++; 03374 req->line[f] = c + 1; 03375 } else if (*c == '\r') { 03376 /* Ignore and eliminate \r's */ 03377 *c = 0; 03378 } 03379 c++; 03380 } 03381 /* Check for last line */ 03382 if (!ast_strlen_zero(req->line[f])) 03383 f++; 03384 req->lines = f; 03385 if (*c) 03386 ast_log(LOG_WARNING, "Odd content, extra stuff left over ('%s')\n", c); 03387 /* Split up the first line parts */ 03388 determine_firstline_parts(req); 03389 }
|
|
parse_sip_options: Parse supported header in incoming packet
Definition at line 985 of file chan_sip.c. References ast_log(), ast_strdupa, ast_strlen_zero(), LOG_DEBUG, option_debug, sip_options, and text. Referenced by handle_request_invite(). 00986 { 00987 char *next = NULL; 00988 char *sep = NULL; 00989 char *temp = ast_strdupa(supported); 00990 int i; 00991 unsigned int profile = 0; 00992 00993 if (ast_strlen_zero(supported) ) 00994 return 0; 00995 00996 if (option_debug > 2 && sipdebug) 00997 ast_log(LOG_DEBUG, "Begin: parsing SIP \"Supported: %s\"\n", supported); 00998 00999 next = temp; 01000 while (next) { 01001 char res=0; 01002 if ( (sep = strchr(next, ',')) != NULL) { 01003 *sep = '\0'; 01004 sep++; 01005 } 01006 while (*next == ' ') /* Skip spaces */ 01007 next++; 01008 if (option_debug > 2 && sipdebug) 01009 ast_log(LOG_DEBUG, "Found SIP option: -%s-\n", next); 01010 for (i=0; (i < (sizeof(sip_options) / sizeof(sip_options[0]))) && !res; i++) { 01011 if (!strcasecmp(next, sip_options[i].text)) { 01012 profile |= sip_options[i].id; 01013 res = 1; 01014 if (option_debug > 2 && sipdebug) 01015 ast_log(LOG_DEBUG, "Matched SIP option: %s\n", next); 01016 } 01017 } 01018 if (!res) 01019 if (option_debug > 2 && sipdebug) 01020 ast_log(LOG_DEBUG, "Found no match for SIP option: %s (Please file bug report!)\n", next); 01021 next = sep; 01022 } 01023 if (pvt) { 01024 pvt->sipoptions = profile; 01025 if (option_debug) 01026 ast_log(LOG_DEBUG, "* SIP extension value: %d for call %s\n", profile, pvt->callid); 01027 } 01028 return profile; 01029 }
|
|
peer_status: Report Peer status in character string
Definition at line 7356 of file chan_sip.c. References sip_peer::lastms, and sip_peer::maxms. 07357 { 07358 int res = 0; 07359 if (peer->maxms) { 07360 if (peer->lastms < 0) { 07361 ast_copy_string(status, "UNREACHABLE", statuslen); 07362 } else if (peer->lastms > peer->maxms) { 07363 snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms); 07364 res = 1; 07365 } else if (peer->lastms) { 07366 snprintf(status, statuslen, "OK (%d ms)", peer->lastms); 07367 res = 1; 07368 } else { 07369 ast_copy_string(status, "UNKNOWN", statuslen); 07370 } 07371 } else { 07372 ast_copy_string(status, "Unmonitored", statuslen); 07373 /* Checking if port is 0 */ 07374 res = -1; 07375 } 07376 return res; 07377 }
|
|
print_codec_to_cli: Print codec list from preference to CLI/manager
Definition at line 7795 of file chan_sip.c. References ast_cli(), ast_codec_pref_index(), and ast_getformatname(). Referenced by _sip_show_peer(), and sip_show_settings(). 07796 { 07797 int x, codec; 07798 07799 for(x = 0; x < 32 ; x++) { 07800 codec = ast_codec_pref_index(pref, x); 07801 if (!codec) 07802 break; 07803 ast_cli(fd, "%s", ast_getformatname(codec)); 07804 if (x < 31 && ast_codec_pref_index(pref, x + 1)) 07805 ast_cli(fd, ","); 07806 } 07807 if (!x) 07808 ast_cli(fd, "none"); 07809 }
|
|
print_group: Print call group and pickup group ---
Definition at line 7612 of file chan_sip.c. References ast_cli(), and ast_print_group(). Referenced by _sip_show_peer(), and sip_show_user(). 07613 { 07614 char buf[256]; 07615 ast_cli(fd, crlf ? "%s\r\n" : "%s\n", ast_print_group(buf, sizeof(buf), group) ); 07616 }
|
|
process_sdp: Process SIP SDP and activate RTP channels---
Definition at line 3392 of file chan_sip.c. References ahp, append_history(), ast_bridged_channel(), ast_clear_flag, ast_codec_choose(), AST_FRAME_NULL, ast_getformatname_multiple(), ast_gethostbyname(), ast_inet_ntoa(), ast_log(), ast_moh_start(), ast_moh_stop(), ast_queue_frame(), AST_RTP_DTMF, ast_rtp_get_current_formats(), ast_rtp_lookup_mime_multiple(), ast_rtp_pt_clear(), ast_rtp_set_m_type(), ast_rtp_set_peer(), ast_rtp_set_rtpmap_type(), ast_rtp_stop(), ast_set_flag, ast_set_read_format(), ast_set_write_format(), ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_verbose(), callevents, sip_pvt::capability, sip_request::data, debug, EVENT_FLAG_CALL, get_header(), get_sdp(), get_sdp_iterate(), host, hp, sip_pvt::jointcapability, sip_pvt::lastrtprx, sip_pvt::lastrtptx, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, LOG_WARNING, manager_event(), ast_channel::name, ast_channel::nativeformats, noncodeccapability, sip_pvt::noncodeccapability, sip_pvt::owner, pedanticsipchecking, sip_pvt::peercapability, portno, sip_pvt::prefs, ast_channel::readformat, sip_pvt::rtp, sdpLineNum_iterator_init(), SIP_CALL_ONHOLD, sip_debug_test_pvt(), SIP_DTMF, SIP_DTMF_AUTO, SIP_DTMF_INBAND, SIP_DTMF_RFC2833, SIP_NOVIDEO, ast_channel::uniqueid, sip_pvt::vrtp, and ast_channel::writeformat. 03393 { 03394 char *m; 03395 char *c; 03396 char *a; 03397 char host[258]; 03398 char iabuf[INET_ADDRSTRLEN]; 03399 int len = -1; 03400 int portno = -1; 03401 int vportno = -1; 03402 int peercapability, peernoncodeccapability; 03403 int vpeercapability=0, vpeernoncodeccapability=0; 03404 struct sockaddr_in sin; 03405 char *codecs; 03406 struct hostent *hp; 03407 struct ast_hostent ahp; 03408 int codec; 03409 int destiterator = 0; 03410 int iterator; 03411 int sendonly = 0; 03412 int x,y; 03413 int debug=sip_debug_test_pvt(p); 03414 struct ast_channel *bridgepeer = NULL; 03415 03416 if (!p->rtp) { 03417 ast_log(LOG_ERROR, "Got SDP but have no RTP session allocated.\n"); 03418 return -1; 03419 } 03420 03421 /* Update our last rtprx when we receive an SDP, too */ 03422 time(&p->lastrtprx); 03423 time(&p->lastrtptx); 03424 03425 /* Get codec and RTP info from SDP */ 03426 if (strcasecmp(get_header(req, "Content-Type"), "application/sdp")) { 03427 ast_log(LOG_NOTICE, "Content is '%s', not 'application/sdp'\n", get_header(req, "Content-Type")); 03428 return -1; 03429 } 03430 m = get_sdp(req, "m"); 03431 sdpLineNum_iterator_init(&destiterator); 03432 c = get_sdp_iterate(&destiterator, req, "c"); 03433 if (ast_strlen_zero(m) || ast_strlen_zero(c)) { 03434 ast_log(LOG_WARNING, "Insufficient information for SDP (m = '%s', c = '%s')\n", m, c); 03435 return -1; 03436 } 03437 if (sscanf(c, "IN IP4 %256s", host) != 1) { 03438 ast_log(LOG_WARNING, "Invalid host in c= line, '%s'\n", c); 03439 return -1; 03440 } 03441 /* XXX This could block for a long time, and block the main thread! XXX */ 03442 hp = ast_gethostbyname(host, &ahp); 03443 if (!hp) { 03444 ast_log(LOG_WARNING, "Unable to lookup host in c= line, '%s'\n", c); 03445 return -1; 03446 } 03447 sdpLineNum_iterator_init(&iterator); 03448 ast_set_flag(p, SIP_NOVIDEO); 03449 while ((m = get_sdp_iterate(&iterator, req, "m"))[0] != '\0') { 03450 int found = 0; 03451 if ((sscanf(m, "audio %d/%d RTP/AVP %n", &x, &y, &len) == 2) || 03452 (sscanf(m, "audio %d RTP/AVP %n", &x, &len) == 1)) { 03453 found = 1; 03454 portno = x; 03455 /* Scan through the RTP payload types specified in a "m=" line: */ 03456 ast_rtp_pt_clear(p->rtp); 03457 codecs = m + len; 03458 while(!ast_strlen_zero(codecs)) { 03459 if (sscanf(codecs, "%d%n", &codec, &len) != 1) { 03460 ast_log(LOG_WARNING, "Error in codec string '%s'\n", codecs); 03461 return -1; 03462 } 03463 if (debug) 03464 ast_verbose("Found RTP audio format %d\n", codec); 03465 ast_rtp_set_m_type(p->rtp, codec); 03466 codecs = ast_skip_blanks(codecs + len); 03467 } 03468 } 03469 if (p->vrtp) 03470 ast_rtp_pt_clear(p->vrtp); /* Must be cleared in case no m=video line exists */ 03471 03472 if (p->vrtp && (sscanf(m, "video %d RTP/AVP %n", &x, &len) == 1)) { 03473 found = 1; 03474 ast_clear_flag(p, SIP_NOVIDEO); 03475 vportno = x; 03476 /* Scan through the RTP payload types specified in a "m=" line: */ 03477 codecs = m + len; 03478 while(!ast_strlen_zero(codecs)) { 03479 if (sscanf(codecs, "%d%n", &codec, &len) != 1) { 03480 ast_log(LOG_WARNING, "Error in codec string '%s'\n", codecs); 03481 return -1; 03482 } 03483 if (debug) 03484 ast_verbose("Found RTP video format %d\n", codec); 03485 ast_rtp_set_m_type(p->vrtp, codec); 03486 codecs = ast_skip_blanks(codecs + len); 03487 } 03488 } 03489 if (!found ) 03490 ast_log(LOG_WARNING, "Unknown SDP media type in offer: %s\n", m); 03491 } 03492 if (portno == -1 && vportno == -1) { 03493 /* No acceptable offer found in SDP */ 03494 return -2; 03495 } 03496 /* Check for Media-description-level-address for audio */ 03497 if (pedanticsipchecking) { 03498 c = get_sdp_iterate(&destiterator, req, "c"); 03499 if (!ast_strlen_zero(c)) { 03500 if (sscanf(c, "IN IP4 %256s", host) != 1) { 03501 ast_log(LOG_WARNING, "Invalid secondary host in c= line, '%s'\n", c); 03502 } else { 03503 /* XXX This could block for a long time, and block the main thread! XXX */ 03504 hp = ast_gethostbyname(host, &ahp); 03505 if (!hp) { 03506 ast_log(LOG_WARNING, "Unable to lookup host in secondary c= line, '%s'\n", c); 03507 return -1; 03508 } 03509 } 03510 } 03511 } 03512 /* RTP addresses and ports for audio and video */ 03513 sin.sin_family = AF_INET; 03514 memcpy(&sin.sin_addr, hp->h_addr, sizeof(sin.sin_addr)); 03515 03516 /* Setup audio port number */ 03517 sin.sin_port = htons(portno); 03518 if (p->rtp && sin.sin_port) { 03519 ast_rtp_set_peer(p->rtp, &sin); 03520 if (debug) { 03521 ast_verbose("Peer audio RTP is at port %s:%d\n", ast_inet_ntoa(iabuf,sizeof(iabuf), sin.sin_addr), ntohs(sin.sin_port)); 03522 ast_log(LOG_DEBUG,"Peer audio RTP is at port %s:%d\n",ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), ntohs(sin.sin_port)); 03523 } 03524 } 03525 /* Check for Media-description-level-address for video */ 03526 if (pedanticsipchecking) { 03527 c = get_sdp_iterate(&destiterator, req, "c"); 03528 if (!ast_strlen_zero(c)) { 03529 if (sscanf(c, "IN IP4 %256s", host) != 1) { 03530 ast_log(LOG_WARNING, "Invalid secondary host in c= line, '%s'\n", c); 03531 } else { 03532 /* XXX This could block for a long time, and block the main thread! XXX */ 03533 hp = ast_gethostbyname(host, &ahp); 03534 if (!hp) { 03535 ast_log(LOG_WARNING, "Unable to lookup host in secondary c= line, '%s'\n", c); 03536 return -1; 03537 } 03538 } 03539 } 03540 } 03541 /* Setup video port number */ 03542 sin.sin_port = htons(vportno); 03543 if (p->vrtp && sin.sin_port) { 03544 ast_rtp_set_peer(p->vrtp, &sin); 03545 if (debug) { 03546 ast_verbose("Peer video RTP is at port %s:%d\n", ast_inet_ntoa(iabuf,sizeof(iabuf), sin.sin_addr), ntohs(sin.sin_port)); 03547 ast_log(LOG_DEBUG,"Peer video RTP is at port %s:%d\n",ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), ntohs(sin.sin_port)); 03548 } 03549 } 03550 03551 /* Next, scan through each "a=rtpmap:" line, noting each 03552 * specified RTP payload type (with corresponding MIME subtype): 03553 */ 03554 sdpLineNum_iterator_init(&iterator); 03555 while ((a = get_sdp_iterate(&iterator, req, "a"))[0] != '\0') { 03556 char* mimeSubtype = ast_strdupa(a); /* ensures we have enough space */ 03557 if (!strcasecmp(a, "sendonly")) { 03558 sendonly=1; 03559 continue; 03560 } 03561 if (!strcasecmp(a, "sendrecv")) { 03562 sendonly=0; 03563 } 03564 if (sscanf(a, "rtpmap: %u %[^/]/", &codec, mimeSubtype) != 2) continue; 03565 if (debug) 03566 ast_verbose("Found description format %s\n", mimeSubtype); 03567 /* Note: should really look at the 'freq' and '#chans' params too */ 03568 ast_rtp_set_rtpmap_type(p->rtp, codec, "audio", mimeSubtype); 03569 if (p->vrtp) 03570 ast_rtp_set_rtpmap_type(p->vrtp, codec, "video", mimeSubtype); 03571 } 03572 03573 /* Now gather all of the codecs that were asked for: */ 03574 ast_rtp_get_current_formats(p->rtp, 03575 &peercapability, &peernoncodeccapability); 03576 if (p->vrtp) 03577 ast_rtp_get_current_formats(p->vrtp, 03578 &vpeercapability, &vpeernoncodeccapability); 03579 p->jointcapability = p->capability & (peercapability | vpeercapability); 03580 p->peercapability = (peercapability | vpeercapability); 03581 p->noncodeccapability = noncodeccapability & peernoncodeccapability; 03582 03583 if (ast_test_flag(p, SIP_DTMF) == SIP_DTMF_AUTO) { 03584 ast_clear_flag(p, SIP_DTMF); 03585 if (p->noncodeccapability & AST_RTP_DTMF) { 03586 /* XXX Would it be reasonable to drop the DSP at this point? XXX */ 03587 ast_set_flag(p, SIP_DTMF_RFC2833); 03588 } else { 03589 ast_set_flag(p, SIP_DTMF_INBAND); 03590 } 03591 } 03592 03593 if (debug) { 03594 /* shame on whoever coded this.... */ 03595 const unsigned slen=512; 03596 char s1[slen], s2[slen], s3[slen], s4[slen]; 03597 03598 ast_verbose("Capabilities: us - %s, peer - audio=%s/video=%s, combined - %s\n", 03599 ast_getformatname_multiple(s1, slen, p->capability), 03600 ast_getformatname_multiple(s2, slen, peercapability), 03601 ast_getformatname_multiple(s3, slen, vpeercapability), 03602 ast_getformatname_multiple(s4, slen, p->jointcapability)); 03603 03604 ast_verbose("Non-codec capabilities: us - %s, peer - %s, combined - %s\n", 03605 ast_rtp_lookup_mime_multiple(s1, slen, noncodeccapability, 0), 03606 ast_rtp_lookup_mime_multiple(s2, slen, peernoncodeccapability, 0), 03607 ast_rtp_lookup_mime_multiple(s3, slen, p->noncodeccapability, 0)); 03608 } 03609 if (!p->jointcapability) { 03610 ast_log(LOG_NOTICE, "No compatible codecs!\n"); 03611 return -1; 03612 } 03613 03614 if (!p->owner) /* There's no open channel owning us */ 03615 return 0; 03616 03617 if (!(p->owner->nativeformats & p->jointcapability)) { 03618 const unsigned slen=512; 03619 char s1[slen], s2[slen]; 03620 ast_log(LOG_DEBUG, "Oooh, we need to change our formats since our peer supports only %s and not %s\n", 03621 ast_getformatname_multiple(s1, slen, p->jointcapability), 03622 ast_getformatname_multiple(s2, slen, p->owner->nativeformats)); 03623 p->owner->nativeformats = ast_codec_choose(&p->prefs, p->jointcapability, 1); 03624 ast_set_read_format(p->owner, p->owner->readformat); 03625 ast_set_write_format(p->owner, p->owner->writeformat); 03626 } 03627 if ((bridgepeer=ast_bridged_channel(p->owner))) { 03628 /* We have a bridge */ 03629 /* Turn on/off music on hold if we are holding/unholding */ 03630 struct ast_frame af = { AST_FRAME_NULL, }; 03631 if (sin.sin_addr.s_addr && !sendonly) { 03632 ast_moh_stop(bridgepeer); 03633 03634 /* Activate a re-invite */ 03635 ast_queue_frame(p->owner, &af); 03636 } else { 03637 /* No address for RTP, we're on hold */ 03638 03639 ast_moh_start(bridgepeer, NULL); 03640 if (sendonly) 03641 ast_rtp_stop(p->rtp); 03642 /* Activate a re-invite */ 03643 ast_queue_frame(p->owner, &af); 03644 } 03645 } 03646 03647 /* Manager Hold and Unhold events must be generated, if necessary */ 03648 if (sin.sin_addr.s_addr && !sendonly) { 03649 append_history(p, "Unhold", req->data); 03650 03651 if (callevents && ast_test_flag(p, SIP_CALL_ONHOLD)) { 03652 manager_event(EVENT_FLAG_CALL, "Unhold", 03653 "Channel: %s\r\n" 03654 "Uniqueid: %s\r\n", 03655 p->owner->name, 03656 p->owner->uniqueid); 03657 03658 } 03659 ast_clear_flag(p, SIP_CALL_ONHOLD); 03660 } else { 03661 /* No address for RTP, we're on hold */ 03662 append_history(p, "Hold", req->data); 03663 03664 if (callevents && !ast_test_flag(p, SIP_CALL_ONHOLD)) { 03665 manager_event(EVENT_FLAG_CALL, "Hold", 03666 "Channel: %s\r\n" 03667 "Uniqueid: %s\r\n", 03668 p->owner->name, 03669 p->owner->uniqueid); 03670 } 03671 ast_set_flag(p, SIP_CALL_ONHOLD); 03672 } 03673 03674 return 0; 03675 }
|
|
realtime_peer: Get peer from realtime storage Checks the "sippeers" realtime family from extconfig.conf
Definition at line 1670 of file chan_sip.c. References ast_copy_flags, ast_inet_ntoa(), ast_load_realtime(), ast_log(), ast_sched_add(), ast_sched_del(), ast_set_flag, ast_test_flag, ast_variables_destroy(), ASTOBJ_CONTAINER_LINK, build_peer(), sip_peer::expire, expire_register(), sip_peer::flags_page2, global_flags_page2, global_rtautoclear, LOG_WARNING, ast_variable::name, ast_variable::next, peerl, sched, SIP_PAGE2_RTAUTOCLEAR, SIP_PAGE2_RTCACHEFRIENDS, SIP_REALTIME, ast_variable::value, and var. 01671 { 01672 struct sip_peer *peer=NULL; 01673 struct ast_variable *var; 01674 struct ast_variable *tmp; 01675 char *newpeername = (char *) peername; 01676 char iabuf[80]; 01677 01678 /* First check on peer name */ 01679 if (newpeername) 01680 var = ast_load_realtime("sippeers", "name", peername, NULL); 01681 else if (sin) { /* Then check on IP address */ 01682 ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr); 01683 var = ast_load_realtime("sippeers", "host", iabuf, NULL); /* First check for fixed IP hosts */ 01684 if (!var) 01685 var = ast_load_realtime("sippeers", "ipaddr", iabuf, NULL); /* Then check for registred hosts */ 01686 01687 } else 01688 return NULL; 01689 01690 if (!var) 01691 return NULL; 01692 01693 tmp = var; 01694 /* If this is type=user, then skip this object. */ 01695 while(tmp) { 01696 if (!strcasecmp(tmp->name, "type") && 01697 !strcasecmp(tmp->value, "user")) { 01698 ast_variables_destroy(var); 01699 return NULL; 01700 } else if (!newpeername && !strcasecmp(tmp->name, "name")) { 01701 newpeername = tmp->value; 01702 } 01703 tmp = tmp->next; 01704 } 01705 01706 if (!newpeername) { /* Did not find peer in realtime */ 01707 ast_log(LOG_WARNING, "Cannot Determine peer name ip=%s\n", iabuf); 01708 ast_variables_destroy(var); 01709 return (struct sip_peer *) NULL; 01710 } 01711 01712 /* Peer found in realtime, now build it in memory */ 01713 peer = build_peer(newpeername, var, !ast_test_flag((&global_flags_page2), SIP_PAGE2_RTCACHEFRIENDS)); 01714 if (!peer) { 01715 ast_variables_destroy(var); 01716 return (struct sip_peer *) NULL; 01717 } 01718 01719 if (ast_test_flag((&global_flags_page2), SIP_PAGE2_RTCACHEFRIENDS)) { 01720 /* Cache peer */ 01721 ast_copy_flags((&peer->flags_page2),(&global_flags_page2), SIP_PAGE2_RTAUTOCLEAR|SIP_PAGE2_RTCACHEFRIENDS); 01722 if (ast_test_flag((&global_flags_page2), SIP_PAGE2_RTAUTOCLEAR)) { 01723 if (peer->expire > -1) { 01724 ast_sched_del(sched, peer->expire); 01725 } 01726 peer->expire = ast_sched_add(sched, (global_rtautoclear) * 1000, expire_register, (void *)peer); 01727 } 01728 ASTOBJ_CONTAINER_LINK(&peerl,peer); 01729 } else { 01730 ast_set_flag(peer, SIP_REALTIME); 01731 } 01732 ast_variables_destroy(var); 01733 01734 return peer; 01735 }
|
|
realtime_update_peer: Update peer object in realtime storage ---
Definition at line 1592 of file chan_sip.c. References ast_inet_ntoa(), ast_update_realtime(), and ipaddr. 01593 { 01594 char port[10]; 01595 char ipaddr[20]; 01596 char regseconds[20]; 01597 time_t nowtime; 01598 01599 time(&nowtime); 01600 nowtime += expirey; 01601 snprintf(regseconds, sizeof(regseconds), "%d", (int)nowtime); /* Expiration time */ 01602 ast_inet_ntoa(ipaddr, sizeof(ipaddr), sin->sin_addr); 01603 snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port)); 01604 01605 if (fullcontact) 01606 ast_update_realtime("sippeers", "name", peername, "ipaddr", ipaddr, "port", port, "regseconds", regseconds, "username", username, "fullcontact", fullcontact, NULL); 01607 else 01608 ast_update_realtime("sippeers", "name", peername, "ipaddr", ipaddr, "port", port, "regseconds", regseconds, "username", username, NULL); 01609 }
|
|
realtime_user: 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 1784 of file chan_sip.c. References ast_load_realtime(), ast_set_flag, ast_test_flag, ast_variables_destroy(), ASTOBJ_CONTAINER_LINK, build_user(), global_flags_page2, ast_variable::name, ast_variable::next, SIP_PAGE2_RTCACHEFRIENDS, SIP_REALTIME, user, userl, ast_variable::value, and var. 01785 { 01786 struct ast_variable *var; 01787 struct ast_variable *tmp; 01788 struct sip_user *user = NULL; 01789 01790 var = ast_load_realtime("sipusers", "name", username, NULL); 01791 01792 if (!var) 01793 return NULL; 01794 01795 tmp = var; 01796 while (tmp) { 01797 if (!strcasecmp(tmp->name, "type") && 01798 !strcasecmp(tmp->value, "peer")) { 01799 ast_variables_destroy(var); 01800 return NULL; 01801 } 01802 tmp = tmp->next; 01803 } 01804 01805 01806 01807 user = build_user(username, var, !ast_test_flag((&global_flags_page2), SIP_PAGE2_RTCACHEFRIENDS)); 01808 01809 if (!user) { /* No user found */ 01810 ast_variables_destroy(var); 01811 return NULL; 01812 } 01813 01814 if (ast_test_flag((&global_flags_page2), SIP_PAGE2_RTCACHEFRIENDS)) { 01815 ast_set_flag((&user->flags_page2), SIP_PAGE2_RTCACHEFRIENDS); 01816 suserobjs++; 01817 ASTOBJ_CONTAINER_LINK(&userl,user); 01818 } else { 01819 /* Move counter from s to r... */ 01820 suserobjs--; 01821 ruserobjs++; 01822 ast_set_flag(user, SIP_REALTIME); 01823 } 01824 ast_variables_destroy(var); 01825 return user; 01826 }
|
|
receive_message: Receive SIP MESSAGE method messages ---
Definition at line 7251 of file chan_sip.c. References AST_FRAME_TEXT, ast_log(), ast_queue_frame(), ast_set_flag, ast_verbose(), sip_pvt::callid, get_header(), get_msg_text(), LOG_WARNING, sip_pvt::owner, sip_debug_test_pvt(), SIP_NEEDDESTROY, and transmit_response(). Referenced by handle_request_message(). 07252 { 07253 char buf[1024]; 07254 struct ast_frame f; 07255 char *content_type; 07256 07257 content_type = get_header(req, "Content-Type"); 07258 if (strcmp(content_type, "text/plain")) { /* No text/plain attachment */ 07259 transmit_response(p, "415 Unsupported Media Type", req); /* Good enough, or? */ 07260 ast_set_flag(p, SIP_NEEDDESTROY); 07261 return; 07262 } 07263 07264 if (get_msg_text(buf, sizeof(buf), req)) { 07265 ast_log(LOG_WARNING, "Unable to retrieve text from %s\n", p->callid); 07266 transmit_response(p, "202 Accepted", req); 07267 ast_set_flag(p, SIP_NEEDDESTROY); 07268 return; 07269 } 07270 07271 if (p->owner) { 07272 if (sip_debug_test_pvt(p)) 07273 ast_verbose("Message received: '%s'\n", buf); 07274 memset(&f, 0, sizeof(f)); 07275 f.frametype = AST_FRAME_TEXT; 07276 f.subclass = 0; 07277 f.offset = 0; 07278 f.data = buf; 07279 f.datalen = strlen(buf); 07280 ast_queue_frame(p->owner, &f); 07281 transmit_response(p, "202 Accepted", req); /* We respond 202 accepted, since we relay the message */ 07282 } else { /* Message outside of a call, we do not support that */ 07283 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); 07284 transmit_response(p, "405 Method Not Allowed", req); /* Good enough, or? */ 07285 } 07286 ast_set_flag(p, SIP_NEEDDESTROY); 07287 return; 07288 }
|
|
reg_source_db: Get registration details from Asterisk DB ---
Definition at line 5670 of file chan_sip.c. References sip_peer::addr, ast_db_get(), ast_inet_ntoa(), ast_sched_add(), ast_sched_del(), ast_test_flag, ast_verbose(), sip_peer::expire, expire_register(), expiry, sip_peer::flags_page2, sip_peer::fullcontact, option_verbose, sip_peer::pokeexpire, register_peer_exten(), SIP_PAGE2_RT_FROMCONTACT, sip_poke_peer(), sip_poke_peer_s(), sipsock, strsep(), thread_safe_rand(), sip_peer::username, username, and VERBOSE_PREFIX_3. 05671 { 05672 char data[256]; 05673 char iabuf[INET_ADDRSTRLEN]; 05674 struct in_addr in; 05675 int expiry; 05676 int port; 05677 char *scan, *addr, *port_str, *expiry_str, *username, *contact; 05678 05679 if (ast_test_flag(&(peer->flags_page2), SIP_PAGE2_RT_FROMCONTACT)) 05680 return; 05681 if (ast_db_get("SIP/Registry", peer->name, data, sizeof(data))) 05682 return; 05683 05684 scan = data; 05685 addr = strsep(&scan, ":"); 05686 port_str = strsep(&scan, ":"); 05687 expiry_str = strsep(&scan, ":"); 05688 username = strsep(&scan, ":"); 05689 contact = scan; /* Contact include sip: and has to be the last part of the database entry as long as we use : as a separator */ 05690 05691 if (!inet_aton(addr, &in)) 05692 return; 05693 05694 if (port_str) 05695 port = atoi(port_str); 05696 else 05697 return; 05698 05699 if (expiry_str) 05700 expiry = atoi(expiry_str); 05701 else 05702 return; 05703 05704 if (username) 05705 ast_copy_string(peer->username, username, sizeof(peer->username)); 05706 if (contact) 05707 ast_copy_string(peer->fullcontact, contact, sizeof(peer->fullcontact)); 05708 05709 if (option_verbose > 2) 05710 ast_verbose(VERBOSE_PREFIX_3 "SIP Seeding peer from astdb: '%s' at %s@%s:%d for %d\n", 05711 peer->name, peer->username, ast_inet_ntoa(iabuf, sizeof(iabuf), in), port, expiry); 05712 05713 memset(&peer->addr, 0, sizeof(peer->addr)); 05714 peer->addr.sin_family = AF_INET; 05715 peer->addr.sin_addr = in; 05716 peer->addr.sin_port = htons(port); 05717 if (sipsock < 0) { 05718 /* SIP isn't up yet, so schedule a poke only, pretty soon */ 05719 if (peer->pokeexpire > -1) 05720 ast_sched_del(sched, peer->pokeexpire); 05721 peer->pokeexpire = ast_sched_add(sched, thread_safe_rand() % 5000 + 1, sip_poke_peer_s, peer); 05722 } else 05723 sip_poke_peer(peer); 05724 if (peer->expire > -1) 05725 ast_sched_del(sched, peer->expire); 05726 peer->expire = ast_sched_add(sched, (expiry + 10) * 1000, expire_register, peer); 05727 register_peer_exten(peer, 1); 05728 }
|
|
register_peer_exten: Automatically add peer extension to dial plan ---
Definition at line 1612 of file chan_sip.c. References ast_add_extension(), ast_context_remove_extension(), ast_strlen_zero(), free, sip_peer::regexten, strdup, and strsep(). 01613 { 01614 char multi[256]; 01615 char *stringp, *ext; 01616 if (!ast_strlen_zero(regcontext)) { 01617 ast_copy_string(multi, ast_strlen_zero(peer->regexten) ? peer->name : peer->regexten, sizeof(multi)); 01618 stringp = multi; 01619 while((ext = strsep(&stringp, "&"))) { 01620 if (onoff) 01621 ast_add_extension(regcontext, 1, ext, 1, NULL, NULL, "Noop", strdup(peer->name), free, channeltype); 01622 else 01623 ast_context_remove_extension(regcontext, ext, 1, NULL); 01624 } 01625 } 01626 }
|
|
register_verify: Verify registration of user
Definition at line 6353 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_test_flag, ast_uri_decode(), ASTOBJ_CONTAINER_LINK, ASTOBJ_UNREF, autocreatepeer, build_contact(), check_auth(), check_sip_domain(), EVENT_FLAG_SYSTEM, sip_pvt::exten, find_peer(), 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, pedanticsipchecking, peerl, sip_pvt::randdata, sip_peer::secret, sip_cancel_destroy(), sip_destroy_peer(), SIP_DYNAMIC, SIP_NAT, SIP_REGISTER, t, temp_peer(), transmit_response(), transmit_response_with_date(), and update_peer(). 06354 { 06355 int res = -3; 06356 struct sip_peer *peer; 06357 char tmp[256]; 06358 char iabuf[INET_ADDRSTRLEN]; 06359 char *name, *c; 06360 char *t; 06361 char *domain; 06362 06363 /* Terminate URI */ 06364 t = uri; 06365 while(*t && (*t > 32) && (*t != ';')) 06366 t++; 06367 *t = '\0'; 06368 06369 ast_copy_string(tmp, get_header(req, "To"), sizeof(tmp)); 06370 if (pedanticsipchecking) 06371 ast_uri_decode(tmp); 06372 06373 c = get_in_brackets(tmp); 06374 /* Ditch ;user=phone */ 06375 name = strchr(c, ';'); 06376 if (name) 06377 *name = '\0'; 06378 06379 if (!strncmp(c, "sip:", 4)) { 06380 name = c + 4; 06381 } else { 06382 name = c; 06383 ast_log(LOG_NOTICE, "Invalid to address: '%s' from %s (missing sip:) trying to use anyway...\n", c, ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr)); 06384 } 06385 06386 /* Strip off the domain name */ 06387 if ((c = strchr(name, '@'))) { 06388 *c++ = '\0'; 06389 domain = c; 06390 if ((c = strchr(domain, ':'))) /* Remove :port */ 06391 *c = '\0'; 06392 if (!AST_LIST_EMPTY(&domain_list)) { 06393 if (!check_sip_domain(domain, NULL, 0)) { 06394 transmit_response(p, "404 Not found (unknown domain)", &p->initreq); 06395 return -3; 06396 } 06397 } 06398 } 06399 06400 ast_copy_string(p->exten, name, sizeof(p->exten)); 06401 build_contact(p); 06402 peer = find_peer(name, NULL, 1); 06403 if (!(peer && ast_apply_ha(peer->ha, sin))) { 06404 if (peer) 06405 ASTOBJ_UNREF(peer,sip_destroy_peer); 06406 } 06407 if (peer) { 06408 if (!ast_test_flag(peer, SIP_DYNAMIC)) { 06409 ast_log(LOG_ERROR, "Peer '%s' is trying to register, but not configured as host=dynamic\n", peer->name); 06410 } else { 06411 ast_copy_flags(p, peer, SIP_NAT); 06412 transmit_response(p, "100 Trying", req); 06413 if (!(res = check_auth(p, req, p->randdata, sizeof(p->randdata), peer->name, peer->secret, peer->md5secret, SIP_REGISTER, uri, 0, ignore))) { 06414 sip_cancel_destroy(p); 06415 switch (parse_register_contact(p, peer, req)) { 06416 case PARSE_REGISTER_FAILED: 06417 ast_log(LOG_WARNING, "Failed to parse contact info\n"); 06418 break; 06419 case PARSE_REGISTER_QUERY: 06420 transmit_response_with_date(p, "200 OK", req); 06421 peer->lastmsgssent = -1; 06422 res = 0; 06423 break; 06424 case PARSE_REGISTER_UPDATE: 06425 update_peer(peer, p->expiry); 06426 /* Say OK and ask subsystem to retransmit msg counter */ 06427 transmit_response_with_date(p, "200 OK", req); 06428 peer->lastmsgssent = -1; 06429 res = 0; 06430 break; 06431 } 06432 } 06433 } 06434 } 06435 if (!peer && autocreatepeer) { 06436 /* Create peer if we have autocreate mode enabled */ 06437 peer = temp_peer(name); 06438 if (peer) { 06439 ASTOBJ_CONTAINER_LINK(&peerl, peer); 06440 peer->lastmsgssent = -1; 06441 sip_cancel_destroy(p); 06442 switch (parse_register_contact(p, peer, req)) { 06443 case PARSE_REGISTER_FAILED: 06444 ast_log(LOG_WARNING, "Failed to parse contact info\n"); 06445 break; 06446 case PARSE_REGISTER_QUERY: 06447 transmit_response_with_date(p, "200 OK", req); 06448 peer->lastmsgssent = -1; 06449 res = 0; 06450 break; 06451 case PARSE_REGISTER_UPDATE: 06452 /* Say OK and ask subsystem to retransmit msg counter */ 06453 transmit_response_with_date(p, "200 OK", req); 06454 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Registered\r\n", peer->name); 06455 peer->lastmsgssent = -1; 06456 res = 0; 06457 break; 06458 } 06459 } 06460 } 06461 if (!res) { 06462 ast_device_state_changed("SIP/%s", peer->name); 06463 } 06464 if (res < 0) { 06465 switch (res) { 06466 case -1: 06467 /* Wrong password in authentication. Go away, don't try again until you fixed it */ 06468 transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq); 06469 break; 06470 case -2: 06471 /* Username and digest username does not match. 06472 Asterisk uses the From: username for authentication. We need the 06473 users to use the same authentication user name until we support 06474 proper authentication by digest auth name */ 06475 transmit_response(p, "403 Authentication user name does not match account name", &p->initreq); 06476 break; 06477 case -3: 06478 /* URI not found */ 06479 transmit_response(p, "404 Not found", &p->initreq); 06480 /* Set res back to -2 because we don't want to return an invalid domain message. That check already happened up above. */ 06481 res = -2; 06482 break; 06483 } 06484 if (option_debug > 1) { 06485 ast_log(LOG_DEBUG, "SIP REGISTER attempt failed for %s : %s\n", 06486 peer->name, 06487 (res == -1) ? "Bad password" : ((res == -2 ) ? "Bad digest user" : "Peer not found")); 06488 } 06489 } 06490 if (peer) 06491 ASTOBJ_UNREF(peer,sip_destroy_peer); 06492 06493 return res; 06494 }
|
|
Definition at line 5217 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. 05218 { 05219 switch(regstate) { 05220 case REG_STATE_FAILED: 05221 return "Failed"; 05222 case REG_STATE_UNREGISTERED: 05223 return "Unregistered"; 05224 case REG_STATE_REGSENT: 05225 return "Request Sent"; 05226 case REG_STATE_AUTHSENT: 05227 return "Auth. Sent"; 05228 case REG_STATE_REGISTERED: 05229 return "Registered"; 05230 case REG_STATE_REJECTED: 05231 return "Rejected"; 05232 case REG_STATE_TIMEOUT: 05233 return "Timeout"; 05234 case REG_STATE_NOAUTH: 05235 return "No Authentication"; 05236 default: 05237 return "Unknown"; 05238 } 05239 }
|
|
Reload stuff. This function is where any reload routines take place. Re-read config files, change signalling, whatever is appropriate on a reload.
Definition at line 13094 of file chan_sip.c. References sip_reload(). 13095 { 13096 return sip_reload(0, 0, NULL); 13097 }
|
|
reload_config: Re-read SIP.conf config file ---
Definition at line 12307 of file chan_sip.c. References __ourip, add_realm_authentication(), add_sip_domain(), ahp, allow_external_domains, ast_append_ha(), ast_category_browse(), ast_clear_flag, ast_config_destroy(), ast_config_load(), ast_context_create(), ast_context_find(), ast_find_ourip(), AST_FLAGS_ALL, ast_get_ip_or_srv(), ast_gethostbyname(), ast_inet_ntoa(), AST_LIST_EMPTY, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_parse_allow_disallow(), ast_set2_flag, ast_set_flag, ast_str2tos(), ast_strdupa, ast_strlen_zero(), ast_true(), ast_variable_browse(), ast_variable_retrieve(), ast_verbose(), ASTOBJ_CONTAINER_LINK, ASTOBJ_UNREF, authl, autocreatepeer, bindaddr, build_peer(), build_user(), callevents, cfg, channeltype, compactheaders, config, context, DEFAULT_CALLERID, default_callerid, DEFAULT_CONTEXT, default_context, DEFAULT_DEFAULT_EXPIRY, default_expiry, DEFAULT_EXPIRY, default_fromdomain, default_language, DEFAULT_MAX_EXPIRY, DEFAULT_MAXMS, DEFAULT_MWITIME, DEFAULT_NOTIFYMIME, default_notifymime, default_qualify, DEFAULT_REALM, DEFAULT_REGISTRATION_TIMEOUT, DEFAULT_SIP_PORT, default_subscribecontext, DEFAULT_USERAGENT, default_useragent, DEFAULT_VMEXTEN, dumphistory, expiry, externexpire, externhost, externip, externrefresh, global_allowguest, global_capability, global_flags, global_flags_page2, global_musicclass, global_mwitime, global_notifyringing, global_realm, global_reg_timeout, global_regattempts_max, global_rtautoclear, global_rtpholdtimeout, global_rtpkeepalive, global_rtptimeout, global_vmexten, handle_common_options(), hp, ast_variable::lineno, localaddr, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, max_expiry, ast_variable::name, ast_variable::next, notify_config, notify_types, option_verbose, ourport, outboundproxyip, pedanticsipchecking, peerl, prefs, recordhistory, regcontext, relaxdtmf, SIP_CAN_REINVITE, SIP_DEBUG_CONFIG, sip_destroy_peer(), sip_destroy_user(), SIP_DOMAIN_AUTO, SIP_DOMAIN_CONFIG, SIP_DTMF_RFC2833, SIP_NAT_RFC3581, SIP_PAGE2_IGNOREREGEXPIRE, SIP_PAGE2_RTAUTOCLEAR, SIP_PAGE2_RTCACHEFRIENDS, SIP_PAGE2_RTUPDATE, sip_register(), SIP_USEREQPHONE, sipdebug, sipsock, srvlookup, tos, user, userl, ast_variable::value, VERBOSE_PREFIX_2, and videosupport. 12308 { 12309 struct ast_config *cfg; 12310 struct ast_variable *v; 12311 struct sip_peer *peer; 12312 struct sip_user *user; 12313 struct ast_hostent ahp; 12314 char *cat; 12315 char *utype; 12316 struct hostent *hp; 12317 int format; 12318 char iabuf[INET_ADDRSTRLEN]; 12319 struct ast_flags dummy; 12320 int auto_sip_domains = 0; 12321 struct sockaddr_in old_bindaddr = bindaddr; 12322 12323 cfg = ast_config_load(config); 12324 12325 /* We *must* have a config file otherwise stop immediately */ 12326 if (!cfg) { 12327 ast_log(LOG_NOTICE, "Unable to load config %s\n", config); 12328 return -1; 12329 } 12330 12331 /* Reset IP addresses */ 12332 memset(&bindaddr, 0, sizeof(bindaddr)); 12333 memset(&localaddr, 0, sizeof(localaddr)); 12334 memset(&externip, 0, sizeof(externip)); 12335 memset(&prefs, 0 , sizeof(prefs)); 12336 sipdebug &= ~SIP_DEBUG_CONFIG; 12337 12338 /* Initialize some reasonable defaults at SIP reload */ 12339 ast_copy_string(default_context, DEFAULT_CONTEXT, sizeof(default_context)); 12340 default_subscribecontext[0] = '\0'; 12341 default_language[0] = '\0'; 12342 default_fromdomain[0] = '\0'; 12343 default_qualify = 0; 12344 allow_external_domains = 1; /* Allow external invites */ 12345 externhost[0] = '\0'; 12346 externexpire = 0; 12347 externrefresh = 10; 12348 ast_copy_string(default_useragent, DEFAULT_USERAGENT, sizeof(default_useragent)); 12349 ast_copy_string(default_notifymime, DEFAULT_NOTIFYMIME, sizeof(default_notifymime)); 12350 global_notifyringing = 1; 12351 ast_copy_string(global_realm, DEFAULT_REALM, sizeof(global_realm)); 12352 ast_copy_string(global_musicclass, "default", sizeof(global_musicclass)); 12353 ast_copy_string(default_callerid, DEFAULT_CALLERID, sizeof(default_callerid)); 12354 memset(&outboundproxyip, 0, sizeof(outboundproxyip)); 12355 outboundproxyip.sin_port = htons(DEFAULT_SIP_PORT); 12356 outboundproxyip.sin_family = AF_INET; /* Type of address: IPv4 */ 12357 videosupport = 0; 12358 compactheaders = 0; 12359 dumphistory = 0; 12360 recordhistory = 0; 12361 relaxdtmf = 0; 12362 callevents = 0; 12363 ourport = DEFAULT_SIP_PORT; 12364 global_rtptimeout = 0; 12365 global_rtpholdtimeout = 0; 12366 global_rtpkeepalive = 0; 12367 global_rtautoclear = 120; 12368 pedanticsipchecking = 0; 12369 global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT; 12370 global_regattempts_max = 0; 12371 ast_clear_flag(&global_flags, AST_FLAGS_ALL); 12372 ast_clear_flag(&global_flags_page2, AST_FLAGS_ALL); 12373 ast_set_flag(&global_flags, SIP_DTMF_RFC2833); 12374 ast_set_flag(&global_flags, SIP_NAT_RFC3581); 12375 ast_set_flag(&global_flags, SIP_CAN_REINVITE); 12376 ast_set_flag(&global_flags_page2, SIP_PAGE2_RTUPDATE); 12377 global_mwitime = DEFAULT_MWITIME; 12378 strcpy(global_vmexten, DEFAULT_VMEXTEN); 12379 srvlookup = 0; 12380 autocreatepeer = 0; 12381 regcontext[0] = '\0'; 12382 tos = 0; 12383 expiry = DEFAULT_EXPIRY; 12384 global_allowguest = 1; 12385 12386 /* Read the [general] config section of sip.conf (or from realtime config) */ 12387 v = ast_variable_browse(cfg, "general"); 12388 while(v) { 12389 if (handle_common_options(&global_flags, &dummy, v)) { 12390 v = v->next; 12391 continue; 12392 } 12393 12394 /* Create the interface list */ 12395 if (!strcasecmp(v->name, "context")) { 12396 ast_copy_string(default_context, v->value, sizeof(default_context)); 12397 } else if (!strcasecmp(v->name, "realm")) { 12398 ast_copy_string(global_realm, v->value, sizeof(global_realm)); 12399 } else if (!strcasecmp(v->name, "useragent")) { 12400 ast_copy_string(default_useragent, v->value, sizeof(default_useragent)); 12401 ast_log(LOG_DEBUG, "Setting User Agent Name to %s\n", 12402 default_useragent); 12403 } else if (!strcasecmp(v->name, "rtcachefriends")) { 12404 ast_set2_flag((&global_flags_page2), ast_true(v->value), SIP_PAGE2_RTCACHEFRIENDS); 12405 } else if (!strcasecmp(v->name, "rtupdate")) { 12406 ast_set2_flag((&global_flags_page2), ast_true(v->value), SIP_PAGE2_RTUPDATE); 12407 } else if (!strcasecmp(v->name, "ignoreregexpire")) { 12408 ast_set2_flag((&global_flags_page2), ast_true(v->value), SIP_PAGE2_IGNOREREGEXPIRE); 12409 } else if (!strcasecmp(v->name, "rtautoclear")) { 12410 int i = atoi(v->value); 12411 if (i > 0) 12412 global_rtautoclear = i; 12413 else 12414 i = 0; 12415 ast_set2_flag((&global_flags_page2), i || ast_true(v->value), SIP_PAGE2_RTAUTOCLEAR); 12416 } else if (!strcasecmp(v->name, "usereqphone")) { 12417 ast_set2_flag((&global_flags), ast_true(v->value), SIP_USEREQPHONE); 12418 } else if (!strcasecmp(v->name, "relaxdtmf")) { 12419 relaxdtmf = ast_true(v->value); 12420 } else if (!strcasecmp(v->name, "checkmwi")) { 12421 if ((sscanf(v->value, "%d", &global_mwitime) != 1) || (global_mwitime < 0)) { 12422 ast_log(LOG_WARNING, "'%s' is not a valid MWI time setting at line %d. Using default (10).\n", v->value, v->lineno); 12423 global_mwitime = DEFAULT_MWITIME; 12424 } 12425 } else if (!strcasecmp(v->name, "vmexten")) { 12426 ast_copy_string(global_vmexten, v->value, sizeof(global_vmexten)); 12427 } else if (!strcasecmp(v->name, "rtptimeout")) { 12428 if ((sscanf(v->value, "%d", &global_rtptimeout) != 1) || (global_rtptimeout < 0)) { 12429 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 12430 global_rtptimeout = 0; 12431 } 12432 } else if (!strcasecmp(v->name, "rtpholdtimeout")) { 12433 if ((sscanf(v->value, "%d", &global_rtpholdtimeout) != 1) || (global_rtpholdtimeout < 0)) { 12434 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 12435 global_rtpholdtimeout = 0; 12436 } 12437 } else if (!strcasecmp(v->name, "rtpkeepalive")) { 12438 if ((sscanf(v->value, "%d", &global_rtpkeepalive) != 1) || (global_rtpkeepalive < 0)) { 12439 ast_log(LOG_WARNING, "'%s' is not a valid RTP keepalive time at line %d. Using default.\n", v->value, v->lineno); 12440 global_rtpkeepalive = 0; 12441 } 12442 } else if (!strcasecmp(v->name, "videosupport")) { 12443 videosupport = ast_true(v->value); 12444 } else if (!strcasecmp(v->name, "compactheaders")) { 12445 compactheaders = ast_true(v->value); 12446 } else if (!strcasecmp(v->name, "notifymimetype")) { 12447 ast_copy_string(default_notifymime, v->value, sizeof(default_notifymime)); 12448 } else if (!strcasecmp(v->name, "notifyringing")) { 12449 global_notifyringing = ast_true(v->value); 12450 } else if (!strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) { 12451 ast_copy_string(global_musicclass, v->value, sizeof(global_musicclass)); 12452 } else if (!strcasecmp(v->name, "language")) { 12453 ast_copy_string(default_language, v->value, sizeof(default_language)); 12454 } else if (!strcasecmp(v->name, "regcontext")) { 12455 ast_copy_string(regcontext, v->value, sizeof(regcontext)); 12456 /* Create context if it doesn't exist already */ 12457 if (!ast_context_find(regcontext)) 12458 ast_context_create(NULL, regcontext, channeltype); 12459 } else if (!strcasecmp(v->name, "callerid")) { 12460 ast_copy_string(default_callerid, v->value, sizeof(default_callerid)); 12461 } else if (!strcasecmp(v->name, "fromdomain")) { 12462 ast_copy_string(default_fromdomain, v->value, sizeof(default_fromdomain)); 12463 } else if (!strcasecmp(v->name, "outboundproxy")) { 12464 if (ast_get_ip_or_srv(&outboundproxyip, v->value, "_sip._udp") < 0) 12465 ast_log(LOG_WARNING, "Unable to locate host '%s'\n", v->value); 12466 } else if (!strcasecmp(v->name, "outboundproxyport")) { 12467 /* Port needs to be after IP */ 12468 sscanf(v->value, "%d", &format); 12469 outboundproxyip.sin_port = htons(format); 12470 } else if (!strcasecmp(v->name, "autocreatepeer")) { 12471 autocreatepeer = ast_true(v->value); 12472 } else if (!strcasecmp(v->name, "srvlookup")) { 12473 srvlookup = ast_true(v->value); 12474 } else if (!strcasecmp(v->name, "pedantic")) { 12475 pedanticsipchecking = ast_true(v->value); 12476 } else if (!strcasecmp(v->name, "maxexpirey") || !strcasecmp(v->name, "maxexpiry")) { 12477 max_expiry = atoi(v->value); 12478 if (max_expiry < 1) 12479 max_expiry = DEFAULT_MAX_EXPIRY; 12480 } else if (!strcasecmp(v->name, "defaultexpiry") || !strcasecmp(v->name, "defaultexpirey")) { 12481 default_expiry = atoi(v->value); 12482 if (default_expiry < 1) 12483 default_expiry = DEFAULT_DEFAULT_EXPIRY; 12484 } else if (!strcasecmp(v->name, "sipdebug")) { 12485 if (ast_true(v->value)) 12486 sipdebug |= SIP_DEBUG_CONFIG; 12487 } else if (!strcasecmp(v->name, "dumphistory")) { 12488 dumphistory = ast_true(v->value); 12489 } else if (!strcasecmp(v->name, "recordhistory")) { 12490 recordhistory = ast_true(v->value); 12491 } else if (!strcasecmp(v->name, "registertimeout")) { 12492 global_reg_timeout = atoi(v->value); 12493 if (global_reg_timeout < 1) 12494 global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT; 12495 } else if (!strcasecmp(v->name, "registerattempts")) { 12496 global_regattempts_max = atoi(v->value); 12497 } else if (!strcasecmp(v->name, "bindaddr")) { 12498 if (!(hp = ast_gethostbyname(v->value, &ahp))) { 12499 ast_log(LOG_WARNING, "Invalid address: %s\n", v->value); 12500 } else { 12501 memcpy(&bindaddr.sin_addr, hp->h_addr, sizeof(bindaddr.sin_addr)); 12502 } 12503 } else if (!strcasecmp(v->name, "localnet")) { 12504 struct ast_ha *na; 12505 if (!(na = ast_append_ha("d", v->value, localaddr))) 12506 ast_log(LOG_WARNING, "Invalid localnet value: %s\n", v->value); 12507 else 12508 localaddr = na; 12509 } else if (!strcasecmp(v->name, "localmask")) { 12510 ast_log(LOG_WARNING, "Use of localmask is no long supported -- use localnet with mask syntax\n"); 12511 } else if (!strcasecmp(v->name, "externip")) { 12512 if (!(hp = ast_gethostbyname(v->value, &ahp))) 12513 ast_log(LOG_WARNING, "Invalid address for externip keyword: %s\n", v->value); 12514 else 12515 memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr)); 12516 externexpire = 0; 12517 } else if (!strcasecmp(v->name, "externhost")) { 12518 ast_copy_string(externhost, v->value, sizeof(externhost)); 12519 if (!(hp = ast_gethostbyname(externhost, &ahp))) 12520 ast_log(LOG_WARNING, "Invalid address for externhost keyword: %s\n", externhost); 12521 else 12522 memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr)); 12523 time(&externexpire); 12524 } else if (!strcasecmp(v->name, "externrefresh")) { 12525 if (sscanf(v->value, "%d", &externrefresh) != 1) { 12526 ast_log(LOG_WARNING, "Invalid externrefresh value '%s', must be an integer >0 at line %d\n", v->value, v->lineno); 12527 externrefresh = 10; 12528 } 12529 } else if (!strcasecmp(v->name, "allow")) { 12530 ast_parse_allow_disallow(&prefs, &global_capability, v->value, 1); 12531 } else if (!strcasecmp(v->name, "disallow")) { 12532 ast_parse_allow_disallow(&prefs, &global_capability, v->value, 0); 12533 } else if (!strcasecmp(v->name, "allowexternaldomains")) { 12534 allow_external_domains = ast_true(v->value); 12535 } else if (!strcasecmp(v->name, "autodomain")) { 12536 auto_sip_domains = ast_true(v->value); 12537 } else if (!strcasecmp(v->name, "domain")) { 12538 char *domain = ast_strdupa(v->value); 12539 char *context = strchr(domain, ','); 12540 12541 if (context) 12542 *context++ = '\0'; 12543 12544 if (ast_strlen_zero(domain)) 12545 ast_log(LOG_WARNING, "Empty domain specified at line %d\n", v->lineno); 12546 else if (ast_strlen_zero(context)) 12547 ast_log(LOG_WARNING, "Empty context specified at line %d for domain '%s'\n", v->lineno, domain); 12548 else 12549 add_sip_domain(ast_strip(domain), SIP_DOMAIN_CONFIG, context ? ast_strip(context) : ""); 12550 } else if (!strcasecmp(v->name, "register")) { 12551 sip_register(v->value, v->lineno); 12552 } else if (!strcasecmp(v->name, "tos")) { 12553 if (ast_str2tos(v->value, &tos)) 12554 ast_log(LOG_WARNING, "Invalid tos value at line %d, should be 'lowdelay', 'throughput', 'reliability', 'mincost', or 'none'\n", v->lineno); 12555 } else if (!strcasecmp(v->name, "bindport")) { 12556 if (sscanf(v->value, "%d", &ourport) == 1) { 12557 bindaddr.sin_port = htons(ourport); 12558 } else { 12559 ast_log(LOG_WARNING, "Invalid port number '%s' at line %d of %s\n", v->value, v->lineno, config); 12560 } 12561 } else if (!strcasecmp(v->name, "qualify")) { 12562 if (!strcasecmp(v->value, "no")) { 12563 default_qualify = 0; 12564 } else if (!strcasecmp(v->value, "yes")) { 12565 default_qualify = DEFAULT_MAXMS; 12566 } else if (sscanf(v->value, "%d", &default_qualify) != 1) { 12567 ast_log(LOG_WARNING, "Qualification default should be 'yes', 'no', or a number of milliseconds at line %d of sip.conf\n", v->lineno); 12568 default_qualify = 0; 12569 } 12570 } else if (!strcasecmp(v->name, "callevents")) { 12571 callevents = ast_true(v->value); 12572 } 12573 /* else if (strcasecmp(v->name,"type")) 12574 * ast_log(LOG_WARNING, "Ignoring %s\n", v->name); 12575 */ 12576 v = v->next; 12577 } 12578 12579 if (!allow_external_domains && AST_LIST_EMPTY(&domain_list)) { 12580 ast_log(LOG_WARNING, "To disallow external domains, you need to configure local SIP domains.\n"); 12581 allow_external_domains = 1; 12582 } 12583 12584 /* Build list of authentication to various SIP realms, i.e. service providers */ 12585 v = ast_variable_browse(cfg, "authentication"); 12586 while(v) { 12587 /* Format for authentication is auth = username:password@realm */ 12588 if (!strcasecmp(v->name, "auth")) { 12589 authl = add_realm_authentication(authl, v->value, v->lineno); 12590 } 12591 v = v->next; 12592 } 12593 12594 /* Load peers, users and friends */ 12595 cat = ast_category_browse(cfg, NULL); 12596 while(cat) { 12597 if (strcasecmp(cat, "general") && strcasecmp(cat, "authentication")) { 12598 utype = ast_variable_retrieve(cfg, cat, "type"); 12599 if (utype) { 12600 if (!strcasecmp(utype, "user") || !strcasecmp(utype, "friend")) { 12601 user = build_user(cat, ast_variable_browse(cfg, cat), 0); 12602 if (user) { 12603 ASTOBJ_CONTAINER_LINK(&userl,user); 12604 ASTOBJ_UNREF(user, sip_destroy_user); 12605 } 12606 } 12607 if (!strcasecmp(utype, "peer") || !strcasecmp(utype, "friend")) { 12608 peer = build_peer(cat, ast_variable_browse(cfg, cat), 0); 12609 if (peer) { 12610 ASTOBJ_CONTAINER_LINK(&peerl,peer); 12611 ASTOBJ_UNREF(peer, sip_destroy_peer); 12612 } 12613 } else if (strcasecmp(utype, "user")) { 12614 ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, "sip.conf"); 12615 } 12616 } else 12617 ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat); 12618 } 12619 cat = ast_category_browse(cfg, cat); 12620 } 12621 if (ast_find_ourip(&__ourip, bindaddr)) { 12622 ast_log(LOG_WARNING, "Unable to get own IP address, SIP disabled\n"); 12623 return 0; 12624 } 12625 if (!ntohs(bindaddr.sin_port)) 12626 bindaddr.sin_port = ntohs(DEFAULT_SIP_PORT); 12627 bindaddr.sin_family = AF_INET; 12628 ast_mutex_lock(&netlock); 12629 if ((sipsock > -1) && (memcmp(&old_bindaddr, &bindaddr, sizeof(struct sockaddr_in)))) { 12630 close(sipsock); 12631 sipsock = -1; 12632 } 12633 if (sipsock < 0) { 12634 sipsock = socket(AF_INET, SOCK_DGRAM, 0); 12635 if (sipsock < 0) { 12636 ast_log(LOG_WARNING, "Unable to create SIP socket: %s\n", strerror(errno)); 12637 } else { 12638 /* Allow SIP clients on the same host to access us: */ 12639 const int reuseFlag = 1; 12640 setsockopt(sipsock, SOL_SOCKET, SO_REUSEADDR, 12641 (const char*)&reuseFlag, 12642 sizeof reuseFlag); 12643 12644 if (bind(sipsock, (struct sockaddr *)&bindaddr, sizeof(bindaddr)) < 0) { 12645 ast_log(LOG_WARNING, "Failed to bind to %s:%d: %s\n", 12646 ast_inet_ntoa(iabuf, sizeof(iabuf), bindaddr.sin_addr), ntohs(bindaddr.sin_port), 12647 strerror(errno)); 12648 close(sipsock); 12649 sipsock = -1; 12650 } else { 12651 if (option_verbose > 1) { 12652 ast_verbose(VERBOSE_PREFIX_2 "SIP Listening on %s:%d\n", 12653 ast_inet_ntoa(iabuf, sizeof(iabuf), bindaddr.sin_addr), ntohs(bindaddr.sin_port)); 12654 ast_verbose(VERBOSE_PREFIX_2 "Using TOS bits %d\n", tos); 12655 } 12656 if (setsockopt(sipsock, IPPROTO_IP, IP_TOS, &tos, sizeof(tos))) 12657 ast_log(LOG_WARNING, "Unable to set TOS to %d\n", tos); 12658 } 12659 } 12660 } 12661 ast_mutex_unlock(&netlock); 12662 12663 /* Add default domains - host name, IP address and IP:port */ 12664 /* Only do this if user added any sip domain with "localdomains" */ 12665 /* In order to *not* break backwards compatibility */ 12666 /* Some phones address us at IP only, some with additional port number */ 12667 if (auto_sip_domains) { 12668 char temp[MAXHOSTNAMELEN]; 12669 12670 /* First our default IP address */ 12671 if (bindaddr.sin_addr.s_addr) { 12672 ast_inet_ntoa(temp, sizeof(temp), bindaddr.sin_addr); 12673 add_sip_domain(temp, SIP_DOMAIN_AUTO, NULL); 12674 } else { 12675 ast_log(LOG_NOTICE, "Can't add wildcard IP address to domain list, please add IP address to domain manually.\n"); 12676 } 12677 12678 /* Our extern IP address, if configured */ 12679 if (externip.sin_addr.s_addr) { 12680 ast_inet_ntoa(temp, sizeof(temp), externip.sin_addr); 12681 add_sip_domain(temp, SIP_DOMAIN_AUTO, NULL); 12682 } 12683 12684 /* Extern host name (NAT traversal support) */ 12685 if (!ast_strlen_zero(externhost)) 12686 add_sip_domain(externhost, SIP_DOMAIN_AUTO, NULL); 12687 12688 /* Our host name */ 12689 if (!gethostname(temp, sizeof(temp))) 12690 add_sip_domain(temp, SIP_DOMAIN_AUTO, NULL); 12691 } 12692 12693 /* Release configuration from memory */ 12694 ast_config_destroy(cfg); 12695 12696 /* Load the list of manual NOTIFY types to support */ 12697 if (notify_types) 12698 ast_config_destroy(notify_types); 12699 notify_types = ast_config_load(notify_config); 12700 12701 return 0; 12702 }
|
|
reply_digest: reply to authentication for outbound registrations ---
Definition at line 8921 of file chan_sip.c. References ast_log(), ast_strlen_zero(), sip_pvt::domain, get_header(), key(), keys, LOG_WARNING, sip_pvt::nonce, sip_pvt::opaque, sip_pvt::qop, sip_pvt::realm, and strsep(). Referenced by do_proxy_auth(), and do_register_auth(). 08923 { 08924 char tmp[512]; 08925 char *c; 08926 char oldnonce[256]; 08927 08928 /* table of recognised keywords, and places where they should be copied */ 08929 const struct x { 08930 const char *key; 08931 char *dst; 08932 int dstlen; 08933 } *i, keys[] = { 08934 { "realm=", p->realm, sizeof(p->realm) }, 08935 { "nonce=", p->nonce, sizeof(p->nonce) }, 08936 { "opaque=", p->opaque, sizeof(p->opaque) }, 08937 { "qop=", p->qop, sizeof(p->qop) }, 08938 { "domain=", p->domain, sizeof(p->domain) }, 08939 { NULL, NULL, 0 }, 08940 }; 08941 08942 ast_copy_string(tmp, get_header(req, header), sizeof(tmp)); 08943 if (ast_strlen_zero(tmp)) 08944 return -1; 08945 if (strncasecmp(tmp, "Digest ", strlen("Digest "))) { 08946 ast_log(LOG_WARNING, "missing Digest.\n"); 08947 return -1; 08948 } 08949 c = tmp + strlen("Digest "); 08950 for (i = keys; i->key != NULL; i++) 08951 i->dst[0] = '\0'; /* init all to empty strings */ 08952 ast_copy_string(oldnonce, p->nonce, sizeof(oldnonce)); 08953 while (c && *(c = ast_skip_blanks(c))) { /* lookup for keys */ 08954 for (i = keys; i->key != NULL; i++) { 08955 char *src, *separator; 08956 if (strncasecmp(c, i->key, strlen(i->key)) != 0) 08957 continue; 08958 /* Found. Skip keyword, take text in quotes or up to the separator. */ 08959 c += strlen(i->key); 08960 if (*c == '\"') { 08961 src = ++c; 08962 separator = "\""; 08963 } else { 08964 src = c; 08965 separator = ","; 08966 } 08967 strsep(&c, separator); /* clear separator and move ptr */ 08968 ast_copy_string(i->dst, src, i->dstlen); 08969 break; 08970 } 08971 if (i->key == NULL) /* not found, try ',' */ 08972 strsep(&c, ","); 08973 } 08974 /* Reset nonce count */ 08975 if (strcmp(p->nonce, oldnonce)) 08976 p->noncecount = 0; 08977 08978 /* Save auth data for following registrations */ 08979 if (p->registry) { 08980 struct sip_registry *r = p->registry; 08981 08982 if (strcmp(r->nonce, p->nonce)) { 08983 ast_copy_string(r->realm, p->realm, sizeof(r->realm)); 08984 ast_copy_string(r->nonce, p->nonce, sizeof(r->nonce)); 08985 ast_copy_string(r->domain, p->domain, sizeof(r->domain)); 08986 ast_copy_string(r->opaque, p->opaque, sizeof(r->opaque)); 08987 ast_copy_string(r->qop, p->qop, sizeof(r->qop)); 08988 r->noncecount = 0; 08989 } 08990 } 08991 return build_reply_digest(p, sipmethod, digest, digest_len); 08992 }
|
|
reqprep: Initialize a SIP request response packet ---
Definition at line 4032 of file chan_sip.c. References add_header(), add_route(), ast_strlen_zero(), ast_test_flag, sip_pvt::branch, build_via(), copy_header(), DEFAULT_MAX_FORWARDS, default_useragent, get_header(), get_in_brackets(), sip_route::hop, init_req(), sip_pvt::initreq, sip_pvt::lastmsg, n, sip_route::next, sip_pvt::ocseq, sip_pvt::okcontacturi, sip_pvt::our_contact, sip_request::rlPart2, sip_pvt::route, sip_pvt::rpid, set_destination(), SIP_ACK, SIP_CANCEL, sip_methods, SIP_OUTGOING, strcasestr(), text, cfsip_methods::text, thread_safe_rand(), sip_pvt::uri, and sip_pvt::via. 04033 { 04034 struct sip_request *orig = &p->initreq; 04035 char stripped[80]; 04036 char tmp[80]; 04037 char newto[256]; 04038 char *c, *n; 04039 char *ot, *of; 04040 int is_strict = 0; /* Strict routing flag */ 04041 04042 memset(req, 0, sizeof(struct sip_request)); 04043 04044 snprintf(p->lastmsg, sizeof(p->lastmsg), "Tx: %s", sip_methods[sipmethod].text); 04045 04046 if (!seqno) { 04047 p->ocseq++; 04048 seqno = p->ocseq; 04049 } 04050 04051 if (newbranch) { 04052 p->branch ^= thread_safe_rand(); 04053 build_via(p, p->via, sizeof(p->via)); 04054 } 04055 04056 /* Check for strict or loose router */ 04057 if (p->route && !ast_strlen_zero(p->route->hop) && strstr(p->route->hop,";lr") == NULL) 04058 is_strict = 1; 04059 04060 if (sipmethod == SIP_CANCEL) { 04061 c = p->initreq.rlPart2; /* Use original URI */ 04062 } else if (sipmethod == SIP_ACK) { 04063 /* Use URI from Contact: in 200 OK (if INVITE) 04064 (we only have the contacturi on INVITEs) */ 04065 if (!ast_strlen_zero(p->okcontacturi)) 04066 c = is_strict ? p->route->hop : p->okcontacturi; 04067 else 04068 c = p->initreq.rlPart2; 04069 } else if (!ast_strlen_zero(p->okcontacturi)) { 04070 c = is_strict ? p->route->hop : p->okcontacturi; /* Use for BYE or REINVITE */ 04071 } else if (!ast_strlen_zero(p->uri)) { 04072 c = p->uri; 04073 } else { 04074 /* We have no URI, use To: or From: header as URI (depending on direction) */ 04075 c = get_header(orig, (ast_test_flag(p, SIP_OUTGOING)) ? "To" : "From"); 04076 ast_copy_string(stripped, c, sizeof(stripped)); 04077 c = get_in_brackets(stripped); 04078 n = strchr(c, ';'); 04079 if (n) 04080 *n = '\0'; 04081 } 04082 init_req(req, sipmethod, c); 04083 04084 snprintf(tmp, sizeof(tmp), "%d %s", seqno, sip_methods[sipmethod].text); 04085 04086 add_header(req, "Via", p->via); 04087 if (p->route) { 04088 set_destination(p, p->route->hop); 04089 if (is_strict) 04090 add_route(req, p->route->next); 04091 else 04092 add_route(req, p->route); 04093 } 04094 04095 ot = get_header(orig, "To"); 04096 of = get_header(orig, "From"); 04097 04098 /* Add tag *unless* this is a CANCEL, in which case we need to send it exactly 04099 as our original request, including tag (or presumably lack thereof) */ 04100 if (!strcasestr(ot, "tag=") && sipmethod != SIP_CANCEL) { 04101 /* Add the proper tag if we don't have it already. If they have specified 04102 their tag, use it. Otherwise, use our own tag */ 04103 if (ast_test_flag(p, SIP_OUTGOING) && !ast_strlen_zero(p->theirtag)) 04104 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->theirtag); 04105 else if (!ast_test_flag(p, SIP_OUTGOING)) 04106 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->tag); 04107 else 04108 snprintf(newto, sizeof(newto), "%s", ot); 04109 ot = newto; 04110 } 04111 04112 if (ast_test_flag(p, SIP_OUTGOING)) { 04113 add_header(req, "From", of); 04114 add_header(req, "To", ot); 04115 } else { 04116 add_header(req, "From", ot); 04117 add_header(req, "To", of); 04118 } 04119 add_header(req, "Contact", p->our_contact); 04120 copy_header(req, orig, "Call-ID"); 04121 add_header(req, "CSeq", tmp); 04122 04123 add_header(req, "User-Agent", default_useragent); 04124 add_header(req, "Max-Forwards", DEFAULT_MAX_FORWARDS); 04125 04126 if (p->rpid) 04127 add_header(req, "Remote-Party-ID", p->rpid); 04128 04129 return 0; 04130 }
|
|
respprep: Prepare SIP response packet ---
Definition at line 3984 of file chan_sip.c. References add_header(), ALLOWED_METHODS, ast_strlen_zero(), ast_test_flag, copy_all_header(), copy_header(), copy_via_headers(), default_useragent, sip_pvt::expiry, get_header(), init_resp(), sip_pvt::method, sip_pvt::our_contact, SIP_OUTGOING, SIP_REGISTER, SIP_SUBSCRIBE, strcasestr(), sip_pvt::tag, and sip_pvt::theirtag. 03985 { 03986 char newto[256], *ot; 03987 03988 memset(resp, 0, sizeof(*resp)); 03989 init_resp(resp, msg, req); 03990 copy_via_headers(p, resp, req, "Via"); 03991 if (msg[0] == '2') 03992 copy_all_header(resp, req, "Record-Route"); 03993 copy_header(resp, req, "From"); 03994 ot = get_header(req, "To"); 03995 if (!strcasestr(ot, "tag=") && strncmp(msg, "100", 3)) { 03996 /* Add the proper tag if we don't have it already. If they have specified 03997 their tag, use it. Otherwise, use our own tag */ 03998 if (!ast_strlen_zero(p->theirtag) && ast_test_flag(p, SIP_OUTGOING)) 03999 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->theirtag); 04000 else if (p->tag && !ast_test_flag(p, SIP_OUTGOING)) 04001 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->tag); 04002 else { 04003 ast_copy_string(newto, ot, sizeof(newto)); 04004 newto[sizeof(newto) - 1] = '\0'; 04005 } 04006 ot = newto; 04007 } 04008 add_header(resp, "To", ot); 04009 copy_header(resp, req, "Call-ID"); 04010 copy_header(resp, req, "CSeq"); 04011 add_header(resp, "User-Agent", default_useragent); 04012 add_header(resp, "Allow", ALLOWED_METHODS); 04013 if (msg[0] == '2' && (p->method == SIP_SUBSCRIBE || p->method == SIP_REGISTER)) { 04014 /* For registration responses, we also need expiry and 04015 contact info */ 04016 char tmp[256]; 04017 04018 snprintf(tmp, sizeof(tmp), "%d", p->expiry); 04019 add_header(resp, "Expires", tmp); 04020 if (p->expiry) { /* Only add contact if we have an expiry time */ 04021 char contact[256]; 04022 snprintf(contact, sizeof(contact), "%s;expires=%d", p->our_contact, p->expiry); 04023 add_header(resp, "Contact", contact); /* Not when we unregister */ 04024 } 04025 } else if (p->our_contact[0]) { 04026 add_header(resp, "Contact", p->our_contact); 04027 } 04028 return 0; 04029 }
|
|
restart_monitor: Start the channel monitor thread ---
Definition at line 11368 of file chan_sip.c. References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_pthread_create, AST_PTHREADT_NULL, AST_PTHREADT_STOP, do_monitor(), LOG_ERROR, LOG_WARNING, and monitor_thread. 11369 { 11370 /* If we're supposed to be stopped -- stay stopped */ 11371 if (monitor_thread == AST_PTHREADT_STOP) 11372 return 0; 11373 if (ast_mutex_lock(&monlock)) { 11374 ast_log(LOG_WARNING, "Unable to lock monitor\n"); 11375 return -1; 11376 } 11377 if (monitor_thread == pthread_self()) { 11378 ast_mutex_unlock(&monlock); 11379 ast_log(LOG_WARNING, "Cannot kill myself\n"); 11380 return -1; 11381 } 11382 if (monitor_thread != AST_PTHREADT_NULL) { 11383 /* Wake up the thread */ 11384 pthread_kill(monitor_thread, SIGURG); 11385 } else { 11386 /* Start a new monitor */ 11387 if (ast_pthread_create(&monitor_thread, NULL, do_monitor, NULL) < 0) { 11388 ast_mutex_unlock(&monlock); 11389 ast_log(LOG_ERROR, "Unable to start monitor thread.\n"); 11390 return -1; 11391 } 11392 } 11393 ast_mutex_unlock(&monlock); 11394 return 0; 11395 }
|
|
retrans_pkt: Retransmit SIP message if no answer ---
Definition at line 1157 of file chan_sip.c. References __sip_xmit(), append_history(), ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_queue_hangup(), ast_set_flag, ast_test_flag, ast_verbose(), sip_pvt::callid, sip_pkt::data, DEFAULT_RETRANS, FLAG_FATAL, FLAG_RESPONSE, free, ast_channel::lock, 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_pvt::recv, sip_pkt::retrans, sip_pkt::retransid, sip_pvt::sa, SIP_ALREADYGONE, sip_debug_test_pvt(), SIP_INVITE, sip_methods, SIP_NAT, SIP_NAT_ROUTE, SIP_NEEDDESTROY, SIP_OPTIONS, sip_pkt::timer_a, and sip_pkt::timer_t1. 01158 { 01159 struct sip_pkt *pkt=data, *prev, *cur = NULL; 01160 char iabuf[INET_ADDRSTRLEN]; 01161 int reschedule = DEFAULT_RETRANS; 01162 01163 /* Lock channel */ 01164 ast_mutex_lock(&pkt->owner->lock); 01165 01166 if (pkt->retrans < MAX_RETRANS) { 01167 char buf[80]; 01168 01169 pkt->retrans++; 01170 if (!pkt->timer_t1) { /* Re-schedule using timer_a and timer_t1 */ 01171 if (sipdebug && option_debug > 3) 01172 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); 01173 } else { 01174 int siptimer_a; 01175 01176 if (sipdebug && option_debug > 3) 01177 ast_log(LOG_DEBUG, "SIP TIMER: Rescheduling retransmission #%d (%d) %s - %d\n", pkt->retransid, pkt->retrans, sip_methods[pkt->method].text, pkt->method); 01178 if (!pkt->timer_a) 01179 pkt->timer_a = 2 ; 01180 else 01181 pkt->timer_a = 2 * pkt->timer_a; 01182 01183 /* For non-invites, a maximum of 4 secs */ 01184 siptimer_a = pkt->timer_t1 * pkt->timer_a; /* Double each time */ 01185 if (pkt->method != SIP_INVITE && siptimer_a > 4000) 01186 siptimer_a = 4000; 01187 01188 /* Reschedule re-transmit */ 01189 reschedule = siptimer_a; 01190 if (option_debug > 3) 01191 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); 01192 } 01193 01194 if (pkt->owner && sip_debug_test_pvt(pkt->owner)) { 01195 if (ast_test_flag(pkt->owner, SIP_NAT) & SIP_NAT_ROUTE) 01196 ast_verbose("Retransmitting #%d (NAT) to %s:%d:\n%s\n---\n", pkt->retrans, ast_inet_ntoa(iabuf, sizeof(iabuf), pkt->owner->recv.sin_addr), ntohs(pkt->owner->recv.sin_port), pkt->data); 01197 else 01198 ast_verbose("Retransmitting #%d (no NAT) to %s:%d:\n%s\n---\n", pkt->retrans, ast_inet_ntoa(iabuf, sizeof(iabuf), pkt->owner->sa.sin_addr), ntohs(pkt->owner->sa.sin_port), pkt->data); 01199 } 01200 snprintf(buf, sizeof(buf), "ReTx %d", reschedule); 01201 01202 append_history(pkt->owner, buf, pkt->data); 01203 __sip_xmit(pkt->owner, pkt->data, pkt->packetlen); 01204 ast_mutex_unlock(&pkt->owner->lock); 01205 return reschedule; 01206 } 01207 /* Too many retries */ 01208 if (pkt->owner && pkt->method != SIP_OPTIONS) { 01209 if (ast_test_flag(pkt, FLAG_FATAL) || sipdebug) /* Tell us if it's critical or if we're debugging */ 01210 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"); 01211 } else { 01212 if (pkt->method == SIP_OPTIONS && sipdebug) 01213 ast_log(LOG_WARNING, "Cancelling retransmit of OPTIONs (call id %s) \n", pkt->owner->callid); 01214 } 01215 append_history(pkt->owner, "MaxRetries", (ast_test_flag(pkt, FLAG_FATAL)) ? "(Critical)" : "(Non-critical)"); 01216 01217 pkt->retransid = -1; 01218 01219 if (ast_test_flag(pkt, FLAG_FATAL)) { 01220 while(pkt->owner->owner && ast_mutex_trylock(&pkt->owner->owner->lock)) { 01221 ast_mutex_unlock(&pkt->owner->lock); 01222 usleep(1); 01223 ast_mutex_lock(&pkt->owner->lock); 01224 } 01225 if (pkt->owner->owner) { 01226 ast_set_flag(pkt->owner, SIP_ALREADYGONE); 01227 ast_log(LOG_WARNING, "Hanging up call %s - no reply to our critical packet.\n", pkt->owner->callid); 01228 ast_queue_hangup(pkt->owner->owner); 01229 ast_mutex_unlock(&pkt->owner->owner->lock); 01230 } else { 01231 /* If no channel owner, destroy now */ 01232 ast_set_flag(pkt->owner, SIP_NEEDDESTROY); 01233 } 01234 } 01235 /* In any case, go ahead and remove the packet */ 01236 prev = NULL; 01237 cur = pkt->owner->packets; 01238 while(cur) { 01239 if (cur == pkt) 01240 break; 01241 prev = cur; 01242 cur = cur->next; 01243 } 01244 if (cur) { 01245 if (prev) 01246 prev->next = cur->next; 01247 else 01248 pkt->owner->packets = cur->next; 01249 ast_mutex_unlock(&pkt->owner->lock); 01250 free(cur); 01251 pkt = NULL; 01252 } else 01253 ast_log(LOG_WARNING, "Weird, couldn't find packet owner!\n"); 01254 if (pkt) 01255 ast_mutex_unlock(&pkt->owner->lock); 01256 return 0; 01257 }
|
|
Definition at line 2876 of file chan_sip.c.
|
|
send_request: Send SIP Request to the other part of the dialogue ---
Definition at line 1499 of file chan_sip.c. References __sip_reliable_xmit(), __sip_xmit(), append_history(), ast_inet_ntoa(), ast_test_flag, ast_verbose(), sip_request::data, get_header(), sip_request::len, sip_request::method, parse_copy(), sip_debug_test_pvt(), SIP_NAT, and SIP_NAT_ROUTE. 01500 { 01501 int res; 01502 char iabuf[INET_ADDRSTRLEN]; 01503 struct sip_request tmp; 01504 char tmpmsg[80]; 01505 01506 if (sip_debug_test_pvt(p)) { 01507 if (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE) 01508 ast_verbose("%sTransmitting (NAT) to %s:%d:\n%s\n---\n", reliable ? "Reliably " : "", ast_inet_ntoa(iabuf, sizeof(iabuf), p->recv.sin_addr), ntohs(p->recv.sin_port), req->data); 01509 else 01510 ast_verbose("%sTransmitting (no NAT) to %s:%d:\n%s\n---\n", reliable ? "Reliably " : "", ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr), ntohs(p->sa.sin_port), req->data); 01511 } 01512 if (reliable) { 01513 if (recordhistory) { 01514 parse_copy(&tmp, req); 01515 snprintf(tmpmsg, sizeof(tmpmsg), "%s / %s", tmp.data, get_header(&tmp, "CSeq")); 01516 append_history(p, "TxReqRel", tmpmsg); 01517 } 01518 res = __sip_reliable_xmit(p, seqno, 0, req->data, req->len, (reliable > 1), req->method); 01519 } else { 01520 if (recordhistory) { 01521 parse_copy(&tmp, req); 01522 snprintf(tmpmsg, sizeof(tmpmsg), "%s / %s", tmp.data, get_header(&tmp, "CSeq")); 01523 append_history(p, "TxReq", tmpmsg); 01524 } 01525 res = __sip_xmit(p, req->data, req->len); 01526 } 01527 return res; 01528 }
|
|
send_response: Transmit response on SIP request---
Definition at line 1465 of file chan_sip.c. References __sip_reliable_xmit(), __sip_xmit(), append_history(), ast_inet_ntoa(), ast_test_flag, ast_verbose(), sip_request::data, get_header(), sip_request::len, sip_request::method, parse_copy(), sip_debug_test_pvt(), SIP_NAT, and SIP_NAT_ROUTE. 01466 { 01467 int res; 01468 char iabuf[INET_ADDRSTRLEN]; 01469 struct sip_request tmp; 01470 char tmpmsg[80]; 01471 01472 if (sip_debug_test_pvt(p)) { 01473 if (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE) 01474 ast_verbose("%sTransmitting (NAT) to %s:%d:\n%s\n---\n", reliable ? "Reliably " : "", ast_inet_ntoa(iabuf, sizeof(iabuf), p->recv.sin_addr), ntohs(p->recv.sin_port), req->data); 01475 else 01476 ast_verbose("%sTransmitting (no NAT) to %s:%d:\n%s\n---\n", reliable ? "Reliably " : "", ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr), ntohs(p->sa.sin_port), req->data); 01477 } 01478 if (reliable) { 01479 if (recordhistory) { 01480 parse_copy(&tmp, req); 01481 snprintf(tmpmsg, sizeof(tmpmsg), "%s / %s", tmp.data, get_header(&tmp, "CSeq")); 01482 append_history(p, "TxRespRel", tmpmsg); 01483 } 01484 res = __sip_reliable_xmit(p, seqno, 1, req->data, req->len, (reliable > 1), req->method); 01485 } else { 01486 if (recordhistory) { 01487 parse_copy(&tmp, req); 01488 snprintf(tmpmsg, sizeof(tmpmsg), "%s / %s", tmp.data, get_header(&tmp, "CSeq")); 01489 append_history(p, "TxResp", tmpmsg); 01490 } 01491 res = __sip_xmit(p, req->data, req->len); 01492 } 01493 if (res > 0) 01494 return 0; 01495 return res; 01496 }
|
|
set_destination: Set destination from SIP URI ---
Definition at line 3888 of file chan_sip.c. References ahp, ast_gethostbyname(), ast_inet_ntoa(), ast_log(), ast_verbose(), debug, DEFAULT_SIP_PORT, hostname, hp, LOG_WARNING, sip_pvt::sa, and sip_debug_test_pvt(). Referenced by reqprep(). 03889 { 03890 char *h, *maddr, hostname[256]; 03891 char iabuf[INET_ADDRSTRLEN]; 03892 int port, hn; 03893 struct hostent *hp; 03894 struct ast_hostent ahp; 03895 int debug=sip_debug_test_pvt(p); 03896 03897 /* Parse uri to h (host) and port - uri is already just the part inside the <> */ 03898 /* general form we are expecting is sip[s]:username[:password]@host[:port][;...] */ 03899 03900 if (debug) 03901 ast_verbose("set_destination: Parsing <%s> for address/port to send to\n", uri); 03902 03903 /* Find and parse hostname */ 03904 h = strchr(uri, '@'); 03905 if (h) 03906 ++h; 03907 else { 03908 h = uri; 03909 if (strncmp(h, "sip:", 4) == 0) 03910 h += 4; 03911 else if (strncmp(h, "sips:", 5) == 0) 03912 h += 5; 03913 } 03914 hn = strcspn(h, ":;>") + 1; 03915 if (hn > sizeof(hostname)) 03916 hn = sizeof(hostname); 03917 ast_copy_string(hostname, h, hn); 03918 h += hn - 1; 03919 03920 /* Is "port" present? if not default to DEFAULT_SIP_PORT */ 03921 if (*h == ':') { 03922 /* Parse port */ 03923 ++h; 03924 port = strtol(h, &h, 10); 03925 } 03926 else 03927 port = DEFAULT_SIP_PORT; 03928 03929 /* Got the hostname:port - but maybe there's a "maddr=" to override address? */ 03930 maddr = strstr(h, "maddr="); 03931 if (maddr) { 03932 maddr += 6; 03933 hn = strspn(maddr, "0123456789.") + 1; 03934 if (hn > sizeof(hostname)) hn = sizeof(hostname); 03935 ast_copy_string(hostname, maddr, hn); 03936 } 03937 03938 hp = ast_gethostbyname(hostname, &ahp); 03939 if (hp == NULL) { 03940 ast_log(LOG_WARNING, "Can't find address for host '%s'\n", hostname); 03941 return; 03942 } 03943 p->sa.sin_family = AF_INET; 03944 memcpy(&p->sa.sin_addr, hp->h_addr, sizeof(p->sa.sin_addr)); 03945 p->sa.sin_port = htons(port); 03946 if (debug) 03947 ast_verbose("set_destination: set destination to %s, port %d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr), port); 03948 }
|
|
sip_addheader: Add a SIP header ---
Definition at line 12851 of file chan_sip.c. References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_strlen_zero(), ast_channel::lock, LOG_DEBUG, LOG_WARNING, pbx_builtin_getvar_helper(), pbx_builtin_setvar_helper(), and sipdebug. Referenced by load_module(). 12852 { 12853 int no = 0; 12854 int ok = 0; 12855 char varbuf[128]; 12856 12857 if (ast_strlen_zero((char *)data)) { 12858 ast_log(LOG_WARNING, "This application requires the argument: Header\n"); 12859 return 0; 12860 } 12861 ast_mutex_lock(&chan->lock); 12862 12863 /* Check for headers */ 12864 while (!ok && no <= 50) { 12865 no++; 12866 snprintf(varbuf, sizeof(varbuf), "_SIPADDHEADER%02d", no); 12867 if (ast_strlen_zero(pbx_builtin_getvar_helper(chan, varbuf + 1))) 12868 ok = 1; 12869 } 12870 if (ok) { 12871 pbx_builtin_setvar_helper (chan, varbuf, (char *)data); 12872 if (sipdebug) 12873 ast_log(LOG_DEBUG,"SIP Header added \"%s\" as %s\n", (char *) data, varbuf); 12874 } else { 12875 ast_log(LOG_WARNING, "Too many SIP headers added, max 50\n"); 12876 } 12877 ast_mutex_unlock(&chan->lock); 12878 return 0; 12879 }
|
|
sip_addrcmp: Support routine for find_peer ---
Definition at line 1738 of file chan_sip.c. References sip_peer::addr, ast_test_flag, inaddrcmp(), and SIP_INSECURE_PORT. Referenced by find_peer(). 01739 { 01740 /* We know name is the first field, so we can cast */ 01741 struct sip_peer *p = (struct sip_peer *)name; 01742 return !(!inaddrcmp(&p->addr, sin) || 01743 (ast_test_flag(p, SIP_INSECURE_PORT) && 01744 (p->addr.sin_addr.s_addr == sin->sin_addr.s_addr))); 01745 }
|
|
sip_alloc: Allocate SIP_PVT structure and set defaults ---
Definition at line 3034 of file chan_sip.c. References __ourip, ast_copy_flags, ast_log(), ast_mutex_destroy(), ast_mutex_init(), ast_mutex_lock(), ast_mutex_unlock(), AST_RTP_DTMF, ast_rtp_new_with_bindaddr(), ast_rtp_setnat(), ast_rtp_settos(), ast_sip_ouraddrfor(), ast_test_flag, ast_variables_destroy(), bindaddr, build_callid(), build_via(), calloc, default_context, default_fromdomain, free, global_capability, global_flags, global_musicclass, global_rtpholdtimeout, global_rtpkeepalive, global_rtptimeout, iflist, io, LOG_DEBUG, LOG_WARNING, make_our_tag(), NONE, option_debug, prefs, SIP_DTMF, SIP_DTMF_AUTO, SIP_DTMF_RFC2833, SIP_FLAGS_TO_COPY, sip_methods, SIP_NAT, SIP_NAT_ROUTE, SIP_OPTIONS, SIP_REGISTER, text, thread_safe_rand(), tos, and videosupport. Referenced by find_call(), sip_notify(), sip_poke_peer(), sip_request_call(), sip_send_mwi_to_peer(), and transmit_register(). 03035 { 03036 struct sip_pvt *p; 03037 03038 if (!(p = calloc(1, sizeof(*p)))) 03039 return NULL; 03040 03041 ast_mutex_init(&p->lock); 03042 03043 p->method = intended_method; 03044 p->initid = -1; 03045 p->autokillid = -1; 03046 p->subscribed = NONE; 03047 p->stateid = -1; 03048 p->prefs = prefs; 03049 if (intended_method != SIP_OPTIONS) /* Peerpoke has it's own system */ 03050 p->timer_t1 = 500; /* Default SIP retransmission timer T1 (RFC 3261) */ 03051 #ifdef OSP_SUPPORT 03052 p->osphandle = -1; 03053 p->osptimelimit = 0; 03054 #endif 03055 if (sin) { 03056 memcpy(&p->sa, sin, sizeof(p->sa)); 03057 if (ast_sip_ouraddrfor(&p->sa.sin_addr,&p->ourip)) 03058 memcpy(&p->ourip, &__ourip, sizeof(p->ourip)); 03059 } else { 03060 memcpy(&p->ourip, &__ourip, sizeof(p->ourip)); 03061 } 03062 03063 p->branch = thread_safe_rand(); 03064 make_our_tag(p->tag, sizeof(p->tag)); 03065 /* Start with 101 instead of 1 */ 03066 p->ocseq = 101; 03067 03068 if (sip_methods[intended_method].need_rtp) { 03069 p->rtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr.sin_addr); 03070 if (videosupport) 03071 p->vrtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr.sin_addr); 03072 if (!p->rtp || (videosupport && !p->vrtp)) { 03073 ast_log(LOG_WARNING, "Unable to create RTP audio %s session: %s\n", videosupport ? "and video" : "", strerror(errno)); 03074 ast_mutex_destroy(&p->lock); 03075 if (p->chanvars) { 03076 ast_variables_destroy(p->chanvars); 03077 p->chanvars = NULL; 03078 } 03079 free(p); 03080 return NULL; 03081 } 03082 ast_rtp_settos(p->rtp, tos); 03083 if (p->vrtp) 03084 ast_rtp_settos(p->vrtp, tos); 03085 p->rtptimeout = global_rtptimeout; 03086 p->rtpholdtimeout = global_rtpholdtimeout; 03087 p->rtpkeepalive = global_rtpkeepalive; 03088 } 03089 03090 if (useglobal_nat && sin) { 03091 /* Setup NAT structure according to global settings if we have an address */ 03092 ast_copy_flags(p, &global_flags, SIP_NAT); 03093 memcpy(&p->recv, sin, sizeof(p->recv)); 03094 if (p->rtp) 03095 ast_rtp_setnat(p->rtp, (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE)); 03096 if (p->vrtp) 03097 ast_rtp_setnat(p->vrtp, (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE)); 03098 } 03099 03100 if (p->method != SIP_REGISTER) 03101 ast_copy_string(p->fromdomain, default_fromdomain, sizeof(p->fromdomain)); 03102 build_via(p, p->via, sizeof(p->via)); 03103 if (!callid) 03104 build_callid(p->callid, sizeof(p->callid), p->ourip, p->fromdomain); 03105 else 03106 ast_copy_string(p->callid, callid, sizeof(p->callid)); 03107 ast_copy_flags(p, &global_flags, SIP_FLAGS_TO_COPY); 03108 /* Assign default music on hold class */ 03109 strcpy(p->musicclass, global_musicclass); 03110 p->capability = global_capability; 03111 if ((ast_test_flag(p, SIP_DTMF) == SIP_DTMF_RFC2833) || (ast_test_flag(p, SIP_DTMF) == SIP_DTMF_AUTO)) 03112 p->noncodeccapability |= AST_RTP_DTMF; 03113 strcpy(p->context, default_context); 03114 03115 /* Add to active dialog list */ 03116 ast_mutex_lock(&iflock); 03117 p->next = iflist; 03118 iflist = p; 03119 ast_mutex_unlock(&iflock); 03120 if (option_debug) 03121 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"); 03122 return p; 03123 }
|
|
sip_answer: Answer SIP call , send 200 OK on Invite Part of PBX interface
Definition at line 2513 of file chan_sip.c. References ast_channel::_state, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_setstate(), AST_STATE_UP, sip_pvt::initreq, sip_pvt::lock, LOG_DEBUG, ast_channel::name, option_debug, ast_channel::tech_pvt, transmit_response_with_sdp(), and try_suggested_sip_codec(). 02514 { 02515 int res = 0; 02516 struct sip_pvt *p = ast->tech_pvt; 02517 02518 ast_mutex_lock(&p->lock); 02519 if (ast->_state != AST_STATE_UP) { 02520 #ifdef OSP_SUPPORT 02521 time(&p->ospstart); 02522 #endif 02523 try_suggested_sip_codec(p); 02524 02525 ast_setstate(ast, AST_STATE_UP); 02526 if (option_debug) 02527 ast_log(LOG_DEBUG, "sip_answer(%s)\n", ast->name); 02528 res = transmit_response_with_sdp(p, "200 OK", &p->initreq, 1); 02529 } 02530 ast_mutex_unlock(&p->lock); 02531 return res; 02532 }
|
|
sip_call: Initiate SIP call from PBX used from the dial() application
Definition at line 2004 of file chan_sip.c. References ast_channel::_state, sip_invite_param::addsipheaders, AST_LIST_TRAVERSE, ast_log(), ast_sched_add(), ast_set_flag, AST_STATE_DOWN, AST_STATE_RESERVED, ast_var_name(), ast_var_value(), auto_congest(), sip_pvt::callingpres, sip_pvt::capability, ast_channel::cid, ast_callerid::cid_pres, sip_invite_param::distinctive_ring, INC_CALL_LIMIT, sip_pvt::initid, sip_pvt::jointcapability, LOG_DEBUG, LOG_WARNING, sip_pvt::maxtime, ast_channel::name, sip_pvt::options, sip_invite_param::osptoken, sched, SIP_INVITE, SIP_OUTGOING, ast_channel::tech_pvt, transmit_invite(), update_call_counter(), sip_invite_param::uri_options, sip_pvt::username, ast_channel::varshead, and sip_invite_param::vxml_url. 02005 { 02006 int res; 02007 struct sip_pvt *p; 02008 #ifdef OSP_SUPPORT 02009 char *osphandle = NULL; 02010 #endif 02011 struct varshead *headp; 02012 struct ast_var_t *current; 02013 02014 02015 02016 p = ast->tech_pvt; 02017 if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) { 02018 ast_log(LOG_WARNING, "sip_call called on %s, neither down nor reserved\n", ast->name); 02019 return -1; 02020 } 02021 02022 02023 /* Check whether there is vxml_url, distinctive ring variables */ 02024 02025 headp=&ast->varshead; 02026 AST_LIST_TRAVERSE(headp,current,entries) { 02027 /* Check whether there is a VXML_URL variable */ 02028 if (!p->options->vxml_url && !strcasecmp(ast_var_name(current), "VXML_URL")) { 02029 p->options->vxml_url = ast_var_value(current); 02030 } else if (!p->options->uri_options && !strcasecmp(ast_var_name(current), "SIP_URI_OPTIONS")) { 02031 p->options->uri_options = ast_var_value(current); 02032 } else if (!p->options->distinctive_ring && !strcasecmp(ast_var_name(current), "ALERT_INFO")) { 02033 /* Check whether there is a ALERT_INFO variable */ 02034 p->options->distinctive_ring = ast_var_value(current); 02035 } else if (!p->options->addsipheaders && !strncasecmp(ast_var_name(current), "SIPADDHEADER", strlen("SIPADDHEADER"))) { 02036 /* Check whether there is a variable with a name starting with SIPADDHEADER */ 02037 p->options->addsipheaders = 1; 02038 } 02039 02040 02041 #ifdef OSP_SUPPORT 02042 else if (!p->options->osptoken && !strcasecmp(ast_var_name(current), "OSPTOKEN")) { 02043 p->options->osptoken = ast_var_value(current); 02044 } else if (!osphandle && !strcasecmp(ast_var_name(current), "OSPHANDLE")) { 02045 osphandle = ast_var_value(current); 02046 } 02047 #endif 02048 } 02049 02050 res = 0; 02051 ast_set_flag(p, SIP_OUTGOING); 02052 #ifdef OSP_SUPPORT 02053 if (!p->options->osptoken || !osphandle || (sscanf(osphandle, "%d", &p->osphandle) != 1)) { 02054 /* Force Disable OSP support */ 02055 ast_log(LOG_DEBUG, "Disabling OSP support for this call. osptoken = %s, osphandle = %s\n", p->options->osptoken, osphandle); 02056 p->options->osptoken = NULL; 02057 osphandle = NULL; 02058 p->osphandle = -1; 02059 } 02060 #endif 02061 ast_log(LOG_DEBUG, "Outgoing Call for %s\n", p->username); 02062 res = update_call_counter(p, INC_CALL_LIMIT); 02063 if ( res != -1 ) { 02064 p->callingpres = ast->cid.cid_pres; 02065 p->jointcapability = p->capability; 02066 transmit_invite(p, SIP_INVITE, 1, 2); 02067 if (p->maxtime) { 02068 /* Initialize auto-congest time */ 02069 p->initid = ast_sched_add(sched, p->maxtime * 4, auto_congest, p); 02070 } 02071 } 02072 return res; 02073 }
|
|
sip_cancel_destroy: Cancel destruction of SIP call ---
Definition at line 1345 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(), and register_verify(). 01346 { 01347 if (p->autokillid > -1) 01348 ast_sched_del(sched, p->autokillid); 01349 append_history(p, "CancelDestroy", ""); 01350 p->autokillid = -1; 01351 return 0; 01352 }
|
|
sip_debug_test_addr: See if we pass debug IP filter
Definition at line 1032 of file chan_sip.c. Referenced by check_user_full(), sip_debug_test_pvt(), and sipsock_read(). 01033 { 01034 if (sipdebug == 0) 01035 return 0; 01036 if (debugaddr.sin_addr.s_addr) { 01037 if (((ntohs(debugaddr.sin_port) != 0) 01038 && (debugaddr.sin_port != addr->sin_port)) 01039 || (debugaddr.sin_addr.s_addr != addr->sin_addr.s_addr)) 01040 return 0; 01041 } 01042 return 1; 01043 }
|
|
sip_debug_test_pvt: Test PVT for debugging output
Definition at line 1046 of file chan_sip.c. References ast_test_flag, sip_pvt::recv, sip_pvt::sa, sip_debug_test_addr(), SIP_NAT, and SIP_NAT_ROUTE. Referenced by __sip_destroy(), add_sdp(), 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(), transmit_invite(), transmit_notify_with_mwi(), transmit_notify_with_sipfrag(), transmit_register(), transmit_reinvite_with_sdp(), and transmit_sip_request(). 01047 { 01048 if (sipdebug == 0) 01049 return 0; 01050 return sip_debug_test_addr(((ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE) ? &p->recv : &p->sa)); 01051 }
|
|
sip_destroy: Destroy SIP call structure ---
Definition at line 2271 of file chan_sip.c. References __sip_destroy(), ast_mutex_lock(), and ast_mutex_unlock(). Referenced by __sip_autodestruct(), 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(). 02272 { 02273 ast_mutex_lock(&iflock); 02274 __sip_destroy(p, 1); 02275 ast_mutex_unlock(&iflock); 02276 }
|
|
|
sip_destroy_user: Remove user object from in-memory storage ---
Definition at line 1767 of file chan_sip.c. References ast_free_ha(), ast_test_flag, ast_variables_destroy(), free, SIP_REALTIME, and user. Referenced by check_user_full(), reload_config(), sip_show_user(), unload_module(), and update_call_counter(). 01768 { 01769 ast_free_ha(user->ha); 01770 if (user->chanvars) { 01771 ast_variables_destroy(user->chanvars); 01772 user->chanvars = NULL; 01773 } 01774 if (ast_test_flag(user, SIP_REALTIME)) 01775 ruserobjs--; 01776 else 01777 suserobjs--; 01778 free(user); 01779 }
|
|
sip_devicestate: Part of PBX channel interface ---
Definition at line 11494 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_UNAVAILABLE, AST_DEVICE_UNKNOWN, ast_gethostbyname(), ast_log(), ast_strdupa, ASTOBJ_UNREF, sip_peer::call_limit, sip_peer::defaddr, find_peer(), host, hp, sip_peer::inUse, sip_peer::lastms, LOG_DEBUG, sip_peer::maxms, option_debug, and sip_destroy_peer(). 11495 { 11496 char *host; 11497 char *tmp; 11498 11499 struct hostent *hp; 11500 struct ast_hostent ahp; 11501 struct sip_peer *p; 11502 11503 int res = AST_DEVICE_INVALID; 11504 11505 host = ast_strdupa(data); 11506 if ((tmp = strchr(host, '@'))) 11507 host = tmp + 1; 11508 11509 if (option_debug > 2) 11510 ast_log(LOG_DEBUG, "Checking device state for peer %s\n", host); 11511 11512 if ((p = find_peer(host, NULL, 1))) { 11513 if (p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) { 11514 /* we have an address for the peer */ 11515 /* if qualify is turned on, check the status */ 11516 if (p->maxms && (p->lastms > p->maxms)) { 11517 res = AST_DEVICE_UNAVAILABLE; 11518 } else { 11519 /* qualify is not on, or the peer is responding properly */ 11520 /* check call limit */ 11521 if (p->call_limit && (p->inUse == p->call_limit)) 11522 res = AST_DEVICE_BUSY; 11523 else if (p->call_limit && p->inUse) 11524 res = AST_DEVICE_INUSE; 11525 else if (p->call_limit) 11526 res = AST_DEVICE_NOT_INUSE; 11527 else 11528 res = AST_DEVICE_UNKNOWN; 11529 } 11530 } else { 11531 /* there is no address, it's unavailable */ 11532 res = AST_DEVICE_UNAVAILABLE; 11533 } 11534 ASTOBJ_UNREF(p,sip_destroy_peer); 11535 } else { 11536 hp = ast_gethostbyname(host, &ahp); 11537 if (hp) 11538 res = AST_DEVICE_UNKNOWN; 11539 } 11540 11541 return res; 11542 }
|
|
sip_do_debug: Turn on SIP debugging (CLI command)
Definition at line 8753 of file chan_sip.c. References ast_cli(), debugaddr, RESULT_SHOWUSAGE, RESULT_SUCCESS, SIP_DEBUG_CONSOLE, sip_do_debug_ip(), sip_do_debug_peer(), and sipdebug. 08754 { 08755 int oldsipdebug = sipdebug & SIP_DEBUG_CONSOLE; 08756 if (argc != 2) { 08757 if (argc != 4) 08758 return RESULT_SHOWUSAGE; 08759 else if (strncmp(argv[2], "ip\0", 3) == 0) 08760 return sip_do_debug_ip(fd, argc, argv); 08761 else if (strncmp(argv[2], "peer\0", 5) == 0) 08762 return sip_do_debug_peer(fd, argc, argv); 08763 else return RESULT_SHOWUSAGE; 08764 } 08765 sipdebug |= SIP_DEBUG_CONSOLE; 08766 memset(&debugaddr, 0, sizeof(debugaddr)); 08767 if (oldsipdebug) 08768 ast_cli(fd, "SIP Debugging re-enabled\n"); 08769 else 08770 ast_cli(fd, "SIP Debugging enabled\n"); 08771 return RESULT_SUCCESS; 08772 }
|
|
sip_do_debug: Enable SIP Debugging in CLI ---
Definition at line 8697 of file chan_sip.c. References ahp, ast_cli(), ast_gethostbyname(), ast_inet_ntoa(), debugaddr, hp, RESULT_SHOWUSAGE, RESULT_SUCCESS, SIP_DEBUG_CONSOLE, and sipdebug. Referenced by sip_do_debug(). 08698 { 08699 struct hostent *hp; 08700 struct ast_hostent ahp; 08701 char iabuf[INET_ADDRSTRLEN]; 08702 int port = 0; 08703 char *p, *arg; 08704 08705 if (argc != 4) 08706 return RESULT_SHOWUSAGE; 08707 arg = argv[3]; 08708 p = strstr(arg, ":"); 08709 if (p) { 08710 *p = '\0'; 08711 p++; 08712 port = atoi(p); 08713 } 08714 hp = ast_gethostbyname(arg, &ahp); 08715 if (hp == NULL) { 08716 return RESULT_SHOWUSAGE; 08717 } 08718 debugaddr.sin_family = AF_INET; 08719 memcpy(&debugaddr.sin_addr, hp->h_addr, sizeof(debugaddr.sin_addr)); 08720 debugaddr.sin_port = htons(port); 08721 if (port == 0) 08722 ast_cli(fd, "SIP Debugging Enabled for IP: %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), debugaddr.sin_addr)); 08723 else 08724 ast_cli(fd, "SIP Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), debugaddr.sin_addr), port); 08725 sipdebug |= SIP_DEBUG_CONSOLE; 08726 return RESULT_SUCCESS; 08727 }
|
|
sip_do_debug_peer: Turn on SIP debugging with peer mask
Definition at line 8730 of file chan_sip.c. References sip_peer::addr, ast_cli(), ast_inet_ntoa(), ASTOBJ_UNREF, debugaddr, find_peer(), RESULT_SHOWUSAGE, RESULT_SUCCESS, SIP_DEBUG_CONSOLE, sip_destroy_peer(), and sipdebug. Referenced by sip_do_debug(). 08731 { 08732 struct sip_peer *peer; 08733 char iabuf[INET_ADDRSTRLEN]; 08734 if (argc != 4) 08735 return RESULT_SHOWUSAGE; 08736 peer = find_peer(argv[3], NULL, 1); 08737 if (peer) { 08738 if (peer->addr.sin_addr.s_addr) { 08739 debugaddr.sin_family = AF_INET; 08740 memcpy(&debugaddr.sin_addr, &peer->addr.sin_addr, sizeof(debugaddr.sin_addr)); 08741 debugaddr.sin_port = peer->addr.sin_port; 08742 ast_cli(fd, "SIP Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), debugaddr.sin_addr), ntohs(debugaddr.sin_port)); 08743 sipdebug |= SIP_DEBUG_CONSOLE; 08744 } else 08745 ast_cli(fd, "Unable to get IP address of peer '%s'\n", argv[3]); 08746 ASTOBJ_UNREF(peer,sip_destroy_peer); 08747 } else 08748 ast_cli(fd, "No such peer '%s'\n", argv[3]); 08749 return RESULT_SUCCESS; 08750 }
|
|
sip_do_history: Enable SIP History logging (CLI) ---
Definition at line 8832 of file chan_sip.c. References ast_cli(), recordhistory, RESULT_SHOWUSAGE, and RESULT_SUCCESS. 08833 { 08834 if (argc != 2) { 08835 return RESULT_SHOWUSAGE; 08836 } 08837 recordhistory = 1; 08838 ast_cli(fd, "SIP History Recording Enabled (use 'sip show history')\n"); 08839 return RESULT_SUCCESS; 08840 }
|
|
sip_do_reload: Reload module
Definition at line 13046 of file chan_sip.c. References ast_log(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, authl, clear_realm_authentication(), clear_sip_domains(), LOG_DEBUG, option_debug, regl, and sip_destroy(). Referenced by do_monitor(). 13047 { 13048 clear_realm_authentication(authl); 13049 clear_sip_domains(); 13050 authl = NULL; 13051 13052 /* First, destroy all outstanding registry calls */ 13053 /* This is needed, since otherwise active registry entries will not be destroyed */ 13054 ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { 13055 ASTOBJ_RDLOCK(iterator); 13056 if (iterator->call) { 13057 if (option_debug > 2) 13058 ast_log(LOG_DEBUG, "Destroying active SIP dialog for registry %s@%s\n", iterator->username, iterator->hostname); 13059 /* This will also remove references to the registry */ 13060 sip_destroy(iterator->call); 13061 } 13062 ASTOBJ_UNLOCK(iterator); 13063 } while(0)); 13064 13065 ASTOBJ_CONTAINER_DESTROYALL(&userl, sip_destroy_user); 13066 ASTOBJ_CONTAINER_DESTROYALL(®l, sip_registry_destroy); 13067 ASTOBJ_CONTAINER_MARKALL(&peerl); 13068 reload_config(); 13069 /* Prune peers who still are supposed to be deleted */ 13070 ASTOBJ_CONTAINER_PRUNE_MARKED(&peerl, sip_destroy_peer); 13071 13072 sip_poke_all_peers(); 13073 sip_send_all_registers(); 13074 13075 return 0; 13076 }
|
|
sip_dtmfmode: change the DTMFmode for a SIP call (application) ---
Definition at line 12801 of file chan_sip.c. References ast_clear_flag, ast_dsp_free(), ast_dsp_new(), ast_dsp_set_features(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_test_flag, channeltype, DSP_FEATURE_DTMF_DETECT, sip_pvt::lock, ast_channel::lock, LOG_WARNING, SIP_DTMF, SIP_DTMF_INBAND, SIP_DTMF_INFO, SIP_DTMF_RFC2833, ast_channel::tech_pvt, ast_channel::type, and sip_pvt::vad. Referenced by load_module(). 12802 { 12803 struct sip_pvt *p; 12804 char *mode; 12805 if (data) 12806 mode = (char *)data; 12807 else { 12808 ast_log(LOG_WARNING, "This application requires the argument: info, inband, rfc2833\n"); 12809 return 0; 12810 } 12811 ast_mutex_lock(&chan->lock); 12812 if (chan->type != channeltype) { 12813 ast_log(LOG_WARNING, "Call this application only on SIP incoming calls\n"); 12814 ast_mutex_unlock(&chan->lock); 12815 return 0; 12816 } 12817 p = chan->tech_pvt; 12818 if (!p) { 12819 ast_mutex_unlock(&chan->lock); 12820 return 0; 12821 } 12822 ast_mutex_lock(&p->lock); 12823 if (!strcasecmp(mode,"info")) { 12824 ast_clear_flag(p, SIP_DTMF); 12825 ast_set_flag(p, SIP_DTMF_INFO); 12826 } else if (!strcasecmp(mode,"rfc2833")) { 12827 ast_clear_flag(p, SIP_DTMF); 12828 ast_set_flag(p, SIP_DTMF_RFC2833); 12829 } else if (!strcasecmp(mode,"inband")) { 12830 ast_clear_flag(p, SIP_DTMF); 12831 ast_set_flag(p, SIP_DTMF_INBAND); 12832 } else 12833 ast_log(LOG_WARNING, "I don't know about this dtmf mode: %s\n",mode); 12834 if (ast_test_flag(p, SIP_DTMF) == SIP_DTMF_INBAND) { 12835 if (!p->vad) { 12836 p->vad = ast_dsp_new(); 12837 ast_dsp_set_features(p->vad, DSP_FEATURE_DTMF_DETECT); 12838 } 12839 } else { 12840 if (p->vad) { 12841 ast_dsp_free(p->vad); 12842 p->vad = NULL; 12843 } 12844 } 12845 ast_mutex_unlock(&p->lock); 12846 ast_mutex_unlock(&chan->lock); 12847 return 0; 12848 }
|
|
dump_history: Dump SIP history to debug log file at end of lifespan for SIP dialog
Definition at line 8578 of file chan_sip.c. References ast_log(), sip_pvt::callid, sip_history::event, sip_pvt::history, LOG_DEBUG, sip_history::next, and sip_pvt::subscribed. Referenced by __sip_destroy(). 08579 { 08580 int x; 08581 struct sip_history *hist; 08582 08583 if (!dialog) 08584 return; 08585 08586 ast_log(LOG_DEBUG, "\n---------- SIP HISTORY for '%s' \n", dialog->callid); 08587 if (dialog->subscribed) 08588 ast_log(LOG_DEBUG, " * Subscription\n"); 08589 else 08590 ast_log(LOG_DEBUG, " * SIP Call\n"); 08591 x = 0; 08592 hist = dialog->history; 08593 while(hist) { 08594 x++; 08595 ast_log(LOG_DEBUG, " %d. %s\n", x, hist->event); 08596 hist = hist->next; 08597 } 08598 if (!x) 08599 ast_log(LOG_DEBUG, "Call '%s' has no history\n", dialog->callid); 08600 ast_log(LOG_DEBUG, "\n---------- END SIP HISTORY for '%s' \n", dialog->callid); 08601 08602 }
|
|
sip_fixup: Fix up a channel: If a channel is consumed, this is called. Basically update any ->owner links ----
Definition at line 2588 of file chan_sip.c. References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), sip_pvt::lock, LOG_WARNING, sip_pvt::owner, and ast_channel::tech_pvt. 02589 { 02590 struct sip_pvt *p = newchan->tech_pvt; 02591 ast_mutex_lock(&p->lock); 02592 if (p->owner != oldchan) { 02593 ast_log(LOG_WARNING, "old channel wasn't %p but was %p\n", oldchan, p->owner); 02594 ast_mutex_unlock(&p->lock); 02595 return -1; 02596 } 02597 p->owner = newchan; 02598 ast_mutex_unlock(&p->lock); 02599 return 0; 02600 }
|
|
sip_get_codec: Return SIP UA's codec (part of the RTP interface) ---
Definition at line 12997 of file chan_sip.c. References sip_pvt::peercapability, and ast_channel::tech_pvt. 12998 { 12999 struct sip_pvt *p = chan->tech_pvt; 13000 return p->peercapability; 13001 }
|
|
sip_get_rtp_peer: Returns null if we can't reinvite (part of RTP interface)
Definition at line 12705 of file chan_sip.c. References ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, sip_pvt::lock, sip_pvt::rtp, SIP_CAN_REINVITE, and ast_channel::tech_pvt. 12706 { 12707 struct sip_pvt *p; 12708 struct ast_rtp *rtp = NULL; 12709 p = chan->tech_pvt; 12710 if (!p) 12711 return NULL; 12712 ast_mutex_lock(&p->lock); 12713 if (p->rtp && ast_test_flag(p, SIP_CAN_REINVITE)) 12714 rtp = p->rtp; 12715 ast_mutex_unlock(&p->lock); 12716 return rtp; 12717 }
|
|
sip_get_vrtp_peer: Returns null if we can't reinvite video (part of RTP interface)
Definition at line 12720 of file chan_sip.c. References ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, sip_pvt::lock, SIP_CAN_REINVITE, ast_channel::tech_pvt, and sip_pvt::vrtp. 12721 { 12722 struct sip_pvt *p; 12723 struct ast_rtp *rtp = NULL; 12724 p = chan->tech_pvt; 12725 if (!p) 12726 return NULL; 12727 12728 ast_mutex_lock(&p->lock); 12729 if (p->vrtp && ast_test_flag(p, SIP_CAN_REINVITE)) 12730 rtp = p->vrtp; 12731 ast_mutex_unlock(&p->lock); 12732 return rtp; 12733 }
|
|
sip_getheader: Get a SIP header (dialplan app) ---
Definition at line 12882 of file chan_sip.c. References ast_goto_if_exists(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_strdupa, ast_strlen_zero(), channeltype, ast_channel::context, dep_warning, ast_channel::exten, get_header(), sip_pvt::initreq, ast_channel::lock, LOG_DEBUG, LOG_WARNING, pbx_builtin_setvar_helper(), ast_channel::priority, strsep(), ast_channel::tech_pvt, and ast_channel::type. Referenced by load_module(). 12883 { 12884 static int dep_warning = 0; 12885 struct sip_pvt *p; 12886 char *argv, *varname = NULL, *header = NULL, *content; 12887 12888 if (!dep_warning) { 12889 ast_log(LOG_WARNING, "SIPGetHeader is deprecated, use the SIP_HEADER function instead.\n"); 12890 dep_warning = 1; 12891 } 12892 12893 argv = ast_strdupa(data); 12894 if (!argv) { 12895 ast_log(LOG_DEBUG, "Memory allocation failed\n"); 12896 return 0; 12897 } 12898 12899 if (strchr (argv, '=') ) { /* Pick out argumenet */ 12900 varname = strsep (&argv, "="); 12901 header = strsep (&argv, "\0"); 12902 } 12903 12904 if (!varname || !header) { 12905 ast_log(LOG_DEBUG, "SipGetHeader: Ignoring command, Syntax error in argument\n"); 12906 return 0; 12907 } 12908 12909 ast_mutex_lock(&chan->lock); 12910 if (chan->type != channeltype) { 12911 ast_log(LOG_WARNING, "Call this application only on incoming SIP calls\n"); 12912 ast_mutex_unlock(&chan->lock); 12913 return 0; 12914 } 12915 12916 p = chan->tech_pvt; 12917 content = get_header(&p->initreq, header); /* Get the header */ 12918 if (!ast_strlen_zero(content)) { 12919 pbx_builtin_setvar_helper(chan, varname, content); 12920 } else { 12921 ast_log(LOG_WARNING,"SIP Header %s not found for channel variable %s\n", header, varname); 12922 ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101); 12923 } 12924 12925 ast_mutex_unlock(&chan->lock); 12926 return 0; 12927 }
|
|
sip_hangup: Hangup SIP call Part of PBX interface, called from ast_hangup
Definition at line 2400 of file chan_sip.c. References __sip_pretend_ack(), ast_channel::_state, AST_CAUSE_NORMAL, ast_clear_flag, ast_copy_flags, ast_dsp_free(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_osp_terminate(), ast_set_flag, AST_STATE_UP, ast_strlen_zero(), ast_test_flag, ast_update_use_count(), sip_pvt::callid, sip_request::data, DEC_CALL_LIMIT, hangup_cause2sip(), ast_channel::hangupcause, INC_CALL_LIMIT, sip_pvt::initreq, sip_pvt::lock, LOG_DEBUG, LOG_WARNING, ast_channel::name, option_debug, sip_pvt::owner, sip_pvt::pendinginvite, SIP_ALREADYGONE, SIP_BYE, SIP_CANCEL, SIP_NEEDDESTROY, SIP_NEEDREINVITE, SIP_OUTGOING, SIP_PENDINGBYE, sip_scheddestroy(), ast_channel::tech_pvt, transmit_request_with_auth(), transmit_response_reliable(), update_call_counter(), usecnt_lock, sip_pvt::username, and sip_pvt::vad. 02401 { 02402 struct sip_pvt *p = ast->tech_pvt; 02403 int needcancel = 0; 02404 struct ast_flags locflags = {0}; 02405 02406 if (!p) { 02407 ast_log(LOG_DEBUG, "Asked to hangup channel not connected\n"); 02408 return 0; 02409 } 02410 if (option_debug) 02411 ast_log(LOG_DEBUG, "Hangup call %s, SIP callid %s)\n", ast->name, p->callid); 02412 02413 ast_mutex_lock(&p->lock); 02414 #ifdef OSP_SUPPORT 02415 if ((p->osphandle > -1) && (ast->_state == AST_STATE_UP)) { 02416 ast_osp_terminate(p->osphandle, AST_CAUSE_NORMAL, p->ospstart, time(NULL) - p->ospstart); 02417 } 02418 #endif 02419 ast_log(LOG_DEBUG, "update_call_counter(%s) - decrement call limit counter\n", p->username); 02420 update_call_counter(p, DEC_CALL_LIMIT); 02421 /* Determine how to disconnect */ 02422 if (p->owner != ast) { 02423 ast_log(LOG_WARNING, "Huh? We aren't the owner? Can't hangup call.\n"); 02424 ast_mutex_unlock(&p->lock); 02425 return 0; 02426 } 02427 /* If the call is not UP, we need to send CANCEL instead of BYE */ 02428 if (ast->_state != AST_STATE_UP) 02429 needcancel = 1; 02430 02431 /* Disconnect */ 02432 p = ast->tech_pvt; 02433 if (p->vad) { 02434 ast_dsp_free(p->vad); 02435 } 02436 p->owner = NULL; 02437 ast->tech_pvt = NULL; 02438 02439 ast_mutex_lock(&usecnt_lock); 02440 usecnt--; 02441 ast_mutex_unlock(&usecnt_lock); 02442 ast_update_use_count(); 02443 02444 ast_set_flag(&locflags, SIP_NEEDDESTROY); 02445 02446 /* Start the process if it's not already started */ 02447 if (!ast_test_flag(p, SIP_ALREADYGONE) && !ast_strlen_zero(p->initreq.data)) { 02448 if (needcancel) { /* Outgoing call, not up */ 02449 if (ast_test_flag(p, SIP_OUTGOING)) { 02450 /* stop retransmitting an INVITE that has not received a response */ 02451 __sip_pretend_ack(p); 02452 02453 /* Send a new request: CANCEL */ 02454 transmit_request_with_auth(p, SIP_CANCEL, p->ocseq, 1, 0); 02455 /* Actually don't destroy us yet, wait for the 487 on our original 02456 INVITE, but do set an autodestruct just in case we never get it. */ 02457 ast_clear_flag(&locflags, SIP_NEEDDESTROY); 02458 sip_scheddestroy(p, 32000); 02459 if ( p->initid != -1 ) { 02460 /* channel still up - reverse dec of inUse counter 02461 only if the channel is not auto-congested */ 02462 update_call_counter(p, INC_CALL_LIMIT); 02463 } 02464 } else { /* Incoming call, not up */ 02465 char *res; 02466 if (ast->hangupcause && ((res = hangup_cause2sip(ast->hangupcause)))) { 02467 transmit_response_reliable(p, res, &p->initreq, 1); 02468 } else 02469 transmit_response_reliable(p, "603 Declined", &p->initreq, 1); 02470 } 02471 } else { /* Call is in UP state, send BYE */ 02472 if (!p->pendinginvite) { 02473 /* Send a hangup */ 02474 transmit_request_with_auth(p, SIP_BYE, 0, 1, 1); 02475 } else { 02476 /* Note we will need a BYE when this all settles out 02477 but we can't send one while we have "INVITE" outstanding. */ 02478 ast_set_flag(p, SIP_PENDINGBYE); 02479 ast_clear_flag(p, SIP_NEEDREINVITE); 02480 } 02481 } 02482 } 02483 ast_copy_flags(p, (&locflags), SIP_NEEDDESTROY); 02484 ast_mutex_unlock(&p->lock); 02485 return 0; 02486 }
|
|
sip_indicate: 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 2645 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_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::callid, sip_pvt::initreq, sip_pvt::lock, LOG_DEBUG, 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(), and sip_pvt::vrtp. 02646 { 02647 struct sip_pvt *p = ast->tech_pvt; 02648 int res = 0; 02649 02650 ast_mutex_lock(&p->lock); 02651 switch(condition) { 02652 case AST_CONTROL_RINGING: 02653 if (ast->_state == AST_STATE_RING) { 02654 if (!ast_test_flag(p, SIP_PROGRESS_SENT) || 02655 (ast_test_flag(p, SIP_PROG_INBAND) == SIP_PROG_INBAND_NEVER)) { 02656 /* Send 180 ringing if out-of-band seems reasonable */ 02657 transmit_response(p, "180 Ringing", &p->initreq); 02658 ast_set_flag(p, SIP_RINGING); 02659 if (ast_test_flag(p, SIP_PROG_INBAND) != SIP_PROG_INBAND_YES) 02660 break; 02661 } else { 02662 /* Well, if it's not reasonable, just send in-band */ 02663 } 02664 } 02665 res = -1; 02666 break; 02667 case AST_CONTROL_BUSY: 02668 if (ast->_state != AST_STATE_UP) { 02669 transmit_response(p, "486 Busy Here", &p->initreq); 02670 ast_set_flag(p, SIP_ALREADYGONE); 02671 ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV); 02672 break; 02673 } 02674 res = -1; 02675 break; 02676 case AST_CONTROL_CONGESTION: 02677 if (ast->_state != AST_STATE_UP) { 02678 transmit_response(p, "503 Service Unavailable", &p->initreq); 02679 ast_set_flag(p, SIP_ALREADYGONE); 02680 ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV); 02681 break; 02682 } 02683 res = -1; 02684 break; 02685 case AST_CONTROL_PROCEEDING: 02686 if ((ast->_state != AST_STATE_UP) && !ast_test_flag(p, SIP_PROGRESS_SENT) && !ast_test_flag(p, SIP_OUTGOING)) { 02687 transmit_response(p, "100 Trying", &p->initreq); 02688 break; 02689 } 02690 res = -1; 02691 break; 02692 case AST_CONTROL_PROGRESS: 02693 if ((ast->_state != AST_STATE_UP) && !ast_test_flag(p, SIP_PROGRESS_SENT) && !ast_test_flag(p, SIP_OUTGOING)) { 02694 transmit_response_with_sdp(p, "183 Session Progress", &p->initreq, 0); 02695 ast_set_flag(p, SIP_PROGRESS_SENT); 02696 break; 02697 } 02698 res = -1; 02699 break; 02700 case AST_CONTROL_HOLD: /* The other part of the bridge are put on hold */ 02701 if (sipdebug) 02702 ast_log(LOG_DEBUG, "Bridged channel now on hold%s\n", p->callid); 02703 res = -1; 02704 break; 02705 case AST_CONTROL_UNHOLD: /* The other part of the bridge are back from hold */ 02706 if (sipdebug) 02707 ast_log(LOG_DEBUG, "Bridged channel is back from hold, let's talk! : %s\n", p->callid); 02708 res = -1; 02709 break; 02710 case AST_CONTROL_VIDUPDATE: /* Request a video frame update */ 02711 if (p->vrtp && !ast_test_flag(p, SIP_NOVIDEO)) { 02712 transmit_info_with_vidupdate(p); 02713 res = 0; 02714 } else 02715 res = -1; 02716 break; 02717 case -1: 02718 res = -1; 02719 break; 02720 default: 02721 ast_log(LOG_WARNING, "Don't know how to indicate condition %d\n", condition); 02722 res = -1; 02723 break; 02724 } 02725 ast_mutex_unlock(&p->lock); 02726 return res; 02727 }
|
|
sip_new: Initiate a call in the SIP channel
Definition at line 2733 of file chan_sip.c. References ast_channel::accountcode, ast_channel::adsicpe, ast_channel::amaflags, AST_ADSI_UNAVAILABLE, ast_best_codec(), ast_channel_alloc(), ast_codec_choose(), ast_dsp_digitmode(), ast_dsp_new(), ast_dsp_set_features(), ast_hangup(), ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_pbx_start(), ast_rtcp_fd(), ast_rtp_fd(), ast_setstate(), AST_STATE_DOWN, AST_STATE_RING, ast_strlen_zero(), ast_test_flag, ast_channel::callgroup, sip_pvt::capability, ast_channel::cid, 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, fmt, sip_pvt::fromdomain, sip_pvt::jointcapability, ast_channel::language, sip_pvt::lock, LOG_WARNING, ast_channel::musicclass, ast_variable::name, ast_channel::name, ast_channel::nativeformats, ast_variable::next, pbx_builtin_setvar_helper(), ast_channel::pickupgroup, sip_pvt::prefs, ast_channel::priority, ast_channel::rawreadformat, ast_channel::rawwriteformat, ast_channel::readformat, ast_channel::rings, SIP_DTMF, SIP_DTMF_INBAND, sip_tech, strdup, ast_channel::tech, ast_channel::tech_pvt, thread_safe_rand(), ast_channel::type, usecnt_lock, ast_variable::value, and ast_channel::writeformat. Referenced by handle_request_invite(), and sip_request_call(). 02734 { 02735 struct ast_channel *tmp; 02736 struct ast_variable *v = NULL; 02737 int fmt; 02738 #ifdef OSP_SUPPORT 02739 char iabuf[INET_ADDRSTRLEN]; 02740 char peer[MAXHOSTNAMELEN]; 02741 #endif 02742 02743 ast_mutex_unlock(&i->lock); 02744 /* Don't hold a sip pvt lock while we allocate a channel */ 02745 tmp = ast_channel_alloc(1); 02746 ast_mutex_lock(&i->lock); 02747 if (!tmp) { 02748 ast_log(LOG_WARNING, "Unable to allocate SIP channel structure\n"); 02749 return NULL; 02750 } 02751 tmp->tech = &sip_tech; 02752 /* Select our native format based on codec preference until we receive 02753 something from another device to the contrary. */ 02754 if (i->jointcapability) 02755 tmp->nativeformats = ast_codec_choose(&i->prefs, i->jointcapability, 1); 02756 else if (i->capability) 02757 tmp->nativeformats = ast_codec_choose(&i->prefs, i->capability, 1); 02758 else 02759 tmp->nativeformats = ast_codec_choose(&i->prefs, global_capability, 1); 02760 fmt = ast_best_codec(tmp->nativeformats); 02761 02762 if (title) 02763 snprintf(tmp->name, sizeof(tmp->name), "SIP/%s-%04x", title, thread_safe_rand() & 0xffff); 02764 else if (strchr(i->fromdomain,':')) 02765 snprintf(tmp->name, sizeof(tmp->name), "SIP/%s-%08x", strchr(i->fromdomain,':')+1, (int)(long)(i)); 02766 else 02767 snprintf(tmp->name, sizeof(tmp->name), "SIP/%s-%08x", i->fromdomain, (int)(long)(i)); 02768 02769 tmp->type = channeltype; 02770 if (ast_test_flag(i, SIP_DTMF) == SIP_DTMF_INBAND) { 02771 i->vad = ast_dsp_new(); 02772 ast_dsp_set_features(i->vad, DSP_FEATURE_DTMF_DETECT); 02773 if (relaxdtmf) 02774 ast_dsp_digitmode(i->vad, DSP_DIGITMODE_DTMF | DSP_DIGITMODE_RELAXDTMF); 02775 } 02776 if (i->rtp) { 02777 tmp->fds[0] = ast_rtp_fd(i->rtp); 02778 tmp->fds[1] = ast_rtcp_fd(i->rtp); 02779 } 02780 if (i->vrtp) { 02781 tmp->fds[2] = ast_rtp_fd(i->vrtp); 02782 tmp->fds[3] = ast_rtcp_fd(i->vrtp); 02783 } 02784 if (state == AST_STATE_RING) 02785 tmp->rings = 1; 02786 tmp->adsicpe = AST_ADSI_UNAVAILABLE; 02787 tmp->writeformat = fmt; 02788 tmp->rawwriteformat = fmt; 02789 tmp->readformat = fmt; 02790 tmp->rawreadformat = fmt; 02791 tmp->tech_pvt = i; 02792 02793 tmp->callgroup = i->callgroup; 02794 tmp->pickupgroup = i->pickupgroup; 02795 tmp->cid.cid_pres = i->callingpres; 02796 if (!ast_strlen_zero(i->accountcode)) 02797 ast_copy_string(tmp->accountcode, i->accountcode, sizeof(tmp->accountcode)); 02798 if (i->amaflags) 02799 tmp->amaflags = i->amaflags; 02800 if (!ast_strlen_zero(i->language)) 02801 ast_copy_string(tmp->language, i->language, sizeof(tmp->language)); 02802 if (!ast_strlen_zero(i->musicclass)) 02803 ast_copy_string(tmp->musicclass, i->musicclass, sizeof(tmp->musicclass)); 02804 i->owner = tmp; 02805 ast_mutex_lock(&usecnt_lock); 02806 usecnt++; 02807 ast_mutex_unlock(&usecnt_lock); 02808 ast_copy_string(tmp->context, i->context, sizeof(tmp->context)); 02809 ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten)); 02810 if (!ast_strlen_zero(i->cid_num)) 02811 tmp->cid.cid_num = strdup(i->cid_num); 02812 if (!ast_strlen_zero(i->cid_name)) 02813 tmp->cid.cid_name = strdup(i->cid_name); 02814 if (!ast_strlen_zero(i->rdnis)) 02815 tmp->cid.cid_rdnis = strdup(i->rdnis); 02816 if (!ast_strlen_zero(i->exten) && strcmp(i->exten, "s")) 02817 tmp->cid.cid_dnid = strdup(i->exten); 02818 tmp->priority = 1; 02819 if (!ast_strlen_zero(i->uri)) { 02820 pbx_builtin_setvar_helper(tmp, "SIPURI", i->uri); 02821 } 02822 if (!ast_strlen_zero(i->domain)) { 02823 pbx_builtin_setvar_helper(tmp, "SIPDOMAIN", i->domain); 02824 } 02825 if (!ast_strlen_zero(i->useragent)) { 02826 pbx_builtin_setvar_helper(tmp, "SIPUSERAGENT", i->useragent); 02827 } 02828 if (!ast_strlen_zero(i->callid)) { 02829 pbx_builtin_setvar_helper(tmp, "SIPCALLID", i->callid); 02830 } 02831 #ifdef OSP_SUPPORT 02832 snprintf(peer, sizeof(peer), "[%s]:%d", ast_inet_ntoa(iabuf, sizeof(iabuf), i->sa.sin_addr), ntohs(i->sa.sin_port)); 02833 pbx_builtin_setvar_helper(tmp, "OSPPEER", peer); 02834 #endif 02835 ast_setstate(tmp, state); 02836 if (state != AST_STATE_DOWN) { 02837 if (ast_pbx_start(tmp)) { 02838 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name); 02839 ast_hangup(tmp); 02840 tmp = NULL; 02841 } 02842 } 02843 /* Set channel variables for this call from configuration */ 02844 for (v = i->chanvars ; v ; v = v->next) 02845 pbx_builtin_setvar_helper(tmp,v->name,v->value); 02846 02847 return tmp; 02848 }
|
|
sip_no_debug: Disable SIP Debugging in CLI ---
Definition at line 8854 of file chan_sip.c. References ast_cli(), RESULT_SHOWUSAGE, RESULT_SUCCESS, SIP_DEBUG_CONSOLE, and sipdebug. 08856 { 08857 if (argc != 3) 08858 return RESULT_SHOWUSAGE; 08859 sipdebug &= ~SIP_DEBUG_CONSOLE; 08860 ast_cli(fd, "SIP Debugging Disabled\n"); 08861 return RESULT_SUCCESS; 08862 }
|
|
sip_no_history: Disable SIP History logging (CLI) ---
Definition at line 8843 of file chan_sip.c. References ast_cli(), recordhistory, RESULT_SHOWUSAGE, and RESULT_SUCCESS. 08844 { 08845 if (argc != 3) { 08846 return RESULT_SHOWUSAGE; 08847 } 08848 recordhistory = 0; 08849 ast_cli(fd, "SIP History Recording Disabled\n"); 08850 return RESULT_SUCCESS; 08851 }
|
|
sip_notify: Send SIP notify to peer
Definition at line 8775 of file chan_sip.c. References __ourip, add_blank_header(), add_header(), ast_cli(), ast_log(), ast_sip_ouraddrfor(), ast_variable_browse(), build_callid(), build_via(), create_addr(), initreqprep(), LOG_WARNING, notify_config, notify_types, sip_pvt::ourip, RESULT_FAILURE, RESULT_SHOWUSAGE, sip_pvt::sa, sip_alloc(), sip_destroy(), SIP_NOTIFY, sip_scheddestroy(), transmit_sip_request(), var, and sip_pvt::via. 08776 { 08777 struct ast_variable *varlist; 08778 int i; 08779 08780 if (argc < 4) 08781 return RESULT_SHOWUSAGE; 08782 08783 if (!notify_types) { 08784 ast_cli(fd, "No %s file found, or no types listed there\n", notify_config); 08785 return RESULT_FAILURE; 08786 } 08787 08788 varlist = ast_variable_browse(notify_types, argv[2]); 08789 08790 if (!varlist) { 08791 ast_cli(fd, "Unable to find notify type '%s'\n", argv[2]); 08792 return RESULT_FAILURE; 08793 } 08794 08795 for (i = 3; i < argc; i++) { 08796 struct sip_pvt *p; 08797 struct sip_request req; 08798 struct ast_variable *var; 08799 08800 p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY); 08801 if (!p) { 08802 ast_log(LOG_WARNING, "Unable to build sip pvt data for notify\n"); 08803 return RESULT_FAILURE; 08804 } 08805 08806 if (create_addr(p, argv[i])) { 08807 /* Maybe they're not registered, etc. */ 08808 sip_destroy(p); 08809 ast_cli(fd, "Could not create address for '%s'\n", argv[i]); 08810 continue; 08811 } 08812 08813 initreqprep(&req, p, SIP_NOTIFY); 08814 08815 for (var = varlist; var; var = var->next) 08816 add_header(&req, var->name, var->value); 08817 08818 add_blank_header(&req); 08819 /* Recalculate our side, and recalculate Call ID */ 08820 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 08821 memcpy(&p->ourip, &__ourip, sizeof(p->ourip)); 08822 build_via(p, p->via, sizeof(p->via)); 08823 build_callid(p->callid, sizeof(p->callid), p->ourip, p->fromdomain); 08824 ast_cli(fd, "Sending NOTIFY of type '%s' to '%s'\n", argv[2], argv[i]); 08825 transmit_sip_request(p, &req); 08826 sip_scheddestroy(p, 15000); 08827 } 08828 08829 return RESULT_SUCCESS; 08830 }
|
|
sip_park: Park a call ---
Definition at line 10072 of file chan_sip.c. References ast_channel_alloc(), ast_channel_masquerade(), ast_do_masquerade(), ast_hangup(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_pthread_create, ast_channel::context, copy_request(), ast_channel::exten, free, ast_channel::lock, LOG_WARNING, malloc, ast_channel::name, ast_channel::priority, ast_channel::readformat, sip_park_thread(), and ast_channel::writeformat. Referenced by handle_request_refer(). 10073 { 10074 struct sip_dual *d; 10075 struct ast_channel *chan1m, *chan2m; 10076 pthread_t th; 10077 chan1m = ast_channel_alloc(0); 10078 chan2m = ast_channel_alloc(0); 10079 if ((!chan2m) || (!chan1m)) { 10080 if (chan1m) 10081 ast_hangup(chan1m); 10082 if (chan2m) 10083 ast_hangup(chan2m); 10084 return -1; 10085 } 10086 snprintf(chan1m->name, sizeof(chan1m->name), "Parking/%s", chan1->name); 10087 /* Make formats okay */ 10088 chan1m->readformat = chan1->readformat; 10089 chan1m->writeformat = chan1->writeformat; 10090 ast_channel_masquerade(chan1m, chan1); 10091 /* Setup the extensions and such */ 10092 ast_copy_string(chan1m->context, chan1->context, sizeof(chan1m->context)); 10093 ast_copy_string(chan1m->exten, chan1->exten, sizeof(chan1m->exten)); 10094 chan1m->priority = chan1->priority; 10095 10096 /* We make a clone of the peer channel too, so we can play 10097 back the announcement */ 10098 snprintf(chan2m->name, sizeof (chan2m->name), "SIPPeer/%s",chan2->name); 10099 /* Make formats okay */ 10100 chan2m->readformat = chan2->readformat; 10101 chan2m->writeformat = chan2->writeformat; 10102 ast_channel_masquerade(chan2m, chan2); 10103 /* Setup the extensions and such */ 10104 ast_copy_string(chan2m->context, chan2->context, sizeof(chan2m->context)); 10105 ast_copy_string(chan2m->exten, chan2->exten, sizeof(chan2m->exten)); 10106 chan2m->priority = chan2->priority; 10107 ast_mutex_lock(&chan2m->lock); 10108 if (ast_do_masquerade(chan2m)) { 10109 ast_log(LOG_WARNING, "Masquerade failed :(\n"); 10110 ast_mutex_unlock(&chan2m->lock); 10111 ast_hangup(chan2m); 10112 return -1; 10113 } 10114 ast_mutex_unlock(&chan2m->lock); 10115 d = malloc(sizeof(struct sip_dual)); 10116 if (d) { 10117 memset(d, 0, sizeof(*d)); 10118 /* Save original request for followup */ 10119 copy_request(&d->req, req); 10120 d->chan1 = chan1m; 10121 d->chan2 = chan2m; 10122 if (!ast_pthread_create(&th, NULL, sip_park_thread, d)) 10123 return 0; 10124 free(d); 10125 } 10126 return -1; 10127 }
|
|
sip_park_thread: Park SIP call support function
Definition at line 10049 of file chan_sip.c. References ast_do_masquerade(), ast_hangup(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_park_call(), sip_dual::chan1, sip_dual::chan2, copy_request(), free, ast_channel::lock, LOG_DEBUG, and sip_dual::req. Referenced by sip_park(). 10050 { 10051 struct ast_channel *chan1, *chan2; 10052 struct sip_dual *d; 10053 struct sip_request req; 10054 int ext; 10055 int res; 10056 d = stuff; 10057 chan1 = d->chan1; 10058 chan2 = d->chan2; 10059 copy_request(&req, &d->req); 10060 free(d); 10061 ast_mutex_lock(&chan1->lock); 10062 ast_do_masquerade(chan1); 10063 ast_mutex_unlock(&chan1->lock); 10064 res = ast_park_call(chan1, chan2, 0, &ext); 10065 /* Then hangup */ 10066 ast_hangup(chan2); 10067 ast_log(LOG_DEBUG, "Parked on extension '%d'\n", ext); 10068 return NULL; 10069 }
|
|
sip_poke_all_peers: Send a poke to all known peers
Definition at line 13013 of file chan_sip.c. References ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_UNLOCK, ASTOBJ_WRLOCK, peerl, and sip_poke_peer(). Referenced by load_module(). 13014 { 13015 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 13016 ASTOBJ_WRLOCK(iterator); 13017 sip_poke_peer(iterator); 13018 ASTOBJ_UNLOCK(iterator); 13019 } while (0) 13020 ); 13021 }
|
|
sip_poke_noanswer: No answer to Qualify poke ---
Definition at line 11398 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, sip_destroy(), and sip_poke_peer_s(). Referenced by sip_poke_peer(). 11399 { 11400 struct sip_peer *peer = data; 11401 11402 peer->pokeexpire = -1; 11403 if (peer->lastms > -1) { 11404 ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Last qualify: %d\n", peer->name, peer->lastms); 11405 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, -1); 11406 } 11407 if (peer->call) 11408 sip_destroy(peer->call); 11409 peer->call = NULL; 11410 peer->lastms = -1; 11411 ast_device_state_changed("SIP/%s", peer->name); 11412 /* Try again quickly */ 11413 peer->pokeexpire = ast_sched_add(sched, DEFAULT_FREQ_NOTOK, sip_poke_peer_s, peer); 11414 return 0; 11415 }
|
|
sip_poke_peer: Check availability of peer, also keep NAT open ---
Definition at line 11420 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_strlen_zero(), build_callid(), build_via(), sip_peer::call, sip_pvt::callid, DEFAULT_MAXMS, sip_pvt::fromdomain, sip_pvt::fullcontact, sip_peer::fullcontact, sip_peer::lastms, LOG_NOTICE, LOG_WARNING, sip_peer::maxms, sip_pvt::ourip, sip_pvt::peerpoke, sip_peer::pokeexpire, sip_peer::ps, sip_pvt::recv, sip_pvt::sa, sip_alloc(), sip_destroy(), SIP_FLAGS_TO_COPY, SIP_INVITE, SIP_OPTIONS, SIP_OUTGOING, sip_poke_noanswer(), sipdebug, sip_pvt::tohost, sip_peer::tohost, transmit_invite(), sip_pvt::username, and sip_pvt::via. Referenced by parse_register_contact(), reg_source_db(), sip_poke_all_peers(), and sip_poke_peer_s(). 11421 { 11422 struct sip_pvt *p; 11423 if (!peer->maxms || !peer->addr.sin_addr.s_addr) { 11424 /* IF we have no IP, or this isn't to be monitored, return 11425 imeediately after clearing things out */ 11426 if (peer->pokeexpire > -1) 11427 ast_sched_del(sched, peer->pokeexpire); 11428 peer->lastms = 0; 11429 peer->pokeexpire = -1; 11430 peer->call = NULL; 11431 return 0; 11432 } 11433 if (peer->call > 0) { 11434 if (sipdebug) 11435 ast_log(LOG_NOTICE, "Still have a QUALIFY dialog active, deleting\n"); 11436 sip_destroy(peer->call); 11437 } 11438 p = peer->call = sip_alloc(NULL, NULL, 0, SIP_OPTIONS); 11439 if (!peer->call) { 11440 ast_log(LOG_WARNING, "Unable to allocate dialog for poking peer '%s'\n", peer->name); 11441 return -1; 11442 } 11443 memcpy(&p->sa, &peer->addr, sizeof(p->sa)); 11444 memcpy(&p->recv, &peer->addr, sizeof(p->sa)); 11445 ast_copy_flags(p, peer, SIP_FLAGS_TO_COPY); 11446 11447 /* Send OPTIONs to peer's fullcontact */ 11448 if (!ast_strlen_zero(peer->fullcontact)) { 11449 ast_copy_string (p->fullcontact, peer->fullcontact, sizeof(p->fullcontact)); 11450 } 11451 11452 if (!ast_strlen_zero(peer->tohost)) 11453 ast_copy_string(p->tohost, peer->tohost, sizeof(p->tohost)); 11454 else 11455 ast_inet_ntoa(p->tohost, sizeof(p->tohost), peer->addr.sin_addr); 11456 11457 /* Recalculate our side, and recalculate Call ID */ 11458 if (ast_sip_ouraddrfor(&p->sa.sin_addr,&p->ourip)) 11459 memcpy(&p->ourip, &__ourip, sizeof(p->ourip)); 11460 build_via(p, p->via, sizeof(p->via)); 11461 build_callid(p->callid, sizeof(p->callid), p->ourip, p->fromdomain); 11462 11463 if (peer->pokeexpire > -1) 11464 ast_sched_del(sched, peer->pokeexpire); 11465 p->peerpoke = peer; 11466 ast_set_flag(p, SIP_OUTGOING); 11467 #ifdef VOCAL_DATA_HACK 11468 ast_copy_string(p->username, "__VOCAL_DATA_SHOULD_READ_THE_SIP_SPEC__", sizeof(p->username)); 11469 transmit_invite(p, SIP_INVITE, 0, 2); 11470 #else 11471 transmit_invite(p, SIP_OPTIONS, 0, 2); 11472 #endif 11473 gettimeofday(&peer->ps, NULL); 11474 peer->pokeexpire = ast_sched_add(sched, DEFAULT_MAXMS * 2, sip_poke_noanswer, peer); 11475 11476 return 0; 11477 }
|
|
Definition at line 5661 of file chan_sip.c. References sip_peer::pokeexpire, and sip_poke_peer(). Referenced by handle_response_peerpoke(), reg_source_db(), and sip_poke_noanswer(). 05662 { 05663 struct sip_peer *peer = data; 05664 peer->pokeexpire = -1; 05665 sip_poke_peer(peer); 05666 return 0; 05667 }
|
|
sip_prune_realtime: Remove temporary realtime objects from memory (CLI) ---
Definition at line 7648 of file chan_sip.c. References ast_test_flag, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_CONTAINER_WRLOCK, ASTOBJ_MARK, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, name, peerl, RESULT_SHOWUSAGE, SIP_PAGE2_RTCACHEFRIENDS, and user. 07649 { 07650 struct sip_peer *peer; 07651 struct sip_user *user; 07652 int pruneuser = 0; 07653 int prunepeer = 0; 07654 int multi = 0; 07655 char *name = NULL; 07656 regex_t regexbuf; 07657 07658 switch (argc) { 07659 case 4: 07660 if (!strcasecmp(argv[3], "user")) 07661 return RESULT_SHOWUSAGE; 07662 if (!strcasecmp(argv[3], "peer")) 07663 return RESULT_SHOWUSAGE; 07664 if (!strcasecmp(argv[3], "like")) 07665 return RESULT_SHOWUSAGE; 07666 if (!strcasecmp(argv[3], "all")) { 07667 multi = 1; 07668 pruneuser = prunepeer = 1; 07669 } else { 07670 pruneuser = prunepeer = 1; 07671 name = argv[3]; 07672 } 07673 break; 07674 case 5: 07675 if (!strcasecmp(argv[4], "like")) 07676 return RESULT_SHOWUSAGE; 07677 if (!strcasecmp(argv[3], "all")) 07678 return RESULT_SHOWUSAGE; 07679 if (!strcasecmp(argv[3], "like")) { 07680 multi = 1; 07681 name = argv[4]; 07682 pruneuser = prunepeer = 1; 07683 } else if (!strcasecmp(argv[3], "user")) { 07684 pruneuser = 1; 07685 if (!strcasecmp(argv[4], "all")) 07686 multi = 1; 07687 else 07688 name = argv[4]; 07689 } else if (!strcasecmp(argv[3], "peer")) { 07690 prunepeer = 1; 07691 if (!strcasecmp(argv[4], "all")) 07692 multi = 1; 07693 else 07694 name = argv[4]; 07695 } else 07696 return RESULT_SHOWUSAGE; 07697 break; 07698 case 6: 07699 if (strcasecmp(argv[4], "like")) 07700 return RESULT_SHOWUSAGE; 07701 if (!strcasecmp(argv[3], "user")) { 07702 pruneuser = 1; 07703 name = argv[5]; 07704 } else if (!strcasecmp(argv[3], "peer")) { 07705 prunepeer = 1; 07706 name = argv[5]; 07707 } else 07708 return RESULT_SHOWUSAGE; 07709 break; 07710 default: 07711 return RESULT_SHOWUSAGE; 07712 } 07713 07714 if (multi && name) { 07715 if (regcomp(®exbuf, name, REG_EXTENDED | REG_NOSUB)) 07716 return RESULT_SHOWUSAGE; 07717 } 07718 07719 if (multi) { 07720 if (prunepeer) { 07721 int pruned = 0; 07722 07723 ASTOBJ_CONTAINER_WRLOCK(&peerl); 07724 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 07725 ASTOBJ_RDLOCK(iterator); 07726 if (name && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 07727 ASTOBJ_UNLOCK(iterator); 07728 continue; 07729 }; 07730 if (ast_test_flag((&iterator->flags_page2), SIP_PAGE2_RTCACHEFRIENDS)) { 07731 ASTOBJ_MARK(iterator); 07732 pruned++; 07733 } 07734 ASTOBJ_UNLOCK(iterator); 07735 } while (0) ); 07736 if (pruned) { 07737 ASTOBJ_CONTAINER_PRUNE_MARKED(&peerl, sip_destroy_peer); 07738 ast_cli(fd, "%d peers pruned.\n", pruned); 07739 } else 07740 ast_cli(fd, "No peers found to prune.\n"); 07741 ASTOBJ_CONTAINER_UNLOCK(&peerl); 07742 } 07743 if (pruneuser) { 07744 int pruned = 0; 07745 07746 ASTOBJ_CONTAINER_WRLOCK(&userl); 07747 ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do { 07748 ASTOBJ_RDLOCK(iterator); 07749 if (name && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 07750 ASTOBJ_UNLOCK(iterator); 07751 continue; 07752 }; 07753 if (ast_test_flag((&iterator->flags_page2), SIP_PAGE2_RTCACHEFRIENDS)) { 07754 ASTOBJ_MARK(iterator); 07755 pruned++; 07756 } 07757 ASTOBJ_UNLOCK(iterator); 07758 } while (0) ); 07759 if (pruned) { 07760 ASTOBJ_CONTAINER_PRUNE_MARKED(&userl, sip_destroy_user); 07761 ast_cli(fd, "%d users pruned.\n", pruned); 07762 } else 07763 ast_cli(fd, "No users found to prune.\n"); 07764 ASTOBJ_CONTAINER_UNLOCK(&userl); 07765 } 07766 } else { 07767 if (prunepeer) { 07768 if ((peer = ASTOBJ_CONTAINER_FIND_UNLINK(&peerl, name))) { 07769 if (!ast_test_flag((&peer->flags_page2), SIP_PAGE2_RTCACHEFRIENDS)) { 07770 ast_cli(fd, "Peer '%s' is not a Realtime peer, cannot be pruned.\n", name); 07771 ASTOBJ_CONTAINER_LINK(&peerl, peer); 07772 } else 07773 ast_cli(fd, "Peer '%s' pruned.\n", name); 07774 ASTOBJ_UNREF(peer, sip_destroy_peer); 07775 } else 07776 ast_cli(fd, "Peer '%s' not found.\n", name); 07777 } 07778 if (pruneuser) { 07779 if ((user = ASTOBJ_CONTAINER_FIND_UNLINK(&userl, name))) { 07780 if (!ast_test_flag((&user->flags_page2), SIP_PAGE2_RTCACHEFRIENDS)) { 07781 ast_cli(fd, "User '%s' is not a Realtime user, cannot be pruned.\n", name); 07782 ASTOBJ_CONTAINER_LINK(&userl, user); 07783 } else 07784 ast_cli(fd, "User '%s' pruned.\n", name); 07785 ASTOBJ_UNREF(user, sip_destroy_user); 07786 } else 07787 ast_cli(fd, "User '%s' not found.\n", name); 07788 } 07789 } 07790 07791 return RESULT_SUCCESS; 07792 }
|
|
sip_read: Read SIP RTP from channel
Definition at line 2997 of file chan_sip.c. References ast_mutex_lock(), ast_mutex_unlock(), sip_pvt::lastrtprx, sip_pvt::lock, sip_rtp_read(), and ast_channel::tech_pvt. 02998 { 02999 struct ast_frame *fr; 03000 struct sip_pvt *p = ast->tech_pvt; 03001 ast_mutex_lock(&p->lock); 03002 fr = sip_rtp_read(ast, p); 03003 time(&p->lastrtprx); 03004 ast_mutex_unlock(&p->lock); 03005 return fr; 03006 }
|
|
sip_reg_timeout: Registration timeout, register again
Definition at line 5279 of file chan_sip.c. References __sip_pretend_ack(), ast_log(), ast_set_flag, ASTOBJ_REF, ASTOBJ_UNREF, sip_registry::call, EVENT_FLAG_SYSTEM, global_regattempts_max, sip_registry::hostname, LOG_NOTICE, manager_event(), REG_STATE_FAILED, REG_STATE_UNREGISTERED, sip_registry::regattempts, sip_pvt::registry, sip_registry::regstate, regstate2str(), SIP_NEEDDESTROY, SIP_REGISTER, sip_registry_destroy(), sip_registry::timeout, transmit_register(), and sip_registry::username. Referenced by transmit_register(). 05280 { 05281 05282 /* if we are here, our registration timed out, so we'll just do it over */ 05283 struct sip_registry *r = ASTOBJ_REF((struct sip_registry *) data); 05284 struct sip_pvt *p; 05285 int res; 05286 05287 /* if we couldn't get a reference to the registry object, punt */ 05288 if (!r) 05289 return 0; 05290 05291 ast_log(LOG_NOTICE, " -- Registration for '%s@%s' timed out, trying again (Attempt #%d)\n", r->username, r->hostname, r->regattempts); 05292 if (r->call) { 05293 /* Unlink us, destroy old call. Locking is not relevant here because all this happens 05294 in the single SIP manager thread. */ 05295 p = r->call; 05296 if (p->registry) 05297 ASTOBJ_UNREF(p->registry, sip_registry_destroy); 05298 r->call = NULL; 05299 ast_set_flag(p, SIP_NEEDDESTROY); 05300 /* Pretend to ACK anything just in case */ 05301 __sip_pretend_ack(p); 05302 } 05303 /* If we have a limit, stop registration and give up */ 05304 if (global_regattempts_max && (r->regattempts > global_regattempts_max)) { 05305 /* Ok, enough is enough. Don't try any more */ 05306 /* We could add an external notification here... 05307 steal it from app_voicemail :-) */ 05308 ast_log(LOG_NOTICE, " -- Giving up forever trying to register '%s@%s'\n", r->username, r->hostname); 05309 r->regstate=REG_STATE_FAILED; 05310 } else { 05311 r->regstate=REG_STATE_UNREGISTERED; 05312 r->timeout = -1; 05313 res=transmit_register(r, SIP_REGISTER, NULL, NULL); 05314 } 05315 manager_event(EVENT_FLAG_SYSTEM, "Registry", "Channel: SIP\r\nUsername: %s\r\nDomain: %s\r\nStatus: %s\r\n", r->username, r->hostname, regstate2str(r->regstate)); 05316 ASTOBJ_UNREF(r,sip_registry_destroy); 05317 return 0; 05318 }
|
|
sip_register: Parse register=> line in sip.conf and add to registry
Definition at line 3202 of file chan_sip.c. References ast_log(), ast_strlen_zero(), ASTOBJ_CONTAINER_LINK, ASTOBJ_INIT, ASTOBJ_UNREF, sip_registry::authuser, sip_registry::callid_valid, sip_registry::contact, copy(), default_expiry, sip_registry::expire, sip_registry::hostname, hostname, LOG_ERROR, LOG_WARNING, malloc, sip_registry::ocseq, sip_registry::portno, sip_registry::refresh, regl, regobjs, sip_registry::secret, secret, sip_registry_destroy(), strsep(), sip_registry::timeout, sip_registry::username, and username. Referenced by reload_config(). 03203 { 03204 struct sip_registry *reg; 03205 char copy[256]; 03206 char *username=NULL, *hostname=NULL, *secret=NULL, *authuser=NULL; 03207 char *porta=NULL; 03208 char *contact=NULL; 03209 char *stringp=NULL; 03210 03211 if (!value) 03212 return -1; 03213 ast_copy_string(copy, value, sizeof(copy)); 03214 stringp=copy; 03215 username = stringp; 03216 hostname = strrchr(stringp, '@'); 03217 if (hostname) { 03218 *hostname = '\0'; 03219 hostname++; 03220 } 03221 if (ast_strlen_zero(username) || ast_strlen_zero(hostname)) { 03222 ast_log(LOG_WARNING, "Format for registration is user[:secret[:authuser]]@host[:port][/contact] at line %d\n", lineno); 03223 return -1; 03224 } 03225 stringp=username; 03226 username = strsep(&stringp, ":"); 03227 if (username) { 03228 secret = strsep(&stringp, ":"); 03229 if (secret) 03230 authuser = strsep(&stringp, ":"); 03231 } 03232 stringp = hostname; 03233 hostname = strsep(&stringp, "/"); 03234 if (hostname) 03235 contact = strsep(&stringp, "/"); 03236 if (ast_strlen_zero(contact)) 03237 contact = "s"; 03238 stringp=hostname; 03239 hostname = strsep(&stringp, ":"); 03240 porta = strsep(&stringp, ":"); 03241 03242 if (porta && !atoi(porta)) { 03243 ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno); 03244 return -1; 03245 } 03246 reg = malloc(sizeof(struct sip_registry)); 03247 if (!reg) { 03248 ast_log(LOG_ERROR, "Out of memory. Can't allocate SIP registry entry\n"); 03249 return -1; 03250 } 03251 memset(reg, 0, sizeof(struct sip_registry)); 03252 regobjs++; 03253 ASTOBJ_INIT(reg); 03254 ast_copy_string(reg->contact, contact, sizeof(reg->contact)); 03255 if (username) 03256 ast_copy_string(reg->username, username, sizeof(reg->username)); 03257 if (hostname) 03258 ast_copy_string(reg->hostname, hostname, sizeof(reg->hostname)); 03259 if (authuser) 03260 ast_copy_string(reg->authuser, authuser, sizeof(reg->authuser)); 03261 if (secret) 03262 ast_copy_string(reg->secret, secret, sizeof(reg->secret)); 03263 reg->expire = -1; 03264 reg->timeout = -1; 03265 reg->refresh = default_expiry; 03266 reg->portno = porta ? atoi(porta) : 0; 03267 reg->callid_valid = 0; 03268 reg->ocseq = 101; 03269 ASTOBJ_CONTAINER_LINK(®l, reg); 03270 ASTOBJ_UNREF(reg,sip_registry_destroy); 03271 return 0; 03272 }
|
|
sip_registry_destroy: Destroy registry object ---
Definition at line 2077 of file chan_sip.c. References ast_sched_del(), sip_registry::call, sip_registry::expire, free, sip_pvt::registry, sched, sip_destroy(), and sip_registry::timeout. Referenced by __sip_destroy(), sip_reg_timeout(), sip_register(), sip_reregister(), and unload_module(). 02078 { 02079 /* Really delete */ 02080 if (reg->call) { 02081 /* Clear registry before destroying to ensure 02082 we don't get reentered trying to grab the registry lock */ 02083 reg->call->registry = NULL; 02084 sip_destroy(reg->call); 02085 } 02086 if (reg->expire > -1) 02087 ast_sched_del(sched, reg->expire); 02088 if (reg->timeout > -1) 02089 ast_sched_del(sched, reg->timeout); 02090 regobjs--; 02091 free(reg); 02092 02093 }
|
|
sip_reload: Force reload of module from cli ---
Definition at line 13079 of file chan_sip.c. References ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), restart_monitor(), and sip_reloading. Referenced by reload(). 13080 { 13081 13082 ast_mutex_lock(&sip_reload_lock); 13083 if (sip_reloading) { 13084 ast_verbose("Previous SIP reload not yet done\n"); 13085 } else 13086 sip_reloading = 1; 13087 ast_mutex_unlock(&sip_reload_lock); 13088 restart_monitor(); 13089 13090 return 0; 13091 }
|
|
sip_request: PBX interface function -build SIP pvt structure ---
Definition at line 11546 of file chan_sip.c. References __ourip, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_SWITCH_CONGESTION, AST_CAUSE_UNREGISTERED, ast_getformatname(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_sip_ouraddrfor(), AST_STATE_DOWN, ast_strlen_zero(), ast_update_use_count(), build_callid(), build_via(), sip_pvt::callid, calloc, create_addr(), sip_pvt::fromdomain, sip_pvt::fullcontact, global_capability, host, sip_pvt::lock, LOG_ERROR, LOG_NOTICE, sip_pvt::options, sip_pvt::ourip, sip_pvt::peername, sip_pvt::prefcodec, restart_monitor(), sip_pvt::sa, sip_alloc(), sip_destroy(), SIP_INVITE, sip_new(), sip_pvt::username, and sip_pvt::via. 11547 { 11548 int oldformat; 11549 struct sip_pvt *p; 11550 struct ast_channel *tmpc = NULL; 11551 char *ext, *host; 11552 char tmp[256]; 11553 char *dest = data; 11554 11555 oldformat = format; 11556 format &= ((AST_FORMAT_MAX_AUDIO << 1) - 1); 11557 if (!format) { 11558 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)); 11559 *cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; /* Can't find codec to connect to host */ 11560 return NULL; 11561 } 11562 p = sip_alloc(NULL, NULL, 0, SIP_INVITE); 11563 if (!p) { 11564 ast_log(LOG_ERROR, "Unable to build sip pvt data for '%s' (Out of memory)\n", (char *)data); 11565 *cause = AST_CAUSE_SWITCH_CONGESTION; 11566 return NULL; 11567 } 11568 11569 p->options = calloc(1, sizeof(*p->options)); 11570 if (!p->options) { 11571 sip_destroy(p); 11572 ast_log(LOG_ERROR, "Unable to build option SIP data structure - Out of memory\n"); 11573 *cause = AST_CAUSE_SWITCH_CONGESTION; 11574 return NULL; 11575 } 11576 11577 ast_copy_string(tmp, dest, sizeof(tmp)); 11578 host = strchr(tmp, '@'); 11579 if (host) { 11580 *host = '\0'; 11581 host++; 11582 ext = tmp; 11583 } else { 11584 ext = strchr(tmp, '/'); 11585 if (ext) { 11586 *ext++ = '\0'; 11587 host = tmp; 11588 } 11589 else { 11590 host = tmp; 11591 ext = NULL; 11592 } 11593 } 11594 11595 if (create_addr(p, host)) { 11596 *cause = AST_CAUSE_UNREGISTERED; 11597 sip_destroy(p); 11598 return NULL; 11599 } 11600 if (ast_strlen_zero(p->peername) && ext) 11601 ast_copy_string(p->peername, ext, sizeof(p->peername)); 11602 /* Recalculate our side, and recalculate Call ID */ 11603 if (ast_sip_ouraddrfor(&p->sa.sin_addr,&p->ourip)) 11604 memcpy(&p->ourip, &__ourip, sizeof(p->ourip)); 11605 build_via(p, p->via, sizeof(p->via)); 11606 build_callid(p->callid, sizeof(p->callid), p->ourip, p->fromdomain); 11607 11608 /* We have an extension to call, don't use the full contact here */ 11609 /* This to enable dialling registered peers with extension dialling, 11610 like SIP/peername/extension 11611 SIP/peername will still use the full contact */ 11612 if (ext) { 11613 ast_copy_string(p->username, ext, sizeof(p->username)); 11614 p->fullcontact[0] = 0; 11615 } 11616 #if 0 11617 printf("Setting up to call extension '%s' at '%s'\n", ext ? ext : "<none>", host); 11618 #endif 11619 p->prefcodec = format; 11620 ast_mutex_lock(&p->lock); 11621 tmpc = sip_new(p, AST_STATE_DOWN, host); /* Place the call */ 11622 ast_mutex_unlock(&p->lock); 11623 if (!tmpc) 11624 sip_destroy(p); 11625 ast_update_use_count(); 11626 restart_monitor(); 11627 return tmpc; 11628 }
|
|
sip_reregister: Update registration with SIP Proxy---
Definition at line 5244 of file chan_sip.c. References __sip_do_register(), append_history(), ast_log(), ASTOBJ_REF, ASTOBJ_UNREF, sip_registry::call, sip_registry::expire, sip_registry::hostname, LOG_NOTICE, recordhistory, sip_registry_destroy(), sipdebug, and sip_registry::username. Referenced by sip_send_all_registers(). 05245 { 05246 /* if we are here, we know that we need to reregister. */ 05247 struct sip_registry *r= ASTOBJ_REF((struct sip_registry *) data); 05248 05249 /* if we couldn't get a reference to the registry object, punt */ 05250 if (!r) 05251 return 0; 05252 05253 if (r->call && recordhistory) { 05254 char tmp[80]; 05255 snprintf(tmp, sizeof(tmp), "Account: %s@%s", r->username, r->hostname); 05256 append_history(r->call, "RegistryRenew", tmp); 05257 } 05258 /* Since registry's are only added/removed by the the monitor thread, this 05259 may be overkill to reference/dereference at all here */ 05260 if (sipdebug) 05261 ast_log(LOG_NOTICE, " -- Re-registration for %s@%s\n", r->username, r->hostname); 05262 05263 r->expire = -1; 05264 __sip_do_register(r); 05265 ASTOBJ_UNREF(r, sip_registry_destroy); 05266 return 0; 05267 }
|
|
sip_rtp_read: Read RTP from network ---
Definition at line 2947 of file chan_sip.c. References ast_dsp_process(), AST_FRAME_DTMF, AST_FRAME_NULL, AST_FRAME_VOICE, ast_log(), ast_rtcp_read(), ast_rtp_read(), ast_set_read_format(), ast_set_write_format(), ast_test_flag, ast_channel::fdno, ast_frame::frametype, LOG_DEBUG, ast_channel::nativeformats, sip_pvt::owner, ast_channel::readformat, sip_pvt::rtp, SIP_DTMF, SIP_DTMF_INBAND, SIP_DTMF_RFC2833, ast_frame::subclass, sip_pvt::vad, sip_pvt::vrtp, and ast_channel::writeformat. Referenced by sip_read(). 02948 { 02949 /* Retrieve audio/etc from channel. Assumes p->lock is already held. */ 02950 struct ast_frame *f; 02951 static struct ast_frame null_frame = { AST_FRAME_NULL, }; 02952 02953 if (!p->rtp) { 02954 /* We have no RTP allocated for this channel */ 02955 return &null_frame; 02956 } 02957 02958 switch(ast->fdno) { 02959 case 0: 02960 f = ast_rtp_read(p->rtp); /* RTP Audio */ 02961 break; 02962 case 1: 02963 f = ast_rtcp_read(p->rtp); /* RTCP Control Channel */ 02964 break; 02965 case 2: 02966 f = ast_rtp_read(p->vrtp); /* RTP Video */ 02967 break; 02968 case 3: 02969 f = ast_rtcp_read(p->vrtp); /* RTCP Control Channel for video */ 02970 break; 02971 default: 02972 f = &null_frame; 02973 } 02974 /* Don't forward RFC2833 if we're not supposed to */ 02975 if (f && (f->frametype == AST_FRAME_DTMF) && (ast_test_flag(p, SIP_DTMF) != SIP_DTMF_RFC2833)) 02976 return &null_frame; 02977 if (p->owner) { 02978 /* We already hold the channel lock */ 02979 if (f->frametype == AST_FRAME_VOICE) { 02980 if (f->subclass != p->owner->nativeformats) { 02981 ast_log(LOG_DEBUG, "Oooh, format changed to %d\n", f->subclass); 02982 p->owner->nativeformats = f->subclass; 02983 ast_set_read_format(p->owner, p->owner->readformat); 02984 ast_set_write_format(p->owner, p->owner->writeformat); 02985 } 02986 if ((ast_test_flag(p, SIP_DTMF) == SIP_DTMF_INBAND) && p->vad) { 02987 f = ast_dsp_process(p->owner, p->vad, f); 02988 if (f && (f->frametype == AST_FRAME_DTMF)) 02989 ast_log(LOG_DEBUG, "* Detected inband DTMF '%c'\n", f->subclass); 02990 } 02991 } 02992 } 02993 return f; 02994 }
|
|
sip_scheddestroy: Schedule destruction of SIP call ---
Definition at line 1328 of file chan_sip.c. References __sip_autodestruct(), append_history(), ast_sched_add(), ast_sched_del(), ast_verbose(), sip_pvt::autokillid, sip_pvt::callid, sched, and sip_debug_test_pvt(). Referenced by cb_extensionstate(), check_auth(), handle_request_register(), handle_request_subscribe(), handle_response_register(), sip_hangup(), sip_notify(), and sip_send_mwi_to_peer(). 01329 { 01330 char tmp[80]; 01331 if (sip_debug_test_pvt(p)) 01332 ast_verbose("Scheduling destruction of call '%s' in %d ms\n", p->callid, ms); 01333 if (recordhistory) { 01334 snprintf(tmp, sizeof(tmp), "%d ms", ms); 01335 append_history(p, "SchedDestroy", tmp); 01336 } 01337 01338 if (p->autokillid > -1) 01339 ast_sched_del(sched, p->autokillid); 01340 p->autokillid = ast_sched_add(sched, ms, __sip_autodestruct, p); 01341 return 0; 01342 }
|
|
sip_send_all_registers: Send all known registrations
Definition at line 13024 of file chan_sip.c. References ast_sched_add(), ast_sched_del(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_UNLOCK, ASTOBJ_WRLOCK, default_expiry, regl, regobjs, and sip_reregister(). Referenced by load_module(). 13025 { 13026 int ms; 13027 int regspacing; 13028 if (!regobjs) 13029 return; 13030 regspacing = default_expiry * 1000/regobjs; 13031 if (regspacing > 100) 13032 regspacing = 100; 13033 ms = regspacing; 13034 ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { 13035 ASTOBJ_WRLOCK(iterator); 13036 if (iterator->expire > -1) 13037 ast_sched_del(sched, iterator->expire); 13038 ms += regspacing; 13039 iterator->expire = ast_sched_add(sched, ms, sip_reregister, iterator); 13040 ASTOBJ_UNLOCK(iterator); 13041 } while (0) 13042 ); 13043 }
|
|
sip_send_mwi_to_peer: Send message waiting indication ---
Definition at line 11195 of file chan_sip.c. References __ourip, ast_app_messagecount(), ast_log(), ast_set_flag, ast_sip_ouraddrfor(), build_callid(), build_via(), create_addr_from_peer(), sip_peer::lastmsgcheck, sip_peer::lastmsgssent, LOG_WARNING, sip_peer::mailbox, sip_alloc(), sip_destroy(), SIP_NOTIFY, SIP_OUTGOING, sip_scheddestroy(), transmit_notify_with_mwi(), and sip_peer::vmexten. 11196 { 11197 /* Called with peerl lock, but releases it */ 11198 struct sip_pvt *p; 11199 int newmsgs, oldmsgs; 11200 11201 /* Check for messages */ 11202 ast_app_messagecount(peer->mailbox, &newmsgs, &oldmsgs); 11203 11204 time(&peer->lastmsgcheck); 11205 11206 /* Return now if it's the same thing we told them last time */ 11207 if (((newmsgs << 8) | (oldmsgs)) == peer->lastmsgssent) { 11208 return 0; 11209 } 11210 11211 p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY); 11212 if (!p) { 11213 ast_log(LOG_WARNING, "Unable to build sip pvt data for MWI\n"); 11214 return -1; 11215 } 11216 peer->lastmsgssent = ((newmsgs << 8) | (oldmsgs)); 11217 if (create_addr_from_peer(p, peer)) { 11218 /* Maybe they're not registered, etc. */ 11219 sip_destroy(p); 11220 return 0; 11221 } 11222 /* Recalculate our side, and recalculate Call ID */ 11223 if (ast_sip_ouraddrfor(&p->sa.sin_addr,&p->ourip)) 11224 memcpy(&p->ourip, &__ourip, sizeof(p->ourip)); 11225 build_via(p, p->via, sizeof(p->via)); 11226 build_callid(p->callid, sizeof(p->callid), p->ourip, p->fromdomain); 11227 /* Send MWI */ 11228 ast_set_flag(p, SIP_OUTGOING); 11229 transmit_notify_with_mwi(p, newmsgs, oldmsgs, peer->vmexten); 11230 sip_scheddestroy(p, 15000); 11231 return 0; 11232 }
|
|
sip_senddigit: Send DTMF character on SIP channel
Definition at line 2604 of file chan_sip.c. References ast_mutex_lock(), ast_mutex_unlock(), ast_rtp_senddigit(), ast_test_flag, sip_pvt::lock, SIP_DTMF, SIP_DTMF_INBAND, SIP_DTMF_INFO, SIP_DTMF_RFC2833, ast_channel::tech_pvt, and transmit_info_with_digit(). 02605 { 02606 struct sip_pvt *p = ast->tech_pvt; 02607 int res = 0; 02608 ast_mutex_lock(&p->lock); 02609 switch (ast_test_flag(p, SIP_DTMF)) { 02610 case SIP_DTMF_INFO: 02611 transmit_info_with_digit(p, digit); 02612 break; 02613 case SIP_DTMF_RFC2833: 02614 if (p->rtp) 02615 ast_rtp_senddigit(p->rtp, digit); 02616 break; 02617 case SIP_DTMF_INBAND: 02618 res = -1; 02619 break; 02620 } 02621 ast_mutex_unlock(&p->lock); 02622 return res; 02623 }
|
|
sip_sendtext: Send SIP MESSAGE text within a call ---
Definition at line 1574 of file chan_sip.c. References ast_strlen_zero(), ast_verbose(), debug, ast_channel::name, sip_debug_test_pvt(), ast_channel::tech_pvt, and transmit_message_with_text(). 01575 { 01576 struct sip_pvt *p = ast->tech_pvt; 01577 int debug=sip_debug_test_pvt(p); 01578 01579 if (debug) 01580 ast_verbose("Sending text %s on %s\n", text, ast->name); 01581 if (!p) 01582 return -1; 01583 if (ast_strlen_zero(text)) 01584 return 0; 01585 if (debug) 01586 ast_verbose("Really sending text %s on %s\n", text, ast->name); 01587 transmit_message_with_text(p, text); 01588 return 0; 01589 }
|
|
sip_set_rtp_peer: Set the RTP peer for this call ---
Definition at line 12736 of file chan_sip.c. References ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_rtp_get_peer(), ast_set_flag, ast_test_flag, sip_pvt::callid, sip_pvt::lastrtprx, sip_pvt::lastrtptx, sip_pvt::lock, LOG_DEBUG, option_debug, sip_pvt::ourip, sip_pvt::pendinginvite, sip_pvt::redircodecs, sip_pvt::redirip, sip_pvt::rtp, SIP_GOTREFER, SIP_NEEDREINVITE, SIP_PENDINGBYE, ast_channel::tech_pvt, transmit_reinvite_with_sdp(), sip_pvt::vredirip, and sip_pvt::vrtp. 12737 { 12738 struct sip_pvt *p; 12739 12740 p = chan->tech_pvt; 12741 if (!p) 12742 return -1; 12743 ast_mutex_lock(&p->lock); 12744 if (rtp) 12745 ast_rtp_get_peer(rtp, &p->redirip); 12746 else 12747 memset(&p->redirip, 0, sizeof(p->redirip)); 12748 if (vrtp) 12749 ast_rtp_get_peer(vrtp, &p->vredirip); 12750 else 12751 memset(&p->vredirip, 0, sizeof(p->vredirip)); 12752 p->redircodecs = codecs; 12753 if (!ast_test_flag(p, SIP_GOTREFER)) { 12754 if (!p->pendinginvite) { 12755 if (option_debug > 2) { 12756 char iabuf[INET_ADDRSTRLEN]; 12757 ast_log(LOG_DEBUG, "Sending reinvite on SIP '%s' - It's audio soon redirected to IP %s\n", p->callid, ast_inet_ntoa(iabuf, sizeof(iabuf), rtp ? p->redirip.sin_addr : p->ourip)); 12758 } 12759 transmit_reinvite_with_sdp(p); 12760 } else if (!ast_test_flag(p, SIP_PENDINGBYE)) { 12761 if (option_debug > 2) { 12762 char iabuf[INET_ADDRSTRLEN]; 12763 ast_log(LOG_DEBUG, "Deferring reinvite on SIP '%s' - It's audio will be redirected to IP %s\n", p->callid, ast_inet_ntoa(iabuf, sizeof(iabuf), rtp ? p->redirip.sin_addr : p->ourip)); 12764 } 12765 ast_set_flag(p, SIP_NEEDREINVITE); 12766 } 12767 } 12768 /* Reset lastrtprx timer */ 12769 time(&p->lastrtprx); 12770 time(&p->lastrtptx); 12771 ast_mutex_unlock(&p->lock); 12772 return 0; 12773 }
|
|
sip_show_channel: Show details of one call ---
Definition at line 8468 of file chan_sip.c. References ast_cli(), ast_getformatname(), ast_inet_ntoa(), ast_mutex_lock(), ast_strlen_zero(), ast_test_flag, sip_pvt::callid, sip_pvt::capability, sip_pvt::cid_num, dtmfmode2str(), sip_route::hop, iflist, sip_pvt::jointcapability, sip_pvt::lastmsg, nat2str(), ast_channel::nativeformats, sip_pvt::next, sip_pvt::noncodeccapability, NONE, sip_pvt::ourip, sip_pvt::owner, sip_pvt::peercapability, sip_pvt::peername, sip_pvt::recv, sip_pvt::redirip, RESULT_SHOWUSAGE, sip_pvt::route, sip_pvt::sa, SIP_DTMF, SIP_NAT, SIP_NEEDDESTROY, sip_options, SIP_OUTGOING, SIP_PROMISCREDIR, sip_pvt::sipoptions, sip_pvt::subscribed, subscription_type2str(), sip_pvt::tag, text, sip_pvt::theirtag, sip_pvt::uri, sip_pvt::useragent, and sip_pvt::username. 08469 { 08470 struct sip_pvt *cur; 08471 char iabuf[INET_ADDRSTRLEN]; 08472 size_t len; 08473 int found = 0; 08474 08475 if (argc != 4) 08476 return RESULT_SHOWUSAGE; 08477 len = strlen(argv[3]); 08478 ast_mutex_lock(&iflock); 08479 cur = iflist; 08480 while(cur) { 08481 if (!strncasecmp(cur->callid, argv[3],len)) { 08482 ast_cli(fd,"\n"); 08483 if (cur->subscribed != NONE) 08484 ast_cli(fd, " * Subscription (type: %s)\n", subscription_type2str(cur->subscribed)); 08485 else 08486 ast_cli(fd, " * SIP Call\n"); 08487 ast_cli(fd, " Direction: %s\n", ast_test_flag(cur, SIP_OUTGOING)?"Outgoing":"Incoming"); 08488 ast_cli(fd, " Call-ID: %s\n", cur->callid); 08489 ast_cli(fd, " Our Codec Capability: %d\n", cur->capability); 08490 ast_cli(fd, " Non-Codec Capability: %d\n", cur->noncodeccapability); 08491 ast_cli(fd, " Their Codec Capability: %d\n", cur->peercapability); 08492 ast_cli(fd, " Joint Codec Capability: %d\n", cur->jointcapability); 08493 ast_cli(fd, " Format %s\n", ast_getformatname(cur->owner ? cur->owner->nativeformats : 0) ); 08494 ast_cli(fd, " Theoretical Address: %s:%d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), cur->sa.sin_addr), ntohs(cur->sa.sin_port)); 08495 ast_cli(fd, " Received Address: %s:%d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), cur->recv.sin_addr), ntohs(cur->recv.sin_port)); 08496 ast_cli(fd, " NAT Support: %s\n", nat2str(ast_test_flag(cur, SIP_NAT))); 08497 ast_cli(fd, " Audio IP: %s %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), cur->redirip.sin_addr.s_addr ? cur->redirip.sin_addr : cur->ourip), cur->redirip.sin_addr.s_addr ? "(Outside bridge)" : "(local)" ); 08498 ast_cli(fd, " Our Tag: %s\n", cur->tag); 08499 ast_cli(fd, " Their Tag: %s\n", cur->theirtag); 08500 ast_cli(fd, " SIP User agent: %s\n", cur->useragent); 08501 if (!ast_strlen_zero(cur->username)) 08502 ast_cli(fd, " Username: %s\n", cur->username); 08503 if (!ast_strlen_zero(cur->peername)) 08504 ast_cli(fd, " Peername: %s\n", cur->peername); 08505 if (!ast_strlen_zero(cur->uri)) 08506 ast_cli(fd, " Original uri: %s\n", cur->uri); 08507 if (!ast_strlen_zero(cur->cid_num)) 08508 ast_cli(fd, " Caller-ID: %s\n", cur->cid_num); 08509 ast_cli(fd, " Need Destroy: %d\n", ast_test_flag(cur, SIP_NEEDDESTROY)); 08510 ast_cli(fd, " Last Message: %s\n", cur->lastmsg); 08511 ast_cli(fd, " Promiscuous Redir: %s\n", ast_test_flag(cur, SIP_PROMISCREDIR) ? "Yes" : "No"); 08512 ast_cli(fd, " Route: %s\n", cur->route ? cur->route->hop : "N/A"); 08513 ast_cli(fd, " DTMF Mode: %s\n", dtmfmode2str(ast_test_flag(cur, SIP_DTMF))); 08514 ast_cli(fd, " SIP Options: "); 08515 if (cur->sipoptions) { 08516 int x; 08517 for (x=0 ; (x < (sizeof(sip_options) / sizeof(sip_options[0]))); x++) { 08518 if (cur->sipoptions & sip_options[x].id) 08519 ast_cli(fd, "%s ", sip_options[x].text); 08520 } 08521 } else 08522 ast_cli(fd, "(none)\n"); 08523 ast_cli(fd, "\n\n"); 08524 found++; 08525 } 08526 cur = cur->next; 08527 } 08528 ast_mutex_unlock(&iflock); 08529 if (!found) 08530 ast_cli(fd, "No such SIP Call ID starting with '%s'\n", argv[3]); 08531 return RESULT_SUCCESS; 08532 }
|
|
sip_show_channels: Show active SIP channels ---
Definition at line 8269 of file chan_sip.c. References __sip_show_channels(). 08270 { 08271 return __sip_show_channels(fd, argc, argv, 0); 08272 }
|
|
Definition at line 7825 of file chan_sip.c. References ast_cli(), AST_LIST_EMPTY, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_strlen_zero(), domain::context, domain::domain, domain_mode_to_text(), FORMAT, list, domain::mode, and RESULT_SUCCESS. 07826 { 07827 struct domain *d; 07828 07829 if (AST_LIST_EMPTY(&domain_list)) { 07830 ast_cli(fd, "SIP Domain support not enabled.\n\n"); 07831 return RESULT_SUCCESS; 07832 } else { 07833 ast_cli(fd, FORMAT, "Our local SIP domains:", "Context", "Set by"); 07834 AST_LIST_LOCK(&domain_list); 07835 AST_LIST_TRAVERSE(&domain_list, d, list) 07836 ast_cli(fd, FORMAT, d->domain, ast_strlen_zero(d->context) ? "(default)": d->context, 07837 domain_mode_to_text(d->mode)); 07838 AST_LIST_UNLOCK(&domain_list); 07839 ast_cli(fd, "\n"); 07840 return RESULT_SUCCESS; 07841 } 07842 }
|
|
sip_show_history: Show history details of one call ---
Definition at line 8535 of file chan_sip.c. References ast_cli(), ast_mutex_lock(), ast_mutex_unlock(), sip_pvt::callid, sip_history::event, sip_pvt::history, iflist, sip_pvt::next, sip_history::next, NONE, recordhistory, RESULT_SHOWUSAGE, RESULT_SUCCESS, and sip_pvt::subscribed. 08536 { 08537 struct sip_pvt *cur; 08538 struct sip_history *hist; 08539 size_t len; 08540 int x; 08541 int found = 0; 08542 08543 if (argc != 4) 08544 return RESULT_SHOWUSAGE; 08545 if (!recordhistory) 08546 ast_cli(fd, "\n***Note: History recording is currently DISABLED. Use 'sip history' to ENABLE.\n"); 08547 len = strlen(argv[3]); 08548 ast_mutex_lock(&iflock); 08549 cur = iflist; 08550 while(cur) { 08551 if (!strncasecmp(cur->callid, argv[3], len)) { 08552 ast_cli(fd,"\n"); 08553 if (cur->subscribed != NONE) 08554 ast_cli(fd, " * Subscription\n"); 08555 else 08556 ast_cli(fd, " * SIP Call\n"); 08557 x = 0; 08558 hist = cur->history; 08559 while(hist) { 08560 x++; 08561 ast_cli(fd, "%d. %s\n", x, hist->event); 08562 hist = hist->next; 08563 } 08564 if (!x) 08565 ast_cli(fd, "Call '%s' has no history\n", cur->callid); 08566 found++; 08567 } 08568 cur = cur->next; 08569 } 08570 ast_mutex_unlock(&iflock); 08571 if (!found) 08572 ast_cli(fd, "No such SIP Call ID starting with '%s'\n", argv[3]); 08573 return RESULT_SUCCESS; 08574 }
|
|
sip_show_inuse: CLI Command to show calls within limits set by call_limit ---
Definition at line 7292 of file chan_sip.c. References ast_cli(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, FORMAT, FORMAT2, RESULT_SHOWUSAGE, and userl. 07292 { 07293 #define FORMAT "%-25.25s %-15.15s %-15.15s \n" 07294 #define FORMAT2 "%-25.25s %-15.15s %-15.15s \n" 07295 char ilimits[40]; 07296 char iused[40]; 07297 int showall = 0; 07298 07299 if (argc < 3) 07300 return RESULT_SHOWUSAGE; 07301 07302 if (argc == 4 && !strcmp(argv[3],"all")) 07303 showall = 1; 07304 07305 ast_cli(fd, FORMAT, "* User name", "In use", "Limit"); 07306 ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do { 07307 ASTOBJ_RDLOCK(iterator); 07308 if (iterator->call_limit) 07309 snprintf(ilimits, sizeof(ilimits), "%d", iterator->call_limit); 07310 else 07311 ast_copy_string(ilimits, "N/A", sizeof(ilimits)); 07312 snprintf(iused, sizeof(iused), "%d", iterator->inUse); 07313 if (showall || iterator->call_limit) 07314 ast_cli(fd, FORMAT2, iterator->name, iused, ilimits); 07315 ASTOBJ_UNLOCK(iterator); 07316 } while (0) ); 07317 07318 ast_cli(fd, FORMAT, "* Peer name", "In use", "Limit"); 07319 07320 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 07321 ASTOBJ_RDLOCK(iterator); 07322 if (iterator->call_limit) 07323 snprintf(ilimits, sizeof(ilimits), "%d", iterator->call_limit); 07324 else 07325 ast_copy_string(ilimits, "N/A", sizeof(ilimits)); 07326 snprintf(iused, sizeof(iused), "%d", iterator->inUse); 07327 if (showall || iterator->call_limit) 07328 ast_cli(fd, FORMAT2, iterator->name, iused, ilimits); 07329 ASTOBJ_UNLOCK(iterator); 07330 } while (0) ); 07331 07332 return RESULT_SUCCESS; 07333 #undef FORMAT 07334 #undef FORMAT2 07335 }
|
|
sip_show_objects: List all allocated SIP Objects ---
Definition at line 7598 of file chan_sip.c. References apeerobjs, ast_cli(), ASTOBJ_CONTAINER_DUMP, peerl, regl, regobjs, RESULT_SHOWUSAGE, RESULT_SUCCESS, rpeerobjs, ruserobjs, speerobjs, suserobjs, and userl. 07599 { 07600 char tmp[256]; 07601 if (argc != 3) 07602 return RESULT_SHOWUSAGE; 07603 ast_cli(fd, "-= User objects: %d static, %d realtime =-\n\n", suserobjs, ruserobjs); 07604 ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), &userl); 07605 ast_cli(fd, "-= Peer objects: %d static, %d realtime, %d autocreate =-\n\n", speerobjs, rpeerobjs, apeerobjs); 07606 ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), &peerl); 07607 ast_cli(fd, "-= Registry objects: %d =-\n\n", regobjs); 07608 ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), ®l); 07609 return RESULT_SUCCESS; 07610 }
|
|
sip_show_peer: Show one peer in detail ---
Definition at line 7882 of file chan_sip.c. References _sip_show_peer(). 07883 { 07884 return _sip_show_peer(0, fd, NULL, NULL, argc, argv); 07885 }
|
|
sip_show_peers: CLI Show Peers command
Definition at line 7459 of file chan_sip.c. References _sip_show_peers(). 07460 { 07461 return _sip_show_peers(fd, NULL, NULL, NULL, argc, argv); 07462 }
|
|
sip_show_registry: Show SIP Registry (registrations with other SIP proxies ---
Definition at line 8134 of file chan_sip.c. References ast_cli(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, DEFAULT_SIP_PORT, FORMAT, FORMAT2, host, regl, regstate2str(), and RESULT_SHOWUSAGE. 08135 { 08136 #define FORMAT2 "%-30.30s %-12.12s %8.8s %-20.20s\n" 08137 #define FORMAT "%-30.30s %-12.12s %8d %-20.20s\n" 08138 char host[80]; 08139 08140 if (argc != 3) 08141 return RESULT_SHOWUSAGE; 08142 ast_cli(fd, FORMAT2, "Host", "Username", "Refresh", "State"); 08143 ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { 08144 ASTOBJ_RDLOCK(iterator); 08145 snprintf(host, sizeof(host), "%s:%d", iterator->hostname, iterator->portno ? iterator->portno : DEFAULT_SIP_PORT); 08146 ast_cli(fd, FORMAT, host, iterator->username, iterator->refresh, regstate2str(iterator->regstate)); 08147 ASTOBJ_UNLOCK(iterator); 08148 } while(0)); 08149 return RESULT_SUCCESS; 08150 #undef FORMAT 08151 #undef FORMAT2 08152 }
|
|
sip_show_settings: List global settings for the SIP channel ---
Definition at line 8155 of file chan_sip.c. References allow_external_domains, ast_check_realtime(), ast_cli(), ast_inet_ntoa(), AST_LIST_EMPTY, ast_strlen_zero(), ast_test_flag, authl, autocreatepeer, bindaddr, callevents, compactheaders, default_callerid, default_context, default_expiry, default_fromdomain, default_language, default_notifymime, default_qualify, default_useragent, dtmfmode2str(), global_allowguest, global_flags, global_flags_page2, global_musicclass, global_mwitime, global_notifyringing, global_realm, global_reg_timeout, global_regattempts_max, global_rtautoclear, global_rtpholdtimeout, global_rtptimeout, global_vmexten, max_expiry, nat2str(), pedanticsipchecking, prefs, print_codec_to_cli(), recordhistory, regcontext, relaxdtmf, RESULT_SHOWUSAGE, RESULT_SUCCESS, SIP_DTMF, SIP_NAT, SIP_PAGE2_IGNOREREGEXPIRE, SIP_PAGE2_RTCACHEFRIENDS, SIP_PAGE2_RTUPDATE, SIP_PROG_INBAND, SIP_PROG_INBAND_NEVER, SIP_PROG_INBAND_NO, SIP_PROMISCREDIR, SIP_USECLIENTCODE, SIP_USEREQPHONE, srvlookup, tos, and videosupport. 08156 { 08157 char tmp[BUFSIZ]; 08158 int realtimepeers = 0; 08159 int realtimeusers = 0; 08160 08161 realtimepeers = ast_check_realtime("sippeers"); 08162 realtimeusers = ast_check_realtime("sipusers"); 08163 08164 if (argc != 3) 08165 return RESULT_SHOWUSAGE; 08166 ast_cli(fd, "\n\nGlobal Settings:\n"); 08167 ast_cli(fd, "----------------\n"); 08168 ast_cli(fd, " SIP Port: %d\n", ntohs(bindaddr.sin_port)); 08169 ast_cli(fd, " Bindaddress: %s\n", ast_inet_ntoa(tmp, sizeof(tmp), bindaddr.sin_addr)); 08170 ast_cli(fd, " Videosupport: %s\n", videosupport ? "Yes" : "No"); 08171 ast_cli(fd, " AutoCreatePeer: %s\n", autocreatepeer ? "Yes" : "No"); 08172 ast_cli(fd, " Allow unknown access: %s\n", global_allowguest ? "Yes" : "No"); 08173 ast_cli(fd, " Promsic. redir: %s\n", ast_test_flag(&global_flags, SIP_PROMISCREDIR) ? "Yes" : "No"); 08174 ast_cli(fd, " SIP domain support: %s\n", AST_LIST_EMPTY(&domain_list) ? "No" : "Yes"); 08175 ast_cli(fd, " Call to non-local dom.: %s\n", allow_external_domains ? "Yes" : "No"); 08176 ast_cli(fd, " URI user is phone no: %s\n", ast_test_flag(&global_flags, SIP_USEREQPHONE) ? "Yes" : "No"); 08177 ast_cli(fd, " Our auth realm %s\n", global_realm); 08178 ast_cli(fd, " Realm. auth: %s\n", authl ? "Yes": "No"); 08179 ast_cli(fd, " User Agent: %s\n", default_useragent); 08180 ast_cli(fd, " MWI checking interval: %d secs\n", global_mwitime); 08181 ast_cli(fd, " Reg. context: %s\n", ast_strlen_zero(regcontext) ? "(not set)" : regcontext); 08182 ast_cli(fd, " Caller ID: %s\n", default_callerid); 08183 ast_cli(fd, " From: Domain: %s\n", default_fromdomain); 08184 ast_cli(fd, " Record SIP history: %s\n", recordhistory ? "On" : "Off"); 08185 ast_cli(fd, " Call Events: %s\n", callevents ? "On" : "Off"); 08186 ast_cli(fd, " IP ToS: 0x%x\n", tos); 08187 #ifdef OSP_SUPPORT 08188 ast_cli(fd, " OSP Support: Yes\n"); 08189 #else 08190 ast_cli(fd, " OSP Support: No\n"); 08191 #endif 08192 if (!realtimepeers && !realtimeusers) 08193 ast_cli(fd, " SIP realtime: Disabled\n" ); 08194 else 08195 ast_cli(fd, " SIP realtime: Enabled\n" ); 08196 08197 ast_cli(fd, "\nGlobal Signalling Settings:\n"); 08198 ast_cli(fd, "---------------------------\n"); 08199 ast_cli(fd, " Codecs: "); 08200 print_codec_to_cli(fd, &prefs); 08201 ast_cli(fd, "\n"); 08202 ast_cli(fd, " Relax DTMF: %s\n", relaxdtmf ? "Yes" : "No"); 08203 ast_cli(fd, " Compact SIP headers: %s\n", compactheaders ? "Yes" : "No"); 08204 ast_cli(fd, " RTP Timeout: %d %s\n", global_rtptimeout, global_rtptimeout ? "" : "(Disabled)" ); 08205 ast_cli(fd, " RTP Hold Timeout: %d %s\n", global_rtpholdtimeout, global_rtpholdtimeout ? "" : "(Disabled)"); 08206 ast_cli(fd, " MWI NOTIFY mime type: %s\n", default_notifymime); 08207 ast_cli(fd, " DNS SRV lookup: %s\n", srvlookup ? "Yes" : "No"); 08208 ast_cli(fd, " Pedantic SIP support: %s\n", pedanticsipchecking ? "Yes" : "No"); 08209 ast_cli(fd, " Reg. max duration: %d secs\n", max_expiry); 08210 ast_cli(fd, " Reg. default duration: %d secs\n", default_expiry); 08211 ast_cli(fd, " Outbound reg. timeout: %d secs\n", global_reg_timeout); 08212 ast_cli(fd, " Outbound reg. attempts: %d\n", global_regattempts_max); 08213 ast_cli(fd, " Notify ringing state: %s\n", global_notifyringing ? "Yes" : "No"); 08214 ast_cli(fd, "\nDefault Settings:\n"); 08215 ast_cli(fd, "-----------------\n"); 08216 ast_cli(fd, " Context: %s\n", default_context); 08217 ast_cli(fd, " Nat: %s\n", nat2str(ast_test_flag(&global_flags, SIP_NAT))); 08218 ast_cli(fd, " DTMF: %s\n", dtmfmode2str(ast_test_flag(&global_flags, SIP_DTMF))); 08219 ast_cli(fd, " Qualify: %d\n", default_qualify); 08220 ast_cli(fd, " Use ClientCode: %s\n", ast_test_flag(&global_flags, SIP_USECLIENTCODE) ? "Yes" : "No"); 08221 ast_cli(fd, " Progress inband: %s\n", (ast_test_flag(&global_flags, SIP_PROG_INBAND) == SIP_PROG_INBAND_NEVER) ? "Never" : (ast_test_flag(&global_flags, SIP_PROG_INBAND) == SIP_PROG_INBAND_NO) ? "No" : "Yes" ); 08222 ast_cli(fd, " Language: %s\n", ast_strlen_zero(default_language) ? "(Defaults to English)" : default_language); 08223 ast_cli(fd, " Musicclass: %s\n", global_musicclass); 08224 ast_cli(fd, " Voice Mail Extension: %s\n", global_vmexten); 08225 08226 08227 if (realtimepeers || realtimeusers) { 08228 ast_cli(fd, "\nRealtime SIP Settings:\n"); 08229 ast_cli(fd, "----------------------\n"); 08230 ast_cli(fd, " Realtime Peers: %s\n", realtimepeers ? "Yes" : "No"); 08231 ast_cli(fd, " Realtime Users: %s\n", realtimeusers ? "Yes" : "No"); 08232 ast_cli(fd, " Cache Friends: %s\n", ast_test_flag(&global_flags_page2, SIP_PAGE2_RTCACHEFRIENDS) ? "Yes" : "No"); 08233 ast_cli(fd, " Update: %s\n", ast_test_flag(&global_flags_page2, SIP_PAGE2_RTUPDATE) ? "Yes" : "No"); 08234 ast_cli(fd, " Ignore Reg. Expire: %s\n", ast_test_flag(&global_flags_page2, SIP_PAGE2_IGNOREREGEXPIRE) ? "Yes" : "No"); 08235 ast_cli(fd, " Auto Clear: %d\n", global_rtautoclear); 08236 } 08237 ast_cli(fd, "\n----\n"); 08238 return RESULT_SUCCESS; 08239 }
|
|
sip_show_subscriptions: Show active SIP subscriptions ---
Definition at line 8275 of file chan_sip.c. References __sip_show_channels(). 08276 { 08277 return __sip_show_channels(fd, argc, argv, 1); 08278 }
|
|
sip_show_user: Show one user in detail ---
Definition at line 8070 of file chan_sip.c. References ast_callerid_merge(), ast_cdr_flags2str(), ast_cli(), ast_codec_pref_index(), ast_describe_caller_presentation(), ast_getformatname(), ast_strlen_zero(), ASTOBJ_UNREF, find_user(), ast_variable::name, ast_variable::next, print_group(), RESULT_SHOWUSAGE, sip_destroy_user(), user, and ast_variable::value. 08071 { 08072 char cbuf[256]; 08073 struct sip_user *user; 08074 struct ast_codec_pref *pref; 08075 struct ast_variable *v; 08076 int x = 0, codec = 0, load_realtime = 0; 08077 08078 if (argc < 4) 08079 return RESULT_SHOWUSAGE; 08080 08081 /* Load from realtime storage? */ 08082 load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? 1 : 0; 08083 08084 user = find_user(argv[3], load_realtime); 08085 if (user) { 08086 ast_cli(fd,"\n\n"); 08087 ast_cli(fd, " * Name : %s\n", user->name); 08088 ast_cli(fd, " Secret : %s\n", ast_strlen_zero(user->secret)?"<Not set>":"<Set>"); 08089 ast_cli(fd, " MD5Secret : %s\n", ast_strlen_zero(user->md5secret)?"<Not set>":"<Set>"); 08090 ast_cli(fd, " Context : %s\n", user->context); 08091 ast_cli(fd, " Language : %s\n", user->language); 08092 if (!ast_strlen_zero(user->accountcode)) 08093 ast_cli(fd, " Accountcode : %s\n", user->accountcode); 08094 ast_cli(fd, " AMA flags : %s\n", ast_cdr_flags2str(user->amaflags)); 08095 ast_cli(fd, " CallingPres : %s\n", ast_describe_caller_presentation(user->callingpres)); 08096 ast_cli(fd, " Call limit : %d\n", user->call_limit); 08097 ast_cli(fd, " Callgroup : "); 08098 print_group(fd, user->callgroup, 0); 08099 ast_cli(fd, " Pickupgroup : "); 08100 print_group(fd, user->pickupgroup, 0); 08101 ast_cli(fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), user->cid_name, user->cid_num, "<unspecified>")); 08102 ast_cli(fd, " ACL : %s\n", (user->ha?"Yes":"No")); 08103 ast_cli(fd, " Codec Order : ("); 08104 pref = &user->prefs; 08105 for(x = 0; x < 32 ; x++) { 08106 codec = ast_codec_pref_index(pref,x); 08107 if (!codec) 08108 break; 08109 ast_cli(fd, "%s", ast_getformatname(codec)); 08110 if (x < 31 && ast_codec_pref_index(pref,x+1)) 08111 ast_cli(fd, "|"); 08112 } 08113 08114 if (!x) 08115 ast_cli(fd, "none"); 08116 ast_cli(fd, ")\n"); 08117 08118 if (user->chanvars) { 08119 ast_cli(fd, " Variables :\n"); 08120 for (v = user->chanvars ; v ; v = v->next) 08121 ast_cli(fd, " %s = %s\n", v->name, v->value); 08122 } 08123 ast_cli(fd,"\n"); 08124 ASTOBJ_UNREF(user,sip_destroy_user); 08125 } else { 08126 ast_cli(fd,"User %s not found.\n", argv[3]); 08127 ast_cli(fd,"\n"); 08128 } 08129 08130 return RESULT_SUCCESS; 08131 }
|
|
sip_show_users: CLI Command 'SIP Show Users' ---
Definition at line 7380 of file chan_sip.c. References ast_cli(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, FORMAT, RESULT_SHOWUSAGE, and userl. 07381 { 07382 regex_t regexbuf; 07383 int havepattern = 0; 07384 07385 #define FORMAT "%-25.25s %-15.15s %-15.15s %-15.15s %-5.5s%-10.10s\n" 07386 07387 switch (argc) { 07388 case 5: 07389 if (!strcasecmp(argv[3], "like")) { 07390 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 07391 return RESULT_SHOWUSAGE; 07392 havepattern = 1; 07393 } else 07394 return RESULT_SHOWUSAGE; 07395 case 3: 07396 break; 07397 default: 07398 return RESULT_SHOWUSAGE; 07399 } 07400 07401 ast_cli(fd, FORMAT, "Username", "Secret", "Accountcode", "Def.Context", "ACL", "NAT"); 07402 ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do { 07403 ASTOBJ_RDLOCK(iterator); 07404 07405 if (havepattern && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 07406 ASTOBJ_UNLOCK(iterator); 07407 continue; 07408 } 07409 07410 ast_cli(fd, FORMAT, iterator->name, 07411 iterator->secret, 07412 iterator->accountcode, 07413 iterator->context, 07414 iterator->ha ? "Yes" : "No", 07415 nat2str(ast_test_flag(iterator, SIP_NAT))); 07416 ASTOBJ_UNLOCK(iterator); 07417 } while (0) 07418 ); 07419 07420 if (havepattern) 07421 regfree(®exbuf); 07422 07423 return RESULT_SUCCESS; 07424 #undef FORMAT 07425 }
|
|
sip_sipredirect: Transfer call before connect with a 302 redirect ---
Definition at line 12933 of file chan_sip.c. References ast_log(), ast_set_flag, ast_strdupa, ast_strlen_zero(), get_header(), host, sip_pvt::initreq, LOG_ERROR, sip_pvt::our_contact, SIP_ALREADYGONE, strsep(), and transmit_response_reliable(). Referenced by sip_transfer(). 12934 { 12935 char *cdest; 12936 char *extension, *host, *port; 12937 char tmp[80]; 12938 12939 cdest = ast_strdupa(dest); 12940 if (!cdest) { 12941 ast_log(LOG_ERROR, "Problem allocating the memory\n"); 12942 return 0; 12943 } 12944 extension = strsep(&cdest, "@"); 12945 host = strsep(&cdest, ":"); 12946 port = strsep(&cdest, ":"); 12947 if (!extension) { 12948 ast_log(LOG_ERROR, "Missing mandatory argument: extension\n"); 12949 return 0; 12950 } 12951 12952 /* we'll issue the redirect message here */ 12953 if (!host) { 12954 char *localtmp; 12955 ast_copy_string(tmp, get_header(&p->initreq, "To"), sizeof(tmp)); 12956 if (!strlen(tmp)) { 12957 ast_log(LOG_ERROR, "Cannot retrieve the 'To' header from the original SIP request!\n"); 12958 return 0; 12959 } 12960 if ((localtmp = strstr(tmp, "sip:")) && (localtmp = strchr(localtmp, '@'))) { 12961 char lhost[80], lport[80]; 12962 memset(lhost, 0, sizeof(lhost)); 12963 memset(lport, 0, sizeof(lport)); 12964 localtmp++; 12965 /* This is okey because lhost and lport are as big as tmp */ 12966 sscanf(localtmp, "%[^<>:; ]:%[^<>:; ]", lhost, lport); 12967 if (!strlen(lhost)) { 12968 ast_log(LOG_ERROR, "Can't find the host address\n"); 12969 return 0; 12970 } 12971 host = ast_strdupa(lhost); 12972 if (!host) { 12973 ast_log(LOG_ERROR, "Problem allocating the memory\n"); 12974 return 0; 12975 } 12976 if (!ast_strlen_zero(lport)) { 12977 port = ast_strdupa(lport); 12978 if (!port) { 12979 ast_log(LOG_ERROR, "Problem allocating the memory\n"); 12980 return 0; 12981 } 12982 } 12983 } 12984 } 12985 12986 snprintf(p->our_contact, sizeof(p->our_contact), "Transfer <sip:%s@%s%s%s>", extension, host, port ? ":" : "", port ? port : ""); 12987 transmit_response_reliable(p, "302 Moved Temporarily", &p->initreq, 1); 12988 12989 /* this is all that we want to send to that SIP device */ 12990 ast_set_flag(p, SIP_ALREADYGONE); 12991 12992 /* hangup here */ 12993 return -1; 12994 }
|
|
sip_transfer: Transfer SIP call
Definition at line 2628 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(). 02629 { 02630 struct sip_pvt *p = ast->tech_pvt; 02631 int res; 02632 02633 ast_mutex_lock(&p->lock); 02634 if (ast->_state == AST_STATE_RING) 02635 res = sip_sipredirect(p, dest); 02636 else 02637 res = transmit_refer(p, dest); 02638 ast_mutex_unlock(&p->lock); 02639 return res; 02640 }
|
|
sip_write: Send frame to media channel (rtp) ---
Definition at line 2535 of file chan_sip.c. References ast_channel::_state, AST_FRAME_IMAGE, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_rtp_write(), ast_set_flag, AST_STATE_UP, ast_test_flag, 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::vrtp, and ast_channel::writeformat. 02536 { 02537 struct sip_pvt *p = ast->tech_pvt; 02538 int res = 0; 02539 switch (frame->frametype) { 02540 case AST_FRAME_VOICE: 02541 if (!(frame->subclass & ast->nativeformats)) { 02542 ast_log(LOG_WARNING, "Asked to transmit frame type %d, while native formats is %d (read/write = %d/%d)\n", 02543 frame->subclass, ast->nativeformats, ast->readformat, ast->writeformat); 02544 return 0; 02545 } 02546 if (p) { 02547 ast_mutex_lock(&p->lock); 02548 if (p->rtp) { 02549 /* If channel is not up, activate early media session */ 02550 if ((ast->_state != AST_STATE_UP) && !ast_test_flag(p, SIP_PROGRESS_SENT) && !ast_test_flag(p, SIP_OUTGOING)) { 02551 transmit_response_with_sdp(p, "183 Session Progress", &p->initreq, 0); 02552 ast_set_flag(p, SIP_PROGRESS_SENT); 02553 } 02554 time(&p->lastrtptx); 02555 res = ast_rtp_write(p->rtp, frame); 02556 } 02557 ast_mutex_unlock(&p->lock); 02558 } 02559 break; 02560 case AST_FRAME_VIDEO: 02561 if (p) { 02562 ast_mutex_lock(&p->lock); 02563 if (p->vrtp) { 02564 /* Activate video early media */ 02565 if ((ast->_state != AST_STATE_UP) && !ast_test_flag(p, SIP_PROGRESS_SENT) && !ast_test_flag(p, SIP_OUTGOING)) { 02566 transmit_response_with_sdp(p, "183 Session Progress", &p->initreq, 0); 02567 ast_set_flag(p, SIP_PROGRESS_SENT); 02568 } 02569 time(&p->lastrtptx); 02570 res = ast_rtp_write(p->vrtp, frame); 02571 } 02572 ast_mutex_unlock(&p->lock); 02573 } 02574 break; 02575 case AST_FRAME_IMAGE: 02576 return 0; 02577 break; 02578 default: 02579 ast_log(LOG_WARNING, "Can't send %d type frames with SIP write\n", frame->frametype); 02580 return 0; 02581 } 02582 02583 return res; 02584 }
|
|
sipsock_read: Read data from SIP socket ---
Definition at line 11105 of file chan_sip.c. References append_history(), ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_set_flag, ast_test_flag, ast_update_use_count(), ast_verbose(), sip_pvt::callid, find_call(), find_sip_method(), get_header(), handle_request(), sip_pvt::lock, ast_channel::lock, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, lws2sws(), sip_pvt::owner, parse_request(), pedanticsipchecking, recordhistory, sip_pvt::recv, sip_debug_test_addr(), SIP_PKT_DEBUG, and sipsock. Referenced by do_monitor(). 11106 { 11107 struct sip_request req; 11108 struct sockaddr_in sin = { 0, }; 11109 struct sip_pvt *p; 11110 int res; 11111 socklen_t len; 11112 int nounlock; 11113 int recount = 0; 11114 char iabuf[INET_ADDRSTRLEN]; 11115 11116 len = sizeof(sin); 11117 memset(&req, 0, sizeof(req)); 11118 res = recvfrom(sipsock, req.data, sizeof(req.data) - 1, 0, (struct sockaddr *)&sin, &len); 11119 if (res < 0) { 11120 #if !defined(__FreeBSD__) 11121 if (errno == EAGAIN) 11122 ast_log(LOG_NOTICE, "SIP: Received packet with bad UDP checksum\n"); 11123 else 11124 #endif 11125 if (errno != ECONNREFUSED) 11126 ast_log(LOG_WARNING, "Recv error: %s\n", strerror(errno)); 11127 return 1; 11128 } 11129 if (res == sizeof(req.data)) { 11130 ast_log(LOG_DEBUG, "Received packet exceeds buffer. Data is possibly lost\n"); 11131 } 11132 req.data[res] = '\0'; 11133 req.len = res; 11134 if(sip_debug_test_addr(&sin)) 11135 ast_set_flag(&req, SIP_PKT_DEBUG); 11136 if (pedanticsipchecking) 11137 req.len = lws2sws(req.data, req.len); /* Fix multiline headers */ 11138 if (ast_test_flag(&req, SIP_PKT_DEBUG)) { 11139 ast_verbose("\n<-- SIP read from %s:%d: \n%s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), ntohs(sin.sin_port), req.data); 11140 } 11141 parse_request(&req); 11142 req.method = find_sip_method(req.rlPart1); 11143 if (ast_test_flag(&req, SIP_PKT_DEBUG)) { 11144 ast_verbose("--- (%d headers %d lines)", req.headers, req.lines); 11145 if (req.headers + req.lines == 0) 11146 ast_verbose(" Nat keepalive "); 11147 ast_verbose("---\n"); 11148 } 11149 11150 if (req.headers < 2) { 11151 /* Must have at least two headers */ 11152 return 1; 11153 } 11154 11155 11156 /* Process request, with netlock held */ 11157 retrylock: 11158 ast_mutex_lock(&netlock); 11159 p = find_call(&req, &sin, req.method); 11160 if (p) { 11161 /* Go ahead and lock the owner if it has one -- we may need it */ 11162 if (p->owner && ast_mutex_trylock(&p->owner->lock)) { 11163 ast_log(LOG_DEBUG, "Failed to grab lock, trying again...\n"); 11164 ast_mutex_unlock(&p->lock); 11165 ast_mutex_unlock(&netlock); 11166 /* Sleep infintismly short amount of time */ 11167 usleep(1); 11168 goto retrylock; 11169 } 11170 memcpy(&p->recv, &sin, sizeof(p->recv)); 11171 if (recordhistory) { 11172 char tmp[80]; 11173 /* This is a response, note what it was for */ 11174 snprintf(tmp, sizeof(tmp), "%s / %s", req.data, get_header(&req, "CSeq")); 11175 append_history(p, "Rx", tmp); 11176 } 11177 nounlock = 0; 11178 if (handle_request(p, &req, &sin, &recount, &nounlock) == -1) { 11179 /* Request failed */ 11180 ast_log(LOG_DEBUG, "SIP message could not be handled, bad request: %-70.70s\n", p->callid[0] ? p->callid : "<no callid>"); 11181 } 11182 11183 if (p->owner && !nounlock) 11184 ast_mutex_unlock(&p->owner->lock); 11185 ast_mutex_unlock(&p->lock); 11186 } 11187 ast_mutex_unlock(&netlock); 11188 if (recount) 11189 ast_update_use_count(); 11190 11191 return 1; 11192 }
|
|
subscription_type2str: Show subscription type in string format
Definition at line 8242 of file chan_sip.c. References subscription_types, and type. Referenced by __sip_show_channels(), and sip_show_channel(). 08242 { 08243 int i; 08244 08245 for (i = 1; (i < (sizeof(subscription_types) / sizeof(subscription_types[0]))); i++) { 08246 if (subscription_types[i].type == subtype) { 08247 return subscription_types[i].text; 08248 } 08249 } 08250 return subscription_types[0].text; 08251 }
|
|
temp_peer: Create temporary peer (used in autocreatepeer mode) ---
Definition at line 12002 of file chan_sip.c. References apeerobjs, ast_copy_flags, ast_set_flag, ASTOBJ_INIT, default_context, default_language, DEFAULT_SIP_PORT, default_subscribecontext, global_capability, global_flags, global_musicclass, global_rtpholdtimeout, global_rtpkeepalive, global_rtptimeout, malloc, prefs, reg_source_db(), SIP_DYNAMIC, SIP_FLAGS_TO_COPY, and SIP_SELFDESTRUCT. Referenced by register_verify(). 12003 { 12004 struct sip_peer *peer; 12005 12006 peer = malloc(sizeof(*peer)); 12007 if (!peer) 12008 return NULL; 12009 12010 memset(peer, 0, sizeof(*peer)); 12011 apeerobjs++; 12012 ASTOBJ_INIT(peer); 12013 12014 peer->expire = -1; 12015 peer->pokeexpire = -1; 12016 ast_copy_string(peer->name, name, sizeof(peer->name)); 12017 ast_copy_flags(peer, &global_flags, SIP_FLAGS_TO_COPY); 12018 strcpy(peer->context, default_context); 12019 strcpy(peer->subscribecontext, default_subscribecontext); 12020 strcpy(peer->language, default_language); 12021 strcpy(peer->musicclass, global_musicclass); 12022 peer->addr.sin_port = htons(DEFAULT_SIP_PORT); 12023 peer->addr.sin_family = AF_INET; 12024 peer->capability = global_capability; 12025 peer->rtptimeout = global_rtptimeout; 12026 peer->rtpholdtimeout = global_rtpholdtimeout; 12027 peer->rtpkeepalive = global_rtpkeepalive; 12028 ast_set_flag(peer, SIP_SELFDESTRUCT); 12029 ast_set_flag(peer, SIP_DYNAMIC); 12030 peer->prefs = prefs; 12031 reg_source_db(peer); 12032 12033 return peer; 12034 }
|
|
Thread-safe random number generator.
Definition at line 956 of file chan_sip.c. References ast_mutex_lock(), and ast_mutex_unlock(). Referenced by build_callid(), build_reply_digest(), check_auth(), make_our_tag(), reg_source_db(), reqprep(), sip_alloc(), sip_new(), transmit_invite(), and transmit_register(). 00957 { 00958 int val; 00959 00960 ast_mutex_lock(&rand_lock); 00961 val = rand(); 00962 ast_mutex_unlock(&rand_lock); 00963 00964 return val; 00965 }
|
|
transmit_info_with_digit: Send SIP INFO dtmf message, see Cisco documentation on cisco.co m ---
Definition at line 5567 of file chan_sip.c. References add_digit(), sip_pvt::ocseq, reqprep(), send_request(), and SIP_INFO. Referenced by sip_senddigit(). 05568 { 05569 struct sip_request req; 05570 reqprep(&req, p, SIP_INFO, 0, 1); 05571 add_digit(&req, digit); 05572 return send_request(p, &req, 1, p->ocseq); 05573 }
|
|
transmit_info_with_vidupdate: Send SIP INFO with video update request ---
Definition at line 5576 of file chan_sip.c. References add_vidupdate(), sip_pvt::ocseq, reqprep(), send_request(), and SIP_INFO. Referenced by sip_indicate(). 05577 { 05578 struct sip_request req; 05579 reqprep(&req, p, SIP_INFO, 0, 1); 05580 add_vidupdate(&req); 05581 return send_request(p, &req, 1, p->ocseq); 05582 }
|
|
transmit_invite: Build REFER/INVITE/OPTIONS message and transmit it ---
Definition at line 4867 of file chan_sip.c. References add_blank_header(), add_header(), add_header_contentLength(), add_sdp(), sip_invite_param::addsipheaders, ALLOWED_METHODS, append_date(), AST_LIST_TRAVERSE, ast_log(), ast_rtp_offered_from_local(), ast_strdupa, ast_strlen_zero(), ast_var_name(), ast_var_value(), ast_verbose(), sip_invite_param::auth, sip_invite_param::authheader, sip_pvt::branch, build_via(), copy_request(), sip_invite_param::distinctive_ring, sip_request::headers, sip_pvt::initreq, initreqprep(), sip_pvt::lastinvite, sip_request::lines, LOG_DEBUG, LOG_WARNING, sip_request::method, sip_pvt::ocseq, sip_pvt::options, sip_invite_param::osptoken, sip_pvt::owner, parse_request(), sip_pvt::refer_to, sip_pvt::referred_by, reqprep(), sip_pvt::rtp, send_request(), sip_debug_test_pvt(), SIP_OPTIONS, SIP_REFER, sipdebug, thread_safe_rand(), ast_channel::varshead, and sip_pvt::via. Referenced by do_proxy_auth(), sip_call(), and sip_poke_peer(). 04868 { 04869 struct sip_request req; 04870 04871 req.method = sipmethod; 04872 if (init) { 04873 /* Bump branch even on initial requests */ 04874 p->branch ^= thread_safe_rand(); 04875 build_via(p, p->via, sizeof(p->via)); 04876 if (init > 1) 04877 initreqprep(&req, p, sipmethod); 04878 else 04879 reqprep(&req, p, sipmethod, 0, 1); 04880 } else 04881 reqprep(&req, p, sipmethod, 0, 1); 04882 04883 if (p->options && p->options->auth) 04884 add_header(&req, p->options->authheader, p->options->auth); 04885 append_date(&req); 04886 if (sipmethod == SIP_REFER) { /* Call transfer */ 04887 if (!ast_strlen_zero(p->refer_to)) 04888 add_header(&req, "Refer-To", p->refer_to); 04889 if (!ast_strlen_zero(p->referred_by)) 04890 add_header(&req, "Referred-By", p->referred_by); 04891 } 04892 #ifdef OSP_SUPPORT 04893 if ((req.method != SIP_OPTIONS) && p->options && !ast_strlen_zero(p->options->osptoken)) { 04894 ast_log(LOG_DEBUG,"Adding OSP Token: %s\n", p->options->osptoken); 04895 add_header(&req, "P-OSP-Auth-Token", p->options->osptoken); 04896 } 04897 #endif 04898 if (p->options && !ast_strlen_zero(p->options->distinctive_ring)) 04899 { 04900 add_header(&req, "Alert-Info", p->options->distinctive_ring); 04901 } 04902 add_header(&req, "Allow", ALLOWED_METHODS); 04903 if (p->options && p->options->addsipheaders ) { 04904 struct ast_channel *ast; 04905 char *header = (char *) NULL; 04906 char *content = (char *) NULL; 04907 char *end = (char *) NULL; 04908 struct varshead *headp = (struct varshead *) NULL; 04909 struct ast_var_t *current; 04910 04911 ast = p->owner; /* The owner channel */ 04912 if (ast) { 04913 char *headdup; 04914 headp = &ast->varshead; 04915 if (!headp) 04916 ast_log(LOG_WARNING,"No Headp for the channel...ooops!\n"); 04917 else { 04918 AST_LIST_TRAVERSE(headp, current, entries) { 04919 /* SIPADDHEADER: Add SIP header to outgoing call */ 04920 if (!strncasecmp(ast_var_name(current), "SIPADDHEADER", strlen("SIPADDHEADER"))) { 04921 header = ast_var_value(current); 04922 headdup = ast_strdupa(header); 04923 /* Strip of the starting " (if it's there) */ 04924 if (*headdup == '"') 04925 headdup++; 04926 if ((content = strchr(headdup, ':'))) { 04927 *content = '\0'; 04928 content++; /* Move pointer ahead */ 04929 /* Skip white space */ 04930 while (*content == ' ') 04931 content++; 04932 /* Strip the ending " (if it's there) */ 04933 end = content + strlen(content) -1; 04934 if (*end == '"') 04935 *end = '\0'; 04936 04937 add_header(&req, headdup, content); 04938 if (sipdebug) 04939 ast_log(LOG_DEBUG, "Adding SIP Header \"%s\" with content :%s: \n", headdup, content); 04940 } 04941 } 04942 } 04943 } 04944 } 04945 } 04946 if (sdp && p->rtp) { 04947 ast_rtp_offered_from_local(p->rtp, 1); 04948 add_sdp(&req, p); 04949 } else { 04950 add_header_contentLength(&req, 0); 04951 add_blank_header(&req); 04952 } 04953 04954 if (!p->initreq.headers) { 04955 /* Use this as the basis */ 04956 copy_request(&p->initreq, &req); 04957 parse_request(&p->initreq); 04958 if (sip_debug_test_pvt(p)) 04959 ast_verbose("%d headers, %d lines\n", p->initreq.headers, p->initreq.lines); 04960 } 04961 p->lastinvite = p->ocseq; 04962 return send_request(p, &req, init ? 2 : 1, p->ocseq); 04963 }
|
|
transmit_message_with_text: Transmit text with SIP MESSAGE method ---
Definition at line 5513 of file chan_sip.c. References add_text(), sip_pvt::ocseq, reqprep(), send_request(), and SIP_MESSAGE. Referenced by sip_sendtext(). 05514 { 05515 struct sip_request req; 05516 reqprep(&req, p, SIP_MESSAGE, 0, 1); 05517 add_text(&req, text); 05518 return send_request(p, &req, 1, p->ocseq); 05519 }
|
|
transmit_notify_with_mwi: Notify user of messages waiting in voicemail ---
Definition at line 5138 of file chan_sip.c. References add_header(), add_header_contentLength(), add_line(), ast_build_string(), ast_inet_ntoa(), ast_log(), ast_strlen_zero(), ast_verbose(), copy_request(), default_notifymime, determine_firstline_parts(), sip_pvt::fromdomain, global_vmexten, sip_request::headers, sip_pvt::initreq, initreqprep(), sip_request::lines, LOG_WARNING, sip_pvt::ocseq, sip_pvt::ourip, parse_request(), send_request(), sip_debug_test_pvt(), SIP_NOTIFY, and t. Referenced by sip_send_mwi_to_peer(). 05139 { 05140 struct sip_request req; 05141 char tmp[500]; 05142 char *t = tmp; 05143 size_t maxbytes = sizeof(tmp); 05144 char iabuf[INET_ADDRSTRLEN]; 05145 05146 initreqprep(&req, p, SIP_NOTIFY); 05147 add_header(&req, "Event", "message-summary"); 05148 add_header(&req, "Content-Type", default_notifymime); 05149 05150 ast_build_string(&t, &maxbytes, "Messages-Waiting: %s\r\n", newmsgs ? "yes" : "no"); 05151 ast_build_string(&t, &maxbytes, "Message-Account: sip:%s@%s\r\n", !ast_strlen_zero(vmexten) ? vmexten : global_vmexten, ast_strlen_zero(p->fromdomain) ? ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip) : p->fromdomain); 05152 ast_build_string(&t, &maxbytes, "Voice-Message: %d/%d (0/0)\r\n", newmsgs, oldmsgs); 05153 05154 if (t > tmp + sizeof(tmp)) 05155 ast_log(LOG_WARNING, "Buffer overflow detected!! (Please file a bug report)\n"); 05156 05157 add_header_contentLength(&req, strlen(tmp)); 05158 add_line(&req, tmp); 05159 05160 if (!p->initreq.headers) { /* Use this as the basis */ 05161 copy_request(&p->initreq, &req); 05162 parse_request(&p->initreq); 05163 if (sip_debug_test_pvt(p)) 05164 ast_verbose("%d headers, %d lines\n", p->initreq.headers, p->initreq.lines); 05165 determine_firstline_parts(&p->initreq); 05166 } 05167 05168 return send_request(p, &req, 1, p->ocseq); 05169 }
|
|
transmit_notify_with_sipfrag: Notify a transferring party of the status of trasnfer ---
Definition at line 5191 of file chan_sip.c. References add_header(), add_header_contentLength(), add_line(), ast_verbose(), copy_request(), determine_firstline_parts(), sip_request::headers, sip_pvt::initreq, sip_request::lines, sip_pvt::ocseq, parse_request(), reqprep(), send_request(), sip_debug_test_pvt(), and SIP_NOTIFY. Referenced by handle_request_refer(). 05192 { 05193 struct sip_request req; 05194 char tmp[20]; 05195 reqprep(&req, p, SIP_NOTIFY, 0, 1); 05196 snprintf(tmp, sizeof(tmp), "refer;id=%d", cseq); 05197 add_header(&req, "Event", tmp); 05198 add_header(&req, "Subscription-state", "terminated;reason=noresource"); 05199 add_header(&req, "Content-Type", "message/sipfrag;version=2.0"); 05200 05201 strcpy(tmp, "SIP/2.0 200 OK"); 05202 add_header_contentLength(&req, strlen(tmp)); 05203 add_line(&req, tmp); 05204 05205 if (!p->initreq.headers) { 05206 /* Use this as the basis */ 05207 copy_request(&p->initreq, &req); 05208 parse_request(&p->initreq); 05209 if (sip_debug_test_pvt(p)) 05210 ast_verbose("%d headers, %d lines\n", p->initreq.headers, p->initreq.lines); 05211 determine_firstline_parts(&p->initreq); 05212 } 05213 05214 return send_request(p, &req, 1, p->ocseq); 05215 }
|
|
transmit_refer: Transmit SIP REFER message ---
Definition at line 5522 of file chan_sip.c. References add_blank_header(), add_header(), ast_log(), ast_strlen_zero(), ast_test_flag, sip_pvt::from, get_header(), get_in_brackets(), sip_pvt::initreq, LOG_NOTICE, sip_pvt::ocseq, sip_pvt::our_contact, sip_pvt::refer_to, sip_pvt::referred_by, reqprep(), send_request(), SIP_OUTGOING, and SIP_REFER. Referenced by sip_transfer(). 05523 { 05524 struct sip_request req; 05525 char from[256]; 05526 char *of, *c; 05527 char referto[256]; 05528 05529 if (ast_test_flag(p, SIP_OUTGOING)) 05530 of = get_header(&p->initreq, "To"); 05531 else 05532 of = get_header(&p->initreq, "From"); 05533 ast_copy_string(from, of, sizeof(from)); 05534 of = get_in_brackets(from); 05535 ast_copy_string(p->from,of,sizeof(p->from)); 05536 if (strncmp(of, "sip:", 4)) { 05537 ast_log(LOG_NOTICE, "From address missing 'sip:', using it anyway\n"); 05538 } else 05539 of += 4; 05540 /* Get just the username part */ 05541 if ((c = strchr(dest, '@'))) { 05542 c = NULL; 05543 } else if ((c = strchr(of, '@'))) { 05544 *c = '\0'; 05545 c++; 05546 } 05547 if (c) { 05548 snprintf(referto, sizeof(referto), "<sip:%s@%s>", dest, c); 05549 } else { 05550 snprintf(referto, sizeof(referto), "<sip:%s>", dest); 05551 } 05552 05553 /* save in case we get 407 challenge */ 05554 ast_copy_string(p->refer_to, referto, sizeof(p->refer_to)); 05555 ast_copy_string(p->referred_by, p->our_contact, sizeof(p->referred_by)); 05556 05557 reqprep(&req, p, SIP_REFER, 0, 1); 05558 add_header(&req, "Refer-To", referto); 05559 if (!ast_strlen_zero(p->our_contact)) 05560 add_header(&req, "Referred-By", p->our_contact); 05561 add_blank_header(&req); 05562 return send_request(p, &req, 1, p->ocseq); 05563 }
|
|
transmit_register: Transmit register to SIP proxy or UA ---
Definition at line 5321 of file chan_sip.c. References __ourip, add_blank_header(), add_header(), add_header_contentLength(), append_history(), ast_log(), ast_sched_add(), ast_sched_del(), ast_set_flag, ast_sip_ouraddrfor(), ast_strlen_zero(), ast_verbose(), ASTOBJ_REF, sip_pvt::authname, sip_registry::authuser, bindaddr, sip_pvt::branch, build_callid(), build_contact(), build_reply_digest(), build_via(), sip_registry::call, sip_pvt::callid, sip_registry::callid, sip_registry::callid_valid, sip_registry::contact, copy_request(), create_addr(), default_expiry, default_fromdomain, DEFAULT_MAX_FORWARDS, default_useragent, determine_firstline_parts(), sip_registry::domain, sip_pvt::domain, sip_pvt::exten, sip_pvt::fromdomain, sip_pvt::fromuser, global_reg_timeout, sip_request::headers, sip_registry::hostname, init_req(), sip_pvt::initreq, sip_request::lines, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, make_our_tag(), sip_registry::md5secret, sip_pvt::nonce, sip_registry::nonce, sip_registry::noncecount, sip_pvt::noncecount, sip_pvt::ocseq, sip_registry::ocseq, sip_registry::opaque, sip_pvt::opaque, option_debug, sip_pvt::our_contact, sip_pvt::ourip, parse_request(), sip_pvt::peermd5secret, sip_pvt::peername, sip_pvt::peersecret, sip_registry::portno, sip_registry::qop, sip_pvt::qop, sip_registry::realm, sip_pvt::realm, recordhistory, REG_STATE_AUTHSENT, REG_STATE_REGSENT, sip_registry::regattempts, sip_pvt::registry, sip_registry::regstate, sip_pvt::sa, sip_registry::secret, send_request(), sip_alloc(), sip_debug_test_pvt(), sip_destroy(), sip_methods, SIP_OUTGOING, sip_reg_timeout(), SIP_REGISTER, sipdebug, sip_pvt::tag, cfsip_methods::text, sip_pvt::theirtag, thread_safe_rand(), sip_registry::timeout, sip_pvt::tohost, sip_pvt::uri, sip_pvt::username, and sip_registry::username. Referenced by __sip_do_register(), do_register_auth(), and sip_reg_timeout(). 05322 { 05323 struct sip_request req; 05324 char from[256]; 05325 char to[256]; 05326 char tmp[80]; 05327 char via[80]; 05328 char addr[80]; 05329 struct sip_pvt *p; 05330 05331 /* exit if we are already in process with this registrar ?*/ 05332 if ( r == NULL || ((auth==NULL) && (r->regstate==REG_STATE_REGSENT || r->regstate==REG_STATE_AUTHSENT))) { 05333 ast_log(LOG_NOTICE, "Strange, trying to register %s@%s when registration already pending\n", r->username, r->hostname); 05334 return 0; 05335 } 05336 05337 if (r->call) { /* We have a registration */ 05338 if (!auth) { 05339 ast_log(LOG_WARNING, "Already have a REGISTER going on to %s@%s?? \n", r->username, r->hostname); 05340 return 0; 05341 } else { 05342 p = r->call; 05343 make_our_tag(p->tag, sizeof(p->tag)); /* create a new local tag for every register attempt */ 05344 p->theirtag[0]='\0'; /* forget their old tag, so we don't match tags when getting response */ 05345 } 05346 } else { 05347 /* Build callid for registration if we haven't registered before */ 05348 if (!r->callid_valid) { 05349 build_callid(r->callid, sizeof(r->callid), __ourip, default_fromdomain); 05350 r->callid_valid = 1; 05351 } 05352 /* Allocate SIP packet for registration */ 05353 p=sip_alloc( r->callid, NULL, 0, SIP_REGISTER); 05354 if (!p) { 05355 ast_log(LOG_WARNING, "Unable to allocate registration call\n"); 05356 return 0; 05357 } 05358 if (recordhistory) { 05359 char tmp[80]; 05360 snprintf(tmp, sizeof(tmp), "Account: %s@%s", r->username, r->hostname); 05361 append_history(p, "RegistryInit", tmp); 05362 } 05363 /* Find address to hostname */ 05364 if (create_addr(p, r->hostname)) { 05365 /* we have what we hope is a temporary network error, 05366 * probably DNS. We need to reschedule a registration try */ 05367 sip_destroy(p); 05368 if (r->timeout > -1) { 05369 ast_sched_del(sched, r->timeout); 05370 r->timeout = ast_sched_add(sched, global_reg_timeout*1000, sip_reg_timeout, r); 05371 ast_log(LOG_WARNING, "Still have a registration timeout for %s@%s (create_addr() error), %d\n", r->username, r->hostname, r->timeout); 05372 } else { 05373 r->timeout = ast_sched_add(sched, global_reg_timeout*1000, sip_reg_timeout, r); 05374 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); 05375 } 05376 r->regattempts++; 05377 return 0; 05378 } 05379 /* Copy back Call-ID in case create_addr changed it */ 05380 ast_copy_string(r->callid, p->callid, sizeof(r->callid)); 05381 if (r->portno) 05382 p->sa.sin_port = htons(r->portno); 05383 else /* Set registry port to the port set from the peer definition/srv or default */ 05384 r->portno = ntohs(p->sa.sin_port); 05385 ast_set_flag(p, SIP_OUTGOING); /* Registration is outgoing call */ 05386 r->call=p; /* Save pointer to SIP packet */ 05387 p->registry=ASTOBJ_REF(r); /* Add pointer to registry in packet */ 05388 if (!ast_strlen_zero(r->secret)) /* Secret (password) */ 05389 ast_copy_string(p->peersecret, r->secret, sizeof(p->peersecret)); 05390 if (!ast_strlen_zero(r->md5secret)) 05391 ast_copy_string(p->peermd5secret, r->md5secret, sizeof(p->peermd5secret)); 05392 /* User name in this realm 05393 - if authuser is set, use that, otherwise use username */ 05394 if (!ast_strlen_zero(r->authuser)) { 05395 ast_copy_string(p->peername, r->authuser, sizeof(p->peername)); 05396 ast_copy_string(p->authname, r->authuser, sizeof(p->authname)); 05397 } else { 05398 if (!ast_strlen_zero(r->username)) { 05399 ast_copy_string(p->peername, r->username, sizeof(p->peername)); 05400 ast_copy_string(p->authname, r->username, sizeof(p->authname)); 05401 ast_copy_string(p->fromuser, r->username, sizeof(p->fromuser)); 05402 } 05403 } 05404 if (!ast_strlen_zero(r->username)) 05405 ast_copy_string(p->username, r->username, sizeof(p->username)); 05406 /* Save extension in packet */ 05407 ast_copy_string(p->exten, r->contact, sizeof(p->exten)); 05408 05409 /* 05410 check which address we should use in our contact header 05411 based on whether the remote host is on the external or 05412 internal network so we can register through nat 05413 */ 05414 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 05415 memcpy(&p->ourip, &bindaddr.sin_addr, sizeof(p->ourip)); 05416 build_contact(p); 05417 } 05418 05419 /* set up a timeout */ 05420 if (auth == NULL) { 05421 if (r->timeout > -1) { 05422 ast_log(LOG_WARNING, "Still have a registration timeout, #%d - deleting it\n", r->timeout); 05423 ast_sched_del(sched, r->timeout); 05424 } 05425 r->timeout = ast_sched_add(sched, global_reg_timeout * 1000, sip_reg_timeout, r); 05426 ast_log(LOG_DEBUG, "Scheduled a registration timeout for %s id #%d \n", r->hostname, r->timeout); 05427 } 05428 05429 if (strchr(r->username, '@')) { 05430 snprintf(from, sizeof(from), "<sip:%s>;tag=%s", r->username, p->tag); 05431 if (!ast_strlen_zero(p->theirtag)) 05432 snprintf(to, sizeof(to), "<sip:%s>;tag=%s", r->username, p->theirtag); 05433 else 05434 snprintf(to, sizeof(to), "<sip:%s>", r->username); 05435 } else { 05436 snprintf(from, sizeof(from), "<sip:%s@%s>;tag=%s", r->username, p->tohost, p->tag); 05437 if (!ast_strlen_zero(p->theirtag)) 05438 snprintf(to, sizeof(to), "<sip:%s@%s>;tag=%s", r->username, p->tohost, p->theirtag); 05439 else 05440 snprintf(to, sizeof(to), "<sip:%s@%s>", r->username, p->tohost); 05441 } 05442 05443 /* Fromdomain is what we are registering to, regardless of actual 05444 host name from SRV */ 05445 if (!ast_strlen_zero(p->fromdomain)) 05446 snprintf(addr, sizeof(addr), "sip:%s", p->fromdomain); 05447 else 05448 snprintf(addr, sizeof(addr), "sip:%s", r->hostname); 05449 ast_copy_string(p->uri, addr, sizeof(p->uri)); 05450 05451 p->branch ^= thread_safe_rand(); 05452 05453 memset(&req, 0, sizeof(req)); 05454 init_req(&req, sipmethod, addr); 05455 05456 /* Add to CSEQ */ 05457 snprintf(tmp, sizeof(tmp), "%u %s", ++r->ocseq, sip_methods[sipmethod].text); 05458 p->ocseq = r->ocseq; 05459 05460 build_via(p, via, sizeof(via)); 05461 add_header(&req, "Via", via); 05462 add_header(&req, "From", from); 05463 add_header(&req, "To", to); 05464 add_header(&req, "Call-ID", p->callid); 05465 add_header(&req, "CSeq", tmp); 05466 add_header(&req, "User-Agent", default_useragent); 05467 add_header(&req, "Max-Forwards", DEFAULT_MAX_FORWARDS); 05468 05469 05470 if (auth) /* Add auth header */ 05471 add_header(&req, authheader, auth); 05472 else if (!ast_strlen_zero(r->nonce)) { 05473 char digest[1024]; 05474 05475 /* We have auth data to reuse, build a digest header! */ 05476 if (sipdebug) 05477 ast_log(LOG_DEBUG, " >>> Re-using Auth data for %s@%s\n", r->username, r->hostname); 05478 ast_copy_string(p->realm, r->realm, sizeof(p->realm)); 05479 ast_copy_string(p->nonce, r->nonce, sizeof(p->nonce)); 05480 ast_copy_string(p->domain, r->domain, sizeof(p->domain)); 05481 ast_copy_string(p->opaque, r->opaque, sizeof(p->opaque)); 05482 ast_copy_string(p->qop, r->qop, sizeof(p->qop)); 05483 p->noncecount = r->noncecount++; 05484 05485 memset(digest,0,sizeof(digest)); 05486 if(!build_reply_digest(p, sipmethod, digest, sizeof(digest))) 05487 add_header(&req, "Authorization", digest); 05488 else 05489 ast_log(LOG_NOTICE, "No authorization available for authentication of registration to %s@%s\n", r->username, r->hostname); 05490 05491 } 05492 05493 snprintf(tmp, sizeof(tmp), "%d", default_expiry); 05494 add_header(&req, "Expires", tmp); 05495 add_header(&req, "Contact", p->our_contact); 05496 add_header(&req, "Event", "registration"); 05497 add_header_contentLength(&req, 0); 05498 add_blank_header(&req); 05499 copy_request(&p->initreq, &req); 05500 parse_request(&p->initreq); 05501 if (sip_debug_test_pvt(p)) { 05502 ast_verbose("REGISTER %d headers, %d lines\n", p->initreq.headers, p->initreq.lines); 05503 } 05504 determine_firstline_parts(&p->initreq); 05505 r->regstate=auth?REG_STATE_AUTHSENT:REG_STATE_REGSENT; 05506 r->regattempts++; /* Another attempt */ 05507 if (option_debug > 3) 05508 ast_verbose("REGISTER attempt %d to %s@%s\n", r->regattempts, r->username, r->hostname); 05509 return send_request(p, &req, 2, p->ocseq); 05510 }
|
|
transmit_reinvite_with_sdp: Transmit reinvite with SDP :-) ---
Definition at line 4594 of file chan_sip.c. References add_header(), add_sdp(), ALLOWED_METHODS, ast_rtp_offered_from_local(), ast_set_flag, ast_test_flag, ast_verbose(), copy_request(), sip_request::headers, sip_pvt::initreq, sip_pvt::lastinvite, sip_request::lines, sip_pvt::ocseq, parse_request(), reqprep(), sip_pvt::rtp, send_request(), sip_debug_test_pvt(), SIP_INVITE, SIP_OUTGOING, SIP_REINVITE_UPDATE, SIP_UPDATE, and sipdebug. Referenced by check_pendings(), and sip_set_rtp_peer(). 04595 { 04596 struct sip_request req; 04597 if (ast_test_flag(p, SIP_REINVITE_UPDATE)) 04598 reqprep(&req, p, SIP_UPDATE, 0, 1); 04599 else 04600 reqprep(&req, p, SIP_INVITE, 0, 1); 04601 04602 add_header(&req, "Allow", ALLOWED_METHODS); 04603 if (sipdebug) 04604 add_header(&req, "X-asterisk-info", "SIP re-invite (RTP bridge)"); 04605 ast_rtp_offered_from_local(p->rtp, 1); 04606 add_sdp(&req, p); 04607 /* Use this as the basis */ 04608 copy_request(&p->initreq, &req); 04609 parse_request(&p->initreq); 04610 if (sip_debug_test_pvt(p)) 04611 ast_verbose("%d headers, %d lines\n", p->initreq.headers, p->initreq.lines); 04612 p->lastinvite = p->ocseq; 04613 ast_set_flag(p, SIP_OUTGOING); 04614 return send_request(p, &req, 1, p->ocseq); 04615 }
|
|
transmit_request: transmit generic SIP request ---
Definition at line 5585 of file chan_sip.c. References add_blank_header(), add_header_contentLength(), sip_pvt::ocseq, reqprep(), and send_request(). Referenced by handle_response(), handle_response_invite(), and handle_response_peerpoke(). 05586 { 05587 struct sip_request resp; 05588 reqprep(&resp, p, sipmethod, seqno, newbranch); 05589 add_header_contentLength(&resp, 0); 05590 add_blank_header(&resp); 05591 return send_request(p, &resp, reliable, seqno ? seqno : p->ocseq); 05592 }
|
|
transmit_request_with_auth: Transmit SIP request, auth added ---
Definition at line 5595 of file chan_sip.c. References add_blank_header(), add_header(), add_header_contentLength(), ast_cause2str(), ast_log(), sip_invite_param::auth_type, build_reply_digest(), sip_pvt::callid, ast_channel::hangupcause, LOG_WARNING, sip_pvt::ocseq, sip_pvt::options, sip_pvt::owner, PROXY_AUTH, sip_pvt::realm, reqprep(), send_request(), SIP_BYE, and WWW_AUTH. Referenced by check_pendings(), handle_request_refer(), and sip_hangup(). 05596 { 05597 struct sip_request resp; 05598 05599 reqprep(&resp, p, sipmethod, seqno, newbranch); 05600 if (*p->realm) { 05601 char digest[1024]; 05602 05603 memset(digest, 0, sizeof(digest)); 05604 if(!build_reply_digest(p, sipmethod, digest, sizeof(digest))) { 05605 if (p->options && p->options->auth_type == PROXY_AUTH) 05606 add_header(&resp, "Proxy-Authorization", digest); 05607 else if (p->options && p->options->auth_type == WWW_AUTH) 05608 add_header(&resp, "Authorization", digest); 05609 else /* Default, to be backwards compatible (maybe being too careful, but leaving it for now) */ 05610 add_header(&resp, "Proxy-Authorization", digest); 05611 } else 05612 ast_log(LOG_WARNING, "No authentication available for call %s\n", p->callid); 05613 } 05614 /* If we are hanging up and know a cause for that, send it in clear text to make 05615 debugging easier. */ 05616 if (sipmethod == SIP_BYE) { 05617 if (p->owner && p->owner->hangupcause) { 05618 add_header(&resp, "X-Asterisk-HangupCause", ast_cause2str(p->owner->hangupcause)); 05619 } 05620 } 05621 05622 add_header_contentLength(&resp, 0); 05623 add_blank_header(&resp); 05624 return send_request(p, &resp, reliable, seqno ? seqno : p->ocseq); 05625 }
|
|
transmit_response: Transmit response, no retransmits
Definition at line 4154 of file chan_sip.c. References __transmit_response(). 04155 { 04156 return __transmit_response(p, msg, req, 0); 04157 }
|
|
transmit_response_reliable: Transmit response, Make sure you get a reply
Definition at line 4170 of file chan_sip.c. References __transmit_response(). Referenced by handle_request(), handle_request_bye(), handle_request_cancel(), handle_request_invite(), sip_hangup(), and sip_sipredirect(). 04171 { 04172 return __transmit_response(p, msg, req, fatal ? 2 : 1); 04173 }
|
|
transmit_response_with_allow: Append Accept header, content length before transmitting response ---
Definition at line 4200 of file chan_sip.c. References add_blank_header(), add_header(), add_header_contentLength(), respprep(), and send_response(). Referenced by handle_request(), handle_request_options(), and handle_request_refer(). 04201 { 04202 struct sip_request resp; 04203 respprep(&resp, p, msg, req); 04204 add_header(&resp, "Accept", "application/sdp"); 04205 add_header_contentLength(&resp, 0); 04206 add_blank_header(&resp); 04207 return send_response(p, &resp, reliable, 0); 04208 }
|
|
Definition at line 4211 of file chan_sip.c. References add_blank_header(), add_header(), add_header_contentLength(), ast_log(), get_header(), global_realm, LOG_WARNING, respprep(), and send_response(). Referenced by check_auth(). 04212 { 04213 struct sip_request resp; 04214 char tmp[256]; 04215 int seqno = 0; 04216 04217 if (reliable && (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1)) { 04218 ast_log(LOG_WARNING, "Unable to determine sequence number from '%s'\n", get_header(req, "CSeq")); 04219 return -1; 04220 } 04221 /* Stale means that they sent us correct authentication, but 04222 based it on an old challenge (nonce) */ 04223 snprintf(tmp, sizeof(tmp), "Digest realm=\"%s\", nonce=\"%s\"%s", global_realm, randdata, stale ? ", stale=true" : ""); 04224 respprep(&resp, p, msg, req); 04225 add_header(&resp, header, tmp); 04226 add_header_contentLength(&resp, 0); 04227 add_blank_header(&resp); 04228 return send_response(p, &resp, reliable, seqno); 04229 }
|
|
transmit_response_with_date: Append date and content length before transmitting response ---
Definition at line 4189 of file chan_sip.c. References add_blank_header(), add_header_contentLength(), append_date(), respprep(), and send_response(). Referenced by register_verify(). 04190 { 04191 struct sip_request resp; 04192 respprep(&resp, p, msg, req); 04193 append_date(&resp); 04194 add_header_contentLength(&resp, 0); 04195 add_blank_header(&resp); 04196 return send_response(p, &resp, 0, 0); 04197 }
|
|
transmit_response_with_sdp: Used for 200 OK and 183 early media ---
Definition at line 4520 of file chan_sip.c. References add_sdp(), ast_log(), ast_rtp_offered_from_local(), sip_pvt::callid, get_header(), LOG_ERROR, LOG_WARNING, respprep(), sip_pvt::rtp, send_response(), and try_suggested_sip_codec(). Referenced by handle_request_invite(), sip_answer(), sip_indicate(), and sip_write(). 04521 { 04522 struct sip_request resp; 04523 int seqno; 04524 if (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1) { 04525 ast_log(LOG_WARNING, "Unable to get seqno from '%s'\n", get_header(req, "CSeq")); 04526 return -1; 04527 } 04528 respprep(&resp, p, msg, req); 04529 if (p->rtp) { 04530 ast_rtp_offered_from_local(p->rtp, 0); 04531 try_suggested_sip_codec(p); 04532 add_sdp(&resp, p); 04533 } else { 04534 ast_log(LOG_ERROR, "Can't add SDP to response, since we have no RTP session allocated. Call-ID %s\n", p->callid); 04535 } 04536 return send_response(p, &resp, retrans, seqno); 04537 }
|
|
transmit_response_with_unsupported: Transmit response, no retransmits
Definition at line 4160 of file chan_sip.c. References add_header(), append_date(), respprep(), and send_response(). Referenced by handle_request_invite(). 04161 { 04162 struct sip_request resp; 04163 respprep(&resp, p, msg, req); 04164 append_date(&resp); 04165 add_header(&resp, "Unsupported", unsupported); 04166 return send_response(p, &resp, 0, 0); 04167 }
|
|
transmit_sip_request: Transmit SIP request
Definition at line 5172 of file chan_sip.c. References ast_verbose(), copy_request(), determine_firstline_parts(), sip_request::headers, sip_pvt::initreq, sip_request::lines, sip_pvt::ocseq, parse_request(), send_request(), and sip_debug_test_pvt(). Referenced by sip_notify(). 05173 { 05174 if (!p->initreq.headers) { 05175 /* Use this as the basis */ 05176 copy_request(&p->initreq, req); 05177 parse_request(&p->initreq); 05178 if (sip_debug_test_pvt(p)) 05179 ast_verbose("%d headers, %d lines\n", p->initreq.headers, p->initreq.lines); 05180 determine_firstline_parts(&p->initreq); 05181 } 05182 05183 return send_request(p, req, 0, p->ocseq); 05184 }
|
|
transmit_state_notify: Used in the SUBSCRIBE notification subsystem ----
Definition at line 4966 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_REMOVED, AST_EXTENSION_RINGING, AST_EXTENSION_UNAVAILABLE, ast_get_hint(), ast_log(), AST_MAX_EXTENSION, sip_pvt::context, CPIM_PIDF_XML, DIALOG_INFO_XML, sip_pvt::dialogver, sip_pvt::expiry, sip_pvt::exten, find_subscription_type(), get_header(), get_in_brackets(), global_notifyringing, sip_pvt::initreq, LOG_WARNING, NONE, sip_pvt::ocseq, PIDF_XML, reqprep(), send_request(), SIP_NOTIFY, sip_pvt::subscribed, t, TIMEOUT, and XPIDF_XML. Referenced by __sip_autodestruct(), cb_extensionstate(), and handle_request_subscribe(). 04967 { 04968 char tmp[4000], from[256], to[256]; 04969 char *t = tmp, *c, *a, *mfrom, *mto; 04970 size_t maxbytes = sizeof(tmp); 04971 struct sip_request req; 04972 char hint[AST_MAX_EXTENSION]; 04973 char *statestring = "terminated"; 04974 const struct cfsubscription_types *subscriptiontype; 04975 enum state { NOTIFY_OPEN, NOTIFY_INUSE, NOTIFY_CLOSED } local_state = NOTIFY_OPEN; 04976 char *pidfstate = "--"; 04977 char *pidfnote= "Ready"; 04978 04979 memset(from, 0, sizeof(from)); 04980 memset(to, 0, sizeof(to)); 04981 memset(tmp, 0, sizeof(tmp)); 04982 04983 switch (state) { 04984 case (AST_EXTENSION_RINGING | AST_EXTENSION_INUSE): 04985 if (global_notifyringing) 04986 statestring = "early"; 04987 else 04988 statestring = "confirmed"; 04989 local_state = NOTIFY_INUSE; 04990 pidfstate = "busy"; 04991 pidfnote = "Ringing"; 04992 break; 04993 case AST_EXTENSION_RINGING: 04994 statestring = "early"; 04995 local_state = NOTIFY_INUSE; 04996 pidfstate = "busy"; 04997 pidfnote = "Ringing"; 04998 break; 04999 case AST_EXTENSION_INUSE: 05000 statestring = "confirmed"; 05001 local_state = NOTIFY_INUSE; 05002 pidfstate = "busy"; 05003 pidfnote = "On the phone"; 05004 break; 05005 case AST_EXTENSION_BUSY: 05006 statestring = "confirmed"; 05007 local_state = NOTIFY_CLOSED; 05008 pidfstate = "busy"; 05009 pidfnote = "On the phone"; 05010 break; 05011 case AST_EXTENSION_UNAVAILABLE: 05012 statestring = "confirmed"; 05013 local_state = NOTIFY_CLOSED; 05014 pidfstate = "away"; 05015 pidfnote = "Unavailable"; 05016 break; 05017 case AST_EXTENSION_NOT_INUSE: 05018 default: 05019 /* Default setting */ 05020 break; 05021 } 05022 05023 subscriptiontype = find_subscription_type(p->subscribed); 05024 05025 /* Check which device/devices we are watching and if they are registered */ 05026 if (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, p->context, p->exten)) { 05027 /* If they are not registered, we will override notification and show no availability */ 05028 if (ast_device_state(hint) == AST_DEVICE_UNAVAILABLE) { 05029 local_state = NOTIFY_CLOSED; 05030 pidfstate = "away"; 05031 pidfnote = "Not online"; 05032 } 05033 } 05034 05035 ast_copy_string(from, get_header(&p->initreq, "From"), sizeof(from)); 05036 c = get_in_brackets(from); 05037 if (strncmp(c, "sip:", 4)) { 05038 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", c); 05039 return -1; 05040 } 05041 if ((a = strchr(c, ';'))) 05042 *a = '\0'; 05043 mfrom = c; 05044 05045 ast_copy_string(to, get_header(&p->initreq, "To"), sizeof(to)); 05046 c = get_in_brackets(to); 05047 if (strncmp(c, "sip:", 4)) { 05048 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", c); 05049 return -1; 05050 } 05051 if ((a = strchr(c, ';'))) 05052 *a = '\0'; 05053 mto = c; 05054 05055 reqprep(&req, p, SIP_NOTIFY, 0, 1); 05056 05057 05058 add_header(&req, "Event", subscriptiontype->event); 05059 add_header(&req, "Content-Type", subscriptiontype->mediatype); 05060 switch(state) { 05061 case AST_EXTENSION_DEACTIVATED: 05062 if (p->subscribed == TIMEOUT) 05063 add_header(&req, "Subscription-State", "terminated;reason=timeout"); 05064 else { 05065 add_header(&req, "Subscription-State", "terminated;reason=probation"); 05066 add_header(&req, "Retry-After", "60"); 05067 } 05068 break; 05069 case AST_EXTENSION_REMOVED: 05070 add_header(&req, "Subscription-State", "terminated;reason=noresource"); 05071 break; 05072 break; 05073 default: 05074 if (p->expiry) 05075 add_header(&req, "Subscription-State", "active"); 05076 else /* Expired */ 05077 add_header(&req, "Subscription-State", "terminated;reason=timeout"); 05078 } 05079 switch (p->subscribed) { 05080 case XPIDF_XML: 05081 case CPIM_PIDF_XML: 05082 ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\"?>\n"); 05083 ast_build_string(&t, &maxbytes, "<!DOCTYPE presence PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n"); 05084 ast_build_string(&t, &maxbytes, "<presence>\n"); 05085 ast_build_string(&t, &maxbytes, "<presentity uri=\"%s;method=SUBSCRIBE\" />\n", mfrom); 05086 ast_build_string(&t, &maxbytes, "<atom id=\"%s\">\n", p->exten); 05087 ast_build_string(&t, &maxbytes, "<address uri=\"%s;user=ip\" priority=\"0.800000\">\n", mto); 05088 ast_build_string(&t, &maxbytes, "<status status=\"%s\" />\n", (local_state == NOTIFY_OPEN) ? "open" : (local_state == NOTIFY_INUSE) ? "inuse" : "closed"); 05089 ast_build_string(&t, &maxbytes, "<msnsubstatus substatus=\"%s\" />\n", (local_state == NOTIFY_OPEN) ? "online" : (local_state == NOTIFY_INUSE) ? "onthephone" : "offline"); 05090 ast_build_string(&t, &maxbytes, "</address>\n</atom>\n</presence>\n"); 05091 break; 05092 case PIDF_XML: /* Eyebeam supports this format */ 05093 ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n"); 05094 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); 05095 ast_build_string(&t, &maxbytes, "<pp:person><status>\n"); 05096 if (pidfstate[0] != '-') 05097 ast_build_string(&t, &maxbytes, "<ep:activities><ep:%s/></ep:activities>\n", pidfstate); 05098 ast_build_string(&t, &maxbytes, "</status></pp:person>\n"); 05099 ast_build_string(&t, &maxbytes, "<note>%s</note>\n", pidfnote); /* Note */ 05100 ast_build_string(&t, &maxbytes, "<tuple id=\"%s\">\n", p->exten); /* Tuple start */ 05101 ast_build_string(&t, &maxbytes, "<contact priority=\"1\">%s</contact>\n", mto); 05102 if (pidfstate[0] == 'b') /* Busy? Still open ... */ 05103 ast_build_string(&t, &maxbytes, "<status><basic>open</basic></status>\n"); 05104 else 05105 ast_build_string(&t, &maxbytes, "<status><basic>%s</basic></status>\n", (local_state != NOTIFY_CLOSED) ? "open" : "closed"); 05106 ast_build_string(&t, &maxbytes, "</tuple>\n</presence>\n"); 05107 break; 05108 case DIALOG_INFO_XML: /* SNOM subscribes in this format */ 05109 ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\"?>\n"); 05110 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); 05111 if ((state & AST_EXTENSION_RINGING) && global_notifyringing) 05112 ast_build_string(&t, &maxbytes, "<dialog id=\"%s\" direction=\"recipient\">\n", p->exten); 05113 else 05114 ast_build_string(&t, &maxbytes, "<dialog id=\"%s\">\n", p->exten); 05115 ast_build_string(&t, &maxbytes, "<state>%s</state>\n", statestring); 05116 ast_build_string(&t, &maxbytes, "</dialog>\n</dialog-info>\n"); 05117 break; 05118 case NONE: 05119 default: 05120 break; 05121 } 05122 05123 if (t > tmp + sizeof(tmp)) 05124 ast_log(LOG_WARNING, "Buffer overflow detected!! (Please file a bug report)\n"); 05125 05126 add_header_contentLength(&req, strlen(tmp)); 05127 add_line(&req, tmp); 05128 05129 return send_request(p, &req, 1, p->ocseq); 05130 }
|
|
Try setting codec suggested by the SIP_CODEC channel variable.
Definition at line 2489 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(). 02490 { 02491 int fmt; 02492 char *codec; 02493 02494 codec = pbx_builtin_getvar_helper(p->owner, "SIP_CODEC"); 02495 if (!codec) 02496 return; 02497 02498 fmt = ast_getformatbyname(codec); 02499 if (fmt) { 02500 ast_log(LOG_NOTICE, "Changing codec to '%s' for this call because of ${SIP_CODEC) variable\n",codec); 02501 if (p->jointcapability & fmt) { 02502 p->jointcapability &= fmt; 02503 p->capability &= fmt; 02504 } else 02505 ast_log(LOG_NOTICE, "Ignoring ${SIP_CODEC} variable because it is not shared by both ends.\n"); 02506 } else 02507 ast_log(LOG_NOTICE, "Ignoring ${SIP_CODEC} variable because of unrecognized/not configured codec (check allow/disallow in sip.conf): %s\n",codec); 02508 return; 02509 }
|
|
|
update_call_counter: Handle call_limit for SIP users Note: This is going to be replaced by app_groupcount Thought: For realtime, we should propably update storage with inuse counter...
Definition at line 2193 of file chan_sip.c. References ast_log(), ast_set_flag, ast_test_flag, ASTOBJ_UNREF, sip_peer::call_limit, sip_user::call_limit, DEC_CALL_LIMIT, find_peer(), find_user(), INC_CALL_LIMIT, sip_peer::inUse, sip_user::inUse, inuse, LOG_DEBUG, LOG_ERROR, name, option_debug, sip_pvt::peername, SIP_CALL_LIMIT, sip_destroy_peer(), sip_destroy_user(), SIP_INC_COUNT, SIP_OUTGOING, and sip_pvt::username. Referenced by handle_request_invite(), handle_response(), sip_call(), and sip_hangup(). 02194 { 02195 char name[256]; 02196 int *inuse, *call_limit; 02197 int outgoing = ast_test_flag(fup, SIP_OUTGOING); 02198 struct sip_user *u = NULL; 02199 struct sip_peer *p = NULL; 02200 02201 if (option_debug > 2) 02202 ast_log(LOG_DEBUG, "Updating call counter for %s call\n", outgoing ? "outgoing" : "incoming"); 02203 /* Test if we need to check call limits, in order to avoid 02204 realtime lookups if we do not need it */ 02205 if (!ast_test_flag(fup, SIP_CALL_LIMIT)) 02206 return 0; 02207 02208 ast_copy_string(name, fup->username, sizeof(name)); 02209 02210 /* Check the list of users */ 02211 u = find_user(name, 1); 02212 if (u) { 02213 inuse = &u->inUse; 02214 call_limit = &u->call_limit; 02215 p = NULL; 02216 } else { 02217 /* Try to find peer */ 02218 if (!p) 02219 p = find_peer(fup->peername, NULL, 1); 02220 if (p) { 02221 inuse = &p->inUse; 02222 call_limit = &p->call_limit; 02223 ast_copy_string(name, fup->peername, sizeof(name)); 02224 } else { 02225 if (option_debug > 1) 02226 ast_log(LOG_DEBUG, "%s is not a local user, no call limit\n", name); 02227 return 0; 02228 } 02229 } 02230 switch(event) { 02231 /* incoming and outgoing affects the inUse counter */ 02232 case DEC_CALL_LIMIT: 02233 if ( *inuse > 0 ) { 02234 if (ast_test_flag(fup,SIP_INC_COUNT)) 02235 (*inuse)--; 02236 } else { 02237 *inuse = 0; 02238 } 02239 if (option_debug > 1 || sipdebug) { 02240 ast_log(LOG_DEBUG, "Call %s %s '%s' removed from call limit %d\n", outgoing ? "to" : "from", u ? "user":"peer", name, *call_limit); 02241 } 02242 break; 02243 case INC_CALL_LIMIT: 02244 if (*call_limit > 0 ) { 02245 if (*inuse >= *call_limit) { 02246 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); 02247 if (u) 02248 ASTOBJ_UNREF(u,sip_destroy_user); 02249 else 02250 ASTOBJ_UNREF(p,sip_destroy_peer); 02251 return -1; 02252 } 02253 } 02254 (*inuse)++; 02255 ast_set_flag(fup,SIP_INC_COUNT); 02256 if (option_debug > 1 || sipdebug) { 02257 ast_log(LOG_DEBUG, "Call %s %s '%s' is %d out of %d\n", outgoing ? "to" : "from", u ? "user":"peer", name, *inuse, *call_limit); 02258 } 02259 break; 02260 default: 02261 ast_log(LOG_ERROR, "update_call_counter(%s, %d) called with no event!\n", name, event); 02262 } 02263 if (u) 02264 ASTOBJ_UNREF(u,sip_destroy_user); 02265 else 02266 ASTOBJ_UNREF(p,sip_destroy_peer); 02267 return 0; 02268 }
|
|
update_peer: Update peer data in database (if used) ---
Definition at line 1658 of file chan_sip.c. References sip_peer::addr, ast_test_flag, sip_peer::flags_page2, sip_peer::fullcontact, global_flags_page2, realtime_update_peer(), SIP_PAGE2_RTCACHEFRIENDS, SIP_PAGE2_RTUPDATE, SIP_REALTIME, and sip_peer::username. Referenced by register_verify(). 01659 { 01660 int rtcachefriends = ast_test_flag(&(p->flags_page2), SIP_PAGE2_RTCACHEFRIENDS); 01661 if (ast_test_flag((&global_flags_page2), SIP_PAGE2_RTUPDATE) && 01662 (ast_test_flag(p, SIP_REALTIME) || rtcachefriends)) { 01663 realtime_update_peer(p->name, &p->addr, p->username, rtcachefriends ? p->fullcontact : NULL, expiry); 01664 } 01665 }
|
|
Provides a usecount. This function will be called by various parts of asterisk. Basically, all it has to do is to return a usecount when called. You will need to maintain your usecount within the module somewhere. The usecount should be how many channels provided by this module are in use.
Definition at line 13277 of file chan_sip.c. References usecnt. 13278 { 13279 return usecnt; 13280 }
|
|
Definition at line 409 of file chan_sip.c. |
|
Structure for conversion between compressed SIP and "normal" SIP.
|
|
Accept calls to external SIP domains? Definition at line 495 of file chan_sip.c. Referenced by get_destination(), reload_config(), and sip_show_settings(). |
|
Definition at line 377 of file chan_sip.c. Referenced by sip_show_objects(), and temp_peer(). |
|
Definition at line 12777 of file chan_sip.c. Referenced by load_module(), and unload_module(). |
|
Definition at line 12779 of file chan_sip.c. Referenced by load_module(), and unload_module(). |
|
Definition at line 12791 of file chan_sip.c. Referenced by load_module(), and unload_module(). |
|
Authentication list Definition at line 877 of file chan_sip.c. Referenced by build_reply_digest(), reload_config(), sip_do_reload(), sip_show_settings(), and unload_module(). |
|
Auto creation of peers at registration? Default off. Definition at line 359 of file chan_sip.c. Referenced by register_verify(), reload_config(), and sip_show_settings(). |
|
Definition at line 867 of file chan_sip.c. |
|
Definition at line 902 of file chan_sip.c. Referenced by process_sdp(), reload_config(), and sip_show_settings(). |
|
Definition at line 143 of file chan_sip.c. |
|
Definition at line 9221 of file chan_sip.c. Referenced by load_module(), and unload_module(). |
|
send compact sip headers Definition at line 422 of file chan_sip.c. Referenced by add_header(), reload_config(), and sip_show_settings(). |
|
Definition at line 144 of file chan_sip.c. |
|
Definition at line 9120 of file chan_sip.c. |
|
Definition at line 416 of file chan_sip.c. Referenced by sip_do_debug(), sip_do_debug_ip(), and sip_do_debug_peer(). |
|
Definition at line 341 of file chan_sip.c. Referenced by build_rpid(), reload_config(), and sip_show_settings(). |
|
Definition at line 332 of file chan_sip.c. |
|
Definition at line 119 of file chan_sip.c. Referenced by parse_register_contact(), reload_config(), sip_register(), sip_send_all_registers(), sip_show_settings(), and transmit_register(). |
|
Definition at line 343 of file chan_sip.c. Referenced by reload_config(), sip_alloc(), sip_show_settings(), and transmit_register(). |
|
Definition at line 338 of file chan_sip.c. Referenced by build_peer(), build_user(), reload_config(), sip_show_settings(), and temp_peer(). |
|
Definition at line 346 of file chan_sip.c. Referenced by reload_config(), sip_show_settings(), and transmit_notify_with_mwi(). |
|
Default Qualify= setting Definition at line 350 of file chan_sip.c. Referenced by build_peer(), reload_config(), and sip_show_settings(). |
|
Definition at line 333 of file chan_sip.c. Referenced by build_peer(), reload_config(), and temp_peer(). |
|
Definition at line 329 of file chan_sip.c. Referenced by reload_config(), reqprep(), respprep(), sip_show_settings(), and transmit_register(). |
|
Definition at line 142 of file chan_sip.c. |
|
Definition at line 12776 of file chan_sip.c. Referenced by load_module(). |
|
Definition at line 12783 of file chan_sip.c. Referenced by load_module(). |
|
Initial value: "" " SIPGetHeader(var=headername): \n" "Sets a channel variable to the content of a SIP header\n" "Skips to priority+101 if header does not exist\n" "Otherwise returns 0\n" Definition at line 12794 of file chan_sip.c. Referenced by load_module(). |
|
Dump history to verbose before destroying SIP dialog Definition at line 425 of file chan_sip.c. Referenced by reload_config(). |
|
Definition at line 433 of file chan_sip.c. Referenced by complete_dpreply(), parse_register_contact(), reg_source_db(), and reload_config(). |
|
Definition at line 870 of file chan_sip.c. Referenced by ast_sip_ouraddrfor(), and reload_config(). |
|
Definition at line 869 of file chan_sip.c. Referenced by ast_sip_ouraddrfor(), and reload_config(). |
|
Definition at line 868 of file chan_sip.c. Referenced by ast_sip_ouraddrfor(), and reload_config(). |
|
Definition at line 871 of file chan_sip.c. Referenced by ast_sip_ouraddrfor(), and reload_config(). |
|
allow unauthenticated users/peers to connect? Definition at line 380 of file chan_sip.c. Referenced by check_auth(), check_user_full(), handle_common_options(), reload_config(), and sip_show_settings(). |
|
Codecs that we support by default:.
Definition at line 406 of file chan_sip.c. Referenced by build_peer(), build_user(), reload_config(), sip_alloc(), sip_request_call(), and temp_peer(). |
|
global SIP_ flags Definition at line 352 of file chan_sip.c. Referenced by build_peer(), build_user(), check_user_full(), reload_config(), sip_alloc(), sip_show_settings(), and temp_peer(). |
|
more global SIP_ flags Definition at line 353 of file chan_sip.c. Referenced by build_peer(), destroy_association(), realtime_peer(), realtime_user(), reload_config(), sip_show_settings(), and update_peer(). |
|
Global music on hold class Definition at line 427 of file chan_sip.c. Referenced by build_peer(), build_user(), reload_config(), sip_alloc(), sip_show_settings(), and temp_peer(). |
|
Time between MWI checks for peers Definition at line 383 of file chan_sip.c. Referenced by do_monitor(), reload_config(), and sip_show_settings(). |
|
Send notifications on ringing Definition at line 348 of file chan_sip.c. Referenced by reload_config(), sip_show_settings(), and transmit_state_notify(). |
|
Default realm Definition at line 429 of file chan_sip.c. Referenced by check_auth(), reload_config(), sip_show_settings(), and transmit_response_with_auth(). |
|
Definition at line 369 of file chan_sip.c. Referenced by reload_config(), sip_show_settings(), and transmit_register(). |
|
Definition at line 370 of file chan_sip.c. Referenced by handle_response_register(), reload_config(), sip_reg_timeout(), and sip_show_settings(). |
|
Definition at line 582 of file chan_sip.c. |
|
Definition at line 365 of file chan_sip.c. Referenced by build_peer(), reload_config(), sip_alloc(), sip_show_settings(), and temp_peer(). |
|
Definition at line 367 of file chan_sip.c. Referenced by build_peer(), reload_config(), sip_alloc(), and temp_peer(). |
|
Definition at line 363 of file chan_sip.c. Referenced by build_peer(), reload_config(), sip_alloc(), sip_show_settings(), and temp_peer(). |
|
Definition at line 336 of file chan_sip.c. Referenced by build_peer(), reload_config(), sip_show_settings(), and transmit_notify_with_mwi(). |
|
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 9137 of file chan_sip.c. |
|
sip_pvt: PVT structures are used for each SIP conversation, ie. a call
|
|
Definition at line 436 of file chan_sip.c. |
|
Definition at line 872 of file chan_sip.c. Referenced by ast_sip_ouraddrfor(), reload_config(), and unload_module(). |
|
Definition at line 7845 of file chan_sip.c. |
|
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 7427 of file chan_sip.c. |
|
Definition at line 118 of file chan_sip.c. Referenced by handle_request_subscribe(), parse_register_contact(), reload_config(), and sip_show_settings(). |
|
This is the thread for the monitor which checks for input on the channels which are not currently in use.
Definition at line 401 of file chan_sip.c. |
|
Definition at line 13099 of file chan_sip.c. |
|
Initial value: "Usage: sip no debug\n" " Disables dumping of SIP packets for debugging purposes\n" Definition at line 9129 of file chan_sip.c. |
|
Initial value: "Usage: sip no history\n" " Disables recording of SIP dialog history for debugging purposes\n" Definition at line 9133 of file chan_sip.c. |
|
Definition at line 407 of file chan_sip.c. Referenced by process_sdp(). |
|
Definition at line 145 of file chan_sip.c. Referenced by reload_config(), and sip_notify(). |
|
Definition at line 875 of file chan_sip.c. Referenced by complete_sipnotify(), reload_config(), and sip_notify(). |
|
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 9069 of file chan_sip.c. |
|
Definition at line 411 of file chan_sip.c. |
|
Definition at line 410 of file chan_sip.c. Referenced by reload_config(). |
|
Extra checking ? Default off Definition at line 357 of file chan_sip.c. Referenced by __get_header(), check_user_full(), find_call(), get_destination(), get_refer_info(), handle_request(), process_sdp(), register_verify(), reload_config(), sip_show_settings(), and sipsock_read(). |
|
The peer list: Peers and Friends ---.
|
|
Definition at line 444 of file chan_sip.c. |
|
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 9111 of file chan_sip.c. |
|
Record SIP history. Off by default Definition at line 424 of file chan_sip.c. Referenced by do_register_auth(), reload_config(), sip_do_history(), sip_no_history(), sip_reregister(), sip_show_history(), sip_show_settings(), sipsock_read(), and transmit_register(). |
|
Context for auto-extensions Definition at line 430 of file chan_sip.c. |
|
The register list: Other SIP proxys we register with and call ---.
Referenced by delete_users(), load_module(), sip_do_reload(), sip_register(), sip_send_all_registers(), sip_show_objects(), sip_show_registry(), and unload_module(). |
|
Definition at line 378 of file chan_sip.c. Referenced by sip_register(), sip_send_all_registers(), and sip_show_objects(). |
|
Definition at line 361 of file chan_sip.c. Referenced by reload_config(), and sip_show_settings(). |
|
Definition at line 376 of file chan_sip.c. Referenced by build_peer(), and sip_show_objects(). |
|
Definition at line 374 of file chan_sip.c. Referenced by sip_show_objects(). |
|
Definition at line 435 of file chan_sip.c. |
|
Initial value: "Usage: sip show channel <channel>\n" " Provides detailed status on a given SIP channel.\n" Definition at line 9093 of file chan_sip.c. |
|
Initial value: "Usage: sip show channels\n" " Lists all currently active SIP channels.\n" Definition at line 9089 of file chan_sip.c. |
|
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 9064 of file chan_sip.c. |
|
Initial value: "Usage: sip show history <channel>\n" " Provides detailed dialog history on a given SIP channel.\n" Definition at line 9097 of file chan_sip.c. |
|
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 9084 of file chan_sip.c. |
|
Initial value: "Usage: sip show objects\n" " Shows status of known SIP objects\n" Definition at line 9150 of file chan_sip.c. |
|
Initial value: "Usage: sip show peer <name> [load]\n" " Lists all details on one SIP peer and the current status.\n" " Option \"load\" forces lookup of peer in realtime storage.\n" Definition at line 9106 of file chan_sip.c. |
|
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 9101 of file chan_sip.c. |
|
Initial value: "Usage: sip show registry\n" " Lists all registration requests and status.\n" Definition at line 9116 of file chan_sip.c. |
|
Initial value: "Usage: sip show settings\n" " Provides detailed list of the configuration of the SIP channel.\n" Definition at line 9154 of file chan_sip.c. |
|
Initial value: "Usage: sip show subscriptions\n" " Shows active SIP subscriptions for extension states\n" Definition at line 9146 of file chan_sip.c. |
|
Initial value: "Usage: sip show user <name> [load]\n" " Lists all details on one SIP user and the current status.\n" " Option \"load\" forces lookup of peer in realtime storage.\n" Definition at line 9079 of file chan_sip.c. |
|
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 9074 of file chan_sip.c. |
|
Definition at line 9200 of file chan_sip.c. Referenced by load_module(), and unload_module(). |
|
|
|
XXX Note that sip_methods[i].id == i must hold or the code breaks Referenced by __sip_ack(), __sip_pretend_ack(), __sip_semi_ack(), build_reply_digest(), check_auth(), do_proxy_auth(), find_call(), find_sip_method(), get_destination(), handle_request(), handle_request_subscribe(), handle_response(), init_req(), reqprep(), retrans_pkt(), sip_alloc(), and transmit_register(). |
|
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(). |
|
Initial value: "Usage: sip reload\n" " Reloads SIP configuration from sip.conf\n" Definition at line 9142 of file chan_sip.c. |
|
Definition at line 799 of file chan_sip.c. Referenced by do_monitor(), and sip_reload(). |
|
sip_rtp: Interface structure with callbacks used to connect to rtp module --
Definition at line 13004 of file chan_sip.c. Referenced by load_module(), and unload_module(). |
|
Definition of this channel for PBX channel registration.
Definition at line 928 of file chan_sip.c. Referenced by load_module(), sip_new(), and unload_module(). |
|
Definition at line 9385 of file chan_sip.c. Referenced by load_module(), and unload_module(). |
|
|
Definition at line 9308 of file chan_sip.c. Referenced by load_module(), and unload_module(). |
|
Definition at line 864 of file chan_sip.c. Referenced by __sip_xmit(), do_monitor(), reg_source_db(), reload_config(), sipsock_read(), and unload_module(). |
|
Definition at line 375 of file chan_sip.c. Referenced by build_peer(), and sip_show_objects(). |
|
SRV Lookup on or off. Default is off, RFC behavior is on Definition at line 355 of file chan_sip.c. Referenced by reload_config(), and sip_show_settings(). |
|
Referenced by find_subscription_type(), and subscription_type2str(). |
|
Definition at line 373 of file chan_sip.c. Referenced by build_user(), and sip_show_objects(). |
|
Definition at line 12775 of file chan_sip.c. Referenced by load_module(). |
|
Definition at line 12780 of file chan_sip.c. Referenced by load_module(). |
|
Definition at line 12792 of file chan_sip.c. Referenced by load_module(). |
|
Definition at line 418 of file chan_sip.c. |
|
Definition at line 385 of file chan_sip.c. |
|
The user list: Users and friends ---.
|
|
Definition at line 420 of file chan_sip.c. Referenced by reload_config(), sip_alloc(), and sip_show_settings(). |