#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 7822 of file chan_sip.c. |
|
sip_show_domains: CLI command to list local domains
Definition at line 7822 of file chan_sip.c. |
|
sip_show_domains: CLI command to list local domains
Definition at line 7822 of file chan_sip.c. |
|
sip_show_domains: CLI command to list local domains
Definition at line 7822 of file chan_sip.c. |
|
sip_show_domains: CLI command to list local domains
Definition at line 7822 of file chan_sip.c. |
|
sip_show_domains: CLI command to list local domains
Definition at line 7822 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 5798 of file chan_sip.c. 05798 { 05799 PARSE_REGISTER_FAILED, 05800 PARSE_REGISTER_UPDATE, 05801 PARSE_REGISTER_QUERY, 05802 };
|
|
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 5268 of file chan_sip.c. References SIP_REGISTER, and transmit_register(). Referenced by sip_reregister(). 05269 { 05270 int res; 05271 05272 res = transmit_register(r, SIP_REGISTER, NULL, NULL); 05273 return res; 05274 }
|
|
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 8278 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(). 08279 { 08280 #define FORMAT3 "%-15.15s %-10.10s %-11.11s %-15.15s %-13.13s %-15.15s\n" 08281 #define FORMAT2 "%-15.15s %-10.10s %-11.11s %-11.11s %-4.4s %-7.7s %-15.15s\n" 08282 #define FORMAT "%-15.15s %-10.10s %-11.11s %5.5d/%5.5d %-4.4s %-3.3s %-3.3s %-15.15s\n" 08283 struct sip_pvt *cur; 08284 char iabuf[INET_ADDRSTRLEN]; 08285 int numchans = 0; 08286 if (argc != 3) 08287 return RESULT_SHOWUSAGE; 08288 ast_mutex_lock(&iflock); 08289 cur = iflist; 08290 if (!subscriptions) 08291 ast_cli(fd, FORMAT2, "Peer", "User/ANR", "Call ID", "Seq (Tx/Rx)", "Format", "Hold", "Last Message"); 08292 else 08293 ast_cli(fd, FORMAT3, "Peer", "User", "Call ID", "Extension", "Last state", "Type"); 08294 while (cur) { 08295 if (cur->subscribed == NONE && !subscriptions) { 08296 ast_cli(fd, FORMAT, ast_inet_ntoa(iabuf, sizeof(iabuf), cur->sa.sin_addr), 08297 ast_strlen_zero(cur->username) ? ( ast_strlen_zero(cur->cid_num) ? "(None)" : cur->cid_num ) : cur->username, 08298 cur->callid, 08299 cur->ocseq, cur->icseq, 08300 ast_getformatname(cur->owner ? cur->owner->nativeformats : 0), 08301 ast_test_flag(cur, SIP_CALL_ONHOLD) ? "Yes" : "No", 08302 ast_test_flag(cur, SIP_NEEDDESTROY) ? "(d)" : "", 08303 cur->lastmsg ); 08304 numchans++; 08305 } 08306 if (cur->subscribed != NONE && subscriptions) { 08307 ast_cli(fd, FORMAT3, ast_inet_ntoa(iabuf, sizeof(iabuf), cur->sa.sin_addr), 08308 ast_strlen_zero(cur->username) ? ( ast_strlen_zero(cur->cid_num) ? "(None)" : cur->cid_num ) : cur->username, 08309 cur->callid, cur->exten, ast_extension_state2str(cur->laststate), 08310 subscription_type2str(cur->subscribed)); 08311 numchans++; 08312 } 08313 cur = cur->next; 08314 } 08315 ast_mutex_unlock(&iflock); 08316 if (!subscriptions) 08317 ast_cli(fd, "%d active SIP channel%s\n", numchans, (numchans != 1) ? "s" : ""); 08318 else 08319 ast_cli(fd, "%d active SIP subscription%s\n", numchans, (numchans != 1) ? "s" : ""); 08320 return RESULT_SUCCESS; 08321 #undef FORMAT 08322 #undef FORMAT2 08323 #undef FORMAT3 08324 }
|
|
__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 4131 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(). 04132 { 04133 struct sip_request resp; 04134 int seqno = 0; 04135 04136 if (reliable && (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1)) { 04137 ast_log(LOG_WARNING, "Unable to determine sequence number from '%s'\n", get_header(req, "CSeq")); 04138 return -1; 04139 } 04140 respprep(&resp, p, msg, req); 04141 add_header_contentLength(&resp, 0); 04142 /* If we are cancelling an incoming invite for some reason, add information 04143 about the reason why we are doing this in clear text */ 04144 if (msg[0] != '1' && p->owner && p->owner->hangupcause) { 04145 add_header(&resp, "X-Asterisk-HangupCause", ast_cause2str(p->owner->hangupcause)); 04146 } 04147 add_blank_header(&resp); 04148 return send_response(p, &resp, reliable, seqno); 04149 }
|
|
Definition at line 7885 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(). 07886 { 07887 char status[30] = ""; 07888 char cbuf[256]; 07889 char iabuf[INET_ADDRSTRLEN]; 07890 struct sip_peer *peer; 07891 char codec_buf[512]; 07892 struct ast_codec_pref *pref; 07893 struct ast_variable *v; 07894 struct sip_auth *auth; 07895 int x = 0, codec = 0, load_realtime = 0; 07896 07897 if (argc < 4) 07898 return RESULT_SHOWUSAGE; 07899 07900 load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? 1 : 0; 07901 peer = find_peer(argv[3], NULL, load_realtime); 07902 if (s) { /* Manager */ 07903 if (peer) 07904 ast_cli(s->fd, "Response: Success\r\n"); 07905 else { 07906 snprintf (cbuf, sizeof(cbuf), "Peer %s not found.\n", argv[3]); 07907 astman_send_error(s, m, cbuf); 07908 return 0; 07909 } 07910 } 07911 if (peer && type==0 ) { /* Normal listing */ 07912 ast_cli(fd,"\n\n"); 07913 ast_cli(fd, " * Name : %s\n", peer->name); 07914 ast_cli(fd, " Secret : %s\n", ast_strlen_zero(peer->secret)?"<Not set>":"<Set>"); 07915 ast_cli(fd, " MD5Secret : %s\n", ast_strlen_zero(peer->md5secret)?"<Not set>":"<Set>"); 07916 auth = peer->auth; 07917 while(auth) { 07918 ast_cli(fd, " Realm-auth : Realm %-15.15s User %-10.20s ", auth->realm, auth->username); 07919 ast_cli(fd, "%s\n", !ast_strlen_zero(auth->secret)?"<Secret set>":(!ast_strlen_zero(auth->md5secret)?"<MD5secret set>" : "<Not set>")); 07920 auth = auth->next; 07921 } 07922 ast_cli(fd, " Context : %s\n", peer->context); 07923 ast_cli(fd, " Subscr.Cont. : %s\n", ast_strlen_zero(peer->subscribecontext)?"<Not set>":peer->subscribecontext); 07924 ast_cli(fd, " Language : %s\n", peer->language); 07925 if (!ast_strlen_zero(peer->accountcode)) 07926 ast_cli(fd, " Accountcode : %s\n", peer->accountcode); 07927 ast_cli(fd, " AMA flags : %s\n", ast_cdr_flags2str(peer->amaflags)); 07928 ast_cli(fd, " CallingPres : %s\n", ast_describe_caller_presentation(peer->callingpres)); 07929 if (!ast_strlen_zero(peer->fromuser)) 07930 ast_cli(fd, " FromUser : %s\n", peer->fromuser); 07931 if (!ast_strlen_zero(peer->fromdomain)) 07932 ast_cli(fd, " FromDomain : %s\n", peer->fromdomain); 07933 ast_cli(fd, " Callgroup : "); 07934 print_group(fd, peer->callgroup, 0); 07935 ast_cli(fd, " Pickupgroup : "); 07936 print_group(fd, peer->pickupgroup, 0); 07937 ast_cli(fd, " Mailbox : %s\n", peer->mailbox); 07938 ast_cli(fd, " VM Extension : %s\n", peer->vmexten); 07939 ast_cli(fd, " LastMsgsSent : %d\n", peer->lastmsgssent); 07940 ast_cli(fd, " Call limit : %d\n", peer->call_limit); 07941 ast_cli(fd, " Dynamic : %s\n", (ast_test_flag(peer, SIP_DYNAMIC)?"Yes":"No")); 07942 ast_cli(fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>")); 07943 ast_cli(fd, " Expire : %d\n", peer->expire); 07944 ast_cli(fd, " Insecure : %s\n", insecure2str(ast_test_flag(peer, SIP_INSECURE_PORT), ast_test_flag(peer, SIP_INSECURE_INVITE))); 07945 ast_cli(fd, " Nat : %s\n", nat2str(ast_test_flag(peer, SIP_NAT))); 07946 ast_cli(fd, " ACL : %s\n", (peer->ha?"Yes":"No")); 07947 ast_cli(fd, " CanReinvite : %s\n", (ast_test_flag(peer, SIP_CAN_REINVITE)?"Yes":"No")); 07948 ast_cli(fd, " PromiscRedir : %s\n", (ast_test_flag(peer, SIP_PROMISCREDIR)?"Yes":"No")); 07949 ast_cli(fd, " User=Phone : %s\n", (ast_test_flag(peer, SIP_USEREQPHONE)?"Yes":"No")); 07950 ast_cli(fd, " Trust RPID : %s\n", (ast_test_flag(peer, SIP_TRUSTRPID) ? "Yes" : "No")); 07951 ast_cli(fd, " Send RPID : %s\n", (ast_test_flag(peer, SIP_SENDRPID) ? "Yes" : "No")); 07952 07953 /* - is enumerated */ 07954 ast_cli(fd, " DTMFmode : %s\n", dtmfmode2str(ast_test_flag(peer, SIP_DTMF))); 07955 ast_cli(fd, " LastMsg : %d\n", peer->lastmsg); 07956 ast_cli(fd, " ToHost : %s\n", peer->tohost); 07957 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)); 07958 ast_cli(fd, " Defaddr->IP : %s Port %d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port)); 07959 ast_cli(fd, " Def. Username: %s\n", peer->username); 07960 ast_cli(fd, " SIP Options : "); 07961 if (peer->sipoptions) { 07962 for (x=0 ; (x < (sizeof(sip_options) / sizeof(sip_options[0]))); x++) { 07963 if (peer->sipoptions & sip_options[x].id) 07964 ast_cli(fd, "%s ", sip_options[x].text); 07965 } 07966 } else 07967 ast_cli(fd, "(none)"); 07968 07969 ast_cli(fd, "\n"); 07970 ast_cli(fd, " Codecs : "); 07971 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability); 07972 ast_cli(fd, "%s\n", codec_buf); 07973 ast_cli(fd, " Codec Order : ("); 07974 print_codec_to_cli(fd, &peer->prefs); 07975 07976 ast_cli(fd, ")\n"); 07977 07978 ast_cli(fd, " Status : "); 07979 peer_status(peer, status, sizeof(status)); 07980 ast_cli(fd, "%s\n",status); 07981 ast_cli(fd, " Useragent : %s\n", peer->useragent); 07982 ast_cli(fd, " Reg. Contact : %s\n", peer->fullcontact); 07983 if (peer->chanvars) { 07984 ast_cli(fd, " Variables :\n"); 07985 for (v = peer->chanvars ; v ; v = v->next) 07986 ast_cli(fd, " %s = %s\n", v->name, v->value); 07987 } 07988 ast_cli(fd,"\n"); 07989 ASTOBJ_UNREF(peer,sip_destroy_peer); 07990 } else if (peer && type == 1) { /* manager listing */ 07991 ast_cli(fd, "Channeltype: SIP\r\n"); 07992 ast_cli(fd, "ObjectName: %s\r\n", peer->name); 07993 ast_cli(fd, "ChanObjectType: peer\r\n"); 07994 ast_cli(fd, "SecretExist: %s\r\n", ast_strlen_zero(peer->secret)?"N":"Y"); 07995 ast_cli(fd, "MD5SecretExist: %s\r\n", ast_strlen_zero(peer->md5secret)?"N":"Y"); 07996 ast_cli(fd, "Context: %s\r\n", peer->context); 07997 ast_cli(fd, "Language: %s\r\n", peer->language); 07998 if (!ast_strlen_zero(peer->accountcode)) 07999 ast_cli(fd, "Accountcode: %s\r\n", peer->accountcode); 08000 ast_cli(fd, "AMAflags: %s\r\n", ast_cdr_flags2str(peer->amaflags)); 08001 ast_cli(fd, "CID-CallingPres: %s\r\n", ast_describe_caller_presentation(peer->callingpres)); 08002 if (!ast_strlen_zero(peer->fromuser)) 08003 ast_cli(fd, "SIP-FromUser: %s\r\n", peer->fromuser); 08004 if (!ast_strlen_zero(peer->fromdomain)) 08005 ast_cli(fd, "SIP-FromDomain: %s\r\n", peer->fromdomain); 08006 ast_cli(fd, "Callgroup: "); 08007 print_group(fd, peer->callgroup, 1); 08008 ast_cli(fd, "Pickupgroup: "); 08009 print_group(fd, peer->pickupgroup, 1); 08010 ast_cli(fd, "VoiceMailbox: %s\r\n", peer->mailbox); 08011 ast_cli(fd, "LastMsgsSent: %d\r\n", peer->lastmsgssent); 08012 ast_cli(fd, "Call limit: %d\r\n", peer->call_limit); 08013 ast_cli(fd, "Dynamic: %s\r\n", (ast_test_flag(peer, SIP_DYNAMIC)?"Y":"N")); 08014 ast_cli(fd, "Callerid: %s\r\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "")); 08015 ast_cli(fd, "RegExpire: %ld seconds\r\n", ast_sched_when(sched,peer->expire)); 08016 ast_cli(fd, "SIP-AuthInsecure: %s\r\n", insecure2str(ast_test_flag(peer, SIP_INSECURE_PORT), ast_test_flag(peer, SIP_INSECURE_INVITE))); 08017 ast_cli(fd, "SIP-NatSupport: %s\r\n", nat2str(ast_test_flag(peer, SIP_NAT))); 08018 ast_cli(fd, "ACL: %s\r\n", (peer->ha?"Y":"N")); 08019 ast_cli(fd, "SIP-CanReinvite: %s\r\n", (ast_test_flag(peer, SIP_CAN_REINVITE)?"Y":"N")); 08020 ast_cli(fd, "SIP-PromiscRedir: %s\r\n", (ast_test_flag(peer, SIP_PROMISCREDIR)?"Y":"N")); 08021 ast_cli(fd, "SIP-UserPhone: %s\r\n", (ast_test_flag(peer, SIP_USEREQPHONE)?"Y":"N")); 08022 08023 /* - is enumerated */ 08024 ast_cli(fd, "SIP-DTMFmode: %s\r\n", dtmfmode2str(ast_test_flag(peer, SIP_DTMF))); 08025 ast_cli(fd, "SIPLastMsg: %d\r\n", peer->lastmsg); 08026 ast_cli(fd, "ToHost: %s\r\n", peer->tohost); 08027 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)); 08028 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)); 08029 ast_cli(fd, "Default-Username: %s\r\n", peer->username); 08030 ast_cli(fd, "Codecs: "); 08031 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability); 08032 ast_cli(fd, "%s\r\n", codec_buf); 08033 ast_cli(fd, "CodecOrder: "); 08034 pref = &peer->prefs; 08035 for(x = 0; x < 32 ; x++) { 08036 codec = ast_codec_pref_index(pref,x); 08037 if (!codec) 08038 break; 08039 ast_cli(fd, "%s", ast_getformatname(codec)); 08040 if (x < 31 && ast_codec_pref_index(pref,x+1)) 08041 ast_cli(fd, ","); 08042 } 08043 08044 ast_cli(fd, "\r\n"); 08045 ast_cli(fd, "Status: "); 08046 peer_status(peer, status, sizeof(status)); 08047 ast_cli(fd, "%s\r\n", status); 08048 ast_cli(fd, "SIP-Useragent: %s\r\n", peer->useragent); 08049 ast_cli(fd, "Reg-Contact : %s\r\n", peer->fullcontact); 08050 if (peer->chanvars) { 08051 for (v = peer->chanvars ; v ; v = v->next) { 08052 ast_cli(fd, "ChanVariable:\n"); 08053 ast_cli(fd, " %s,%s\r\n", v->name, v->value); 08054 } 08055 } 08056 08057 ASTOBJ_UNREF(peer,sip_destroy_peer); 08058 08059 } else { 08060 ast_cli(fd,"Peer %s not found.\n", argv[3]); 08061 ast_cli(fd,"\n"); 08062 } 08063 08064 return RESULT_SUCCESS; 08065 }
|
|
_sip_show_peers: Execute sip show peers command
Definition at line 7463 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(). 07464 { 07465 regex_t regexbuf; 07466 int havepattern = 0; 07467 07468 #define FORMAT2 "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8s %-10s\n" 07469 #define FORMAT "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8d %-10s\n" 07470 07471 char name[256]; 07472 char iabuf[INET_ADDRSTRLEN]; 07473 int total_peers = 0; 07474 int peers_online = 0; 07475 int peers_offline = 0; 07476 char *id; 07477 char idtext[256] = ""; 07478 07479 if (s) { /* Manager - get ActionID */ 07480 id = astman_get_header(m,"ActionID"); 07481 if (!ast_strlen_zero(id)) 07482 snprintf(idtext,256,"ActionID: %s\r\n",id); 07483 } 07484 07485 switch (argc) { 07486 case 5: 07487 if (!strcasecmp(argv[3], "like")) { 07488 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 07489 return RESULT_SHOWUSAGE; 07490 havepattern = 1; 07491 } else 07492 return RESULT_SHOWUSAGE; 07493 case 3: 07494 break; 07495 default: 07496 return RESULT_SHOWUSAGE; 07497 } 07498 07499 if (!s) { /* Normal list */ 07500 ast_cli(fd, FORMAT2, "Name/username", "Host", "Dyn", "Nat", "ACL", "Port", "Status"); 07501 } 07502 07503 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 07504 char status[20] = ""; 07505 char srch[2000]; 07506 char pstatus; 07507 07508 ASTOBJ_RDLOCK(iterator); 07509 07510 if (havepattern && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 07511 ASTOBJ_UNLOCK(iterator); 07512 continue; 07513 } 07514 07515 if (!ast_strlen_zero(iterator->username) && !s) 07516 snprintf(name, sizeof(name), "%s/%s", iterator->name, iterator->username); 07517 else 07518 ast_copy_string(name, iterator->name, sizeof(name)); 07519 07520 pstatus = peer_status(iterator, status, sizeof(status)); 07521 if (pstatus) 07522 peers_online++; 07523 else { 07524 if (pstatus == 0) 07525 peers_offline++; 07526 else { /* Unmonitored */ 07527 /* Checking if port is 0 */ 07528 if ( ntohs(iterator->addr.sin_port) == 0 ) { 07529 peers_offline++; 07530 } else { 07531 peers_online++; 07532 } 07533 } 07534 } 07535 07536 snprintf(srch, sizeof(srch), FORMAT, name, 07537 iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), iterator->addr.sin_addr) : "(Unspecified)", 07538 ast_test_flag(iterator, SIP_DYNAMIC) ? " D " : " ", /* Dynamic or not? */ 07539 (ast_test_flag(iterator, SIP_NAT) & SIP_NAT_ROUTE) ? " N " : " ", /* NAT=yes? */ 07540 iterator->ha ? " A " : " ", /* permit/deny */ 07541 ntohs(iterator->addr.sin_port), status); 07542 07543 if (!s) {/* Normal CLI list */ 07544 ast_cli(fd, FORMAT, name, 07545 iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), iterator->addr.sin_addr) : "(Unspecified)", 07546 ast_test_flag(iterator, SIP_DYNAMIC) ? " D " : " ", /* Dynamic or not? */ 07547 (ast_test_flag(iterator, SIP_NAT) & SIP_NAT_ROUTE) ? " N " : " ", /* NAT=yes? */ 07548 iterator->ha ? " A " : " ", /* permit/deny */ 07549 07550 ntohs(iterator->addr.sin_port), status); 07551 } else { /* Manager format */ 07552 /* The names here need to be the same as other channels */ 07553 ast_cli(fd, 07554 "Event: PeerEntry\r\n%s" 07555 "Channeltype: SIP\r\n" 07556 "ObjectName: %s\r\n" 07557 "ChanObjectType: peer\r\n" /* "peer" or "user" */ 07558 "IPaddress: %s\r\n" 07559 "IPport: %d\r\n" 07560 "Dynamic: %s\r\n" 07561 "Natsupport: %s\r\n" 07562 "ACL: %s\r\n" 07563 "Status: %s\r\n\r\n", 07564 idtext, 07565 iterator->name, 07566 iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), iterator->addr.sin_addr) : "-none-", 07567 ntohs(iterator->addr.sin_port), 07568 ast_test_flag(iterator, SIP_DYNAMIC) ? "yes" : "no", /* Dynamic or not? */ 07569 (ast_test_flag(iterator, SIP_NAT) & SIP_NAT_ROUTE) ? "yes" : "no", /* NAT=yes? */ 07570 iterator->ha ? "yes" : "no", /* permit/deny */ 07571 status); 07572 } 07573 07574 ASTOBJ_UNLOCK(iterator); 07575 07576 total_peers++; 07577 } while(0) ); 07578 07579 if (!s) { 07580 ast_cli(fd,"%d sip peers [%d online , %d offline]\n",total_peers,peers_online,peers_offline); 07581 } 07582 07583 if (havepattern) 07584 regfree(®exbuf); 07585 07586 if (total) 07587 *total = total_peers; 07588 07589 07590 return RESULT_SUCCESS; 07591 #undef FORMAT 07592 #undef FORMAT2 07593 }
|
|
add_blank_header: Add blank header to SIP message
Definition at line 3720 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(). 03721 { 03722 if (req->headers == SIP_MAX_HEADERS) { 03723 ast_log(LOG_WARNING, "Out of SIP header space\n"); 03724 return -1; 03725 } 03726 if (req->lines) { 03727 ast_log(LOG_WARNING, "Can't add more headers when lines have been added\n"); 03728 return -1; 03729 } 03730 if (req->len >= sizeof(req->data) - 4) { 03731 ast_log(LOG_WARNING, "Out of space, can't add anymore\n"); 03732 return -1; 03733 } 03734 req->header[req->headers] = req->data + req->len; 03735 snprintf(req->header[req->headers], sizeof(req->data) - req->len, "\r\n"); 03736 req->len += strlen(req->header[req->headers]); 03737 req->headers++; 03738 return 0; 03739 }
|
|
Definition at line 4272 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(). 04275 { 04276 int rtp_code; 04277 04278 if (debug) 04279 ast_verbose("Adding codec 0x%x (%s) to SDP\n", codec, ast_getformatname(codec)); 04280 if ((rtp_code = ast_rtp_lookup_code(p->rtp, 1, codec)) == -1) 04281 return; 04282 04283 ast_build_string(m_buf, m_size, " %d", rtp_code); 04284 ast_build_string(a_buf, a_size, "a=rtpmap:%d %s/%d\r\n", rtp_code, 04285 ast_rtp_lookup_mime_subtype(1, codec), 04286 sample_rate); 04287 if (codec == AST_FORMAT_G729A) 04288 /* Indicate that we don't support VAD (G.729 annex B) */ 04289 ast_build_string(a_buf, a_size, "a=fmtp:%d annexb=no\r\n", rtp_code); 04290 }
|
|
add_digit: add DTMF INFO tone to sip message ---
Definition at line 4241 of file chan_sip.c. References add_header(), add_header_contentLength(), and add_line(). Referenced by transmit_info_with_digit(). 04242 { 04243 char tmp[256]; 04244 04245 snprintf(tmp, sizeof(tmp), "Signal=%c\r\nDuration=250\r\n", digit); 04246 add_header(req, "Content-Type", "application/dtmf-relay"); 04247 add_header_contentLength(req, strlen(tmp)); 04248 add_line(req, tmp); 04249 return 0; 04250 }
|
|
add_header: Add header to SIP message
Definition at line 3676 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. 03677 { 03678 int x = 0; 03679 03680 if (req->headers == SIP_MAX_HEADERS) { 03681 ast_log(LOG_WARNING, "Out of SIP header space\n"); 03682 return -1; 03683 } 03684 03685 if (req->lines) { 03686 ast_log(LOG_WARNING, "Can't add more headers when lines have been added\n"); 03687 return -1; 03688 } 03689 03690 if (req->len >= sizeof(req->data) - 4) { 03691 ast_log(LOG_WARNING, "Out of space, can't add anymore (%s:%s)\n", var, value); 03692 return -1; 03693 } 03694 03695 req->header[req->headers] = req->data + req->len; 03696 03697 if (compactheaders) { 03698 for (x = 0; x < (sizeof(aliases) / sizeof(aliases[0])); x++) 03699 if (!strcasecmp(aliases[x].fullname, var)) 03700 var = aliases[x].shortname; 03701 } 03702 03703 snprintf(req->header[req->headers], sizeof(req->data) - req->len - 4, "%s: %s\r\n", var, value); 03704 req->len += strlen(req->header[req->headers]); 03705 req->headers++; 03706 03707 return 0; 03708 }
|
|
add_header_contentLen: Add 'Content-Length' header to SIP message
Definition at line 3711 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(). 03712 { 03713 char clen[10]; 03714 03715 snprintf(clen, sizeof(clen), "%d", len); 03716 return add_header(req, "Content-Length", clen); 03717 }
|
|
add_line: Add content (not header) to SIP message
Definition at line 3742 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. 03743 { 03744 if (req->lines == SIP_MAX_LINES) { 03745 ast_log(LOG_WARNING, "Out of SIP line space\n"); 03746 return -1; 03747 } 03748 if (!req->lines) { 03749 /* Add extra empty return */ 03750 snprintf(req->data + req->len, sizeof(req->data) - req->len, "\r\n"); 03751 req->len += strlen(req->data + req->len); 03752 } 03753 if (req->len >= sizeof(req->data) - 4) { 03754 ast_log(LOG_WARNING, "Out of space, can't add anymore\n"); 03755 return -1; 03756 } 03757 req->line[req->lines] = req->data + req->len; 03758 snprintf(req->line[req->lines], sizeof(req->data) - req->len, "%s", line); 03759 req->len += strlen(req->line[req->lines]); 03760 req->lines++; 03761 return 0; 03762 }
|
|
Definition at line 4292 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. 04295 { 04296 int rtp_code; 04297 04298 if (debug) 04299 ast_verbose("Adding non-codec 0x%x (%s) to SDP\n", format, ast_rtp_lookup_mime_subtype(0, format)); 04300 if ((rtp_code = ast_rtp_lookup_code(p->rtp, 0, format)) == -1) 04301 return; 04302 04303 ast_build_string(m_buf, m_size, " %d", rtp_code); 04304 ast_build_string(a_buf, a_size, "a=rtpmap:%d %s/%d\r\n", rtp_code, 04305 ast_rtp_lookup_mime_subtype(0, format), 04306 sample_rate); 04307 if (format == AST_RTP_DTMF) 04308 /* Indicate we support DTMF and FLASH... */ 04309 ast_build_string(a_buf, a_size, "a=fmtp:%d 0-16\r\n", rtp_code); 04310 }
|
|
add_realm_authentication: Add realm authentication in list ---
Definition at line 11799 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(). 11800 { 11801 char authcopy[256]; 11802 char *username=NULL, *realm=NULL, *secret=NULL, *md5secret=NULL; 11803 char *stringp; 11804 struct sip_auth *auth; 11805 struct sip_auth *b = NULL, *a = authlist; 11806 11807 if (ast_strlen_zero(configuration)) 11808 return authlist; 11809 11810 ast_log(LOG_DEBUG, "Auth config :: %s\n", configuration); 11811 11812 ast_copy_string(authcopy, configuration, sizeof(authcopy)); 11813 stringp = authcopy; 11814 11815 username = stringp; 11816 realm = strrchr(stringp, '@'); 11817 if (realm) { 11818 *realm = '\0'; 11819 realm++; 11820 } 11821 if (ast_strlen_zero(username) || ast_strlen_zero(realm)) { 11822 ast_log(LOG_WARNING, "Format for authentication entry is user[:secret]@realm at line %d\n", lineno); 11823 return authlist; 11824 } 11825 stringp = username; 11826 username = strsep(&stringp, ":"); 11827 if (username) { 11828 secret = strsep(&stringp, ":"); 11829 if (!secret) { 11830 stringp = username; 11831 md5secret = strsep(&stringp,"#"); 11832 } 11833 } 11834 auth = malloc(sizeof(struct sip_auth)); 11835 if (auth) { 11836 memset(auth, 0, sizeof(struct sip_auth)); 11837 ast_copy_string(auth->realm, realm, sizeof(auth->realm)); 11838 ast_copy_string(auth->username, username, sizeof(auth->username)); 11839 if (secret) 11840 ast_copy_string(auth->secret, secret, sizeof(auth->secret)); 11841 if (md5secret) 11842 ast_copy_string(auth->md5secret, md5secret, sizeof(auth->md5secret)); 11843 } else { 11844 ast_log(LOG_ERROR, "Allocation of auth structure failed, Out of memory\n"); 11845 return authlist; 11846 } 11847 11848 /* Add authentication to authl */ 11849 if (!authlist) { /* No existing list */ 11850 return auth; 11851 } 11852 while(a) { 11853 b = a; 11854 a = a->next; 11855 } 11856 b->next = auth; /* Add structure add end of list */ 11857 11858 if (option_verbose > 2) 11859 ast_verbose("Added authentication for realm %s\n", realm); 11860 11861 return authlist; 11862 11863 }
|
|
add_route: Add route header into request per learned route ---
Definition at line 3860 of file chan_sip.c. References add_header(), sip_route::hop, n, and sip_route::next. Referenced by reqprep(). 03861 { 03862 char r[256], *p; 03863 int n, rem = sizeof(r); 03864 03865 if (!route) return; 03866 03867 p = r; 03868 while (route) { 03869 n = strlen(route->hop); 03870 if ((n+3)>rem) break; 03871 if (p != r) { 03872 *p++ = ','; 03873 --rem; 03874 } 03875 *p++ = '<'; 03876 ast_copy_string(p, route->hop, rem); p += n; 03877 *p++ = '>'; 03878 rem -= (n+2); 03879 route = route->next; 03880 } 03881 *p = '\0'; 03882 add_header(req, "Route", r); 03883 }
|
|
add_sdp: Add Session Description Protocol message ---
Definition at line 4313 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. 04314 { 04315 int len = 0; 04316 int pref_codec; 04317 int alreadysent = 0; 04318 struct sockaddr_in sin; 04319 struct sockaddr_in vsin; 04320 char v[256]; 04321 char s[256]; 04322 char o[256]; 04323 char c[256]; 04324 char t[256]; 04325 char m_audio[256]; 04326 char m_video[256]; 04327 char a_audio[1024]; 04328 char a_video[1024]; 04329 char *m_audio_next = m_audio; 04330 char *m_video_next = m_video; 04331 size_t m_audio_left = sizeof(m_audio); 04332 size_t m_video_left = sizeof(m_video); 04333 char *a_audio_next = a_audio; 04334 char *a_video_next = a_video; 04335 size_t a_audio_left = sizeof(a_audio); 04336 size_t a_video_left = sizeof(a_video); 04337 char iabuf[INET_ADDRSTRLEN]; 04338 int x; 04339 int capability; 04340 struct sockaddr_in dest; 04341 struct sockaddr_in vdest = { 0, }; 04342 int debug; 04343 04344 debug = sip_debug_test_pvt(p); 04345 04346 len = 0; 04347 if (!p->rtp) { 04348 ast_log(LOG_WARNING, "No way to add SDP without an RTP structure\n"); 04349 return -1; 04350 } 04351 capability = p->jointcapability; 04352 04353 if (!p->sessionid) { 04354 p->sessionid = getpid(); 04355 p->sessionversion = p->sessionid; 04356 } else 04357 p->sessionversion++; 04358 ast_rtp_get_us(p->rtp, &sin); 04359 if (p->vrtp) 04360 ast_rtp_get_us(p->vrtp, &vsin); 04361 04362 if (p->redirip.sin_addr.s_addr) { 04363 dest.sin_port = p->redirip.sin_port; 04364 dest.sin_addr = p->redirip.sin_addr; 04365 if (p->redircodecs) 04366 capability = p->redircodecs; 04367 } else { 04368 dest.sin_addr = p->ourip; 04369 dest.sin_port = sin.sin_port; 04370 } 04371 04372 /* Determine video destination */ 04373 if (p->vrtp) { 04374 if (p->vredirip.sin_addr.s_addr) { 04375 vdest.sin_port = p->vredirip.sin_port; 04376 vdest.sin_addr = p->vredirip.sin_addr; 04377 } else { 04378 vdest.sin_addr = p->ourip; 04379 vdest.sin_port = vsin.sin_port; 04380 } 04381 } 04382 if (debug){ 04383 ast_verbose("We're at %s port %d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip), ntohs(sin.sin_port)); 04384 if (p->vrtp) 04385 ast_verbose("Video is at %s port %d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip), ntohs(vsin.sin_port)); 04386 } 04387 04388 /* We break with the "recommendation" and send our IP, in order that our 04389 peer doesn't have to ast_gethostbyname() us */ 04390 04391 snprintf(v, sizeof(v), "v=0\r\n"); 04392 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)); 04393 snprintf(s, sizeof(s), "s=session\r\n"); 04394 snprintf(c, sizeof(c), "c=IN IP4 %s\r\n", ast_inet_ntoa(iabuf, sizeof(iabuf), dest.sin_addr)); 04395 snprintf(t, sizeof(t), "t=0 0\r\n"); 04396 04397 ast_build_string(&m_audio_next, &m_audio_left, "m=audio %d RTP/AVP", ntohs(dest.sin_port)); 04398 ast_build_string(&m_video_next, &m_video_left, "m=video %d RTP/AVP", ntohs(vdest.sin_port)); 04399 04400 /* Prefer the codec we were requested to use, first, no matter what */ 04401 if (capability & p->prefcodec) { 04402 if (p->prefcodec <= AST_FORMAT_MAX_AUDIO) 04403 add_codec_to_sdp(p, p->prefcodec, 8000, 04404 &m_audio_next, &m_audio_left, 04405 &a_audio_next, &a_audio_left, 04406 debug); 04407 else 04408 add_codec_to_sdp(p, p->prefcodec, 90000, 04409 &m_video_next, &m_video_left, 04410 &a_video_next, &a_video_left, 04411 debug); 04412 alreadysent |= p->prefcodec; 04413 } 04414 04415 /* Start by sending our preferred codecs */ 04416 for (x = 0; x < 32; x++) { 04417 if (!(pref_codec = ast_codec_pref_index(&p->prefs, x))) 04418 break; 04419 04420 if (!(capability & pref_codec)) 04421 continue; 04422 04423 if (alreadysent & pref_codec) 04424 continue; 04425 04426 if (pref_codec <= AST_FORMAT_MAX_AUDIO) 04427 add_codec_to_sdp(p, pref_codec, 8000, 04428 &m_audio_next, &m_audio_left, 04429 &a_audio_next, &a_audio_left, 04430 debug); 04431 else 04432 add_codec_to_sdp(p, pref_codec, 90000, 04433 &m_video_next, &m_video_left, 04434 &a_video_next, &a_video_left, 04435 debug); 04436 alreadysent |= pref_codec; 04437 } 04438 04439 /* Now send any other common codecs, and non-codec formats: */ 04440 for (x = 1; x <= ((videosupport && p->vrtp) ? AST_FORMAT_MAX_VIDEO : AST_FORMAT_MAX_AUDIO); x <<= 1) { 04441 if (!(capability & x)) 04442 continue; 04443 04444 if (alreadysent & x) 04445 continue; 04446 04447 if (x <= AST_FORMAT_MAX_AUDIO) 04448 add_codec_to_sdp(p, x, 8000, 04449 &m_audio_next, &m_audio_left, 04450 &a_audio_next, &a_audio_left, 04451 debug); 04452 else 04453 add_codec_to_sdp(p, x, 90000, 04454 &m_video_next, &m_video_left, 04455 &a_video_next, &a_video_left, 04456 debug); 04457 } 04458 04459 for (x = 1; x <= AST_RTP_MAX; x <<= 1) { 04460 if (!(p->noncodeccapability & x)) 04461 continue; 04462 04463 add_noncodec_to_sdp(p, x, 8000, 04464 &m_audio_next, &m_audio_left, 04465 &a_audio_next, &a_audio_left, 04466 debug); 04467 } 04468 04469 ast_build_string(&a_audio_next, &a_audio_left, "a=silenceSupp:off - - - -\r\n"); 04470 04471 if ((m_audio_left < 2) || (m_video_left < 2) || (a_audio_left == 0) || (a_video_left == 0)) 04472 ast_log(LOG_WARNING, "SIP SDP may be truncated due to undersized buffer!!\n"); 04473 04474 ast_build_string(&m_audio_next, &m_audio_left, "\r\n"); 04475 ast_build_string(&m_video_next, &m_video_left, "\r\n"); 04476 04477 len = strlen(v) + strlen(s) + strlen(o) + strlen(c) + strlen(t) + strlen(m_audio) + strlen(a_audio); 04478 if ((p->vrtp) && (!ast_test_flag(p, SIP_NOVIDEO)) && (capability & VIDEO_CODEC_MASK)) /* only if video response is appropriate */ 04479 len += strlen(m_video) + strlen(a_video); 04480 04481 add_header(resp, "Content-Type", "application/sdp"); 04482 add_header_contentLength(resp, len); 04483 add_line(resp, v); 04484 add_line(resp, o); 04485 add_line(resp, s); 04486 add_line(resp, c); 04487 add_line(resp, t); 04488 add_line(resp, m_audio); 04489 add_line(resp, a_audio); 04490 if ((p->vrtp) && (!ast_test_flag(p, SIP_NOVIDEO)) && (capability & VIDEO_CODEC_MASK)) { /* only if video response is appropriate */ 04491 add_line(resp, m_video); 04492 add_line(resp, a_video); 04493 } 04494 04495 /* Update lastrtprx when we send our SDP */ 04496 time(&p->lastrtprx); 04497 time(&p->lastrtptx); 04498 04499 return 0; 04500 }
|
|
add_sip_domain: Add SIP domain to list of domains we are responsible for
Definition at line 11732 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(). 11733 { 11734 struct domain *d; 11735 11736 if (ast_strlen_zero(domain)) { 11737 ast_log(LOG_WARNING, "Zero length domain.\n"); 11738 return 1; 11739 } 11740 11741 d = calloc(1, sizeof(*d)); 11742 if (!d) { 11743 ast_log(LOG_ERROR, "Allocation of domain structure failed, Out of memory\n"); 11744 return 0; 11745 } 11746 11747 ast_copy_string(d->domain, domain, sizeof(d->domain)); 11748 11749 if (!ast_strlen_zero(context)) 11750 ast_copy_string(d->context, context, sizeof(d->context)); 11751 11752 d->mode = mode; 11753 11754 AST_LIST_LOCK(&domain_list); 11755 AST_LIST_INSERT_TAIL(&domain_list, d, list); 11756 AST_LIST_UNLOCK(&domain_list); 11757 11758 if (sipdebug) 11759 ast_log(LOG_DEBUG, "Added local SIP domain '%s'\n", domain); 11760 11761 return 1; 11762 }
|
|
add_text: Add text body to SIP message ---
Definition at line 4230 of file chan_sip.c. References add_header(), add_header_contentLength(), and add_line(). Referenced by transmit_message_with_text(). 04231 { 04232 /* XXX Convert \n's to \r\n's XXX */ 04233 add_header(req, "Content-Type", "text/plain"); 04234 add_header_contentLength(req, strlen(text)); 04235 add_line(req, text); 04236 return 0; 04237 }
|
|
add_vidupdate: add XML encoded media control with update ---
Definition at line 4254 of file chan_sip.c. References add_header(), add_header_contentLength(), and add_line(). Referenced by transmit_info_with_vidupdate(). 04255 { 04256 const char *xml_is_a_huge_waste_of_space = 04257 "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\r\n" 04258 " <media_control>\r\n" 04259 " <vc_primitive>\r\n" 04260 " <to_encoder>\r\n" 04261 " <picture_fast_update>\r\n" 04262 " </picture_fast_update>\r\n" 04263 " </to_encoder>\r\n" 04264 " </vc_primitive>\r\n" 04265 " </media_control>\r\n"; 04266 add_header(req, "Content-Type", "application/media_control+xml"); 04267 add_header_contentLength(req, strlen(xml_is_a_huge_waste_of_space)); 04268 add_line(req, xml_is_a_huge_waste_of_space); 04269 return 0; 04270 }
|
|
append_date: Append date to SIP message ---
Definition at line 4174 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(). 04175 { 04176 char tmpdat[256]; 04177 struct tm tm; 04178 time_t t; 04179 04180 time(&t); 04181 gmtime_r(&t, &tm); 04182 strftime(tmpdat, sizeof(tmpdat), "%a, %d %b %Y %T GMT", &tm); 04183 add_header(req, "Date", tmpdat); 04184 }
|
|
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 10128 of file chan_sip.c. References ast_channel::_state, ast_deactivate_generator(), AST_STATE_UP, and ast_channel::generatordata. Referenced by attempt_transfer(). 10129 { 10130 if (chan && chan->_state == AST_STATE_UP) { 10131 if (chan->generatordata) 10132 ast_deactivate_generator(chan); 10133 } 10134 }
|
|
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 10137 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. 10138 { 10139 int res = 0; 10140 struct ast_channel 10141 *chana = NULL, 10142 *chanb = NULL, 10143 *bridgea = NULL, 10144 *bridgeb = NULL, 10145 *peera = NULL, 10146 *peerb = NULL, 10147 *peerc = NULL, 10148 *peerd = NULL; 10149 10150 if (!p1->owner || !p2->owner) { 10151 ast_log(LOG_WARNING, "Transfer attempted without dual ownership?\n"); 10152 return -1; 10153 } 10154 chana = p1->owner; 10155 chanb = p2->owner; 10156 bridgea = ast_bridged_channel(chana); 10157 bridgeb = ast_bridged_channel(chanb); 10158 10159 if (bridgea) { 10160 peera = chana; 10161 peerb = chanb; 10162 peerc = bridgea; 10163 peerd = bridgeb; 10164 } else if (bridgeb) { 10165 peera = chanb; 10166 peerb = chana; 10167 peerc = bridgeb; 10168 peerd = bridgea; 10169 } 10170 10171 if (peera && peerb && peerc && (peerb != peerc)) { 10172 ast_quiet_chan(peera); 10173 ast_quiet_chan(peerb); 10174 ast_quiet_chan(peerc); 10175 ast_quiet_chan(peerd); 10176 10177 if (peera->cdr && peerb->cdr) { 10178 peerb->cdr = ast_cdr_append(peerb->cdr, peera->cdr); 10179 } else if (peera->cdr) { 10180 peerb->cdr = peera->cdr; 10181 } 10182 peera->cdr = NULL; 10183 10184 if (peerb->cdr && peerc->cdr) { 10185 peerb->cdr = ast_cdr_append(peerb->cdr, peerc->cdr); 10186 } else if (peerc->cdr) { 10187 peerb->cdr = peerc->cdr; 10188 } 10189 peerc->cdr = NULL; 10190 10191 if (ast_channel_masquerade(peerb, peerc)) { 10192 ast_log(LOG_WARNING, "Failed to masquerade %s into %s\n", peerb->name, peerc->name); 10193 res = -1; 10194 } 10195 return res; 10196 } else { 10197 ast_log(LOG_NOTICE, "Transfer attempted with no appropriate bridged calls to transfer\n"); 10198 if (chana) 10199 ast_softhangup_nolock(chana, AST_SOFTHANGUP_DEV); 10200 if (chanb) 10201 ast_softhangup_nolock(chanb, AST_SOFTHANGUP_DEV); 10202 return -1; 10203 } 10204 return 0; 10205 }
|
|
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 4630 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(). 04631 { 04632 char iabuf[INET_ADDRSTRLEN]; 04633 04634 /* Construct Contact: header */ 04635 if (ourport != 5060) /* Needs to be 5060, according to the RFC */ 04636 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); 04637 else 04638 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)); 04639 }
|
|
build_peer: Build peer from config file ---
Definition at line 12029 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. 12030 { 12031 struct sip_peer *peer = NULL; 12032 struct ast_ha *oldha = NULL; 12033 int obproxyfound=0; 12034 int found=0; 12035 int format=0; /* Ama flags */ 12036 time_t regseconds; 12037 char *varname = NULL, *varval = NULL; 12038 struct ast_variable *tmpvar = NULL; 12039 struct ast_flags peerflags = {(0)}; 12040 struct ast_flags mask = {(0)}; 12041 12042 12043 if (!realtime) 12044 /* Note we do NOT use find_peer here, to avoid realtime recursion */ 12045 /* We also use a case-sensitive comparison (unlike find_peer) so 12046 that case changes made to the peer name will be properly handled 12047 during reload 12048 */ 12049 peer = ASTOBJ_CONTAINER_FIND_UNLINK_FULL(&peerl, name, name, 0, 0, strcmp); 12050 12051 if (peer) { 12052 /* Already in the list, remove it and it will be added back (or FREE'd) */ 12053 found++; 12054 } else { 12055 peer = malloc(sizeof(*peer)); 12056 if (peer) { 12057 memset(peer, 0, sizeof(*peer)); 12058 if (realtime) 12059 rpeerobjs++; 12060 else 12061 speerobjs++; 12062 ASTOBJ_INIT(peer); 12063 peer->expire = -1; 12064 peer->pokeexpire = -1; 12065 } else { 12066 ast_log(LOG_WARNING, "Can't allocate SIP peer memory\n"); 12067 } 12068 } 12069 /* Note that our peer HAS had its reference count incrased */ 12070 if (!peer) 12071 return NULL; 12072 12073 peer->lastmsgssent = -1; 12074 if (!found) { 12075 if (name) 12076 ast_copy_string(peer->name, name, sizeof(peer->name)); 12077 peer->addr.sin_port = htons(DEFAULT_SIP_PORT); 12078 peer->addr.sin_family = AF_INET; 12079 peer->defaddr.sin_family = AF_INET; 12080 } 12081 /* If we have channel variables, remove them (reload) */ 12082 if (peer->chanvars) { 12083 ast_variables_destroy(peer->chanvars); 12084 peer->chanvars = NULL; 12085 } 12086 strcpy(peer->context, default_context); 12087 strcpy(peer->subscribecontext, default_subscribecontext); 12088 strcpy(peer->vmexten, global_vmexten); 12089 strcpy(peer->language, default_language); 12090 strcpy(peer->musicclass, global_musicclass); 12091 ast_copy_flags(peer, &global_flags, SIP_USEREQPHONE); 12092 peer->secret[0] = '\0'; 12093 peer->md5secret[0] = '\0'; 12094 peer->cid_num[0] = '\0'; 12095 peer->cid_name[0] = '\0'; 12096 peer->fromdomain[0] = '\0'; 12097 peer->fromuser[0] = '\0'; 12098 peer->regexten[0] = '\0'; 12099 peer->mailbox[0] = '\0'; 12100 peer->callgroup = 0; 12101 peer->pickupgroup = 0; 12102 peer->rtpkeepalive = global_rtpkeepalive; 12103 peer->maxms = default_qualify; 12104 peer->prefs = prefs; 12105 oldha = peer->ha; 12106 peer->ha = NULL; 12107 peer->addr.sin_family = AF_INET; 12108 ast_copy_flags(peer, &global_flags, SIP_FLAGS_TO_COPY); 12109 peer->capability = global_capability; 12110 peer->rtptimeout = global_rtptimeout; 12111 peer->rtpholdtimeout = global_rtpholdtimeout; 12112 while(v) { 12113 if (handle_common_options(&peerflags, &mask, v)) { 12114 v = v->next; 12115 continue; 12116 } 12117 12118 if (realtime && !strcasecmp(v->name, "regseconds")) { 12119 if (sscanf(v->value, "%ld", (time_t *)®seconds) != 1) 12120 regseconds = 0; 12121 } else if (realtime && !strcasecmp(v->name, "ipaddr") && !ast_strlen_zero(v->value) ) { 12122 inet_aton(v->value, &(peer->addr.sin_addr)); 12123 } else if (realtime && !strcasecmp(v->name, "name")) 12124 ast_copy_string(peer->name, v->value, sizeof(peer->name)); 12125 else if (realtime && !strcasecmp(v->name, "fullcontact")) { 12126 ast_copy_string(peer->fullcontact, v->value, sizeof(peer->fullcontact)); 12127 ast_set_flag((&peer->flags_page2), SIP_PAGE2_RT_FROMCONTACT); 12128 } else if (!strcasecmp(v->name, "secret")) 12129 ast_copy_string(peer->secret, v->value, sizeof(peer->secret)); 12130 else if (!strcasecmp(v->name, "md5secret")) 12131 ast_copy_string(peer->md5secret, v->value, sizeof(peer->md5secret)); 12132 else if (!strcasecmp(v->name, "auth")) 12133 peer->auth = add_realm_authentication(peer->auth, v->value, v->lineno); 12134 else if (!strcasecmp(v->name, "callerid")) { 12135 ast_callerid_split(v->value, peer->cid_name, sizeof(peer->cid_name), peer->cid_num, sizeof(peer->cid_num)); 12136 } else if (!strcasecmp(v->name, "context")) { 12137 ast_copy_string(peer->context, v->value, sizeof(peer->context)); 12138 } else if (!strcasecmp(v->name, "subscribecontext")) { 12139 ast_copy_string(peer->subscribecontext, v->value, sizeof(peer->subscribecontext)); 12140 } else if (!strcasecmp(v->name, "fromdomain")) 12141 ast_copy_string(peer->fromdomain, v->value, sizeof(peer->fromdomain)); 12142 else if (!strcasecmp(v->name, "usereqphone")) 12143 ast_set2_flag(peer, ast_true(v->value), SIP_USEREQPHONE); 12144 else if (!strcasecmp(v->name, "fromuser")) 12145 ast_copy_string(peer->fromuser, v->value, sizeof(peer->fromuser)); 12146 else if (!strcasecmp(v->name, "host") || !strcasecmp(v->name, "outboundproxy")) { 12147 if (!strcasecmp(v->value, "dynamic")) { 12148 if (!strcasecmp(v->name, "outboundproxy") || obproxyfound) { 12149 ast_log(LOG_WARNING, "You can't have a dynamic outbound proxy, you big silly head at line %d.\n", v->lineno); 12150 } else { 12151 /* They'll register with us */ 12152 ast_set_flag(peer, SIP_DYNAMIC); 12153 if (!found) { 12154 /* Initialize stuff iff we're not found, otherwise 12155 we keep going with what we had */ 12156 memset(&peer->addr.sin_addr, 0, 4); 12157 if (peer->addr.sin_port) { 12158 /* If we've already got a port, make it the default rather than absolute */ 12159 peer->defaddr.sin_port = peer->addr.sin_port; 12160 peer->addr.sin_port = 0; 12161 } 12162 } 12163 } 12164 } else { 12165 /* Non-dynamic. Make sure we become that way if we're not */ 12166 if (peer->expire > -1) 12167 ast_sched_del(sched, peer->expire); 12168 peer->expire = -1; 12169 ast_clear_flag(peer, SIP_DYNAMIC); 12170 if (!obproxyfound || !strcasecmp(v->name, "outboundproxy")) { 12171 if (ast_get_ip_or_srv(&peer->addr, v->value, "_sip._udp")) { 12172 ASTOBJ_UNREF(peer, sip_destroy_peer); 12173 return NULL; 12174 } 12175 } 12176 if (!strcasecmp(v->name, "outboundproxy")) 12177 obproxyfound=1; 12178 else { 12179 ast_copy_string(peer->tohost, v->value, sizeof(peer->tohost)); 12180 if (!peer->addr.sin_port) 12181 peer->addr.sin_port = htons(DEFAULT_SIP_PORT); 12182 } 12183 } 12184 } else if (!strcasecmp(v->name, "defaultip")) { 12185 if (ast_get_ip(&peer->defaddr, v->value)) { 12186 ASTOBJ_UNREF(peer, sip_destroy_peer); 12187 return NULL; 12188 } 12189 } else if (!strcasecmp(v->name, "permit") || !strcasecmp(v->name, "deny")) { 12190 peer->ha = ast_append_ha(v->name, v->value, peer->ha); 12191 } else if (!strcasecmp(v->name, "port")) { 12192 if (!realtime && ast_test_flag(peer, SIP_DYNAMIC)) 12193 peer->defaddr.sin_port = htons(atoi(v->value)); 12194 else 12195 peer->addr.sin_port = htons(atoi(v->value)); 12196 } else if (!strcasecmp(v->name, "callingpres")) { 12197 peer->callingpres = ast_parse_caller_presentation(v->value); 12198 if (peer->callingpres == -1) 12199 peer->callingpres = atoi(v->value); 12200 } else if (!strcasecmp(v->name, "username")) { 12201 ast_copy_string(peer->username, v->value, sizeof(peer->username)); 12202 } else if (!strcasecmp(v->name, "language")) { 12203 ast_copy_string(peer->language, v->value, sizeof(peer->language)); 12204 } else if (!strcasecmp(v->name, "regexten")) { 12205 ast_copy_string(peer->regexten, v->value, sizeof(peer->regexten)); 12206 } else if (!strcasecmp(v->name, "call-limit") || !strcasecmp(v->name, "incominglimit")) { 12207 peer->call_limit = atoi(v->value); 12208 if (peer->call_limit < 0) 12209 peer->call_limit = 0; 12210 } else if (!strcasecmp(v->name, "amaflags")) { 12211 format = ast_cdr_amaflags2int(v->value); 12212 if (format < 0) { 12213 ast_log(LOG_WARNING, "Invalid AMA Flags for peer: %s at line %d\n", v->value, v->lineno); 12214 } else { 12215 peer->amaflags = format; 12216 } 12217 } else if (!strcasecmp(v->name, "accountcode")) { 12218 ast_copy_string(peer->accountcode, v->value, sizeof(peer->accountcode)); 12219 } else if (!strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) { 12220 ast_copy_string(peer->musicclass, v->value, sizeof(peer->musicclass)); 12221 } else if (!strcasecmp(v->name, "mailbox")) { 12222 ast_copy_string(peer->mailbox, v->value, sizeof(peer->mailbox)); 12223 } else if (!strcasecmp(v->name, "vmexten")) { 12224 ast_copy_string(peer->vmexten, v->value, sizeof(peer->vmexten)); 12225 } else if (!strcasecmp(v->name, "callgroup")) { 12226 peer->callgroup = ast_get_group(v->value); 12227 } else if (!strcasecmp(v->name, "pickupgroup")) { 12228 peer->pickupgroup = ast_get_group(v->value); 12229 } else if (!strcasecmp(v->name, "allow")) { 12230 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1); 12231 } else if (!strcasecmp(v->name, "disallow")) { 12232 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0); 12233 } else if (!strcasecmp(v->name, "rtptimeout")) { 12234 if ((sscanf(v->value, "%d", &peer->rtptimeout) != 1) || (peer->rtptimeout < 0)) { 12235 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 12236 peer->rtptimeout = global_rtptimeout; 12237 } 12238 } else if (!strcasecmp(v->name, "rtpholdtimeout")) { 12239 if ((sscanf(v->value, "%d", &peer->rtpholdtimeout) != 1) || (peer->rtpholdtimeout < 0)) { 12240 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 12241 peer->rtpholdtimeout = global_rtpholdtimeout; 12242 } 12243 } else if (!strcasecmp(v->name, "rtpkeepalive")) { 12244 if ((sscanf(v->value, "%d", &peer->rtpkeepalive) != 1) || (peer->rtpkeepalive < 0)) { 12245 ast_log(LOG_WARNING, "'%s' is not a valid RTP keepalive time at line %d. Using default.\n", v->value, v->lineno); 12246 peer->rtpkeepalive = global_rtpkeepalive; 12247 } 12248 } else if (!strcasecmp(v->name, "setvar")) { 12249 /* Set peer channel variable */ 12250 varname = ast_strdupa(v->value); 12251 if (varname && (varval = strchr(varname,'='))) { 12252 *varval = '\0'; 12253 varval++; 12254 if ((tmpvar = ast_variable_new(varname, varval))) { 12255 tmpvar->next = peer->chanvars; 12256 peer->chanvars = tmpvar; 12257 } 12258 } 12259 } else if (!strcasecmp(v->name, "qualify")) { 12260 if (!strcasecmp(v->value, "no")) { 12261 peer->maxms = 0; 12262 } else if (!strcasecmp(v->value, "yes")) { 12263 peer->maxms = DEFAULT_MAXMS; 12264 } else if (sscanf(v->value, "%d", &peer->maxms) != 1) { 12265 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); 12266 peer->maxms = 0; 12267 } 12268 } 12269 /* else if (strcasecmp(v->name,"type")) 12270 * ast_log(LOG_WARNING, "Ignoring %s\n", v->name); 12271 */ 12272 v=v->next; 12273 } 12274 if (!ast_test_flag((&global_flags_page2), SIP_PAGE2_IGNOREREGEXPIRE) && ast_test_flag(peer, SIP_DYNAMIC) && realtime) { 12275 time_t nowtime; 12276 12277 time(&nowtime); 12278 if ((nowtime - regseconds) > 0) { 12279 destroy_association(peer); 12280 memset(&peer->addr, 0, sizeof(peer->addr)); 12281 if (option_debug) 12282 ast_log(LOG_DEBUG, "Bah, we're expired (%d/%d/%d)!\n", (int)(nowtime - regseconds), (int)regseconds, (int)nowtime); 12283 } 12284 } 12285 ast_copy_flags(peer, &peerflags, mask.flags); 12286 if (!found && ast_test_flag(peer, SIP_DYNAMIC) && !ast_test_flag(peer, SIP_REALTIME)) 12287 reg_source_db(peer); 12288 ASTOBJ_UNMARK(peer); 12289 ast_free_ha(oldha); 12290 return peer; 12291 }
|
|
build_reply_digest: Build reply digest ---
Definition at line 8996 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(). 08997 { 08998 char a1[256]; 08999 char a2[256]; 09000 char a1_hash[256]; 09001 char a2_hash[256]; 09002 char resp[256]; 09003 char resp_hash[256]; 09004 char uri[256]; 09005 char cnonce[80]; 09006 char iabuf[INET_ADDRSTRLEN]; 09007 char *username; 09008 char *secret; 09009 char *md5secret; 09010 struct sip_auth *auth = (struct sip_auth *) NULL; /* Realm authentication */ 09011 09012 if (!ast_strlen_zero(p->domain)) 09013 ast_copy_string(uri, p->domain, sizeof(uri)); 09014 else if (!ast_strlen_zero(p->uri)) 09015 ast_copy_string(uri, p->uri, sizeof(uri)); 09016 else 09017 snprintf(uri, sizeof(uri), "sip:%s@%s",p->username, ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr)); 09018 09019 snprintf(cnonce, sizeof(cnonce), "%08x", thread_safe_rand()); 09020 09021 /* Check if we have separate auth credentials */ 09022 if ((auth = find_realm_authentication(authl, p->realm))) { 09023 username = auth->username; 09024 secret = auth->secret; 09025 md5secret = auth->md5secret; 09026 if (sipdebug) 09027 ast_log(LOG_DEBUG,"Using realm %s authentication for call %s\n", p->realm, p->callid); 09028 } else { 09029 /* No authentication, use peer or register= config */ 09030 username = p->authname; 09031 secret = p->peersecret; 09032 md5secret = p->peermd5secret; 09033 } 09034 if (ast_strlen_zero(username)) /* We have no authentication */ 09035 return -1; 09036 09037 09038 /* Calculate SIP digest response */ 09039 snprintf(a1,sizeof(a1),"%s:%s:%s", username, p->realm, secret); 09040 snprintf(a2,sizeof(a2),"%s:%s", sip_methods[method].text, uri); 09041 if (!ast_strlen_zero(md5secret)) 09042 ast_copy_string(a1_hash, md5secret, sizeof(a1_hash)); 09043 else 09044 ast_md5_hash(a1_hash,a1); 09045 ast_md5_hash(a2_hash,a2); 09046 09047 p->noncecount++; 09048 if (!ast_strlen_zero(p->qop)) 09049 snprintf(resp,sizeof(resp),"%s:%s:%08x:%s:%s:%s", a1_hash, p->nonce, p->noncecount, cnonce, "auth", a2_hash); 09050 else 09051 snprintf(resp,sizeof(resp),"%s:%s:%s", a1_hash, p->nonce, a2_hash); 09052 ast_md5_hash(resp_hash, resp); 09053 /* XXX We hard code our qop to "auth" for now. XXX */ 09054 if (!ast_strlen_zero(p->qop)) 09055 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); 09056 else 09057 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); 09058 09059 return 0; 09060 }
|
|
build_route: Build route list from Record-Route header ---
Definition at line 5981 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(). 05982 { 05983 struct sip_route *thishop, *head, *tail; 05984 int start = 0; 05985 int len; 05986 char *rr, *contact, *c; 05987 05988 /* Once a persistant route is set, don't fool with it */ 05989 if (p->route && p->route_persistant) { 05990 ast_log(LOG_DEBUG, "build_route: Retaining previous route: <%s>\n", p->route->hop); 05991 return; 05992 } 05993 05994 if (p->route) { 05995 free_old_route(p->route); 05996 p->route = NULL; 05997 } 05998 05999 p->route_persistant = backwards; 06000 06001 /* We build up head, then assign it to p->route when we're done */ 06002 head = NULL; tail = head; 06003 /* 1st we pass through all the hops in any Record-Route headers */ 06004 for (;;) { 06005 /* Each Record-Route header */ 06006 rr = __get_header(req, "Record-Route", &start); 06007 if (*rr == '\0') break; 06008 for (;;) { 06009 /* Each route entry */ 06010 /* Find < */ 06011 rr = strchr(rr, '<'); 06012 if (!rr) break; /* No more hops */ 06013 ++rr; 06014 len = strcspn(rr, ">") + 1; 06015 /* Make a struct route */ 06016 thishop = malloc(sizeof(*thishop) + len); 06017 if (thishop) { 06018 ast_copy_string(thishop->hop, rr, len); 06019 ast_log(LOG_DEBUG, "build_route: Record-Route hop: <%s>\n", thishop->hop); 06020 /* Link in */ 06021 if (backwards) { 06022 /* Link in at head so they end up in reverse order */ 06023 thishop->next = head; 06024 head = thishop; 06025 /* If this was the first then it'll be the tail */ 06026 if (!tail) tail = thishop; 06027 } else { 06028 thishop->next = NULL; 06029 /* Link in at the end */ 06030 if (tail) 06031 tail->next = thishop; 06032 else 06033 head = thishop; 06034 tail = thishop; 06035 } 06036 } 06037 rr += len; 06038 } 06039 } 06040 06041 /* Only append the contact if we are dealing with a strict router */ 06042 if (!head || (!ast_strlen_zero(head->hop) && strstr(head->hop,";lr") == NULL) ) { 06043 /* 2nd append the Contact: if there is one */ 06044 /* Can be multiple Contact headers, comma separated values - we just take the first */ 06045 contact = get_header(req, "Contact"); 06046 if (!ast_strlen_zero(contact)) { 06047 ast_log(LOG_DEBUG, "build_route: Contact hop: %s\n", contact); 06048 /* Look for <: delimited address */ 06049 c = strchr(contact, '<'); 06050 if (c) { 06051 /* Take to > */ 06052 ++c; 06053 len = strcspn(c, ">") + 1; 06054 } else { 06055 /* No <> - just take the lot */ 06056 c = contact; 06057 len = strlen(contact) + 1; 06058 } 06059 thishop = malloc(sizeof(*thishop) + len); 06060 if (thishop) { 06061 ast_copy_string(thishop->hop, c, len); 06062 thishop->next = NULL; 06063 /* Goes at the end */ 06064 if (tail) 06065 tail->next = thishop; 06066 else 06067 head = thishop; 06068 } 06069 } 06070 } 06071 06072 /* Store as new route */ 06073 p->route = head; 06074 06075 /* For debugging dump what we ended up with */ 06076 if (sip_debug_test_pvt(p)) 06077 list_route(p->route); 06078 }
|
|
build_rpid: Build the Remote Party-ID & From using callingpres options ---
Definition at line 4642 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. 04643 { 04644 int send_pres_tags = 1; 04645 const char *privacy=NULL; 04646 const char *screen=NULL; 04647 char buf[256]; 04648 const char *clid = default_callerid; 04649 const char *clin = NULL; 04650 char iabuf[INET_ADDRSTRLEN]; 04651 const char *fromdomain; 04652 04653 if (p->rpid || p->rpid_from) 04654 return; 04655 04656 if (p->owner && p->owner->cid.cid_num) 04657 clid = p->owner->cid.cid_num; 04658 if (p->owner && p->owner->cid.cid_name) 04659 clin = p->owner->cid.cid_name; 04660 if (ast_strlen_zero(clin)) 04661 clin = clid; 04662 04663 switch (p->callingpres) { 04664 case AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED: 04665 privacy = "off"; 04666 screen = "no"; 04667 break; 04668 case AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN: 04669 privacy = "off"; 04670 screen = "pass"; 04671 break; 04672 case AST_PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN: 04673 privacy = "off"; 04674 screen = "fail"; 04675 break; 04676 case AST_PRES_ALLOWED_NETWORK_NUMBER: 04677 privacy = "off"; 04678 screen = "yes"; 04679 break; 04680 case AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED: 04681 privacy = "full"; 04682 screen = "no"; 04683 break; 04684 case AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN: 04685 privacy = "full"; 04686 screen = "pass"; 04687 break; 04688 case AST_PRES_PROHIB_USER_NUMBER_FAILED_SCREEN: 04689 privacy = "full"; 04690 screen = "fail"; 04691 break; 04692 case AST_PRES_PROHIB_NETWORK_NUMBER: 04693 privacy = "full"; 04694 screen = "pass"; 04695 break; 04696 case AST_PRES_NUMBER_NOT_AVAILABLE: 04697 send_pres_tags = 0; 04698 break; 04699 default: 04700 ast_log(LOG_WARNING, "Unsupported callingpres (%d)\n", p->callingpres); 04701 if ((p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED) 04702 privacy = "full"; 04703 else 04704 privacy = "off"; 04705 screen = "no"; 04706 break; 04707 } 04708 04709 fromdomain = ast_strlen_zero(p->fromdomain) ? ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip) : p->fromdomain; 04710 04711 snprintf(buf, sizeof(buf), "\"%s\" <sip:%s@%s>", clin, clid, fromdomain); 04712 if (send_pres_tags) 04713 snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), ";privacy=%s;screen=%s", privacy, screen); 04714 p->rpid = strdup(buf); 04715 04716 snprintf(buf, sizeof(buf), "\"%s\" <sip:%s@%s>;tag=%s", clin, 04717 ast_strlen_zero(p->fromuser) ? clid : p->fromuser, 04718 fromdomain, p->tag); 04719 p->rpid_from = strdup(buf); 04720 }
|
|
build_user: Initiate a SIP user structure from sip.conf ---
Definition at line 11896 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. 11897 { 11898 struct sip_user *user; 11899 int format; 11900 struct ast_ha *oldha = NULL; 11901 char *varname = NULL, *varval = NULL; 11902 struct ast_variable *tmpvar = NULL; 11903 struct ast_flags userflags = {(0)}; 11904 struct ast_flags mask = {(0)}; 11905 11906 11907 user = (struct sip_user *)malloc(sizeof(struct sip_user)); 11908 if (!user) { 11909 return NULL; 11910 } 11911 memset(user, 0, sizeof(struct sip_user)); 11912 suserobjs++; 11913 ASTOBJ_INIT(user); 11914 ast_copy_string(user->name, name, sizeof(user->name)); 11915 oldha = user->ha; 11916 user->ha = NULL; 11917 ast_copy_flags(user, &global_flags, SIP_FLAGS_TO_COPY); 11918 user->capability = global_capability; 11919 user->prefs = prefs; 11920 /* set default context */ 11921 strcpy(user->context, default_context); 11922 strcpy(user->language, default_language); 11923 strcpy(user->musicclass, global_musicclass); 11924 while(v) { 11925 if (handle_common_options(&userflags, &mask, v)) { 11926 v = v->next; 11927 continue; 11928 } 11929 11930 if (!strcasecmp(v->name, "context")) { 11931 ast_copy_string(user->context, v->value, sizeof(user->context)); 11932 } else if (!strcasecmp(v->name, "subscribecontext")) { 11933 ast_copy_string(user->subscribecontext, v->value, sizeof(user->subscribecontext)); 11934 } else if (!strcasecmp(v->name, "setvar")) { 11935 varname = ast_strdupa(v->value); 11936 if (varname && (varval = strchr(varname,'='))) { 11937 *varval = '\0'; 11938 varval++; 11939 if ((tmpvar = ast_variable_new(varname, varval))) { 11940 tmpvar->next = user->chanvars; 11941 user->chanvars = tmpvar; 11942 } 11943 } 11944 } else if (!strcasecmp(v->name, "permit") || 11945 !strcasecmp(v->name, "deny")) { 11946 user->ha = ast_append_ha(v->name, v->value, user->ha); 11947 } else if (!strcasecmp(v->name, "secret")) { 11948 ast_copy_string(user->secret, v->value, sizeof(user->secret)); 11949 } else if (!strcasecmp(v->name, "md5secret")) { 11950 ast_copy_string(user->md5secret, v->value, sizeof(user->md5secret)); 11951 } else if (!strcasecmp(v->name, "callerid")) { 11952 ast_callerid_split(v->value, user->cid_name, sizeof(user->cid_name), user->cid_num, sizeof(user->cid_num)); 11953 } else if (!strcasecmp(v->name, "callgroup")) { 11954 user->callgroup = ast_get_group(v->value); 11955 } else if (!strcasecmp(v->name, "pickupgroup")) { 11956 user->pickupgroup = ast_get_group(v->value); 11957 } else if (!strcasecmp(v->name, "language")) { 11958 ast_copy_string(user->language, v->value, sizeof(user->language)); 11959 } else if (!strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) { 11960 ast_copy_string(user->musicclass, v->value, sizeof(user->musicclass)); 11961 } else if (!strcasecmp(v->name, "accountcode")) { 11962 ast_copy_string(user->accountcode, v->value, sizeof(user->accountcode)); 11963 } else if (!strcasecmp(v->name, "call-limit") || !strcasecmp(v->name, "incominglimit")) { 11964 user->call_limit = atoi(v->value); 11965 if (user->call_limit < 0) 11966 user->call_limit = 0; 11967 } else if (!strcasecmp(v->name, "amaflags")) { 11968 format = ast_cdr_amaflags2int(v->value); 11969 if (format < 0) { 11970 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno); 11971 } else { 11972 user->amaflags = format; 11973 } 11974 } else if (!strcasecmp(v->name, "allow")) { 11975 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1); 11976 } else if (!strcasecmp(v->name, "disallow")) { 11977 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 0); 11978 } else if (!strcasecmp(v->name, "callingpres")) { 11979 user->callingpres = ast_parse_caller_presentation(v->value); 11980 if (user->callingpres == -1) 11981 user->callingpres = atoi(v->value); 11982 } 11983 /*else if (strcasecmp(v->name,"type")) 11984 * ast_log(LOG_WARNING, "Ignoring %s\n", v->name); 11985 */ 11986 v = v->next; 11987 } 11988 ast_copy_flags(user, &userflags, mask.flags); 11989 ast_free_ha(oldha); 11990 return user; 11991 }
|
|
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 6324 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(). 06325 { 06326 struct sip_pvt *p = data; 06327 06328 switch(state) { 06329 case AST_EXTENSION_DEACTIVATED: /* Retry after a while */ 06330 case AST_EXTENSION_REMOVED: /* Extension is gone */ 06331 if (p->autokillid > -1) 06332 sip_cancel_destroy(p); /* Remove subscription expiry for renewals */ 06333 sip_scheddestroy(p, 15000); /* Delete subscription in 15 secs */ 06334 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); 06335 p->stateid = -1; 06336 p->subscribed = NONE; 06337 append_history(p, "Subscribestatus", state == AST_EXTENSION_REMOVED ? "HintRemoved" : "Deactivated"); 06338 break; 06339 default: /* Tell user */ 06340 p->laststate = state; 06341 break; 06342 } 06343 transmit_state_notify(p, state, 1, 1); 06344 06345 if (option_debug > 1) 06346 ast_verbose(VERBOSE_PREFIX_1 "Extension Changed %s new state %s for Notify User %s\n", exten, ast_extension_state2str(state), p->username); 06347 return 0; 06348 }
|
|
check_auth: Check user authorization from peer definition ---
Definition at line 6099 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(). 06100 { 06101 int res = -1; 06102 char *response = "407 Proxy Authentication Required"; 06103 char *reqheader = "Proxy-Authorization"; 06104 char *respheader = "Proxy-Authenticate"; 06105 char *authtoken; 06106 #ifdef OSP_SUPPORT 06107 char *osptoken; 06108 #endif 06109 /* Always OK if no secret */ 06110 if (ast_strlen_zero(secret) && ast_strlen_zero(md5secret) 06111 #ifdef OSP_SUPPORT 06112 && !ast_test_flag(p, SIP_OSPAUTH) 06113 && global_allowguest != 2 06114 #endif 06115 ) 06116 return 0; 06117 if (sipmethod == SIP_REGISTER || sipmethod == SIP_SUBSCRIBE) { 06118 /* On a REGISTER, we have to use 401 and its family of headers instead of 407 and its family 06119 of headers -- GO SIP! Whoo hoo! Two things that do the same thing but are used in 06120 different circumstances! What a surprise. */ 06121 response = "401 Unauthorized"; 06122 reqheader = "Authorization"; 06123 respheader = "WWW-Authenticate"; 06124 } 06125 #ifdef OSP_SUPPORT 06126 else { 06127 ast_log (LOG_DEBUG, "Checking OSP Authentication!\n"); 06128 osptoken = get_header (req, "P-OSP-Auth-Token"); 06129 switch (ast_test_flag (p, SIP_OSPAUTH)) { 06130 case SIP_OSPAUTH_NO: 06131 break; 06132 case SIP_OSPAUTH_GATEWAY: 06133 if (ast_strlen_zero (osptoken)) { 06134 if (ast_strlen_zero (secret) && ast_strlen_zero (md5secret)) { 06135 return (0); 06136 } 06137 } 06138 else { 06139 return (check_osptoken (p, osptoken)); 06140 } 06141 break; 06142 case SIP_OSPAUTH_PROXY: 06143 if (ast_strlen_zero (osptoken)) { 06144 return (0); 06145 } 06146 else { 06147 return (check_osptoken (p, osptoken)); 06148 } 06149 break; 06150 case SIP_OSPAUTH_EXCLUSIVE: 06151 if (ast_strlen_zero (osptoken)) { 06152 return (-1); 06153 } 06154 else { 06155 return (check_osptoken (p, osptoken)); 06156 } 06157 break; 06158 default: 06159 return (-1); 06160 } 06161 } 06162 #endif 06163 authtoken = get_header(req, reqheader); 06164 if (ignore && !ast_strlen_zero(randdata) && ast_strlen_zero(authtoken)) { 06165 /* This is a retransmitted invite/register/etc, don't reconstruct authentication 06166 information */ 06167 if (!ast_strlen_zero(randdata)) { 06168 if (!reliable) { 06169 /* Resend message if this was NOT a reliable delivery. Otherwise the 06170 retransmission should get it */ 06171 transmit_response_with_auth(p, response, req, randdata, reliable, respheader, 0); 06172 /* Schedule auto destroy in 15 seconds */ 06173 sip_scheddestroy(p, 15000); 06174 } 06175 res = 1; 06176 } 06177 } else if (ast_strlen_zero(randdata) || ast_strlen_zero(authtoken)) { 06178 snprintf(randdata, randlen, "%08x", thread_safe_rand()); 06179 transmit_response_with_auth(p, response, req, randdata, reliable, respheader, 0); 06180 /* Schedule auto destroy in 15 seconds */ 06181 sip_scheddestroy(p, 15000); 06182 res = 1; 06183 } else { 06184 /* Whoever came up with the authentication section of SIP can suck my %&#$&* for not putting 06185 an example in the spec of just what it is you're doing a hash on. */ 06186 char a1[256]; 06187 char a2[256]; 06188 char a1_hash[256]; 06189 char a2_hash[256]; 06190 char resp[256]; 06191 char resp_hash[256]=""; 06192 char tmp[256]; 06193 char *c; 06194 char *z; 06195 char *ua_hash =""; 06196 char *resp_uri =""; 06197 char *nonce = ""; 06198 char *digestusername = ""; 06199 int wrongnonce = 0; 06200 char *usednonce = randdata; 06201 06202 /* Find their response among the mess that we'r sent for comparison */ 06203 ast_copy_string(tmp, authtoken, sizeof(tmp)); 06204 c = tmp; 06205 06206 while(c) { 06207 c = ast_skip_blanks(c); 06208 if (!*c) 06209 break; 06210 if (!strncasecmp(c, "response=", strlen("response="))) { 06211 c+= strlen("response="); 06212 if ((*c == '\"')) { 06213 ua_hash=++c; 06214 if ((c = strchr(c,'\"'))) 06215 *c = '\0'; 06216 06217 } else { 06218 ua_hash=c; 06219 if ((c = strchr(c,','))) 06220 *c = '\0'; 06221 } 06222 06223 } else if (!strncasecmp(c, "uri=", strlen("uri="))) { 06224 c+= strlen("uri="); 06225 if ((*c == '\"')) { 06226 resp_uri=++c; 06227 if ((c = strchr(c,'\"'))) 06228 *c = '\0'; 06229 } else { 06230 resp_uri=c; 06231 if ((c = strchr(c,','))) 06232 *c = '\0'; 06233 } 06234 06235 } else if (!strncasecmp(c, "username=", strlen("username="))) { 06236 c+= strlen("username="); 06237 if ((*c == '\"')) { 06238 digestusername=++c; 06239 if((c = strchr(c,'\"'))) 06240 *c = '\0'; 06241 } else { 06242 digestusername=c; 06243 if((c = strchr(c,','))) 06244 *c = '\0'; 06245 } 06246 } else if (!strncasecmp(c, "nonce=", strlen("nonce="))) { 06247 c+= strlen("nonce="); 06248 if ((*c == '\"')) { 06249 nonce=++c; 06250 if ((c = strchr(c,'\"'))) 06251 *c = '\0'; 06252 } else { 06253 nonce=c; 06254 if ((c = strchr(c,','))) 06255 *c = '\0'; 06256 } 06257 06258 } else 06259 if ((z = strchr(c,' ')) || (z = strchr(c,','))) c=z; 06260 if (c) 06261 c++; 06262 } 06263 /* Verify that digest username matches the username we auth as */ 06264 if (strcmp(username, digestusername)) { 06265 /* Oops, we're trying something here */ 06266 return -2; 06267 } 06268 06269 /* Verify nonce from request matches our nonce. If not, send 401 with new nonce */ 06270 if (strncasecmp(randdata, nonce, randlen)) { 06271 wrongnonce = 1; 06272 usednonce = nonce; 06273 } 06274 06275 snprintf(a1, sizeof(a1), "%s:%s:%s", username, global_realm, secret); 06276 06277 if (!ast_strlen_zero(resp_uri)) 06278 snprintf(a2, sizeof(a2), "%s:%s", sip_methods[sipmethod].text, resp_uri); 06279 else 06280 snprintf(a2, sizeof(a2), "%s:%s", sip_methods[sipmethod].text, uri); 06281 06282 if (!ast_strlen_zero(md5secret)) 06283 snprintf(a1_hash, sizeof(a1_hash), "%s", md5secret); 06284 else 06285 ast_md5_hash(a1_hash, a1); 06286 06287 ast_md5_hash(a2_hash, a2); 06288 06289 snprintf(resp, sizeof(resp), "%s:%s:%s", a1_hash, usednonce, a2_hash); 06290 ast_md5_hash(resp_hash, resp); 06291 06292 if (wrongnonce) { 06293 06294 snprintf(randdata, randlen, "%08x", thread_safe_rand()); 06295 if (ua_hash && !strncasecmp(ua_hash, resp_hash, strlen(resp_hash))) { 06296 if (sipdebug) 06297 ast_log(LOG_NOTICE, "stale nonce received from '%s'\n", get_header(req, "To")); 06298 /* We got working auth token, based on stale nonce . */ 06299 transmit_response_with_auth(p, response, req, randdata, reliable, respheader, 1); 06300 } else { 06301 /* Everything was wrong, so give the device one more try with a new challenge */ 06302 if (sipdebug) 06303 ast_log(LOG_NOTICE, "Bad authentication received from '%s'\n", get_header(req, "To")); 06304 transmit_response_with_auth(p, response, req, randdata, reliable, respheader, 0); 06305 } 06306 06307 /* Schedule auto destroy in 15 seconds */ 06308 sip_scheddestroy(p, 15000); 06309 return 1; 06310 } 06311 /* resp_hash now has the expected response, compare the two */ 06312 if (ua_hash && !strncasecmp(ua_hash, resp_hash, strlen(resp_hash))) { 06313 /* Auth is OK */ 06314 res = 0; 06315 } 06316 } 06317 /* Failure */ 06318 return res; 06319 }
|
|
check_pendings: Check pending actions on SIP call ---
Definition at line 9434 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(). 09435 { 09436 /* Go ahead and send bye at this point */ 09437 if (ast_test_flag(p, SIP_PENDINGBYE)) { 09438 transmit_request_with_auth(p, SIP_BYE, 0, 1, 1); 09439 ast_set_flag(p, SIP_NEEDDESTROY); 09440 ast_clear_flag(p, SIP_NEEDREINVITE); 09441 } else if (ast_test_flag(p, SIP_NEEDREINVITE)) { 09442 ast_log(LOG_DEBUG, "Sending pending reinvite on '%s'\n", p->callid); 09443 /* Didn't get to reinvite yet, so do it now */ 09444 transmit_reinvite_with_sdp(p); 09445 ast_clear_flag(p, SIP_NEEDREINVITE); 09446 } 09447 }
|
|
check_sip_domain: Check if domain part of uri is local to our server
Definition at line 11765 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(). 11766 { 11767 struct domain *d; 11768 int result = 0; 11769 11770 AST_LIST_LOCK(&domain_list); 11771 AST_LIST_TRAVERSE(&domain_list, d, list) { 11772 if (strcasecmp(d->domain, domain)) 11773 continue; 11774 11775 if (len && !ast_strlen_zero(d->context)) 11776 ast_copy_string(context, d->context, len); 11777 11778 result = 1; 11779 break; 11780 } 11781 AST_LIST_UNLOCK(&domain_list); 11782 11783 return result; 11784 }
|
|
check_user: Find user ---
Definition at line 7219 of file chan_sip.c. References check_user_full(). Referenced by handle_request_invite(). 07220 { 07221 return check_user_full(p, req, sipmethod, uri, reliable, sin, ignore, NULL, 0); 07222 }
|
|
check_user_full: Check if matching user or peer is defined ---
Definition at line 6956 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(). 06957 { 06958 struct sip_user *user = NULL; 06959 struct sip_peer *peer; 06960 char *of, from[256], *c; 06961 char *rpid,rpid_num[50]; 06962 char iabuf[INET_ADDRSTRLEN]; 06963 int res = 0; 06964 char *t; 06965 char calleridname[50]; 06966 int debug=sip_debug_test_addr(sin); 06967 struct ast_variable *tmpvar = NULL, *v = NULL; 06968 06969 /* Terminate URI */ 06970 t = uri; 06971 while(*t && (*t > 32) && (*t != ';')) 06972 t++; 06973 *t = '\0'; 06974 of = get_header(req, "From"); 06975 if (pedanticsipchecking) 06976 ast_uri_decode(of); 06977 06978 ast_copy_string(from, of, sizeof(from)); 06979 06980 memset(calleridname,0,sizeof(calleridname)); 06981 get_calleridname(from, calleridname, sizeof(calleridname)); 06982 if (calleridname[0]) 06983 ast_copy_string(p->cid_name, calleridname, sizeof(p->cid_name)); 06984 06985 rpid = get_header(req, "Remote-Party-ID"); 06986 memset(rpid_num,0,sizeof(rpid_num)); 06987 if (!ast_strlen_zero(rpid)) 06988 p->callingpres = get_rpid_num(rpid,rpid_num, sizeof(rpid_num)); 06989 06990 of = get_in_brackets(from); 06991 if (ast_strlen_zero(p->exten)) { 06992 t = uri; 06993 if (!strncmp(t, "sip:", 4)) 06994 t+= 4; 06995 ast_copy_string(p->exten, t, sizeof(p->exten)); 06996 t = strchr(p->exten, '@'); 06997 if (t) 06998 *t = '\0'; 06999 if (ast_strlen_zero(p->our_contact)) 07000 build_contact(p); 07001 } 07002 /* save the URI part of the From header */ 07003 ast_copy_string(p->from, of, sizeof(p->from)); 07004 if (strncmp(of, "sip:", 4)) { 07005 ast_log(LOG_NOTICE, "From address missing 'sip:', using it anyway\n"); 07006 } else 07007 of += 4; 07008 /* Get just the username part */ 07009 if ((c = strchr(of, '@'))) { 07010 *c = '\0'; 07011 if ((c = strchr(of, ':'))) 07012 *c = '\0'; 07013 ast_copy_string(p->cid_num, of, sizeof(p->cid_num)); 07014 ast_shrink_phone_number(p->cid_num); 07015 } 07016 if (ast_strlen_zero(of)) 07017 return 0; 07018 07019 if (!mailbox) /* If it's a mailbox SUBSCRIBE, don't check users */ 07020 user = find_user(of, 1); 07021 07022 /* Find user based on user name in the from header */ 07023 if (user && ast_apply_ha(user->ha, sin)) { 07024 ast_copy_flags(p, user, SIP_FLAGS_TO_COPY); 07025 /* copy channel vars */ 07026 for (v = user->chanvars ; v ; v = v->next) { 07027 if ((tmpvar = ast_variable_new(v->name, v->value))) { 07028 tmpvar->next = p->chanvars; 07029 p->chanvars = tmpvar; 07030 } 07031 } 07032 p->prefs = user->prefs; 07033 /* replace callerid if rpid found, and not restricted */ 07034 if (!ast_strlen_zero(rpid_num) && ast_test_flag(p, SIP_TRUSTRPID)) { 07035 if (*calleridname) 07036 ast_copy_string(p->cid_name, calleridname, sizeof(p->cid_name)); 07037 ast_copy_string(p->cid_num, rpid_num, sizeof(p->cid_num)); 07038 ast_shrink_phone_number(p->cid_num); 07039 } 07040 07041 if (p->rtp) { 07042 ast_log(LOG_DEBUG, "Setting NAT on RTP to %d\n", (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE)); 07043 ast_rtp_setnat(p->rtp, (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE)); 07044 } 07045 if (p->vrtp) { 07046 ast_log(LOG_DEBUG, "Setting NAT on VRTP to %d\n", (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE)); 07047 ast_rtp_setnat(p->vrtp, (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE)); 07048 } 07049 if (!(res = check_auth(p, req, p->randdata, sizeof(p->randdata), user->name, user->secret, user->md5secret, sipmethod, uri, reliable, ignore))) { 07050 sip_cancel_destroy(p); 07051 ast_copy_flags(p, user, SIP_FLAGS_TO_COPY); 07052 /* Copy SIP extensions profile from INVITE */ 07053 if (p->sipoptions) 07054 user->sipoptions = p->sipoptions; 07055 07056 /* If we have a call limit, set flag */ 07057 if (user->call_limit) 07058 ast_set_flag(p, SIP_CALL_LIMIT); 07059 if (!ast_strlen_zero(user->context)) 07060 ast_copy_string(p->context, user->context, sizeof(p->context)); 07061 if (!ast_strlen_zero(user->cid_num) && !ast_strlen_zero(p->cid_num)) { 07062 ast_copy_string(p->cid_num, user->cid_num, sizeof(p->cid_num)); 07063 ast_shrink_phone_number(p->cid_num); 07064 } 07065 if (!ast_strlen_zero(user->cid_name) && !ast_strlen_zero(p->cid_num)) 07066 ast_copy_string(p->cid_name, user->cid_name, sizeof(p->cid_name)); 07067 ast_copy_string(p->username, user->name, sizeof(p->username)); 07068 ast_copy_string(p->peersecret, user->secret, sizeof(p->peersecret)); 07069 ast_copy_string(p->subscribecontext, user->subscribecontext, sizeof(p->subscribecontext)); 07070 ast_copy_string(p->peermd5secret, user->md5secret, sizeof(p->peermd5secret)); 07071 ast_copy_string(p->accountcode, user->accountcode, sizeof(p->accountcode)); 07072 ast_copy_string(p->language, user->language, sizeof(p->language)); 07073 ast_copy_string(p->musicclass, user->musicclass, sizeof(p->musicclass)); 07074 p->amaflags = user->amaflags; 07075 p->callgroup = user->callgroup; 07076 p->pickupgroup = user->pickupgroup; 07077 p->callingpres = user->callingpres; 07078 p->capability = user->capability; 07079 p->jointcapability = user->capability; 07080 if (p->peercapability) 07081 p->jointcapability &= p->peercapability; 07082 if ((ast_test_flag(p, SIP_DTMF) == SIP_DTMF_RFC2833) || (ast_test_flag(p, SIP_DTMF) == SIP_DTMF_AUTO)) 07083 p->noncodeccapability |= AST_RTP_DTMF; 07084 else 07085 p->noncodeccapability &= ~AST_RTP_DTMF; 07086 } 07087 if (user && debug) 07088 ast_verbose("Found user '%s'\n", user->name); 07089 } else { 07090 if (user) { 07091 if (!mailbox && debug) 07092 ast_verbose("Found user '%s', but fails host access\n", user->name); 07093 ASTOBJ_UNREF(user,sip_destroy_user); 07094 } 07095 user = NULL; 07096 } 07097 07098 if (!user) { 07099 /* If we didn't find a user match, check for peers */ 07100 if (sipmethod == SIP_SUBSCRIBE) 07101 /* For subscribes, match on peer name only */ 07102 peer = find_peer(of, NULL, 1); 07103 else 07104 /* Look for peer based on the IP address we received data from */ 07105 /* If peer is registered from this IP address or have this as a default 07106 IP address, this call is from the peer 07107 */ 07108 peer = find_peer(NULL, &p->recv, 1); 07109 07110 if (peer) { 07111 if (debug) 07112 ast_verbose("Found peer '%s'\n", peer->name); 07113 /* Take the peer */ 07114 ast_copy_flags(p, peer, SIP_FLAGS_TO_COPY); 07115 07116 /* Copy SIP extensions profile to peer */ 07117 if (p->sipoptions) 07118 peer->sipoptions = p->sipoptions; 07119 07120 /* replace callerid if rpid found, and not restricted */ 07121 if (!ast_strlen_zero(rpid_num) && ast_test_flag(p, SIP_TRUSTRPID)) { 07122 if (*calleridname) 07123 ast_copy_string(p->cid_name, calleridname, sizeof(p->cid_name)); 07124 ast_copy_string(p->cid_num, rpid_num, sizeof(p->cid_num)); 07125 ast_shrink_phone_number(p->cid_num); 07126 } 07127 if (p->rtp) { 07128 ast_log(LOG_DEBUG, "Setting NAT on RTP to %d\n", (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE)); 07129 ast_rtp_setnat(p->rtp, (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE)); 07130 } 07131 if (p->vrtp) { 07132 ast_log(LOG_DEBUG, "Setting NAT on VRTP to %d\n", (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE)); 07133 ast_rtp_setnat(p->vrtp, (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE)); 07134 } 07135 ast_copy_string(p->peersecret, peer->secret, sizeof(p->peersecret)); 07136 p->peersecret[sizeof(p->peersecret)-1] = '\0'; 07137 ast_copy_string(p->subscribecontext, peer->subscribecontext, sizeof(p->subscribecontext)); 07138 ast_copy_string(p->peermd5secret, peer->md5secret, sizeof(p->peermd5secret)); 07139 p->peermd5secret[sizeof(p->peermd5secret)-1] = '\0'; 07140 p->callingpres = peer->callingpres; 07141 if (peer->maxms && peer->lastms) 07142 p->timer_t1 = peer->lastms; 07143 if (ast_test_flag(peer, SIP_INSECURE_INVITE)) { 07144 /* Pretend there is no required authentication */ 07145 p->peersecret[0] = '\0'; 07146 p->peermd5secret[0] = '\0'; 07147 } 07148 if (!(res = check_auth(p, req, p->randdata, sizeof(p->randdata), peer->name, p->peersecret, p->peermd5secret, sipmethod, uri, reliable, ignore))) { 07149 ast_copy_flags(p, peer, SIP_FLAGS_TO_COPY); 07150 /* If we have a call limit, set flag */ 07151 if (peer->call_limit) 07152 ast_set_flag(p, SIP_CALL_LIMIT); 07153 ast_copy_string(p->peername, peer->name, sizeof(p->peername)); 07154 ast_copy_string(p->authname, peer->name, sizeof(p->authname)); 07155 /* copy channel vars */ 07156 for (v = peer->chanvars ; v ; v = v->next) { 07157 if ((tmpvar = ast_variable_new(v->name, v->value))) { 07158 tmpvar->next = p->chanvars; 07159 p->chanvars = tmpvar; 07160 } 07161 } 07162 if (mailbox) 07163 snprintf(mailbox, mailboxlen, ",%s,", peer->mailbox); 07164 if (!ast_strlen_zero(peer->username)) { 07165 ast_copy_string(p->username, peer->username, sizeof(p->username)); 07166 /* Use the default username for authentication on outbound calls */ 07167 ast_copy_string(p->authname, peer->username, sizeof(p->authname)); 07168 } 07169 if (!ast_strlen_zero(peer->cid_num) && !ast_strlen_zero(p->cid_num)) { 07170 ast_copy_string(p->cid_num, peer->cid_num, sizeof(p->cid_num)); 07171 ast_shrink_phone_number(p->cid_num); 07172 } 07173 if (!ast_strlen_zero(peer->cid_name) && !ast_strlen_zero(p->cid_name)) 07174 ast_copy_string(p->cid_name, peer->cid_name, sizeof(p->cid_name)); 07175 ast_copy_string(p->fullcontact, peer->fullcontact, sizeof(p->fullcontact)); 07176 if (!ast_strlen_zero(peer->context)) 07177 ast_copy_string(p->context, peer->context, sizeof(p->context)); 07178 ast_copy_string(p->peersecret, peer->secret, sizeof(p->peersecret)); 07179 ast_copy_string(p->peermd5secret, peer->md5secret, sizeof(p->peermd5secret)); 07180 ast_copy_string(p->language, peer->language, sizeof(p->language)); 07181 ast_copy_string(p->accountcode, peer->accountcode, sizeof(p->accountcode)); 07182 p->amaflags = peer->amaflags; 07183 p->callgroup = peer->callgroup; 07184 p->pickupgroup = peer->pickupgroup; 07185 p->capability = peer->capability; 07186 p->prefs = peer->prefs; 07187 p->jointcapability = peer->capability; 07188 if (p->peercapability) 07189 p->jointcapability &= p->peercapability; 07190 if ((ast_test_flag(p, SIP_DTMF) == SIP_DTMF_RFC2833) || (ast_test_flag(p, SIP_DTMF) == SIP_DTMF_AUTO)) 07191 p->noncodeccapability |= AST_RTP_DTMF; 07192 else 07193 p->noncodeccapability &= ~AST_RTP_DTMF; 07194 } 07195 ASTOBJ_UNREF(peer,sip_destroy_peer); 07196 } else { 07197 if (debug) 07198 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)); 07199 07200 /* do we allow guests? */ 07201 if (!global_allowguest) 07202 res = -1; /* we don't want any guests, authentication will fail */ 07203 #ifdef OSP_SUPPORT 07204 else if (global_allowguest == 2) { 07205 ast_copy_flags(p, &global_flags, SIP_OSPAUTH); 07206 res = check_auth(p, req, p->randdata, sizeof(p->randdata), "", "", "", sipmethod, uri, reliable, ignore); 07207 } 07208 #endif 07209 } 07210 07211 } 07212 07213 if (user) 07214 ASTOBJ_UNREF(user,sip_destroy_user); 07215 return res; 07216 }
|
|
check Via: header for hostname, port and rport request/answer
Definition at line 6832 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(). 06833 { 06834 char via[256]; 06835 char iabuf[INET_ADDRSTRLEN]; 06836 char *c, *pt; 06837 struct hostent *hp; 06838 struct ast_hostent ahp; 06839 06840 ast_copy_string(via, get_header(req, "Via"), sizeof(via)); 06841 06842 /* Check for rport */ 06843 c = strstr(via, ";rport"); 06844 if (c && (c[6] != '=')) /* rport query, not answer */ 06845 ast_set_flag(p, SIP_NAT_ROUTE); 06846 06847 c = strchr(via, ';'); 06848 if (c) 06849 *c = '\0'; 06850 06851 c = strchr(via, ' '); 06852 if (c) { 06853 *c = '\0'; 06854 c = ast_skip_blanks(c+1); 06855 if (strcasecmp(via, "SIP/2.0/UDP")) { 06856 ast_log(LOG_WARNING, "Don't know how to respond via '%s'\n", via); 06857 return -1; 06858 } 06859 pt = strchr(c, ':'); 06860 if (pt) 06861 *pt++ = '\0'; /* remember port pointer */ 06862 hp = ast_gethostbyname(c, &ahp); 06863 if (!hp) { 06864 ast_log(LOG_WARNING, "'%s' is not a valid host\n", c); 06865 return -1; 06866 } 06867 memset(&p->sa, 0, sizeof(p->sa)); 06868 p->sa.sin_family = AF_INET; 06869 memcpy(&p->sa.sin_addr, hp->h_addr, sizeof(p->sa.sin_addr)); 06870 p->sa.sin_port = htons(pt ? atoi(pt) : DEFAULT_SIP_PORT); 06871 06872 if (sip_debug_test_pvt(p)) { 06873 c = (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE) ? "NAT" : "non-NAT"; 06874 ast_verbose("Sending to %s : %d (%s)\n", ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr), ntohs(p->sa.sin_port), c); 06875 } 06876 } 06877 return 0; 06878 }
|
|
clear_realm_authentication: Clear realm authentication list (at reload) ---
Definition at line 11866 of file chan_sip.c. References free, and sip_auth::next. Referenced by sip_destroy_peer(), sip_do_reload(), and unload_module(). 11867 { 11868 struct sip_auth *a = authlist; 11869 struct sip_auth *b; 11870 11871 while (a) { 11872 b = a; 11873 a = a->next; 11874 free(b); 11875 } 11876 11877 return 1; 11878 }
|
|
clear_sip_domains: Clear our domain list (at reload)
Definition at line 11787 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(). 11788 { 11789 struct domain *d; 11790 11791 AST_LIST_LOCK(&domain_list); 11792 while ((d = AST_LIST_REMOVE_HEAD(&domain_list, list))) 11793 free(d); 11794 AST_LIST_UNLOCK(&domain_list); 11795 }
|
|
complete_sip_debug_peer: Support routine for 'sip debug peer' CLI ---
Definition at line 8378 of file chan_sip.c. References complete_sip_peer(). 08379 { 08380 if (pos == 3) 08381 return complete_sip_peer(word, state, 0); 08382 08383 return NULL; 08384 }
|
|
complete_sip_peer: Do completion on peer name ---
Definition at line 8349 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(). 08350 { 08351 char *result = NULL; 08352 int wordlen = strlen(word); 08353 int which = 0; 08354 08355 ASTOBJ_CONTAINER_TRAVERSE(&peerl, !result, do { 08356 /* locking of the object is not required because only the name and flags are being compared */ 08357 if (!strncasecmp(word, iterator->name, wordlen)) { 08358 if (flags2 && !ast_test_flag((&iterator->flags_page2), flags2)) 08359 continue; 08360 if (++which > state) { 08361 result = strdup(iterator->name); 08362 } 08363 } 08364 } while(0) ); 08365 return result; 08366 }
|
|
complete_sip_prune_realtime_peer: Support routine for 'sip prune realtime peer' CLI ---
Definition at line 8449 of file chan_sip.c. References complete_sip_peer(), and SIP_PAGE2_RTCACHEFRIENDS. 08450 { 08451 if (pos == 4) 08452 return complete_sip_peer(word, state, SIP_PAGE2_RTCACHEFRIENDS); 08453 return NULL; 08454 }
|
|
complete_sip_prune_realtime_user: Support routine for 'sip prune realtime user' CLI ---
Definition at line 8457 of file chan_sip.c. References complete_sip_user(), and SIP_PAGE2_RTCACHEFRIENDS. 08458 { 08459 if (pos == 4) 08460 return complete_sip_user(word, state, SIP_PAGE2_RTCACHEFRIENDS); 08461 08462 return NULL; 08463 }
|
|
complete_sip_show_peer: Support routine for 'sip show peer' CLI ---
Definition at line 8369 of file chan_sip.c. References complete_sip_peer(). 08370 { 08371 if (pos == 3) 08372 return complete_sip_peer(word, state, 0); 08373 08374 return NULL; 08375 }
|
|
complete_sip_show_user: Support routine for 'sip show user' CLI ---
Definition at line 8407 of file chan_sip.c. References complete_sip_user(). 08408 { 08409 if (pos == 3) 08410 return complete_sip_user(word, state, 0); 08411 08412 return NULL; 08413 }
|
|
complete_sip_user: Do completion on user name ---
Definition at line 8387 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(). 08388 { 08389 char *result = NULL; 08390 int wordlen = strlen(word); 08391 int which = 0; 08392 08393 ASTOBJ_CONTAINER_TRAVERSE(&userl, !result, do { 08394 /* locking of the object is not required because only the name and flags are being compared */ 08395 if (!strncasecmp(word, iterator->name, wordlen)) { 08396 if (flags2 && !ast_test_flag(&(iterator->flags_page2), flags2)) 08397 continue; 08398 if (++which > state) { 08399 result = strdup(iterator->name); 08400 } 08401 } 08402 } while(0) ); 08403 return result; 08404 }
|
|
complete_sipch: Support routine for 'sip show channel' CLI ---
Definition at line 8327 of file chan_sip.c. References ast_mutex_lock(), ast_mutex_unlock(), sip_pvt::callid, iflist, sip_pvt::next, and strdup. 08328 { 08329 int which=0; 08330 struct sip_pvt *cur; 08331 char *c = NULL; 08332 08333 ast_mutex_lock(&iflock); 08334 cur = iflist; 08335 while(cur) { 08336 if (!strncasecmp(word, cur->callid, strlen(word))) { 08337 if (++which > state) { 08338 c = strdup(cur->callid); 08339 break; 08340 } 08341 } 08342 cur = cur->next; 08343 } 08344 ast_mutex_unlock(&iflock); 08345 return c; 08346 }
|
|
complete_sipnotify: Support routine for 'sip notify' CLI ---
Definition at line 8416 of file chan_sip.c. References ast_category_browse(), complete_sip_peer(), notify_types, and strdup. 08417 { 08418 char *c = NULL; 08419 08420 if (pos == 2) { 08421 int which = 0; 08422 char *cat; 08423 08424 /* do completion for notify type */ 08425 08426 if (!notify_types) 08427 return NULL; 08428 08429 cat = ast_category_browse(notify_types, NULL); 08430 while(cat) { 08431 if (!strncasecmp(word, cat, strlen(word))) { 08432 if (++which > state) { 08433 c = strdup(cat); 08434 break; 08435 } 08436 } 08437 cat = ast_category_browse(notify_types, cat); 08438 } 08439 return c; 08440 } 08441 08442 if (pos > 2) 08443 return complete_sip_peer(word, state, 0); 08444 08445 return NULL; 08446 }
|
|
copy_all_header: Copy all headers from one request to another ---
Definition at line 3778 of file chan_sip.c. References __get_header(), add_header(), and ast_strlen_zero(). Referenced by respprep(). 03779 { 03780 char *tmp; 03781 int start = 0; 03782 int copied = 0; 03783 for (;;) { 03784 tmp = __get_header(orig, field, &start); 03785 if (!ast_strlen_zero(tmp)) { 03786 /* Add what we're responding to */ 03787 add_header(req, field, tmp); 03788 copied++; 03789 } else 03790 break; 03791 } 03792 return copied ? 0 : -1; 03793 }
|
|
copy_header: Copy one header field from one request to another
Definition at line 3765 of file chan_sip.c. References add_header(), ast_log(), ast_strlen_zero(), get_header(), and LOG_NOTICE. Referenced by reqprep(), and respprep(). 03766 { 03767 char *tmp; 03768 tmp = get_header(orig, field); 03769 if (!ast_strlen_zero(tmp)) { 03770 /* Add what we're responding to */ 03771 return add_header(req, field, tmp); 03772 } 03773 ast_log(LOG_NOTICE, "No field '%s' present to copy\n", field); 03774 return -1; 03775 }
|
|
copy_request: copy SIP request (mostly used to save request for responses) ---
Definition at line 4503 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(). 04504 { 04505 long offset; 04506 int x; 04507 offset = ((void *)dst) - ((void *)src); 04508 /* First copy stuff */ 04509 memcpy(dst, src, sizeof(*dst)); 04510 /* Now fix pointer arithmetic */ 04511 for (x=0; x < src->headers; x++) 04512 dst->header[x] += offset; 04513 for (x=0; x < src->lines; x++) 04514 dst->line[x] += offset; 04515 }
|
|
copy_via_headers: Copy SIP VIA Headers from the request to the response ---
Definition at line 3801 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(). 03802 { 03803 char tmp[256], *oh, *end; 03804 int start = 0; 03805 int copied = 0; 03806 char iabuf[INET_ADDRSTRLEN]; 03807 03808 for (;;) { 03809 oh = __get_header(orig, field, &start); 03810 if (!ast_strlen_zero(oh)) { 03811 if (!copied) { /* Only check for empty rport in topmost via header */ 03812 char *rport; 03813 char new[256]; 03814 03815 /* Find ;rport; (empty request) */ 03816 rport = strstr(oh, ";rport"); 03817 if (rport && *(rport+6) == '=') 03818 rport = NULL; /* We already have a parameter to rport */ 03819 03820 if (rport && (ast_test_flag(p, SIP_NAT) == SIP_NAT_ALWAYS)) { 03821 /* We need to add received port - rport */ 03822 ast_copy_string(tmp, oh, sizeof(tmp)); 03823 03824 rport = strstr(tmp, ";rport"); 03825 03826 if (rport) { 03827 end = strchr(rport + 1, ';'); 03828 if (end) 03829 memmove(rport, end, strlen(end) + 1); 03830 else 03831 *rport = '\0'; 03832 } 03833 03834 /* Add rport to first VIA header if requested */ 03835 /* Whoo hoo! Now we can indicate port address translation too! Just 03836 another RFC (RFC3581). I'll leave the original comments in for 03837 posterity. */ 03838 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)); 03839 } else { 03840 /* We should *always* add a received to the topmost via */ 03841 snprintf(new, sizeof(new), "%s;received=%s", oh, ast_inet_ntoa(iabuf, sizeof(iabuf), p->recv.sin_addr)); 03842 } 03843 add_header(req, field, new); 03844 } else { 03845 /* Add the following via headers untouched */ 03846 add_header(req, field, oh); 03847 } 03848 copied++; 03849 } else 03850 break; 03851 } 03852 if (!copied) { 03853 ast_log(LOG_NOTICE, "No header field '%s' present to copy\n", field); 03854 return -1; 03855 } 03856 return 0; 03857 }
|
|
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 13279 of file chan_sip.c. References desc. 13280 { 13281 return (char *) desc; 13282 }
|
|
Definition at line 5625 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(). 05626 { 05627 if (!ast_test_flag((&global_flags_page2), SIP_PAGE2_IGNOREREGEXPIRE)) { 05628 if (ast_test_flag(&(peer->flags_page2), SIP_PAGE2_RT_FROMCONTACT)) { 05629 ast_update_realtime("sippeers", "name", peer->name, "fullcontact", "", "ipaddr", "", "port", "", "regseconds", "0", "username", "", NULL); 05630 } else { 05631 ast_db_del("SIP/Registry", peer->name); 05632 } 05633 } 05634 }
|
|
determine_firstline_parts: parse first line of incoming SIP request
Definition at line 4538 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(). 04539 { 04540 char *e, *cmd; 04541 int len; 04542 04543 cmd = ast_skip_blanks(req->header[0]); 04544 if (!*cmd) 04545 return -1; 04546 req->rlPart1 = cmd; 04547 e = ast_skip_nonblanks(cmd); 04548 /* Get the command */ 04549 if (*e) 04550 *e++ = '\0'; 04551 e = ast_skip_blanks(e); 04552 if ( !*e ) 04553 return -1; 04554 04555 if ( !strcasecmp(cmd, "SIP/2.0") ) { 04556 /* We have a response */ 04557 req->rlPart2 = e; 04558 len = strlen( req->rlPart2 ); 04559 if ( len < 2 ) { 04560 return -1; 04561 } 04562 ast_trim_blanks(e); 04563 } else { 04564 /* We have a request */ 04565 if ( *e == '<' ) { 04566 e++; 04567 if ( !*e ) { 04568 return -1; 04569 } 04570 } 04571 req->rlPart2 = e; /* URI */ 04572 if ( ( e= strrchr( req->rlPart2, 'S' ) ) == NULL ) { 04573 return -1; 04574 } 04575 /* XXX maybe trim_blanks() ? */ 04576 while( isspace( *(--e) ) ) {} 04577 if ( *e == '>' ) { 04578 *e = '\0'; 04579 } else { 04580 *(++e)= '\0'; 04581 } 04582 } 04583 return 1; 04584 }
|
|
do_monitor: The SIP monitoring thread ---
Definition at line 11227 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. 11228 { 11229 int res; 11230 struct sip_pvt *sip; 11231 struct sip_peer *peer = NULL; 11232 time_t t; 11233 int fastrestart =0; 11234 int lastpeernum = -1; 11235 int curpeernum; 11236 int reloading; 11237 11238 /* Add an I/O event to our UDP socket */ 11239 if (sipsock > -1) 11240 ast_io_add(io, sipsock, sipsock_read, AST_IO_IN, NULL); 11241 11242 /* This thread monitors all the frame relay interfaces which are not yet in use 11243 (and thus do not have a separate thread) indefinitely */ 11244 /* From here on out, we die whenever asked */ 11245 for(;;) { 11246 /* Check for a reload request */ 11247 ast_mutex_lock(&sip_reload_lock); 11248 reloading = sip_reloading; 11249 sip_reloading = 0; 11250 ast_mutex_unlock(&sip_reload_lock); 11251 if (reloading) { 11252 if (option_verbose > 0) 11253 ast_verbose(VERBOSE_PREFIX_1 "Reloading SIP\n"); 11254 sip_do_reload(); 11255 } 11256 /* Check for interfaces needing to be killed */ 11257 ast_mutex_lock(&iflock); 11258 restartsearch: 11259 time(&t); 11260 sip = iflist; 11261 while(sip) { 11262 ast_mutex_lock(&sip->lock); 11263 if (sip->rtp && sip->owner && (sip->owner->_state == AST_STATE_UP) && !sip->redirip.sin_addr.s_addr) { 11264 if (sip->lastrtptx && sip->rtpkeepalive && t > sip->lastrtptx + sip->rtpkeepalive) { 11265 /* Need to send an empty RTP packet */ 11266 time(&sip->lastrtptx); 11267 ast_rtp_sendcng(sip->rtp, 0); 11268 } 11269 if (sip->lastrtprx && (sip->rtptimeout || sip->rtpholdtimeout) && t > sip->lastrtprx + sip->rtptimeout) { 11270 /* Might be a timeout now -- see if we're on hold */ 11271 struct sockaddr_in sin; 11272 ast_rtp_get_peer(sip->rtp, &sin); 11273 if (sin.sin_addr.s_addr || 11274 (sip->rtpholdtimeout && 11275 (t > sip->lastrtprx + sip->rtpholdtimeout))) { 11276 /* Needs a hangup */ 11277 if (sip->rtptimeout) { 11278 while(sip->owner && ast_mutex_trylock(&sip->owner->lock)) { 11279 ast_mutex_unlock(&sip->lock); 11280 usleep(1); 11281 ast_mutex_lock(&sip->lock); 11282 } 11283 if (sip->owner) { 11284 ast_log(LOG_NOTICE, "Disconnecting call '%s' for lack of RTP activity in %ld seconds\n", sip->owner->name, (long)(t - sip->lastrtprx)); 11285 /* Issue a softhangup */ 11286 ast_softhangup(sip->owner, AST_SOFTHANGUP_DEV); 11287 ast_mutex_unlock(&sip->owner->lock); 11288 } 11289 } 11290 } 11291 } 11292 } 11293 if (ast_test_flag(sip, SIP_NEEDDESTROY) && !sip->packets && !sip->owner) { 11294 ast_mutex_unlock(&sip->lock); 11295 __sip_destroy(sip, 1); 11296 goto restartsearch; 11297 } 11298 ast_mutex_unlock(&sip->lock); 11299 sip = sip->next; 11300 } 11301 ast_mutex_unlock(&iflock); 11302 /* Don't let anybody kill us right away. Nobody should lock the interface list 11303 and wait for the monitor list, but the other way around is okay. */ 11304 ast_mutex_lock(&monlock); 11305 /* Lock the network interface */ 11306 ast_mutex_lock(&netlock); 11307 /* Okay, now that we know what to do, release the network lock */ 11308 ast_mutex_unlock(&netlock); 11309 /* And from now on, we're okay to be killed, so release the monitor lock as well */ 11310 ast_mutex_unlock(&monlock); 11311 pthread_testcancel(); 11312 /* Wait for sched or io */ 11313 res = ast_sched_wait(sched); 11314 if ((res < 0) || (res > 1000)) 11315 res = 1000; 11316 /* If we might need to send more mailboxes, don't wait long at all.*/ 11317 if (fastrestart) 11318 res = 1; 11319 res = ast_io_wait(io, res); 11320 if (res > 20) 11321 ast_log(LOG_DEBUG, "chan_sip: ast_io_wait ran %d all at once\n", res); 11322 ast_mutex_lock(&monlock); 11323 if (res >= 0) { 11324 res = ast_sched_runq(sched); 11325 if (res >= 20) 11326 ast_log(LOG_DEBUG, "chan_sip: ast_sched_runq ran %d all at once\n", res); 11327 } 11328 11329 /* needs work to send mwi to realtime peers */ 11330 time(&t); 11331 fastrestart = 0; 11332 curpeernum = 0; 11333 peer = NULL; 11334 ASTOBJ_CONTAINER_TRAVERSE(&peerl, !peer, do { 11335 if ((curpeernum > lastpeernum) && !ast_strlen_zero(iterator->mailbox) && ((t - iterator->lastmsgcheck) > global_mwitime)) { 11336 fastrestart = 1; 11337 lastpeernum = curpeernum; 11338 peer = ASTOBJ_REF(iterator); 11339 }; 11340 curpeernum++; 11341 } while (0) 11342 ); 11343 if (peer) { 11344 ASTOBJ_WRLOCK(peer); 11345 sip_send_mwi_to_peer(peer); 11346 ASTOBJ_UNLOCK(peer); 11347 ASTOBJ_UNREF(peer,sip_destroy_peer); 11348 } else { 11349 /* Reset where we come from */ 11350 lastpeernum = -1; 11351 } 11352 ast_mutex_unlock(&monlock); 11353 } 11354 /* Never reached */ 11355 return NULL; 11356 11357 }
|
|
do_proxy_auth: Add authentication on outbound SIP packet ---
Definition at line 8889 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(). 08890 { 08891 char digest[1024]; 08892 08893 if (!p->options) { 08894 p->options = calloc(1, sizeof(*p->options)); 08895 if (!p->options) { 08896 ast_log(LOG_ERROR, "Out of memory\n"); 08897 return -2; 08898 } 08899 } 08900 08901 p->authtries++; 08902 if (option_debug > 1) 08903 ast_log(LOG_DEBUG, "Auth attempt %d on %s\n", p->authtries, sip_methods[sipmethod].text); 08904 memset(digest, 0, sizeof(digest)); 08905 if (reply_digest(p, req, header, sipmethod, digest, sizeof(digest) )) { 08906 /* No way to authenticate */ 08907 return -1; 08908 } 08909 /* Now we have a reply digest */ 08910 p->options->auth = digest; 08911 p->options->authheader = respheader; 08912 return transmit_invite(p, sipmethod, sipmethod == SIP_INVITE, init); 08913 }
|
|
do_register_auth: Authenticate for outbound registration ---
Definition at line 8865 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(). 08866 { 08867 char digest[1024]; 08868 p->authtries++; 08869 memset(digest,0,sizeof(digest)); 08870 if (reply_digest(p, req, header, SIP_REGISTER, digest, sizeof(digest))) { 08871 /* There's nothing to use for authentication */ 08872 /* No digest challenge in request */ 08873 if (sip_debug_test_pvt(p) && p->registry) 08874 ast_verbose("No authentication challenge, sending blank registration to domain/host name %s\n", p->registry->hostname); 08875 /* No old challenge */ 08876 return -1; 08877 } 08878 if (recordhistory) { 08879 char tmp[80]; 08880 snprintf(tmp, sizeof(tmp), "Try: %d", p->authtries); 08881 append_history(p, "RegistryAuth", tmp); 08882 } 08883 if (sip_debug_test_pvt(p) && p->registry) 08884 ast_verbose("Responding to challenge, registration to domain/host name %s\n", p->registry->hostname); 08885 return transmit_register(p->registry, SIP_REGISTER, digest, respheader); 08886 }
|
|
Definition at line 7809 of file chan_sip.c. References SIP_DOMAIN_AUTO, and SIP_DOMAIN_CONFIG. Referenced by sip_show_domains(). 07810 { 07811 switch (mode) { 07812 case SIP_DOMAIN_AUTO: 07813 return "[Automatic]"; 07814 case SIP_DOMAIN_CONFIG: 07815 return "[Configured]"; 07816 } 07817 07818 return ""; 07819 }
|
|
dtmfmode2str: Convert DTMF mode to printable string ---
Definition at line 7617 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(). 07618 { 07619 switch (mode) { 07620 case SIP_DTMF_RFC2833: 07621 return "rfc2833"; 07622 case SIP_DTMF_INFO: 07623 return "info"; 07624 case SIP_DTMF_INBAND: 07625 return "inband"; 07626 case SIP_DTMF_AUTO: 07627 return "auto"; 07628 } 07629 return "<error>"; 07630 }
|
|
|
extract_uri: Check Contact: URI of SIP message ---
Definition at line 4616 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(). 04617 { 04618 char stripped[256]; 04619 char *c, *n; 04620 ast_copy_string(stripped, get_header(req, "Contact"), sizeof(stripped)); 04621 c = get_in_brackets(stripped); 04622 n = strchr(c, ';'); 04623 if (n) 04624 *n = '\0'; 04625 if (!ast_strlen_zero(c)) 04626 ast_copy_string(p->uri, c, sizeof(p->uri)); 04627 }
|
|
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 11881 of file chan_sip.c. References sip_auth::next, and sip_auth::realm. Referenced by build_reply_digest(). 11882 { 11883 struct sip_auth *a = authlist; /* First entry in auth list */ 11884 11885 while (a) { 11886 if (!strcasecmp(a->realm, realm)){ 11887 break; 11888 } 11889 a = a->next; 11890 } 11891 11892 return a; 11893 }
|
|
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 8252 of file chan_sip.c. References subscription_types, and type. Referenced by transmit_state_notify(). 08252 { 08253 int i; 08254 08255 for (i = 1; (i < (sizeof(subscription_types) / sizeof(subscription_types[0]))); i++) { 08256 if (subscription_types[i].type == subtype) { 08257 return &subscription_types[i]; 08258 } 08259 } 08260 return &subscription_types[0]; 08261 }
|
|
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 5957 of file chan_sip.c. References free, and sip_route::next. Referenced by __sip_destroy(), and build_route(). 05958 { 05959 struct sip_route *next; 05960 while (route) { 05961 next = route->next; 05962 free(route); 05963 route = next; 05964 } 05965 }
|
|
function_check_sipdomain: Dial plan function to check if domain is local
Definition at line 9206 of file chan_sip.c. References ast_log(), ast_strlen_zero(), check_sip_domain(), and LOG_WARNING. 09207 { 09208 if (ast_strlen_zero(data)) { 09209 ast_log(LOG_WARNING, "CHECKSIPDOMAIN requires an argument - A domain name\n"); 09210 return buf; 09211 } 09212 if (check_sip_domain(data, NULL, 0)) 09213 ast_copy_string(buf, data, len); 09214 else 09215 buf[0] = '\0'; 09216 return buf; 09217 }
|
|
func_header_read: Read SIP header (dialplan function)
Definition at line 9159 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. 09160 { 09161 struct sip_pvt *p; 09162 char *content; 09163 09164 if (!data) { 09165 ast_log(LOG_WARNING, "This function requires a header name.\n"); 09166 return NULL; 09167 } 09168 09169 ast_mutex_lock(&chan->lock); 09170 if (chan->type != channeltype) { 09171 ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n"); 09172 ast_mutex_unlock(&chan->lock); 09173 return NULL; 09174 } 09175 09176 p = chan->tech_pvt; 09177 09178 /* If there is no private structure, this channel is no longer alive */ 09179 if (!p) { 09180 ast_mutex_unlock(&chan->lock); 09181 return NULL; 09182 } 09183 09184 content = get_header(&p->initreq, data); 09185 09186 if (ast_strlen_zero(content)) { 09187 ast_mutex_unlock(&chan->lock); 09188 return NULL; 09189 } 09190 09191 ast_copy_string(buf, content, len); 09192 ast_mutex_unlock(&chan->lock); 09193 09194 return buf; 09195 }
|
|
function_sipchaninfo_read: ${SIPCHANINFO()} Dialplan function - reads sip channel data
Definition at line 9333 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. 09334 { 09335 struct sip_pvt *p; 09336 char iabuf[INET_ADDRSTRLEN]; 09337 09338 *buf = 0; 09339 09340 if (!data) { 09341 ast_log(LOG_WARNING, "This function requires a parameter name.\n"); 09342 return NULL; 09343 } 09344 09345 ast_mutex_lock(&chan->lock); 09346 if (chan->type != channeltype) { 09347 ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n"); 09348 ast_mutex_unlock(&chan->lock); 09349 return NULL; 09350 } 09351 09352 /* ast_verbose("function_sipchaninfo_read: %s\n", data); */ 09353 p = chan->tech_pvt; 09354 09355 /* If there is no private structure, this channel is no longer alive */ 09356 if (!p) { 09357 ast_mutex_unlock(&chan->lock); 09358 return NULL; 09359 } 09360 09361 if (!strcasecmp(data, "peerip")) { 09362 ast_copy_string(buf, p->sa.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr) : "", len); 09363 } else if (!strcasecmp(data, "recvip")) { 09364 ast_copy_string(buf, p->recv.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), p->recv.sin_addr) : "", len); 09365 } else if (!strcasecmp(data, "from")) { 09366 ast_copy_string(buf, p->from, len); 09367 } else if (!strcasecmp(data, "uri")) { 09368 ast_copy_string(buf, p->uri, len); 09369 } else if (!strcasecmp(data, "useragent")) { 09370 ast_copy_string(buf, p->useragent, len); 09371 } else if (!strcasecmp(data, "peername")) { 09372 ast_copy_string(buf, p->peername, len); 09373 } else { 09374 ast_mutex_unlock(&chan->lock); 09375 return NULL; 09376 } 09377 ast_mutex_unlock(&chan->lock); 09378 09379 return buf; 09380 }
|
|
function_sippeer: ${SIPPEER()} Dialplan function - reads peer data
Definition at line 9232 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. 09233 { 09234 char *ret = NULL; 09235 struct sip_peer *peer; 09236 char *peername, *colname; 09237 char iabuf[INET_ADDRSTRLEN]; 09238 09239 if (!(peername = ast_strdupa(data))) { 09240 ast_log(LOG_ERROR, "Memory Error!\n"); 09241 return ret; 09242 } 09243 09244 if ((colname = strchr(peername, ':'))) { 09245 *colname = '\0'; 09246 colname++; 09247 } else { 09248 colname = "ip"; 09249 } 09250 if (!(peer = find_peer(peername, NULL, 1))) 09251 return ret; 09252 09253 if (!strcasecmp(colname, "ip")) { 09254 ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), peer->addr.sin_addr) : "", len); 09255 } else if (!strcasecmp(colname, "status")) { 09256 peer_status(peer, buf, sizeof(buf)); 09257 } else if (!strcasecmp(colname, "language")) { 09258 ast_copy_string(buf, peer->language, len); 09259 } else if (!strcasecmp(colname, "regexten")) { 09260 ast_copy_string(buf, peer->regexten, len); 09261 } else if (!strcasecmp(colname, "limit")) { 09262 snprintf(buf, len, "%d", peer->call_limit); 09263 } else if (!strcasecmp(colname, "curcalls")) { 09264 snprintf(buf, len, "%d", peer->inUse); 09265 } else if (!strcasecmp(colname, "accountcode")) { 09266 ast_copy_string(buf, peer->accountcode, len); 09267 } else if (!strcasecmp(colname, "useragent")) { 09268 ast_copy_string(buf, peer->useragent, len); 09269 } else if (!strcasecmp(colname, "mailbox")) { 09270 ast_copy_string(buf, peer->mailbox, len); 09271 } else if (!strcasecmp(colname, "context")) { 09272 ast_copy_string(buf, peer->context, len); 09273 } else if (!strcasecmp(colname, "expire")) { 09274 snprintf(buf, len, "%d", peer->expire); 09275 } else if (!strcasecmp(colname, "dynamic")) { 09276 ast_copy_string(buf, (ast_test_flag(peer, SIP_DYNAMIC) ? "yes" : "no"), len); 09277 } else if (!strcasecmp(colname, "callerid_name")) { 09278 ast_copy_string(buf, peer->cid_name, len); 09279 } else if (!strcasecmp(colname, "callerid_num")) { 09280 ast_copy_string(buf, peer->cid_num, len); 09281 } else if (!strcasecmp(colname, "codecs")) { 09282 ast_getformatname_multiple(buf, len -1, peer->capability); 09283 } else if (!strncasecmp(colname, "codec[", 6)) { 09284 char *codecnum, *ptr; 09285 int index = 0, codec = 0; 09286 09287 codecnum = strchr(colname, '['); 09288 *codecnum = '\0'; 09289 codecnum++; 09290 if ((ptr = strchr(codecnum, ']'))) { 09291 *ptr = '\0'; 09292 } 09293 index = atoi(codecnum); 09294 if((codec = ast_codec_pref_index(&peer->prefs, index))) { 09295 ast_copy_string(buf, ast_getformatname(codec), len); 09296 } 09297 } 09298 ret = buf; 09299 09300 ASTOBJ_UNREF(peer, sip_destroy_peer); 09301 09302 return ret; 09303 }
|
|
get_also_info: Call transfer support (old way, depreciated)--
Definition at line 6790 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(). 06791 { 06792 char tmp[256], *c, *a; 06793 struct sip_request *req; 06794 06795 req = oreq; 06796 if (!req) 06797 req = &p->initreq; 06798 ast_copy_string(tmp, get_header(req, "Also"), sizeof(tmp)); 06799 06800 c = get_in_brackets(tmp); 06801 06802 06803 if (strncmp(c, "sip:", 4)) { 06804 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", c); 06805 return -1; 06806 } 06807 c += 4; 06808 if ((a = strchr(c, '@'))) 06809 *a = '\0'; 06810 if ((a = strchr(c, ';'))) 06811 *a = '\0'; 06812 06813 if (sip_debug_test_pvt(p)) { 06814 ast_verbose("Looking for %s in %s\n", c, p->context); 06815 } 06816 if (ast_exists_extension(NULL, p->context, c, 1, NULL)) { 06817 /* This is an unsupervised transfer */ 06818 ast_log(LOG_DEBUG,"Assigning Extension %s to REFER-TO\n", c); 06819 ast_copy_string(p->refer_to, c, sizeof(p->refer_to)); 06820 ast_copy_string(p->referred_by, "", sizeof(p->referred_by)); 06821 ast_copy_string(p->refer_contact, "", sizeof(p->refer_contact)); 06822 p->refer_call = NULL; 06823 return 0; 06824 } else if (ast_canmatch_extension(NULL, p->context, c, 1, NULL)) { 06825 return 1; 06826 } 06827 06828 return -1; 06829 }
|
|
get_calleridname: Get caller id name from SIP headers ---
Definition at line 6881 of file chan_sip.c. Referenced by check_user_full(). 06882 { 06883 char *end = strchr(input,'<'); 06884 char *tmp = strchr(input,'\"'); 06885 int bytes = 0; 06886 int maxbytes = outputsize - 1; 06887 06888 if (!end || (end == input)) return NULL; 06889 /* move away from "<" */ 06890 end--; 06891 /* we found "name" */ 06892 if (tmp && tmp < end) { 06893 end = strchr(tmp+1, '\"'); 06894 if (!end) return NULL; 06895 bytes = (int) (end - tmp); 06896 /* protect the output buffer */ 06897 if (bytes > maxbytes) 06898 bytes = maxbytes; 06899 ast_copy_string(output, tmp + 1, bytes); 06900 } else { 06901 /* we didn't find "name" */ 06902 /* clear the empty characters in the begining*/ 06903 input = ast_skip_blanks(input); 06904 /* clear the empty characters in the end */ 06905 while(*end && (*end < 33) && end > input) 06906 end--; 06907 if (end >= input) { 06908 bytes = (int) (end - input) + 2; 06909 /* protect the output buffer */ 06910 if (bytes > maxbytes) { 06911 bytes = maxbytes; 06912 } 06913 ast_copy_string(output, input, bytes); 06914 } 06915 else 06916 return NULL; 06917 } 06918 return output; 06919 }
|
|
get_destination: Find out who the call is for --
Definition at line 6523 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(). 06524 { 06525 char tmp[256] = "", *uri, *a; 06526 char tmpf[256], *from; 06527 struct sip_request *req; 06528 char *colon; 06529 06530 req = oreq; 06531 if (!req) 06532 req = &p->initreq; 06533 if (req->rlPart2) 06534 ast_copy_string(tmp, req->rlPart2, sizeof(tmp)); 06535 uri = get_in_brackets(tmp); 06536 06537 ast_copy_string(tmpf, get_header(req, "From"), sizeof(tmpf)); 06538 06539 from = get_in_brackets(tmpf); 06540 06541 if (strncmp(uri, "sip:", 4)) { 06542 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", uri); 06543 return -1; 06544 } 06545 uri += 4; 06546 if (!ast_strlen_zero(from)) { 06547 if (strncmp(from, "sip:", 4)) { 06548 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", from); 06549 return -1; 06550 } 06551 from += 4; 06552 } else 06553 from = NULL; 06554 06555 if (pedanticsipchecking) { 06556 ast_uri_decode(uri); 06557 ast_uri_decode(from); 06558 } 06559 06560 /* Skip any options */ 06561 if ((a = strchr(uri, ';'))) { 06562 *a = '\0'; 06563 } 06564 06565 /* Get the target domain */ 06566 if ((a = strchr(uri, '@'))) { 06567 *a = '\0'; 06568 a++; 06569 } else { /* No username part */ 06570 a = uri; 06571 uri = "s"; /* Set extension to "s" */ 06572 } 06573 colon = strchr(a, ':'); /* Remove :port */ 06574 if (colon) 06575 *colon = '\0'; 06576 06577 ast_copy_string(p->domain, a, sizeof(p->domain)); 06578 06579 if (!AST_LIST_EMPTY(&domain_list)) { 06580 char domain_context[AST_MAX_EXTENSION]; 06581 06582 domain_context[0] = '\0'; 06583 if (!check_sip_domain(p->domain, domain_context, sizeof(domain_context))) { 06584 if (!allow_external_domains && (req->method == SIP_INVITE || req->method == SIP_REFER)) { 06585 ast_log(LOG_DEBUG, "Got SIP %s to non-local domain '%s'; refusing request.\n", sip_methods[req->method].text, p->domain); 06586 return -2; 06587 } 06588 } 06589 /* If we have a context defined, overwrite the original context */ 06590 if (!ast_strlen_zero(domain_context)) 06591 ast_copy_string(p->context, domain_context, sizeof(p->context)); 06592 } 06593 06594 if (from) { 06595 if ((a = strchr(from, ';'))) 06596 *a = '\0'; 06597 if ((a = strchr(from, '@'))) { 06598 *a = '\0'; 06599 ast_copy_string(p->fromdomain, a + 1, sizeof(p->fromdomain)); 06600 } else 06601 ast_copy_string(p->fromdomain, from, sizeof(p->fromdomain)); 06602 } 06603 if (sip_debug_test_pvt(p)) 06604 ast_verbose("Looking for %s in %s (domain %s)\n", uri, p->context, p->domain); 06605 06606 /* Return 0 if we have a matching extension */ 06607 if (ast_exists_extension(NULL, p->context, uri, 1, from) || 06608 !strcmp(uri, ast_pickup_ext())) { 06609 if (!oreq) 06610 ast_copy_string(p->exten, uri, sizeof(p->exten)); 06611 return 0; 06612 } 06613 06614 /* Return 1 for overlap dialling support */ 06615 if (ast_canmatch_extension(NULL, p->context, uri, 1, from) || 06616 !strncmp(uri, ast_pickup_ext(),strlen(uri))) { 06617 return 1; 06618 } 06619 06620 return -1; 06621 }
|
|
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 7225 of file chan_sip.c. References sip_request::line, and sip_request::lines. Referenced by receive_message(). 07226 { 07227 int x; 07228 int y; 07229 07230 buf[0] = '\0'; 07231 y = len - strlen(buf) - 5; 07232 if (y < 0) 07233 y = 0; 07234 for (x=0;x<req->lines;x++) { 07235 strncat(buf, req->line[x], y); /* safe */ 07236 y -= strlen(req->line[x]) + 1; 07237 if (y < 0) 07238 y = 0; 07239 if (y != 0) 07240 strcat(buf, "\n"); /* safe */ 07241 } 07242 return 0; 07243 }
|
|
get_rdnis: get referring dnis ---
Definition at line 6495 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(). 06496 { 06497 char tmp[256], *c, *a; 06498 struct sip_request *req; 06499 06500 req = oreq; 06501 if (!req) 06502 req = &p->initreq; 06503 ast_copy_string(tmp, get_header(req, "Diversion"), sizeof(tmp)); 06504 if (ast_strlen_zero(tmp)) 06505 return 0; 06506 c = get_in_brackets(tmp); 06507 if (strncmp(c, "sip:", 4)) { 06508 ast_log(LOG_WARNING, "Huh? Not an RDNIS SIP header (%s)?\n", c); 06509 return -1; 06510 } 06511 c += 4; 06512 if ((a = strchr(c, '@')) || (a = strchr(c, ';'))) { 06513 *a = '\0'; 06514 } 06515 if (sip_debug_test_pvt(p)) 06516 ast_verbose("RDNIS is %s\n", c); 06517 ast_copy_string(p->rdnis, c, sizeof(p->rdnis)); 06518 06519 return 0; 06520 }
|
|
get_refer_info: Call transfer support (the REFER method) ---
Definition at line 6653 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(). 06654 { 06655 06656 char *p_refer_to = NULL, *p_referred_by = NULL, *h_refer_to = NULL, *h_referred_by = NULL, *h_contact = NULL; 06657 char *replace_callid = "", *refer_to = NULL, *referred_by = NULL, *ptr = NULL; 06658 struct sip_request *req = NULL; 06659 struct sip_pvt *sip_pvt_ptr = NULL; 06660 struct ast_channel *chan = NULL, *peer = NULL; 06661 06662 req = outgoing_req; 06663 06664 if (!req) { 06665 req = &sip_pvt->initreq; 06666 } 06667 06668 if (!( (p_refer_to = get_header(req, "Refer-To")) && (h_refer_to = ast_strdupa(p_refer_to)) )) { 06669 ast_log(LOG_WARNING, "No Refer-To Header That's illegal\n"); 06670 return -1; 06671 } 06672 06673 refer_to = get_in_brackets(h_refer_to); 06674 06675 if (!( (p_referred_by = get_header(req, "Referred-By")) && (h_referred_by = ast_strdupa(p_referred_by)) )) { 06676 ast_log(LOG_WARNING, "No Referrred-By Header That's not illegal\n"); 06677 return -1; 06678 } else { 06679 if (pedanticsipchecking) { 06680 ast_uri_decode(h_referred_by); 06681 } 06682 referred_by = get_in_brackets(h_referred_by); 06683 } 06684 h_contact = get_header(req, "Contact"); 06685 06686 if (strncmp(refer_to, "sip:", 4)) { 06687 ast_log(LOG_WARNING, "Refer-to: Huh? Not a SIP header (%s)?\n", refer_to); 06688 return -1; 06689 } 06690 06691 if (strncmp(referred_by, "sip:", 4)) { 06692 ast_log(LOG_WARNING, "Referred-by: Huh? Not a SIP header (%s) Ignoring?\n", referred_by); 06693 referred_by = NULL; 06694 } 06695 06696 if (refer_to) 06697 refer_to += 4; 06698 06699 if (referred_by) 06700 referred_by += 4; 06701 06702 if ((ptr = strchr(refer_to, '?'))) { 06703 /* Search for arguments */ 06704 *ptr = '\0'; 06705 ptr++; 06706 if (!strncasecmp(ptr, "REPLACES=", 9)) { 06707 char *p; 06708 replace_callid = ast_strdupa(ptr + 9); 06709 /* someday soon to support invite/replaces properly! 06710 replaces_header = ast_strdupa(replace_callid); 06711 -anthm 06712 */ 06713 ast_uri_decode(replace_callid); 06714 if ((ptr = strchr(replace_callid, '%'))) 06715 *ptr = '\0'; 06716 if ((ptr = strchr(replace_callid, ';'))) 06717 *ptr = '\0'; 06718 /* Skip leading whitespace XXX memmove behaviour with overlaps ? */ 06719 p = ast_skip_blanks(replace_callid); 06720 if (p != replace_callid) 06721 memmove(replace_callid, p, strlen(p)); 06722 } 06723 } 06724 06725 if ((ptr = strchr(refer_to, '@'))) /* Skip domain (should be saved in SIPDOMAIN) */ 06726 *ptr = '\0'; 06727 if ((ptr = strchr(refer_to, ';'))) 06728 *ptr = '\0'; 06729 06730 if (referred_by) { 06731 if ((ptr = strchr(referred_by, '@'))) 06732 *ptr = '\0'; 06733 if ((ptr = strchr(referred_by, ';'))) 06734 *ptr = '\0'; 06735 } 06736 06737 if (sip_debug_test_pvt(sip_pvt)) { 06738 ast_verbose("Transfer to %s in %s\n", refer_to, sip_pvt->context); 06739 if (referred_by) 06740 ast_verbose("Transfer from %s in %s\n", referred_by, sip_pvt->context); 06741 } 06742 if (!ast_strlen_zero(replace_callid)) { 06743 /* This is a supervised transfer */ 06744 ast_log(LOG_DEBUG,"Assigning Replace-Call-ID Info %s to REPLACE_CALL_ID\n",replace_callid); 06745 06746 ast_copy_string(sip_pvt->refer_to, "", sizeof(sip_pvt->refer_to)); 06747 ast_copy_string(sip_pvt->referred_by, "", sizeof(sip_pvt->referred_by)); 06748 ast_copy_string(sip_pvt->refer_contact, "", sizeof(sip_pvt->refer_contact)); 06749 sip_pvt->refer_call = NULL; 06750 if ((sip_pvt_ptr = get_sip_pvt_byid_locked(replace_callid))) { 06751 sip_pvt->refer_call = sip_pvt_ptr; 06752 if (sip_pvt->refer_call == sip_pvt) { 06753 ast_log(LOG_NOTICE, "Supervised transfer attempted to transfer into same call id (%s == %s)!\n", replace_callid, sip_pvt->callid); 06754 sip_pvt->refer_call = NULL; 06755 } else 06756 return 0; 06757 } else { 06758 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); 06759 /* XXX The refer_to could contain a call on an entirely different machine, requiring an 06760 INVITE with a replaces header -anthm XXX */ 06761 /* The only way to find out is to use the dialplan - oej */ 06762 } 06763 } else if (ast_exists_extension(NULL, sip_pvt->context, refer_to, 1, NULL) || !strcmp(refer_to, ast_parking_ext())) { 06764 /* This is an unsupervised transfer (blind transfer) */ 06765 06766 ast_log(LOG_DEBUG,"Unsupervised transfer to (Refer-To): %s\n", refer_to); 06767 if (referred_by) 06768 ast_log(LOG_DEBUG,"Transferred by (Referred-by: ) %s \n", referred_by); 06769 ast_log(LOG_DEBUG,"Transfer Contact Info %s (REFER_CONTACT)\n", h_contact); 06770 ast_copy_string(sip_pvt->refer_to, refer_to, sizeof(sip_pvt->refer_to)); 06771 if (referred_by) 06772 ast_copy_string(sip_pvt->referred_by, referred_by, sizeof(sip_pvt->referred_by)); 06773 if (h_contact) { 06774 ast_copy_string(sip_pvt->refer_contact, h_contact, sizeof(sip_pvt->refer_contact)); 06775 } 06776 sip_pvt->refer_call = NULL; 06777 if ((chan = sip_pvt->owner) && (peer = ast_bridged_channel(sip_pvt->owner))) { 06778 pbx_builtin_setvar_helper(chan, "BLINDTRANSFER", peer->name); 06779 pbx_builtin_setvar_helper(peer, "BLINDTRANSFER", chan->name); 06780 } 06781 return 0; 06782 } else if (ast_canmatch_extension(NULL, sip_pvt->context, refer_to, 1, NULL)) { 06783 return 1; 06784 } 06785 06786 return -1; 06787 }
|
|
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 6925 of file chan_sip.c. References AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED. Referenced by check_user_full(). 06926 { 06927 char *start; 06928 char *end; 06929 06930 start = strchr(input,':'); 06931 if (!start) { 06932 output[0] = '\0'; 06933 return 0; 06934 } 06935 start++; 06936 06937 /* we found "number" */ 06938 ast_copy_string(output,start,maxlen); 06939 output[maxlen-1] = '\0'; 06940 06941 end = strchr(output,'@'); 06942 if (end) 06943 *end = '\0'; 06944 else 06945 output[0] = '\0'; 06946 if (strstr(input,"privacy=full") || strstr(input,"privacy=uri")) 06947 return AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED; 06948 06949 return 0; 06950 }
|
|
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 6624 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(). 06625 { 06626 struct sip_pvt *sip_pvt_ptr = NULL; 06627 06628 /* Search interfaces and find the match */ 06629 ast_mutex_lock(&iflock); 06630 sip_pvt_ptr = iflist; 06631 while(sip_pvt_ptr) { 06632 if (!strcmp(sip_pvt_ptr->callid, callid)) { 06633 /* Go ahead and lock it (and its owner) before returning */ 06634 ast_mutex_lock(&sip_pvt_ptr->lock); 06635 if (sip_pvt_ptr->owner) { 06636 while(ast_mutex_trylock(&sip_pvt_ptr->owner->lock)) { 06637 ast_mutex_unlock(&sip_pvt_ptr->lock); 06638 usleep(1); 06639 ast_mutex_lock(&sip_pvt_ptr->lock); 06640 if (!sip_pvt_ptr->owner) 06641 break; 06642 } 06643 } 06644 break; 06645 } 06646 sip_pvt_ptr = sip_pvt_ptr->next; 06647 } 06648 ast_mutex_unlock(&iflock); 06649 return sip_pvt_ptr; 06650 }
|
|
gettag: Get tag from packet
Definition at line 10208 of file chan_sip.c. References get_header(), and strcasestr(). Referenced by find_call(), handle_request(), and handle_response(). 10209 { 10210 10211 char *thetag, *sep; 10212 10213 10214 if (!tagbuf) 10215 return NULL; 10216 tagbuf[0] = '\0'; /* reset the buffer */ 10217 thetag = get_header(req, header); 10218 thetag = strcasestr(thetag, ";tag="); 10219 if (thetag) { 10220 thetag += 5; 10221 ast_copy_string(tagbuf, thetag, tagbufsize); 10222 sep = strchr(tagbuf, ';'); 10223 if (sep) 10224 *sep = '\0'; 10225 } 10226 return thetag; 10227 }
|
|
handle_common_options: Handle flag-type options common to users and peers ---
Definition at line 11623 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(). 11624 { 11625 int res = 0; 11626 11627 if (!strcasecmp(v->name, "trustrpid")) { 11628 ast_set_flag(mask, SIP_TRUSTRPID); 11629 ast_set2_flag(flags, ast_true(v->value), SIP_TRUSTRPID); 11630 res = 1; 11631 } else if (!strcasecmp(v->name, "sendrpid")) { 11632 ast_set_flag(mask, SIP_SENDRPID); 11633 ast_set2_flag(flags, ast_true(v->value), SIP_SENDRPID); 11634 res = 1; 11635 } else if (!strcasecmp(v->name, "useclientcode")) { 11636 ast_set_flag(mask, SIP_USECLIENTCODE); 11637 ast_set2_flag(flags, ast_true(v->value), SIP_USECLIENTCODE); 11638 res = 1; 11639 } else if (!strcasecmp(v->name, "dtmfmode")) { 11640 ast_set_flag(mask, SIP_DTMF); 11641 ast_clear_flag(flags, SIP_DTMF); 11642 if (!strcasecmp(v->value, "inband")) 11643 ast_set_flag(flags, SIP_DTMF_INBAND); 11644 else if (!strcasecmp(v->value, "rfc2833")) 11645 ast_set_flag(flags, SIP_DTMF_RFC2833); 11646 else if (!strcasecmp(v->value, "info")) 11647 ast_set_flag(flags, SIP_DTMF_INFO); 11648 else if (!strcasecmp(v->value, "auto")) 11649 ast_set_flag(flags, SIP_DTMF_AUTO); 11650 else { 11651 ast_log(LOG_WARNING, "Unknown dtmf mode '%s' on line %d, using rfc2833\n", v->value, v->lineno); 11652 ast_set_flag(flags, SIP_DTMF_RFC2833); 11653 } 11654 } else if (!strcasecmp(v->name, "nat")) { 11655 ast_set_flag(mask, SIP_NAT); 11656 ast_clear_flag(flags, SIP_NAT); 11657 if (!strcasecmp(v->value, "never")) 11658 ast_set_flag(flags, SIP_NAT_NEVER); 11659 else if (!strcasecmp(v->value, "route")) 11660 ast_set_flag(flags, SIP_NAT_ROUTE); 11661 else if (ast_true(v->value)) 11662 ast_set_flag(flags, SIP_NAT_ALWAYS); 11663 else 11664 ast_set_flag(flags, SIP_NAT_RFC3581); 11665 } else if (!strcasecmp(v->name, "canreinvite")) { 11666 ast_set_flag(mask, SIP_REINVITE); 11667 ast_clear_flag(flags, SIP_REINVITE); 11668 if (!strcasecmp(v->value, "update")) 11669 ast_set_flag(flags, SIP_REINVITE_UPDATE | SIP_CAN_REINVITE); 11670 else 11671 ast_set2_flag(flags, ast_true(v->value), SIP_CAN_REINVITE); 11672 } else if (!strcasecmp(v->name, "insecure")) { 11673 ast_set_flag(mask, SIP_INSECURE_PORT | SIP_INSECURE_INVITE); 11674 ast_clear_flag(flags, SIP_INSECURE_PORT | SIP_INSECURE_INVITE); 11675 if (!strcasecmp(v->value, "very")) 11676 ast_set_flag(flags, SIP_INSECURE_PORT | SIP_INSECURE_INVITE); 11677 else if (ast_true(v->value)) 11678 ast_set_flag(flags, SIP_INSECURE_PORT); 11679 else if (!ast_false(v->value)) { 11680 char buf[64]; 11681 char *word, *next; 11682 11683 ast_copy_string(buf, v->value, sizeof(buf)); 11684 next = buf; 11685 while ((word = strsep(&next, ","))) { 11686 if (!strcasecmp(word, "port")) 11687 ast_set_flag(flags, SIP_INSECURE_PORT); 11688 else if (!strcasecmp(word, "invite")) 11689 ast_set_flag(flags, SIP_INSECURE_INVITE); 11690 else 11691 ast_log(LOG_WARNING, "Unknown insecure mode '%s' on line %d\n", v->value, v->lineno); 11692 } 11693 } 11694 } else if (!strcasecmp(v->name, "progressinband")) { 11695 ast_set_flag(mask, SIP_PROG_INBAND); 11696 ast_clear_flag(flags, SIP_PROG_INBAND); 11697 if (ast_true(v->value)) 11698 ast_set_flag(flags, SIP_PROG_INBAND_YES); 11699 else if (strcasecmp(v->value, "never")) 11700 ast_set_flag(flags, SIP_PROG_INBAND_NO); 11701 } else if (!strcasecmp(v->name, "allowguest")) { 11702 #ifdef OSP_SUPPORT 11703 if (!strcasecmp(v->value, "osp")) 11704 global_allowguest = 2; 11705 else 11706 #endif 11707 if (ast_true(v->value)) 11708 global_allowguest = 1; 11709 else 11710 global_allowguest = 0; 11711 #ifdef OSP_SUPPORT 11712 } else if (!strcasecmp(v->name, "ospauth")) { 11713 ast_set_flag(mask, SIP_OSPAUTH); 11714 ast_clear_flag(flags, SIP_OSPAUTH); 11715 if (!strcasecmp(v->value, "proxy")) 11716 ast_set_flag(flags, SIP_OSPAUTH_PROXY); 11717 else if (!strcasecmp(v->value, "gateway")) 11718 ast_set_flag(flags, SIP_OSPAUTH_GATEWAY); 11719 else if(!strcasecmp (v->value, "exclusive")) 11720 ast_set_flag(flags, SIP_OSPAUTH_EXCLUSIVE); 11721 #endif 11722 } else if (!strcasecmp(v->name, "promiscredir")) { 11723 ast_set_flag(mask, SIP_PROMISCREDIR); 11724 ast_set2_flag(flags, ast_true(v->value), SIP_PROMISCREDIR); 11725 res = 1; 11726 } 11727 11728 return res; 11729 }
|
|
handle_request: Handle SIP requests (methods) ---
Definition at line 10897 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. 10898 { 10899 /* Called with p->lock held, as well as p->owner->lock if appropriate, keeping things 10900 relatively static */ 10901 struct sip_request resp; 10902 char *cmd; 10903 char *cseq; 10904 char *useragent; 10905 int seqno; 10906 int len; 10907 int ignore=0; 10908 int respid; 10909 int res = 0; 10910 char iabuf[INET_ADDRSTRLEN]; 10911 int debug = sip_debug_test_pvt(p); 10912 char *e; 10913 int error = 0; 10914 10915 /* Clear out potential response */ 10916 memset(&resp, 0, sizeof(resp)); 10917 10918 /* Get Method and Cseq */ 10919 cseq = get_header(req, "Cseq"); 10920 cmd = req->header[0]; 10921 10922 /* Must have Cseq */ 10923 if (ast_strlen_zero(cmd) || ast_strlen_zero(cseq)) { 10924 ast_log(LOG_ERROR, "Missing Cseq. Dropping this SIP message, it's incomplete.\n"); 10925 error = 1; 10926 } 10927 if (!error && sscanf(cseq, "%d%n", &seqno, &len) != 1) { 10928 ast_log(LOG_ERROR, "No seqno in '%s'. Dropping incomplete message.\n", cmd); 10929 error = 1; 10930 } 10931 if (error) { 10932 if (!p->initreq.header) /* New call */ 10933 ast_set_flag(p, SIP_NEEDDESTROY); /* Make sure we destroy this dialog */ 10934 return -1; 10935 } 10936 /* Get the command XXX */ 10937 10938 cmd = req->rlPart1; 10939 e = req->rlPart2; 10940 10941 /* Save useragent of the client */ 10942 useragent = get_header(req, "User-Agent"); 10943 if (!ast_strlen_zero(useragent)) 10944 ast_copy_string(p->useragent, useragent, sizeof(p->useragent)); 10945 10946 /* Find out SIP method for incoming request */ 10947 if (req->method == SIP_RESPONSE) { /* Response to our request */ 10948 /* Response to our request -- Do some sanity checks */ 10949 if (!p->initreq.headers) { 10950 ast_log(LOG_DEBUG, "That's odd... Got a response on a call we dont know about. Cseq %d Cmd %s\n", seqno, cmd); 10951 ast_set_flag(p, SIP_NEEDDESTROY); 10952 return 0; 10953 } else if (p->ocseq && (p->ocseq < seqno)) { 10954 ast_log(LOG_DEBUG, "Ignoring out of order response %d (expecting %d)\n", seqno, p->ocseq); 10955 return -1; 10956 } else if (p->ocseq && (p->ocseq != seqno)) { 10957 /* ignore means "don't do anything with it" but still have to 10958 respond appropriately */ 10959 ignore=1; 10960 } 10961 10962 e = ast_skip_blanks(e); 10963 if (sscanf(e, "%d %n", &respid, &len) != 1) { 10964 ast_log(LOG_WARNING, "Invalid response: '%s'\n", e); 10965 } else { 10966 /* More SIP ridiculousness, we have to ignore bogus contacts in 100 etc responses */ 10967 if ((respid == 200) || ((respid >= 300) && (respid <= 399))) 10968 extract_uri(p, req); 10969 handle_response(p, respid, e + len, req, ignore, seqno); 10970 } 10971 return 0; 10972 } 10973 10974 /* New SIP request coming in 10975 (could be new request in existing SIP dialog as well...) 10976 */ 10977 10978 p->method = req->method; /* Find out which SIP method they are using */ 10979 if (option_debug > 2) 10980 ast_log(LOG_DEBUG, "**** Received %s (%d) - Command in SIP %s\n", sip_methods[p->method].text, sip_methods[p->method].id, cmd); 10981 10982 if (p->icseq && (p->icseq > seqno)) { 10983 if (option_debug) 10984 ast_log(LOG_DEBUG, "Ignoring too old SIP packet packet %d (expecting >= %d)\n", seqno, p->icseq); 10985 if (req->method != SIP_ACK) 10986 transmit_response(p, "503 Server error", req); /* We must respond according to RFC 3261 sec 12.2 */ 10987 return -1; 10988 } else if (p->icseq && (p->icseq == seqno) && req->method != SIP_ACK &&(p->method != SIP_CANCEL|| ast_test_flag(p, SIP_ALREADYGONE))) { 10989 /* ignore means "don't do anything with it" but still have to 10990 respond appropriately. We do this if we receive a repeat of 10991 the last sequence number */ 10992 ignore=2; 10993 if (option_debug > 2) 10994 ast_log(LOG_DEBUG, "Ignoring SIP message because of retransmit (%s Seqno %d, ours %d)\n", sip_methods[p->method].text, p->icseq, seqno); 10995 } 10996 10997 if (seqno >= p->icseq) 10998 /* Next should follow monotonically (but not necessarily 10999 incrementally -- thanks again to the genius authors of SIP -- 11000 increasing */ 11001 p->icseq = seqno; 11002 11003 /* Find their tag if we haven't got it */ 11004 if (ast_strlen_zero(p->theirtag)) { 11005 gettag(req, "From", p->theirtag, sizeof(p->theirtag)); 11006 } 11007 snprintf(p->lastmsg, sizeof(p->lastmsg), "Rx: %s", cmd); 11008 11009 if (pedanticsipchecking) { 11010 /* If this is a request packet without a from tag, it's not 11011 correct according to RFC 3261 */ 11012 /* Check if this a new request in a new dialog with a totag already attached to it, 11013 RFC 3261 - section 12.2 - and we don't want to mess with recovery */ 11014 if (!p->initreq.headers && ast_test_flag(req, SIP_PKT_WITH_TOTAG)) { 11015 /* If this is a first request and it got a to-tag, it is not for us */ 11016 if (!ignore && req->method == SIP_INVITE) { 11017 transmit_response_reliable(p, "481 Call/Transaction Does Not Exist", req, 1); 11018 /* Will cease to exist after ACK */ 11019 } else { 11020 transmit_response(p, "481 Call/Transaction Does Not Exist", req); 11021 ast_set_flag(p, SIP_NEEDDESTROY); 11022 } 11023 return res; 11024 } 11025 } 11026 11027 /* Handle various incoming SIP methods in requests */ 11028 switch (p->method) { 11029 case SIP_OPTIONS: 11030 res = handle_request_options(p, req, debug); 11031 break; 11032 case SIP_INVITE: 11033 res = handle_request_invite(p, req, debug, ignore, seqno, sin, recount, e); 11034 break; 11035 case SIP_REFER: 11036 res = handle_request_refer(p, req, debug, ignore, seqno, nounlock); 11037 break; 11038 case SIP_CANCEL: 11039 res = handle_request_cancel(p, req, debug, ignore); 11040 break; 11041 case SIP_BYE: 11042 res = handle_request_bye(p, req, debug, ignore); 11043 break; 11044 case SIP_MESSAGE: 11045 res = handle_request_message(p, req, debug, ignore); 11046 break; 11047 case SIP_SUBSCRIBE: 11048 res = handle_request_subscribe(p, req, debug, ignore, sin, seqno, e); 11049 break; 11050 case SIP_REGISTER: 11051 res = handle_request_register(p, req, debug, ignore, sin, e); 11052 break; 11053 case SIP_INFO: 11054 if (!ignore) { 11055 if (debug) 11056 ast_verbose("Receiving INFO!\n"); 11057 handle_request_info(p, req); 11058 } else { /* if ignoring, transmit response */ 11059 transmit_response(p, "200 OK", req); 11060 } 11061 break; 11062 case SIP_NOTIFY: 11063 /* XXX we get NOTIFY's from some servers. WHY?? Maybe we should 11064 look into this someday XXX */ 11065 transmit_response(p, "200 OK", req); 11066 if (!p->lastinvite) 11067 ast_set_flag(p, SIP_NEEDDESTROY); 11068 break; 11069 case SIP_ACK: 11070 /* Make sure we don't ignore this */ 11071 if (seqno == p->pendinginvite) { 11072 p->pendinginvite = 0; 11073 __sip_ack(p, seqno, FLAG_RESPONSE, 0); 11074 if (!ast_strlen_zero(get_header(req, "Content-Type"))) { 11075 if (process_sdp(p, req)) 11076 return -1; 11077 } 11078 check_pendings(p); 11079 } 11080 if (!p->lastinvite && ast_strlen_zero(p->randdata)) 11081 ast_set_flag(p, SIP_NEEDDESTROY); 11082 break; 11083 default: 11084 transmit_response_with_allow(p, "501 Method Not Implemented", req, 0); 11085 ast_log(LOG_NOTICE, "Unknown SIP command '%s' from '%s'\n", 11086 cmd, ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr)); 11087 /* If this is some new method, and we don't have a call, destroy it now */ 11088 if (!p->initreq.headers) 11089 ast_set_flag(p, SIP_NEEDDESTROY); 11090 break; 11091 } 11092 return res; 11093 }
|
|
handle_request_bye: Handle incoming BYE request ---
Definition at line 10609 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(). 10610 { 10611 struct ast_channel *c=NULL; 10612 int res; 10613 struct ast_channel *bridged_to; 10614 char iabuf[INET_ADDRSTRLEN]; 10615 10616 if (p->pendinginvite && !ast_test_flag(p, SIP_OUTGOING) && !ignore) 10617 transmit_response_reliable(p, "487 Request Terminated", &p->initreq, 1); 10618 10619 copy_request(&p->initreq, req); 10620 check_via(p, req); 10621 ast_set_flag(p, SIP_ALREADYGONE); 10622 if (p->rtp) { 10623 /* Immediately stop RTP */ 10624 ast_rtp_stop(p->rtp); 10625 } 10626 if (p->vrtp) { 10627 /* Immediately stop VRTP */ 10628 ast_rtp_stop(p->vrtp); 10629 } 10630 if (!ast_strlen_zero(get_header(req, "Also"))) { 10631 ast_log(LOG_NOTICE, "Client '%s' using deprecated BYE/Also transfer method. Ask vendor to support REFER instead\n", 10632 ast_inet_ntoa(iabuf, sizeof(iabuf), p->recv.sin_addr)); 10633 if (ast_strlen_zero(p->context)) 10634 strcpy(p->context, default_context); 10635 res = get_also_info(p, req); 10636 if (!res) { 10637 c = p->owner; 10638 if (c) { 10639 bridged_to = ast_bridged_channel(c); 10640 if (bridged_to) { 10641 /* Don't actually hangup here... */ 10642 ast_moh_stop(bridged_to); 10643 ast_async_goto(bridged_to, p->context, p->refer_to,1); 10644 } else 10645 ast_queue_hangup(p->owner); 10646 } 10647 } else { 10648 ast_log(LOG_WARNING, "Invalid transfer information from '%s'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), p->recv.sin_addr)); 10649 if (p->owner) 10650 ast_queue_hangup(p->owner); 10651 } 10652 } else if (p->owner) 10653 ast_queue_hangup(p->owner); 10654 else 10655 ast_set_flag(p, SIP_NEEDDESTROY); 10656 transmit_response(p, "200 OK", req); 10657 10658 return 1; 10659 }
|
|
handle_request_cancel: Handle incoming CANCEL request ---
Definition at line 10580 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(). 10581 { 10582 10583 check_via(p, req); 10584 ast_set_flag(p, SIP_ALREADYGONE); 10585 if (p->rtp) { 10586 /* Immediately stop RTP */ 10587 ast_rtp_stop(p->rtp); 10588 } 10589 if (p->vrtp) { 10590 /* Immediately stop VRTP */ 10591 ast_rtp_stop(p->vrtp); 10592 } 10593 if (p->owner) 10594 ast_queue_hangup(p->owner); 10595 else 10596 ast_set_flag(p, SIP_NEEDDESTROY); 10597 if (p->initreq.len > 0) { 10598 if (!ignore) 10599 transmit_response_reliable(p, "487 Request Terminated", &p->initreq, 1); 10600 transmit_response(p, "200 OK", req); 10601 return 1; 10602 } else { 10603 transmit_response(p, "481 Call Leg Does Not Exist", req); 10604 return 0; 10605 } 10606 }
|
|
handle_request_info: Receive SIP INFO Message ---
Definition at line 8605 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(). 08606 { 08607 char buf[1024]; 08608 unsigned int event; 08609 char *c; 08610 08611 /* Need to check the media/type */ 08612 if (!strcasecmp(get_header(req, "Content-Type"), "application/dtmf-relay") || 08613 !strcasecmp(get_header(req, "Content-Type"), "application/vnd.nortelnetworks.digits")) { 08614 08615 /* Try getting the "signal=" part */ 08616 if (ast_strlen_zero(c = get_sdp(req, "Signal")) && ast_strlen_zero(c = get_sdp(req, "d"))) { 08617 ast_log(LOG_WARNING, "Unable to retrieve DTMF signal from INFO message from %s\n", p->callid); 08618 transmit_response(p, "200 OK", req); /* Should return error */ 08619 return; 08620 } else { 08621 ast_copy_string(buf, c, sizeof(buf)); 08622 } 08623 08624 if (!p->owner) { /* not a PBX call */ 08625 transmit_response(p, "481 Call leg/transaction does not exist", req); 08626 ast_set_flag(p, SIP_NEEDDESTROY); 08627 return; 08628 } 08629 08630 if (ast_strlen_zero(buf)) { 08631 transmit_response(p, "200 OK", req); 08632 return; 08633 } 08634 08635 if (buf[0] == '*') 08636 event = 10; 08637 else if (buf[0] == '#') 08638 event = 11; 08639 else if ((buf[0] >= 'A') && (buf[0] <= 'D')) 08640 event = 12 + buf[0] - 'A'; 08641 else 08642 event = atoi(buf); 08643 if (event == 16) { 08644 /* send a FLASH event */ 08645 struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_FLASH, }; 08646 ast_queue_frame(p->owner, &f); 08647 if (sipdebug) 08648 ast_verbose("* DTMF-relay event received: FLASH\n"); 08649 } else { 08650 /* send a DTMF event */ 08651 struct ast_frame f = { AST_FRAME_DTMF, }; 08652 if (event < 10) { 08653 f.subclass = '0' + event; 08654 } else if (event < 11) { 08655 f.subclass = '*'; 08656 } else if (event < 12) { 08657 f.subclass = '#'; 08658 } else if (event < 16) { 08659 f.subclass = 'A' + (event - 12); 08660 } 08661 ast_queue_frame(p->owner, &f); 08662 if (sipdebug) 08663 ast_verbose("* DTMF-relay event received: %c\n", f.subclass); 08664 } 08665 transmit_response(p, "200 OK", req); 08666 return; 08667 } else if (!strcasecmp(get_header(req, "Content-Type"), "application/media_control+xml")) { 08668 /* Eh, we'll just assume it's a fast picture update for now */ 08669 if (p->owner) 08670 ast_queue_control(p->owner, AST_CONTROL_VIDUPDATE); 08671 transmit_response(p, "200 OK", req); 08672 return; 08673 } else if ((c = get_header(req, "X-ClientCode"))) { 08674 /* Client code (from SNOM phone) */ 08675 if (ast_test_flag(p, SIP_USECLIENTCODE)) { 08676 if (p->owner && p->owner->cdr) 08677 ast_cdr_setuserfield(p->owner, c); 08678 if (p->owner && ast_bridged_channel(p->owner) && ast_bridged_channel(p->owner)->cdr) 08679 ast_cdr_setuserfield(ast_bridged_channel(p->owner), c); 08680 transmit_response(p, "200 OK", req); 08681 } else { 08682 transmit_response(p, "403 Unauthorized", req); 08683 } 08684 return; 08685 } 08686 /* Other type of INFO message, not really understood by Asterisk */ 08687 /* if (get_msg_text(buf, sizeof(buf), req)) { */ 08688 08689 ast_log(LOG_WARNING, "Unable to parse INFO message from %s. Content %s\n", p->callid, buf); 08690 transmit_response(p, "415 Unsupported media type", req); 08691 return; 08692 }
|
|
handle_request_invite: Handle incoming INVITE request
Definition at line 10254 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(). 10255 { 10256 int res = 1; 10257 struct ast_channel *c=NULL; 10258 int gotdest; 10259 struct ast_frame af = { AST_FRAME_NULL, }; 10260 char *supported; 10261 char *required; 10262 unsigned int required_profile = 0; 10263 10264 /* Find out what they support */ 10265 if (!p->sipoptions) { 10266 supported = get_header(req, "Supported"); 10267 if (supported) 10268 parse_sip_options(p, supported); 10269 } 10270 required = get_header(req, "Required"); 10271 if (!ast_strlen_zero(required)) { 10272 required_profile = parse_sip_options(NULL, required); 10273 if (required_profile) { /* They require something */ 10274 /* At this point we support no extensions, so fail */ 10275 transmit_response_with_unsupported(p, "420 Bad extension", req, required); 10276 if (!p->lastinvite) 10277 ast_set_flag(p, SIP_NEEDDESTROY); 10278 return -1; 10279 10280 } 10281 } 10282 10283 /* Check if this is a loop */ 10284 /* This happens since we do not properly support SIP domain 10285 handling yet... -oej */ 10286 if (ast_test_flag(p, SIP_OUTGOING) && p->owner && (p->owner->_state != AST_STATE_UP)) { 10287 /* This is a call to ourself. Send ourselves an error code and stop 10288 processing immediately, as SIP really has no good mechanism for 10289 being able to call yourself */ 10290 transmit_response(p, "482 Loop Detected", req); 10291 /* We do NOT destroy p here, so that our response will be accepted */ 10292 return 0; 10293 } 10294 if (!ignore) { 10295 /* Use this as the basis */ 10296 if (debug) 10297 ast_verbose("Using INVITE request as basis request - %s\n", p->callid); 10298 sip_cancel_destroy(p); 10299 /* This call is no longer outgoing if it ever was */ 10300 ast_clear_flag(p, SIP_OUTGOING); 10301 /* This also counts as a pending invite */ 10302 p->pendinginvite = seqno; 10303 copy_request(&p->initreq, req); 10304 check_via(p, req); 10305 if (p->owner) { 10306 /* Handle SDP here if we already have an owner */ 10307 if (!strcasecmp(get_header(req, "Content-Type"), "application/sdp")) { 10308 if (process_sdp(p, req)) { 10309 transmit_response(p, "488 Not acceptable here", req); 10310 if (!p->lastinvite) 10311 ast_set_flag(p, SIP_NEEDDESTROY); 10312 return -1; 10313 } 10314 } else { 10315 p->jointcapability = p->capability; 10316 ast_log(LOG_DEBUG, "Hm.... No sdp for the moment\n"); 10317 } 10318 } 10319 } else if (debug) 10320 ast_verbose("Ignoring this INVITE request\n"); 10321 if (!p->lastinvite && !ignore && !p->owner) { 10322 /* Handle authentication if this is our first invite */ 10323 res = check_user(p, req, SIP_INVITE, e, 1, sin, ignore); 10324 if (res) { 10325 if (res < 0) { 10326 ast_log(LOG_NOTICE, "Failed to authenticate user %s\n", get_header(req, "From")); 10327 if (ignore) 10328 transmit_response(p, "403 Forbidden", req); 10329 else 10330 transmit_response_reliable(p, "403 Forbidden", req, 1); 10331 ast_set_flag(p, SIP_NEEDDESTROY); 10332 p->theirtag[0] = '\0'; /* Forget their to-tag, we'll get a new one */ 10333 } 10334 return 0; 10335 } 10336 /* Process the SDP portion */ 10337 if (!ast_strlen_zero(get_header(req, "Content-Type"))) { 10338 if (process_sdp(p, req)) { 10339 transmit_response(p, "488 Not acceptable here", req); 10340 ast_set_flag(p, SIP_NEEDDESTROY); 10341 return -1; 10342 } 10343 } else { 10344 p->jointcapability = p->capability; 10345 ast_log(LOG_DEBUG, "Hm.... No sdp for the moment\n"); 10346 } 10347 /* Queue NULL frame to prod ast_rtp_bridge if appropriate */ 10348 if (p->owner) 10349 ast_queue_frame(p->owner, &af); 10350 /* Initialize the context if it hasn't been already */ 10351 if (ast_strlen_zero(p->context)) 10352 strcpy(p->context, default_context); 10353 /* Check number of concurrent calls -vs- incoming limit HERE */ 10354 ast_log(LOG_DEBUG, "Checking SIP call limits for device %s\n", p->username); 10355 res = update_call_counter(p, INC_CALL_LIMIT); 10356 if (res) { 10357 if (res < 0) { 10358 ast_log(LOG_NOTICE, "Failed to place call for user %s, too many calls\n", p->username); 10359 if (ignore) 10360 transmit_response(p, "480 Temporarily Unavailable (Call limit)", req); 10361 else 10362 transmit_response_reliable(p, "480 Temporarily Unavailable (Call limit) ", req, 1); 10363 ast_set_flag(p, SIP_NEEDDESTROY); 10364 } 10365 return 0; 10366 } 10367 /* Get destination right away */ 10368 gotdest = get_destination(p, NULL); 10369 10370 get_rdnis(p, NULL); 10371 extract_uri(p, req); 10372 build_contact(p); 10373 10374 if (gotdest) { 10375 if (gotdest < 0) { 10376 if (ignore) 10377 transmit_response(p, "404 Not Found", req); 10378 else 10379 transmit_response_reliable(p, "404 Not Found", req, 1); 10380 update_call_counter(p, DEC_CALL_LIMIT); 10381 } else { 10382 if (ignore) 10383 transmit_response(p, "484 Address Incomplete", req); 10384 else 10385 transmit_response_reliable(p, "484 Address Incomplete", req, 1); 10386 update_call_counter(p, DEC_CALL_LIMIT); 10387 } 10388 ast_set_flag(p, SIP_NEEDDESTROY); 10389 } else { 10390 /* If no extension was specified, use the s one */ 10391 if (ast_strlen_zero(p->exten)) 10392 ast_copy_string(p->exten, "s", sizeof(p->exten)); 10393 /* Initialize tag */ 10394 make_our_tag(p->tag, sizeof(p->tag)); 10395 /* First invitation */ 10396 c = sip_new(p, AST_STATE_DOWN, ast_strlen_zero(p->username) ? NULL : p->username ); 10397 *recount = 1; 10398 /* Save Record-Route for any later requests we make on this dialogue */ 10399 build_route(p, req, 0); 10400 if (c) { 10401 /* Pre-lock the call */ 10402 ast_mutex_lock(&c->lock); 10403 } 10404 } 10405 10406 } else { 10407 if (option_debug > 1 && sipdebug) 10408 ast_log(LOG_DEBUG, "Got a SIP re-invite for call %s\n", p->callid); 10409 c = p->owner; 10410 } 10411 if (!ignore && p) 10412 p->lastinvite = seqno; 10413 if (c) { 10414 #ifdef OSP_SUPPORT 10415 ast_channel_setwhentohangup (c, p->osptimelimit); 10416 #endif 10417 switch(c->_state) { 10418 case AST_STATE_DOWN: 10419 transmit_response(p, "100 Trying", req); 10420 ast_setstate(c, AST_STATE_RING); 10421 if (strcmp(p->exten, ast_pickup_ext())) { 10422 enum ast_pbx_result res; 10423 10424 res = ast_pbx_start(c); 10425 10426 switch (res) { 10427 case AST_PBX_FAILED: 10428 ast_log(LOG_WARNING, "Failed to start PBX :(\n"); 10429 if (ignore) 10430 transmit_response(p, "503 Unavailable", req); 10431 else 10432 transmit_response_reliable(p, "503 Unavailable", req, 1); 10433 break; 10434 case AST_PBX_CALL_LIMIT: 10435 ast_log(LOG_WARNING, "Failed to start PBX (call limit reached) \n"); 10436 if (ignore) 10437 transmit_response(p, "480 Temporarily Unavailable", req); 10438 else 10439 transmit_response_reliable(p, "480 Temporarily Unavailable", req, 1); 10440 break; 10441 case AST_PBX_SUCCESS: 10442 /* nothing to do */ 10443 break; 10444 } 10445 10446 if (res) { 10447 ast_log(LOG_WARNING, "Failed to start PBX :(\n"); 10448 /* Unlock locks so ast_hangup can do its magic */ 10449 ast_mutex_unlock(&c->lock); 10450 ast_mutex_unlock(&p->lock); 10451 ast_hangup(c); 10452 ast_mutex_lock(&p->lock); 10453 c = NULL; 10454 } 10455 } else { 10456 ast_mutex_unlock(&c->lock); 10457 if (ast_pickup_call(c)) { 10458 ast_log(LOG_NOTICE, "Nothing to pick up\n"); 10459 if (ignore) 10460 transmit_response(p, "503 Unavailable", req); 10461 else 10462 transmit_response_reliable(p, "503 Unavailable", req, 1); 10463 ast_set_flag(p, SIP_ALREADYGONE); 10464 /* Unlock locks so ast_hangup can do its magic */ 10465 ast_mutex_unlock(&p->lock); 10466 ast_hangup(c); 10467 ast_mutex_lock(&p->lock); 10468 c = NULL; 10469 } else { 10470 ast_mutex_unlock(&p->lock); 10471 ast_setstate(c, AST_STATE_DOWN); 10472 ast_hangup(c); 10473 ast_mutex_lock(&p->lock); 10474 c = NULL; 10475 } 10476 } 10477 break; 10478 case AST_STATE_RING: 10479 transmit_response(p, "100 Trying", req); 10480 break; 10481 case AST_STATE_RINGING: 10482 transmit_response(p, "180 Ringing", req); 10483 break; 10484 case AST_STATE_UP: 10485 transmit_response_with_sdp(p, "200 OK", req, 1); 10486 break; 10487 default: 10488 ast_log(LOG_WARNING, "Don't know how to handle INVITE in state %d\n", c->_state); 10489 transmit_response(p, "100 Trying", req); 10490 } 10491 } else { 10492 if (p && !ast_test_flag(p, SIP_NEEDDESTROY) && !ignore) { 10493 if (!p->jointcapability) { 10494 if (ignore) 10495 transmit_response(p, "488 Not Acceptable Here (codec error)", req); 10496 else 10497 transmit_response_reliable(p, "488 Not Acceptable Here (codec error)", req, 1); 10498 ast_set_flag(p, SIP_NEEDDESTROY); 10499 } else { 10500 ast_log(LOG_NOTICE, "Unable to create/find channel\n"); 10501 if (ignore) 10502 transmit_response(p, "503 Unavailable", req); 10503 else 10504 transmit_response_reliable(p, "503 Unavailable", req, 1); 10505 ast_set_flag(p, SIP_NEEDDESTROY); 10506 } 10507 } 10508 } 10509 return res; 10510 }
|
|
handle_request_message: Handle incoming MESSAGE request ---
Definition at line 10662 of file chan_sip.c. References ast_verbose(), receive_message(), and transmit_response(). Referenced by handle_request(). 10663 { 10664 if (!ignore) { 10665 if (debug) 10666 ast_verbose("Receiving message!\n"); 10667 receive_message(p, req); 10668 } else { 10669 transmit_response(p, "202 Accepted", req); 10670 } 10671 return 1; 10672 }
|
|
handle_request_options: Handle incoming OPTIONS request
Definition at line 10230 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(). 10231 { 10232 int res; 10233 10234 res = get_destination(p, req); 10235 build_contact(p); 10236 /* XXX Should we authenticate OPTIONS? XXX */ 10237 if (ast_strlen_zero(p->context)) 10238 strcpy(p->context, default_context); 10239 if (res < 0) 10240 transmit_response_with_allow(p, "404 Not Found", req, 0); 10241 else if (res > 0) 10242 transmit_response_with_allow(p, "484 Address Incomplete", req, 0); 10243 else 10244 transmit_response_with_allow(p, "200 OK", req, 0); 10245 /* Destroy if this OPTIONS was the opening request, but not if 10246 it's in the middle of a normal call flow. */ 10247 if (!p->lastinvite) 10248 ast_set_flag(p, SIP_NEEDDESTROY); 10249 10250 return res; 10251 }
|
|
handle_request_refer: Handle incoming REFER request ---
Definition at line 10513 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(). 10514 { 10515 struct ast_channel *c=NULL; 10516 int res; 10517 struct ast_channel *transfer_to; 10518 10519 if (option_debug > 2) 10520 ast_log(LOG_DEBUG, "SIP call transfer received for call %s (REFER)!\n", p->callid); 10521 if (ast_strlen_zero(p->context)) 10522 strcpy(p->context, default_context); 10523 res = get_refer_info(p, req); 10524 if (res < 0) 10525 transmit_response_with_allow(p, "404 Not Found", req, 1); 10526 else if (res > 0) 10527 transmit_response_with_allow(p, "484 Address Incomplete", req, 1); 10528 else { 10529 int nobye = 0; 10530 if (!ignore) { 10531 if (p->refer_call) { 10532 ast_log(LOG_DEBUG,"202 Accepted (supervised)\n"); 10533 attempt_transfer(p, p->refer_call); 10534 if (p->refer_call->owner) 10535 ast_mutex_unlock(&p->refer_call->owner->lock); 10536 ast_mutex_unlock(&p->refer_call->lock); 10537 p->refer_call = NULL; 10538 ast_set_flag(p, SIP_GOTREFER); 10539 } else { 10540 ast_log(LOG_DEBUG,"202 Accepted (blind)\n"); 10541 c = p->owner; 10542 if (c) { 10543 transfer_to = ast_bridged_channel(c); 10544 if (transfer_to) { 10545 ast_log(LOG_DEBUG, "Got SIP blind transfer, applying to '%s'\n", transfer_to->name); 10546 ast_moh_stop(transfer_to); 10547 if (!strcmp(p->refer_to, ast_parking_ext())) { 10548 /* Must release c's lock now, because it will not longer 10549 be accessible after the transfer! */ 10550 *nounlock = 1; 10551 ast_mutex_unlock(&c->lock); 10552 sip_park(transfer_to, c, req); 10553 nobye = 1; 10554 } else { 10555 /* Must release c's lock now, because it will not longer 10556 be accessible after the transfer! */ 10557 *nounlock = 1; 10558 ast_mutex_unlock(&c->lock); 10559 ast_async_goto(transfer_to,p->context, p->refer_to,1); 10560 } 10561 } else { 10562 ast_log(LOG_DEBUG, "Got SIP blind transfer but nothing to transfer to.\n"); 10563 ast_queue_hangup(p->owner); 10564 } 10565 } 10566 ast_set_flag(p, SIP_GOTREFER); 10567 } 10568 transmit_response(p, "202 Accepted", req); 10569 transmit_notify_with_sipfrag(p, seqno); 10570 /* Always increment on a BYE */ 10571 if (!nobye) { 10572 transmit_request_with_auth(p, SIP_BYE, 0, 1, 1); 10573 ast_set_flag(p, SIP_ALREADYGONE); 10574 } 10575 } 10576 } 10577 return res; 10578 }
|
|
handle_request_register: Handle incoming REGISTER request ---
Definition at line 10875 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(). 10876 { 10877 int res = 0; 10878 char iabuf[INET_ADDRSTRLEN]; 10879 10880 /* Use this as the basis */ 10881 if (debug) 10882 ast_verbose("Using latest REGISTER request as basis request\n"); 10883 copy_request(&p->initreq, req); 10884 check_via(p, req); 10885 if ((res = register_verify(p, sin, req, e, ignore)) < 0) 10886 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")); 10887 if (res < 1) { 10888 /* Destroy the session, but keep us around for just a bit in case they don't 10889 get our 200 OK */ 10890 sip_scheddestroy(p, 15*1000); 10891 } 10892 return res; 10893 }
|
|
handle_request_subscribe: Handle incoming SUBSCRIBE request ---
Definition at line 10674 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(). 10675 { 10676 int gotdest; 10677 int res = 0; 10678 int firststate = AST_EXTENSION_REMOVED; 10679 10680 if (p->initreq.headers) { 10681 /* We already have a dialog */ 10682 if (p->initreq.method != SIP_SUBSCRIBE) { 10683 /* This is a SUBSCRIBE within another SIP dialog, which we do not support */ 10684 /* For transfers, this could happen, but since we haven't seen it happening, let us just refuse this */ 10685 transmit_response(p, "403 Forbidden (within dialog)", req); 10686 /* Do not destroy session, since we will break the call if we do */ 10687 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); 10688 return 0; 10689 } else { 10690 if (debug) 10691 ast_log(LOG_DEBUG, "Got a re-subscribe on existing subscription %s\n", p->callid); 10692 } 10693 } 10694 if (!ignore && !p->initreq.headers) { 10695 /* Use this as the basis */ 10696 if (debug) 10697 ast_verbose("Using latest SUBSCRIBE request as basis request\n"); 10698 /* This call is no longer outgoing if it ever was */ 10699 ast_clear_flag(p, SIP_OUTGOING); 10700 copy_request(&p->initreq, req); 10701 check_via(p, req); 10702 } else if (debug && ignore) 10703 ast_verbose("Ignoring this SUBSCRIBE request\n"); 10704 10705 if (!p->lastinvite) { 10706 char mailboxbuf[256]=""; 10707 int found = 0; 10708 char *mailbox = NULL; 10709 int mailboxsize = 0; 10710 char *eventparam; 10711 10712 char *event = get_header(req, "Event"); /* Get Event package name */ 10713 char *accept = get_header(req, "Accept"); 10714 10715 /* Find parameters to Event: header value and remove them for now */ 10716 eventparam = strchr(event, ';'); 10717 if (eventparam) { 10718 *eventparam = '\0'; 10719 eventparam++; 10720 } 10721 10722 if (!strcmp(event, "message-summary") && !strcmp(accept, "application/simple-message-summary")) { 10723 mailbox = mailboxbuf; 10724 mailboxsize = sizeof(mailboxbuf); 10725 } 10726 /* Handle authentication if this is our first subscribe */ 10727 res = check_user_full(p, req, SIP_SUBSCRIBE, e, 0, sin, ignore, mailbox, mailboxsize); 10728 if (res) { 10729 if (res < 0) { 10730 ast_log(LOG_NOTICE, "Failed to authenticate user %s for SUBSCRIBE\n", get_header(req, "From")); 10731 ast_set_flag(p, SIP_NEEDDESTROY); 10732 } 10733 return 0; 10734 } 10735 /* Initialize the context if it hasn't been already */ 10736 if (!ast_strlen_zero(p->subscribecontext)) 10737 ast_copy_string(p->context, p->subscribecontext, sizeof(p->context)); 10738 else if (ast_strlen_zero(p->context)) 10739 strcpy(p->context, default_context); 10740 /* Get destination right away */ 10741 gotdest = get_destination(p, NULL); 10742 build_contact(p); 10743 if (gotdest) { 10744 if (gotdest < 0) 10745 transmit_response(p, "404 Not Found", req); 10746 else 10747 transmit_response(p, "484 Address Incomplete", req); /* Overlap dialing on SUBSCRIBE?? */ 10748 ast_set_flag(p, SIP_NEEDDESTROY); 10749 } else { 10750 10751 /* Initialize tag for new subscriptions */ 10752 if (ast_strlen_zero(p->tag)) 10753 make_our_tag(p->tag, sizeof(p->tag)); 10754 10755 if (!strcmp(event, "presence") || !strcmp(event, "dialog")) { /* Presence, RFC 3842 */ 10756 10757 /* Header from Xten Eye-beam Accept: multipart/related, application/rlmi+xml, application/pidf+xml, application/xpidf+xml */ 10758 if (strstr(accept, "application/pidf+xml")) { 10759 p->subscribed = PIDF_XML; /* RFC 3863 format */ 10760 } else if (strstr(accept, "application/dialog-info+xml")) { 10761 p->subscribed = DIALOG_INFO_XML; 10762 /* IETF draft: draft-ietf-sipping-dialog-package-05.txt */ 10763 } else if (strstr(accept, "application/cpim-pidf+xml")) { 10764 p->subscribed = CPIM_PIDF_XML; /* RFC 3863 format */ 10765 } else if (strstr(accept, "application/xpidf+xml")) { 10766 p->subscribed = XPIDF_XML; /* Early pre-RFC 3863 format with MSN additions (Microsoft Messenger) */ 10767 } else if (strstr(p->useragent, "Polycom")) { 10768 p->subscribed = XPIDF_XML; /* Polycoms subscribe for "event: dialog" but don't include an "accept:" header */ 10769 } else { 10770 /* Can't find a format for events that we know about */ 10771 transmit_response(p, "489 Bad Event", req); 10772 ast_set_flag(p, SIP_NEEDDESTROY); 10773 return 0; 10774 } 10775 } else if (!strcmp(event, "message-summary") && !strcmp(accept, "application/simple-message-summary")) { 10776 /* Looks like they actually want a mailbox status */ 10777 10778 /* At this point, we should check if they subscribe to a mailbox that 10779 has the same extension as the peer or the mailbox id. If we configure 10780 the context to be the same as a SIP domain, we could check mailbox 10781 context as well. To be able to securely accept subscribes on mailbox 10782 IDs, not extensions, we need to check the digest auth user to make 10783 sure that the user has access to the mailbox. 10784 10785 Since we do not act on this subscribe anyway, we might as well 10786 accept any authenticated peer with a mailbox definition in their 10787 config section. 10788 10789 */ 10790 if (!ast_strlen_zero(mailbox)) { 10791 found++; 10792 } 10793 10794 if (found){ 10795 transmit_response(p, "200 OK", req); 10796 ast_set_flag(p, SIP_NEEDDESTROY); 10797 } else { 10798 transmit_response(p, "404 Not found", req); 10799 ast_set_flag(p, SIP_NEEDDESTROY); 10800 } 10801 return 0; 10802 } else { /* At this point, Asterisk does not understand the specified event */ 10803 transmit_response(p, "489 Bad Event", req); 10804 if (option_debug > 1) 10805 ast_log(LOG_DEBUG, "Received SIP subscribe for unknown event package: %s\n", event); 10806 ast_set_flag(p, SIP_NEEDDESTROY); 10807 return 0; 10808 } 10809 if (p->subscribed != NONE) 10810 p->stateid = ast_extension_state_add(p->context, p->exten, cb_extensionstate, p); 10811 } 10812 } 10813 10814 if (!ignore && p) 10815 p->lastinvite = seqno; 10816 if (p && !ast_test_flag(p, SIP_NEEDDESTROY)) { 10817 p->expiry = atoi(get_header(req, "Expires")); 10818 10819 /* The next 4 lines can be removed if the SNOM Expires bug is fixed */ 10820 if (p->subscribed == DIALOG_INFO_XML) { 10821 if (p->expiry > max_expiry) 10822 p->expiry = max_expiry; 10823 } 10824 if (sipdebug || option_debug > 1) 10825 ast_log(LOG_DEBUG, "Adding subscription for extension %s context %s for peer %s\n", p->exten, p->context, p->username); 10826 if (p->autokillid > -1) 10827 sip_cancel_destroy(p); /* Remove subscription expiry for renewals */ 10828 sip_scheddestroy(p, (p->expiry + 10) * 1000); /* Set timer for destruction of call at expiration */ 10829 10830 if ((firststate = ast_extension_state(NULL, p->context, p->exten)) < 0) { 10831 ast_log(LOG_ERROR, "Got SUBSCRIBE for extensions without hint. Please add hint to %s in context %s\n", p->exten, p->context); 10832 transmit_response(p, "404 Not found", req); 10833 ast_set_flag(p, SIP_NEEDDESTROY); 10834 return 0; 10835 } else { 10836 struct sip_pvt *p_old; 10837 10838 transmit_response(p, "200 OK", req); 10839 transmit_state_notify(p, firststate, 1, 1); /* Send first notification */ 10840 append_history(p, "Subscribestatus", ast_extension_state2str(firststate)); 10841 10842 /* remove any old subscription from this peer for the same exten/context, 10843 as the peer has obviously forgotten about it and it's wasteful to wait 10844 for it to expire and send NOTIFY messages to the peer only to have them 10845 ignored (or generate errors) 10846 */ 10847 ast_mutex_lock(&iflock); 10848 for (p_old = iflist; p_old; p_old = p_old->next) { 10849 if (p_old == p) 10850 continue; 10851 if (p_old->initreq.method != SIP_SUBSCRIBE) 10852 continue; 10853 if (p_old->subscribed == NONE) 10854 continue; 10855 ast_mutex_lock(&p_old->lock); 10856 if (!strcmp(p_old->username, p->username)) { 10857 if (!strcmp(p_old->exten, p->exten) && 10858 !strcmp(p_old->context, p->context)) { 10859 ast_set_flag(p_old, SIP_NEEDDESTROY); 10860 ast_mutex_unlock(&p_old->lock); 10861 break; 10862 } 10863 } 10864 ast_mutex_unlock(&p_old->lock); 10865 } 10866 ast_mutex_unlock(&iflock); 10867 } 10868 if (!p->expiry) 10869 ast_set_flag(p, SIP_NEEDDESTROY); 10870 } 10871 return 1; 10872 }
|
|
handle_response: Handle SIP response in dialogue ---
Definition at line 9761 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. 09762 { 09763 char *msg, *c; 09764 struct ast_channel *owner; 09765 char iabuf[INET_ADDRSTRLEN]; 09766 int sipmethod; 09767 int res = 1; 09768 09769 c = get_header(req, "Cseq"); 09770 msg = strchr(c, ' '); 09771 if (!msg) 09772 msg = ""; 09773 else 09774 msg++; 09775 sipmethod = find_sip_method(msg); 09776 09777 owner = p->owner; 09778 if (owner) 09779 owner->hangupcause = hangup_sip2cause(resp); 09780 09781 /* Acknowledge whatever it is destined for */ 09782 if ((resp >= 100) && (resp <= 199)) 09783 __sip_semi_ack(p, seqno, 0, sipmethod); 09784 else 09785 __sip_ack(p, seqno, 0, sipmethod); 09786 09787 /* Get their tag if we haven't already */ 09788 if (ast_strlen_zero(p->theirtag) || (resp >= 200)) { 09789 gettag(req, "To", p->theirtag, sizeof(p->theirtag)); 09790 } 09791 if (p->peerpoke) { 09792 /* We don't really care what the response is, just that it replied back. 09793 Well, as long as it's not a 100 response... since we might 09794 need to hang around for something more "definitive" */ 09795 09796 res = handle_response_peerpoke(p, resp, rest, req, ignore, seqno, sipmethod); 09797 } else if (ast_test_flag(p, SIP_OUTGOING)) { 09798 /* Acknowledge sequence number */ 09799 if (p->initid > -1) { 09800 /* Don't auto congest anymore since we've gotten something useful back */ 09801 ast_sched_del(sched, p->initid); 09802 p->initid = -1; 09803 } 09804 switch(resp) { 09805 case 100: /* 100 Trying */ 09806 if (sipmethod == SIP_INVITE) 09807 handle_response_invite(p, resp, rest, req, ignore, seqno); 09808 break; 09809 case 183: /* 183 Session Progress */ 09810 if (sipmethod == SIP_INVITE) 09811 handle_response_invite(p, resp, rest, req, ignore, seqno); 09812 break; 09813 case 180: /* 180 Ringing */ 09814 if (sipmethod == SIP_INVITE) 09815 handle_response_invite(p, resp, rest, req, ignore, seqno); 09816 break; 09817 case 200: /* 200 OK */ 09818 p->authtries = 0; /* Reset authentication counter */ 09819 if (sipmethod == SIP_MESSAGE) { 09820 /* We successfully transmitted a message */ 09821 ast_set_flag(p, SIP_NEEDDESTROY); 09822 } else if (sipmethod == SIP_NOTIFY) { 09823 /* They got the notify, this is the end */ 09824 if (p->owner) { 09825 ast_log(LOG_WARNING, "Notify answer on an owned channel?\n"); 09826 ast_queue_hangup(p->owner); 09827 } else { 09828 if (p->subscribed == NONE) { 09829 ast_set_flag(p, SIP_NEEDDESTROY); 09830 } 09831 } 09832 } else if (sipmethod == SIP_INVITE) { 09833 handle_response_invite(p, resp, rest, req, ignore, seqno); 09834 } else if (sipmethod == SIP_REGISTER) { 09835 res = handle_response_register(p, resp, rest, req, ignore, seqno); 09836 } 09837 break; 09838 case 401: /* Not www-authorized on SIP method */ 09839 if (sipmethod == SIP_INVITE) { 09840 handle_response_invite(p, resp, rest, req, ignore, seqno); 09841 } else if (p->registry && sipmethod == SIP_REGISTER) { 09842 res = handle_response_register(p, resp, rest, req, ignore, seqno); 09843 } else { 09844 ast_log(LOG_WARNING, "Got authentication request (401) on unknown %s to '%s'\n", sip_methods[sipmethod].text, get_header(req, "To")); 09845 ast_set_flag(p, SIP_NEEDDESTROY); 09846 } 09847 break; 09848 case 403: /* Forbidden - we failed authentication */ 09849 if (sipmethod == SIP_INVITE) { 09850 handle_response_invite(p, resp, rest, req, ignore, seqno); 09851 } else if (p->registry && sipmethod == SIP_REGISTER) { 09852 res = handle_response_register(p, resp, rest, req, ignore, seqno); 09853 } else { 09854 ast_log(LOG_WARNING, "Forbidden - wrong password on authentication for %s\n", msg); 09855 } 09856 break; 09857 case 404: /* Not found */ 09858 if (p->registry && sipmethod == SIP_REGISTER) { 09859 res = handle_response_register(p, resp, rest, req, ignore, seqno); 09860 } else if (sipmethod == SIP_INVITE) { 09861 handle_response_invite(p, resp, rest, req, ignore, seqno); 09862 } else if (owner) 09863 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 09864 break; 09865 case 407: /* Proxy auth required */ 09866 if (sipmethod == SIP_INVITE) { 09867 handle_response_invite(p, resp, rest, req, ignore, seqno); 09868 } else if (sipmethod == SIP_BYE || sipmethod == SIP_REFER) { 09869 if (ast_strlen_zero(p->authname)) 09870 ast_log(LOG_WARNING, "Asked to authenticate %s, to %s:%d but we have no matching peer!\n", 09871 msg, ast_inet_ntoa(iabuf, sizeof(iabuf), p->recv.sin_addr), ntohs(p->recv.sin_port)); 09872 ast_set_flag(p, SIP_NEEDDESTROY); 09873 if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, "Proxy-Authenticate", "Proxy-Authorization", sipmethod, 0)) { 09874 ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From")); 09875 ast_set_flag(p, SIP_NEEDDESTROY); 09876 } 09877 } else if (p->registry && sipmethod == SIP_REGISTER) { 09878 res = handle_response_register(p, resp, rest, req, ignore, seqno); 09879 } else /* We can't handle this, giving up in a bad way */ 09880 ast_set_flag(p, SIP_NEEDDESTROY); 09881 09882 break; 09883 case 491: /* Pending */ 09884 if (sipmethod == SIP_INVITE) { 09885 handle_response_invite(p, resp, rest, req, ignore, seqno); 09886 } 09887 case 501: /* Not Implemented */ 09888 if (sipmethod == SIP_INVITE) { 09889 handle_response_invite(p, resp, rest, req, ignore, seqno); 09890 } else 09891 ast_log(LOG_WARNING, "Host '%s' does not implement '%s'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr), msg); 09892 break; 09893 default: 09894 if ((resp >= 300) && (resp < 700)) { 09895 if ((option_verbose > 2) && (resp != 487)) 09896 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)); 09897 ast_set_flag(p, SIP_ALREADYGONE); 09898 if (p->rtp) { 09899 /* Immediately stop RTP */ 09900 ast_rtp_stop(p->rtp); 09901 } 09902 if (p->vrtp) { 09903 /* Immediately stop VRTP */ 09904 ast_rtp_stop(p->vrtp); 09905 } 09906 /* XXX Locking issues?? XXX */ 09907 switch(resp) { 09908 case 300: /* Multiple Choices */ 09909 case 301: /* Moved permenantly */ 09910 case 302: /* Moved temporarily */ 09911 case 305: /* Use Proxy */ 09912 parse_moved_contact(p, req); 09913 /* Fall through */ 09914 case 486: /* Busy here */ 09915 case 600: /* Busy everywhere */ 09916 case 603: /* Decline */ 09917 if (p->owner) 09918 ast_queue_control(p->owner, AST_CONTROL_BUSY); 09919 break; 09920 case 487: 09921 /* channel now destroyed - dec the inUse counter */ 09922 update_call_counter(p, DEC_CALL_LIMIT); 09923 break; 09924 case 482: /* SIP is incapable of performing a hairpin call, which 09925 is yet another failure of not having a layer 2 (again, YAY 09926 IETF for thinking ahead). So we treat this as a call 09927 forward and hope we end up at the right place... */ 09928 ast_log(LOG_DEBUG, "Hairpin detected, setting up call forward for what it's worth\n"); 09929 if (p->owner) 09930 snprintf(p->owner->call_forward, sizeof(p->owner->call_forward), "Local/%s@%s", p->username, p->context); 09931 /* Fall through */ 09932 case 488: /* Not acceptable here - codec error */ 09933 case 480: /* Temporarily Unavailable */ 09934 case 404: /* Not Found */ 09935 case 410: /* Gone */ 09936 case 400: /* Bad Request */ 09937 case 500: /* Server error */ 09938 case 503: /* Service Unavailable */ 09939 if (owner) 09940 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 09941 break; 09942 default: 09943 /* Send hangup */ 09944 if (owner) 09945 ast_queue_hangup(p->owner); 09946 break; 09947 } 09948 /* ACK on invite */ 09949 if (sipmethod == SIP_INVITE) 09950 transmit_request(p, SIP_ACK, seqno, 0, 0); 09951 ast_set_flag(p, SIP_ALREADYGONE); 09952 if (!p->owner) 09953 ast_set_flag(p, SIP_NEEDDESTROY); 09954 } else if ((resp >= 100) && (resp < 200)) { 09955 if (sipmethod == SIP_INVITE) { 09956 sip_cancel_destroy(p); 09957 if (!ast_strlen_zero(get_header(req, "Content-Type"))) 09958 process_sdp(p, req); 09959 if (p->owner) { 09960 /* Queue a progress frame */ 09961 ast_queue_control(p->owner, AST_CONTROL_PROGRESS); 09962 } 09963 } 09964 } else 09965 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)); 09966 } 09967 } else { 09968 /* Responses to OUTGOING SIP requests on INCOMING calls 09969 get handled here. As well as out-of-call message responses */ 09970 if (req->debug) 09971 ast_verbose("SIP Response message for INCOMING dialog %s arrived\n", msg); 09972 if (resp == 200) { 09973 /* Tags in early session is replaced by the tag in 200 OK, which is 09974 the final reply to our INVITE */ 09975 gettag(req, "To", p->theirtag, sizeof(p->theirtag)); 09976 } 09977 09978 switch(resp) { 09979 case 200: 09980 if (sipmethod == SIP_INVITE) { 09981 handle_response_invite(p, resp, rest, req, ignore, seqno); 09982 } else if (sipmethod == SIP_CANCEL) { 09983 ast_log(LOG_DEBUG, "Got 200 OK on CANCEL\n"); 09984 } else if (sipmethod == SIP_MESSAGE) 09985 /* We successfully transmitted a message */ 09986 ast_set_flag(p, SIP_NEEDDESTROY); 09987 break; 09988 case 401: /* www-auth */ 09989 case 407: 09990 if (sipmethod == SIP_BYE || sipmethod == SIP_REFER) { 09991 char *auth, *auth2; 09992 09993 if (resp == 407) { 09994 auth = "Proxy-Authenticate"; 09995 auth2 = "Proxy-Authorization"; 09996 } else { 09997 auth = "WWW-Authenticate"; 09998 auth2 = "Authorization"; 09999 } 10000 if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, auth, auth2, sipmethod, 0)) { 10001 ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From")); 10002 ast_set_flag(p, SIP_NEEDDESTROY); 10003 } 10004 } else if (sipmethod == SIP_INVITE) { 10005 handle_response_invite(p, resp, rest, req, ignore, seqno); 10006 } 10007 break; 10008 case 481: /* Call leg does not exist */ 10009 if (sipmethod == SIP_INVITE) { 10010 /* Re-invite failed */ 10011 handle_response_invite(p, resp, rest, req, ignore, seqno); 10012 } 10013 break; 10014 default: /* Errors without handlers */ 10015 if ((resp >= 100) && (resp < 200)) { 10016 if (sipmethod == SIP_INVITE) { /* re-invite */ 10017 sip_cancel_destroy(p); 10018 } 10019 } 10020 if ((resp >= 300) && (resp < 700)) { 10021 if ((option_verbose > 2) && (resp != 487)) 10022 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)); 10023 switch(resp) { 10024 case 488: /* Not acceptable here - codec error */ 10025 case 603: /* Decline */ 10026 case 500: /* Server error */ 10027 case 503: /* Service Unavailable */ 10028 10029 if (sipmethod == SIP_INVITE) { /* re-invite failed */ 10030 sip_cancel_destroy(p); 10031 } 10032 break; 10033 } 10034 } 10035 break; 10036 } 10037 } 10038 }
|
|
handle_response_invite: Handle SIP response in dialogue ---
Definition at line 9450 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(). 09451 { 09452 int outgoing = ast_test_flag(p, SIP_OUTGOING); 09453 09454 if (option_debug > 3) { 09455 int reinvite = (p->owner && p->owner->_state == AST_STATE_UP); 09456 if (reinvite) 09457 ast_log(LOG_DEBUG, "SIP response %d to RE-invite on %s call %s\n", resp, outgoing ? "outgoing" : "incoming", p->callid); 09458 else 09459 ast_log(LOG_DEBUG, "SIP response %d to standard invite\n", resp); 09460 } 09461 09462 if (ast_test_flag(p, SIP_ALREADYGONE)) { /* This call is already gone */ 09463 ast_log(LOG_DEBUG, "Got response on call that is already terminated: %s (ignoring)\n", p->callid); 09464 return; 09465 } 09466 09467 switch (resp) { 09468 case 100: /* Trying */ 09469 sip_cancel_destroy(p); 09470 break; 09471 case 180: /* 180 Ringing */ 09472 sip_cancel_destroy(p); 09473 if (!ignore && p->owner) { 09474 ast_queue_control(p->owner, AST_CONTROL_RINGING); 09475 if (p->owner->_state != AST_STATE_UP) 09476 ast_setstate(p->owner, AST_STATE_RINGING); 09477 } 09478 if (!strcasecmp(get_header(req, "Content-Type"), "application/sdp")) { 09479 process_sdp(p, req); 09480 if (!ignore && p->owner) { 09481 /* Queue a progress frame only if we have SDP in 180 */ 09482 ast_queue_control(p->owner, AST_CONTROL_PROGRESS); 09483 } 09484 } 09485 break; 09486 case 183: /* Session progress */ 09487 sip_cancel_destroy(p); 09488 /* Ignore 183 Session progress without SDP */ 09489 if (!strcasecmp(get_header(req, "Content-Type"), "application/sdp")) { 09490 process_sdp(p, req); 09491 if (!ignore && p->owner) { 09492 /* Queue a progress frame */ 09493 ast_queue_control(p->owner, AST_CONTROL_PROGRESS); 09494 } 09495 } 09496 break; 09497 case 200: /* 200 OK on invite - someone's answering our call */ 09498 sip_cancel_destroy(p); 09499 p->authtries = 0; 09500 if (!strcasecmp(get_header(req, "Content-Type"), "application/sdp")) { 09501 process_sdp(p, req); 09502 } 09503 09504 /* Parse contact header for continued conversation */ 09505 /* When we get 200 OK, we know which device (and IP) to contact for this call */ 09506 /* This is important when we have a SIP proxy between us and the phone */ 09507 if (outgoing) { 09508 parse_ok_contact(p, req); 09509 09510 /* Save Record-Route for any later requests we make on this dialogue */ 09511 build_route(p, req, 1); 09512 } 09513 09514 if (!ignore && p->owner) { 09515 if (p->owner->_state != AST_STATE_UP) { 09516 #ifdef OSP_SUPPORT 09517 time(&p->ospstart); 09518 #endif 09519 ast_queue_control(p->owner, AST_CONTROL_ANSWER); 09520 } else { /* RE-invite */ 09521 struct ast_frame af = { AST_FRAME_NULL, }; 09522 ast_queue_frame(p->owner, &af); 09523 } 09524 } else { 09525 /* It's possible we're getting an ACK after we've tried to disconnect 09526 by sending CANCEL */ 09527 /* THIS NEEDS TO BE CHECKED: OEJ */ 09528 if (!ignore) 09529 ast_set_flag(p, SIP_PENDINGBYE); 09530 } 09531 /* If I understand this right, the branch is different for a non-200 ACK only */ 09532 transmit_request(p, SIP_ACK, seqno, 0, 1); 09533 check_pendings(p); 09534 break; 09535 case 407: /* Proxy authentication */ 09536 case 401: /* Www auth */ 09537 /* First we ACK */ 09538 transmit_request(p, SIP_ACK, seqno, 0, 0); 09539 if (p->options) 09540 p->options->auth_type = (resp == 401 ? WWW_AUTH : PROXY_AUTH); 09541 09542 /* Then we AUTH */ 09543 p->theirtag[0]='\0'; /* forget their old tag, so we don't match tags when getting response */ 09544 if (!ignore) { 09545 char *authenticate = (resp == 401 ? "WWW-Authenticate" : "Proxy-Authenticate"); 09546 char *authorization = (resp == 401 ? "Authorization" : "Proxy-Authorization"); 09547 if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, authenticate, authorization, SIP_INVITE, 1)) { 09548 ast_log(LOG_NOTICE, "Failed to authenticate on INVITE to '%s'\n", get_header(&p->initreq, "From")); 09549 ast_set_flag(p, SIP_NEEDDESTROY); 09550 ast_set_flag(p, SIP_ALREADYGONE); 09551 if (p->owner) 09552 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 09553 } 09554 } 09555 break; 09556 case 403: /* Forbidden */ 09557 /* First we ACK */ 09558 transmit_request(p, SIP_ACK, seqno, 0, 0); 09559 ast_log(LOG_WARNING, "Forbidden - wrong password on authentication for INVITE to '%s'\n", get_header(&p->initreq, "From")); 09560 if (!ignore && p->owner) 09561 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 09562 ast_set_flag(p, SIP_NEEDDESTROY); 09563 ast_set_flag(p, SIP_ALREADYGONE); 09564 break; 09565 case 404: /* Not found */ 09566 transmit_request(p, SIP_ACK, seqno, 0, 0); 09567 if (p->owner && !ignore) 09568 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 09569 ast_set_flag(p, SIP_ALREADYGONE); 09570 break; 09571 case 481: /* Call leg does not exist */ 09572 /* Could be REFER or INVITE */ 09573 ast_log(LOG_WARNING, "Re-invite to non-existing call leg on other UA. SIP dialog '%s'. Giving up.\n", p->callid); 09574 transmit_request(p, SIP_ACK, seqno, 0, 0); 09575 break; 09576 case 491: /* Pending */ 09577 /* we have to wait a while, then retransmit */ 09578 /* Transmission is rescheduled, so everything should be taken care of. 09579 We should support the retry-after at some point */ 09580 break; 09581 case 501: /* Not implemented */ 09582 if (p->owner) 09583 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 09584 break; 09585 } 09586 }
|
|
handle_response_peerpoke: Handle qualification responses (OPTIONS)
Definition at line 9705 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(). 09706 { 09707 struct sip_peer *peer; 09708 int pingtime; 09709 struct timeval tv; 09710 09711 if (resp != 100) { 09712 int statechanged = 0; 09713 int newstate = 0; 09714 peer = p->peerpoke; 09715 gettimeofday(&tv, NULL); 09716 pingtime = ast_tvdiff_ms(tv, peer->ps); 09717 if (pingtime < 1) 09718 pingtime = 1; 09719 if ((peer->lastms < 0) || (peer->lastms > peer->maxms)) { 09720 if (pingtime <= peer->maxms) { 09721 ast_log(LOG_NOTICE, "Peer '%s' is now REACHABLE! (%dms / %dms)\n", peer->name, pingtime, peer->maxms); 09722 statechanged = 1; 09723 newstate = 1; 09724 } 09725 } else if ((peer->lastms > 0) && (peer->lastms <= peer->maxms)) { 09726 if (pingtime > peer->maxms) { 09727 ast_log(LOG_NOTICE, "Peer '%s' is now TOO LAGGED! (%dms / %dms)\n", peer->name, pingtime, peer->maxms); 09728 statechanged = 1; 09729 newstate = 2; 09730 } 09731 } 09732 if (!peer->lastms) 09733 statechanged = 1; 09734 peer->lastms = pingtime; 09735 peer->call = NULL; 09736 if (statechanged) { 09737 ast_device_state_changed("SIP/%s", peer->name); 09738 if (newstate == 2) { 09739 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Lagged\r\nTime: %d\r\n", peer->name, pingtime); 09740 } else { 09741 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Reachable\r\nTime: %d\r\n", peer->name, pingtime); 09742 } 09743 } 09744 09745 if (peer->pokeexpire > -1) 09746 ast_sched_del(sched, peer->pokeexpire); 09747 if (sipmethod == SIP_INVITE) /* Does this really happen? */ 09748 transmit_request(p, SIP_ACK, seqno, 0, 0); 09749 ast_set_flag(p, SIP_NEEDDESTROY); 09750 09751 /* Try again eventually */ 09752 if ((peer->lastms < 0) || (peer->lastms > peer->maxms)) 09753 peer->pokeexpire = ast_sched_add(sched, DEFAULT_FREQ_NOTOK, sip_poke_peer_s, peer); 09754 else 09755 peer->pokeexpire = ast_sched_add(sched, DEFAULT_FREQ_OK, sip_poke_peer_s, peer); 09756 } 09757 return 1; 09758 }
|
|
handle_response_register: Handle responses on REGISTER to services ---
Definition at line 9589 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(). 09590 { 09591 int expires, expires_ms; 09592 struct sip_registry *r; 09593 r=p->registry; 09594 09595 switch (resp) { 09596 case 401: /* Unauthorized */ 09597 if ((p->authtries == MAX_AUTHTRIES) || do_register_auth(p, req, "WWW-Authenticate", "Authorization")) { 09598 ast_log(LOG_NOTICE, "Failed to authenticate on REGISTER to '%s@%s' (Tries %d)\n", p->registry->username, p->registry->hostname, p->authtries); 09599 ast_set_flag(p, SIP_NEEDDESTROY); 09600 } 09601 break; 09602 case 403: /* Forbidden */ 09603 ast_log(LOG_WARNING, "Forbidden - wrong password on authentication for REGISTER for '%s' to '%s'\n", p->registry->username, p->registry->hostname); 09604 if (global_regattempts_max) 09605 p->registry->regattempts = global_regattempts_max+1; 09606 ast_sched_del(sched, r->timeout); 09607 ast_set_flag(p, SIP_NEEDDESTROY); 09608 break; 09609 case 404: /* Not found */ 09610 ast_log(LOG_WARNING, "Got 404 Not found on SIP register to service %s@%s, giving up\n", p->registry->username,p->registry->hostname); 09611 if (global_regattempts_max) 09612 p->registry->regattempts = global_regattempts_max+1; 09613 ast_set_flag(p, SIP_NEEDDESTROY); 09614 r->call = NULL; 09615 ast_sched_del(sched, r->timeout); 09616 break; 09617 case 407: /* Proxy auth */ 09618 if ((p->authtries == MAX_AUTHTRIES) || do_register_auth(p, req, "Proxy-Authenticate", "Proxy-Authorization")) { 09619 ast_log(LOG_NOTICE, "Failed to authenticate on REGISTER to '%s' (tries '%d')\n", get_header(&p->initreq, "From"), p->authtries); 09620 ast_set_flag(p, SIP_NEEDDESTROY); 09621 } 09622 break; 09623 case 479: /* SER: Not able to process the URI - address is wrong in register*/ 09624 ast_log(LOG_WARNING, "Got error 479 on register to %s@%s, giving up (check config)\n", p->registry->username,p->registry->hostname); 09625 if (global_regattempts_max) 09626 p->registry->regattempts = global_regattempts_max+1; 09627 ast_set_flag(p, SIP_NEEDDESTROY); 09628 r->call = NULL; 09629 ast_sched_del(sched, r->timeout); 09630 break; 09631 case 200: /* 200 OK */ 09632 if (!r) { 09633 ast_log(LOG_WARNING, "Got 200 OK on REGISTER that isn't a register\n"); 09634 ast_set_flag(p, SIP_NEEDDESTROY); 09635 return 0; 09636 } 09637 09638 r->regstate=REG_STATE_REGISTERED; 09639 manager_event(EVENT_FLAG_SYSTEM, "Registry", "Channel: SIP\r\nDomain: %s\r\nStatus: %s\r\n", r->hostname, regstate2str(r->regstate)); 09640 r->regattempts = 0; 09641 ast_log(LOG_DEBUG, "Registration successful\n"); 09642 if (r->timeout > -1) { 09643 ast_log(LOG_DEBUG, "Cancelling timeout %d\n", r->timeout); 09644 ast_sched_del(sched, r->timeout); 09645 } 09646 r->timeout=-1; 09647 r->call = NULL; 09648 p->registry = NULL; 09649 /* Let this one hang around until we have all the responses */ 09650 sip_scheddestroy(p, 32000); 09651 /* ast_set_flag(p, SIP_NEEDDESTROY); */ 09652 09653 /* set us up for re-registering */ 09654 /* figure out how long we got registered for */ 09655 if (r->expire > -1) 09656 ast_sched_del(sched, r->expire); 09657 /* according to section 6.13 of RFC, contact headers override 09658 expires headers, so check those first */ 09659 expires = 0; 09660 if (!ast_strlen_zero(get_header(req, "Contact"))) { 09661 char *contact = NULL; 09662 char *tmptmp = NULL; 09663 int start = 0; 09664 for(;;) { 09665 contact = __get_header(req, "Contact", &start); 09666 /* this loop ensures we get a contact header about our register request */ 09667 if(!ast_strlen_zero(contact)) { 09668 if( (tmptmp=strstr(contact, p->our_contact))) { 09669 contact=tmptmp; 09670 break; 09671 } 09672 } else 09673 break; 09674 } 09675 tmptmp = strcasestr(contact, "expires="); 09676 if (tmptmp) { 09677 if (sscanf(tmptmp + 8, "%d;", &expires) != 1) 09678 expires = 0; 09679 } 09680 09681 } 09682 if (!expires) 09683 expires=atoi(get_header(req, "expires")); 09684 if (!expires) 09685 expires=default_expiry; 09686 09687 expires_ms = expires * 1000; 09688 if (expires <= EXPIRY_GUARD_LIMIT) 09689 expires_ms -= MAX((expires_ms * EXPIRY_GUARD_PCT),EXPIRY_GUARD_MIN); 09690 else 09691 expires_ms -= EXPIRY_GUARD_SECS * 1000; 09692 if (sipdebug) 09693 ast_log(LOG_NOTICE, "Outbound Registration: Expiry for %s is %d sec (Scheduling reregistration in %d s)\n", r->hostname, expires, expires_ms/1000); 09694 09695 r->refresh= (int) expires_ms / 1000; 09696 09697 /* Schedule re-registration before we expire */ 09698 r->expire=ast_sched_add(sched, expires_ms, sip_reregister, r); 09699 ASTOBJ_UNREF(r, sip_registry_destroy); 09700 } 09701 return 1; 09702 }
|
|
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 3965 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. 03966 { 03967 /* Initialize a response */ 03968 if (req->headers || req->len) { 03969 ast_log(LOG_WARNING, "Request already initialized?!?\n"); 03970 return -1; 03971 } 03972 req->header[req->headers] = req->data + req->len; 03973 snprintf(req->header[req->headers], sizeof(req->data) - req->len, "%s %s SIP/2.0\r\n", sip_methods[sipmethod].text, recip); 03974 req->len += strlen(req->header[req->headers]); 03975 req->headers++; 03976 req->method = sipmethod; 03977 return 0; 03978 }
|
|
init_resp: Initialize SIP response, based on SIP request ---
Definition at line 3949 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. 03950 { 03951 /* Initialize a response */ 03952 if (req->headers || req->len) { 03953 ast_log(LOG_WARNING, "Request already initialized?!?\n"); 03954 return -1; 03955 } 03956 req->method = SIP_RESPONSE; 03957 req->header[req->headers] = req->data + req->len; 03958 snprintf(req->header[req->headers], sizeof(req->data) - req->len, "SIP/2.0 %s\r\n", resp); 03959 req->len += strlen(req->header[req->headers]); 03960 req->headers++; 03961 return 0; 03962 }
|
|
initreqprep: Initiate new SIP request to peer/user ---
Definition at line 4723 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(). 04724 { 04725 char invite_buf[256] = ""; 04726 char *invite = invite_buf; 04727 size_t invite_max = sizeof(invite_buf); 04728 char from[256]; 04729 char to[256]; 04730 char tmp[BUFSIZ/2]; 04731 char tmp2[BUFSIZ/2]; 04732 char iabuf[INET_ADDRSTRLEN]; 04733 char *l = NULL, *n = NULL; 04734 int x; 04735 char urioptions[256]=""; 04736 04737 if (ast_test_flag(p, SIP_USEREQPHONE)) { 04738 char onlydigits = 1; 04739 x=0; 04740 04741 /* Test p->username against allowed characters in AST_DIGIT_ANY 04742 If it matches the allowed characters list, then sipuser = ";user=phone" 04743 If not, then sipuser = "" 04744 */ 04745 /* + is allowed in first position in a tel: uri */ 04746 if (p->username && p->username[0] == '+') 04747 x=1; 04748 04749 for (; x < strlen(p->username); x++) { 04750 if (!strchr(AST_DIGIT_ANYNUM, p->username[x])) { 04751 onlydigits = 0; 04752 break; 04753 } 04754 } 04755 04756 /* If we have only digits, add ;user=phone to the uri */ 04757 if (onlydigits) 04758 strcpy(urioptions, ";user=phone"); 04759 } 04760 04761 04762 snprintf(p->lastmsg, sizeof(p->lastmsg), "Init: %s", sip_methods[sipmethod].text); 04763 04764 if (p->owner) { 04765 l = p->owner->cid.cid_num; 04766 n = p->owner->cid.cid_name; 04767 } 04768 /* if we are not sending RPID and user wants his callerid restricted */ 04769 if (!ast_test_flag(p, SIP_SENDRPID) && ((p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED)) { 04770 l = CALLERID_UNKNOWN; 04771 n = l; 04772 } 04773 if (!l) 04774 l = default_callerid; 04775 if (ast_strlen_zero(n)) 04776 n = l; 04777 /* Allow user to be overridden */ 04778 if (!ast_strlen_zero(p->fromuser)) 04779 l = p->fromuser; 04780 else /* Save for any further attempts */ 04781 ast_copy_string(p->fromuser, l, sizeof(p->fromuser)); 04782 04783 /* Allow user to be overridden */ 04784 if (!ast_strlen_zero(p->fromname)) 04785 n = p->fromname; 04786 else /* Save for any further attempts */ 04787 ast_copy_string(p->fromname, n, sizeof(p->fromname)); 04788 04789 if (pedanticsipchecking) { 04790 ast_uri_encode(n, tmp, sizeof(tmp), 0); 04791 n = tmp; 04792 ast_uri_encode(l, tmp2, sizeof(tmp2), 0); 04793 l = tmp2; 04794 } 04795 04796 if ((ourport != 5060) && ast_strlen_zero(p->fromdomain)) /* Needs to be 5060 */ 04797 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); 04798 else 04799 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); 04800 04801 /* If we're calling a registered SIP peer, use the fullcontact to dial to the peer */ 04802 if (!ast_strlen_zero(p->fullcontact)) { 04803 /* If we have full contact, trust it */ 04804 ast_build_string(&invite, &invite_max, "%s", p->fullcontact); 04805 } else { 04806 /* Otherwise, use the username while waiting for registration */ 04807 ast_build_string(&invite, &invite_max, "sip:"); 04808 if (!ast_strlen_zero(p->username)) { 04809 n = p->username; 04810 if (pedanticsipchecking) { 04811 ast_uri_encode(n, tmp, sizeof(tmp), 0); 04812 n = tmp; 04813 } 04814 ast_build_string(&invite, &invite_max, "%s@", n); 04815 } 04816 ast_build_string(&invite, &invite_max, "%s", p->tohost); 04817 if (ntohs(p->sa.sin_port) != 5060) /* Needs to be 5060 */ 04818 ast_build_string(&invite, &invite_max, ":%d", ntohs(p->sa.sin_port)); 04819 ast_build_string(&invite, &invite_max, "%s", urioptions); 04820 } 04821 04822 /* If custom URI options have been provided, append them */ 04823 if (p->options && p->options->uri_options) 04824 ast_build_string(&invite, &invite_max, ";%s", p->options->uri_options); 04825 04826 ast_copy_string(p->uri, invite_buf, sizeof(p->uri)); 04827 04828 if (sipmethod == SIP_NOTIFY && !ast_strlen_zero(p->theirtag)) { 04829 /* If this is a NOTIFY, use the From: tag in the subscribe (RFC 3265) */ 04830 snprintf(to, sizeof(to), "<sip:%s>;tag=%s", p->uri, p->theirtag); 04831 } else if (p->options && p->options->vxml_url) { 04832 /* If there is a VXML URL append it to the SIP URL */ 04833 snprintf(to, sizeof(to), "<%s>;%s", p->uri, p->options->vxml_url); 04834 } else { 04835 snprintf(to, sizeof(to), "<%s>", p->uri); 04836 } 04837 04838 memset(req, 0, sizeof(struct sip_request)); 04839 init_req(req, sipmethod, p->uri); 04840 snprintf(tmp, sizeof(tmp), "%d %s", ++p->ocseq, sip_methods[sipmethod].text); 04841 04842 add_header(req, "Via", p->via); 04843 /* SLD: FIXME?: do Route: here too? I think not cos this is the first request. 04844 * OTOH, then we won't have anything in p->route anyway */ 04845 /* Build Remote Party-ID and From */ 04846 if (ast_test_flag(p, SIP_SENDRPID) && (sipmethod == SIP_INVITE)) { 04847 build_rpid(p); 04848 add_header(req, "From", p->rpid_from); 04849 } else { 04850 add_header(req, "From", from); 04851 } 04852 add_header(req, "To", to); 04853 ast_copy_string(p->exten, l, sizeof(p->exten)); 04854 build_contact(p); 04855 add_header(req, "Contact", p->our_contact); 04856 add_header(req, "Call-ID", p->callid); 04857 add_header(req, "CSeq", tmp); 04858 add_header(req, "User-Agent", default_useragent); 04859 add_header(req, "Max-Forwards", DEFAULT_MAX_FORWARDS); 04860 if (p->rpid) 04861 add_header(req, "Remote-Party-ID", p->rpid); 04862 }
|
|
insecure2str: Convert Insecure setting to printable string ---
Definition at line 7633 of file chan_sip.c. Referenced by _sip_show_peer(). 07634 { 07635 if (port && invite) 07636 return "port,invite"; 07637 else if (port) 07638 return "port"; 07639 else if (invite) 07640 return "invite"; 07641 else 07642 return "no"; 07643 }
|
|
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 13274 of file chan_sip.c. References ASTERISK_GPL_KEY. 13275 { 13276 return ASTERISK_GPL_KEY; 13277 }
|
|
list_route: List all routes - mostly for debugging ---
Definition at line 5968 of file chan_sip.c. References ast_verbose(), sip_route::hop, and sip_route::next. 05969 { 05970 if (!route) { 05971 ast_verbose("list_route: no route\n"); 05972 return; 05973 } 05974 while (route) { 05975 ast_verbose("list_route: hop: <%s>\n", route->hop); 05976 route = route->next; 05977 } 05978 }
|
|
|
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 7853 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(). 07854 { 07855 char *id = astman_get_header(m,"ActionID"); 07856 char *a[4]; 07857 char *peer; 07858 int ret; 07859 07860 peer = astman_get_header(m,"Peer"); 07861 if (ast_strlen_zero(peer)) { 07862 astman_send_error(s, m, "Peer: <name> missing.\n"); 07863 return 0; 07864 } 07865 a[0] = "sip"; 07866 a[1] = "show"; 07867 a[2] = "peer"; 07868 a[3] = peer; 07869 07870 if (!ast_strlen_zero(id)) 07871 ast_cli(s->fd, "ActionID: %s\r\n",id); 07872 ret = _sip_show_peer(1, s->fd, s, m, 4, a ); 07873 ast_cli( s->fd, "\r\n\r\n" ); 07874 return ret; 07875 }
|
|
manager_sip_show_peers: Show SIP peers in the manager API ---
Definition at line 7434 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(). 07435 { 07436 char *id = astman_get_header(m,"ActionID"); 07437 char *a[] = { "sip", "show", "peers" }; 07438 char idtext[256] = ""; 07439 int total = 0; 07440 07441 if (!ast_strlen_zero(id)) 07442 snprintf(idtext,256,"ActionID: %s\r\n",id); 07443 07444 astman_send_ack(s, m, "Peer status list will follow"); 07445 /* List the peers in separate manager events */ 07446 _sip_show_peers(s->fd, &total, s, m, 3, a); 07447 /* Send final confirmation */ 07448 ast_cli(s->fd, 07449 "Event: PeerlistComplete\r\n" 07450 "ListItems: %d\r\n" 07451 "%s" 07452 "\r\n", total, idtext); 07453 return 0; 07454 }
|
|
nat2str: Convert NAT setting to text string
Definition at line 7336 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(). 07337 { 07338 switch(nat) { 07339 case SIP_NAT_NEVER: 07340 return "No"; 07341 case SIP_NAT_ROUTE: 07342 return "Route"; 07343 case SIP_NAT_ALWAYS: 07344 return "Always"; 07345 case SIP_NAT_RFC3581: 07346 return "RFC3581"; 07347 default: 07348 return "Unknown"; 07349 } 07350 }
|
|
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 9400 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(). 09401 { 09402 char tmp[256]; 09403 char *s, *e; 09404 ast_copy_string(tmp, get_header(req, "Contact"), sizeof(tmp)); 09405 s = get_in_brackets(tmp); 09406 e = strchr(s, ';'); 09407 if (e) 09408 *e = '\0'; 09409 if (ast_test_flag(p, SIP_PROMISCREDIR)) { 09410 if (!strncasecmp(s, "sip:", 4)) 09411 s += 4; 09412 e = strchr(s, '/'); 09413 if (e) 09414 *e = '\0'; 09415 ast_log(LOG_DEBUG, "Found promiscuous redirection to 'SIP/%s'\n", s); 09416 if (p->owner) 09417 snprintf(p->owner->call_forward, sizeof(p->owner->call_forward), "SIP/%s", s); 09418 } else { 09419 e = strchr(tmp, '@'); 09420 if (e) 09421 *e = '\0'; 09422 e = strchr(tmp, '/'); 09423 if (e) 09424 *e = '\0'; 09425 if (!strncasecmp(s, "sip:", 4)) 09426 s += 4; 09427 ast_log(LOG_DEBUG, "Found 302 Redirect to extension '%s'\n", s); 09428 if (p->owner) 09429 ast_copy_string(p->owner->call_forward, s, sizeof(p->owner->call_forward)); 09430 } 09431 }
|
|
parse_ok_contact: Parse contact header for 200 OK on INVITE ---
Definition at line 5729 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(). 05730 { 05731 char contact[250]; 05732 char *c, *n, *pt; 05733 int port; 05734 struct hostent *hp; 05735 struct ast_hostent ahp; 05736 struct sockaddr_in oldsin; 05737 05738 /* Look for brackets */ 05739 ast_copy_string(contact, get_header(req, "Contact"), sizeof(contact)); 05740 c = get_in_brackets(contact); 05741 05742 /* Save full contact to call pvt for later bye or re-invite */ 05743 ast_copy_string(pvt->fullcontact, c, sizeof(pvt->fullcontact)); 05744 05745 /* Save URI for later ACKs, BYE or RE-invites */ 05746 ast_copy_string(pvt->okcontacturi, c, sizeof(pvt->okcontacturi)); 05747 05748 /* Make sure it's a SIP URL */ 05749 if (strncasecmp(c, "sip:", 4)) { 05750 ast_log(LOG_NOTICE, "'%s' is not a valid SIP contact (missing sip:) trying to use anyway\n", c); 05751 } else 05752 c += 4; 05753 05754 /* Ditch arguments */ 05755 n = strchr(c, ';'); 05756 if (n) 05757 *n = '\0'; 05758 05759 /* Grab host */ 05760 n = strchr(c, '@'); 05761 if (!n) { 05762 n = c; 05763 c = NULL; 05764 } else { 05765 *n = '\0'; 05766 n++; 05767 } 05768 pt = strchr(n, ':'); 05769 if (pt) { 05770 *pt = '\0'; 05771 pt++; 05772 port = atoi(pt); 05773 } else 05774 port = DEFAULT_SIP_PORT; 05775 05776 memcpy(&oldsin, &pvt->sa, sizeof(oldsin)); 05777 05778 if (!(ast_test_flag(pvt, SIP_NAT) & SIP_NAT_ROUTE)) { 05779 /* XXX This could block for a long time XXX */ 05780 /* We should only do this if it's a name, not an IP */ 05781 hp = ast_gethostbyname(n, &ahp); 05782 if (!hp) { 05783 ast_log(LOG_WARNING, "Invalid host '%s'\n", n); 05784 return -1; 05785 } 05786 pvt->sa.sin_family = AF_INET; 05787 memcpy(&pvt->sa.sin_addr, hp->h_addr, sizeof(pvt->sa.sin_addr)); 05788 pvt->sa.sin_port = htons(port); 05789 } else { 05790 /* Don't trust the contact field. Just use what they came to us 05791 with. */ 05792 memcpy(&pvt->sa, &pvt->recv, sizeof(pvt->sa)); 05793 } 05794 return 0; 05795 }
|
|
parse_register_contact: Parse contact header and save registration ---
Definition at line 5805 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(). 05806 { 05807 char contact[80]; 05808 char data[256]; 05809 char iabuf[INET_ADDRSTRLEN]; 05810 char *expires = get_header(req, "Expires"); 05811 int expiry = atoi(expires); 05812 char *c, *n, *pt; 05813 int port; 05814 char *useragent; 05815 struct hostent *hp; 05816 struct ast_hostent ahp; 05817 struct sockaddr_in oldsin; 05818 05819 if (ast_strlen_zero(expires)) { /* No expires header */ 05820 expires = strcasestr(get_header(req, "Contact"), ";expires="); 05821 if (expires) { 05822 char *ptr; 05823 if ((ptr = strchr(expires, ';'))) 05824 *ptr = '\0'; 05825 if (sscanf(expires + 9, "%d", &expiry) != 1) 05826 expiry = default_expiry; 05827 } else { 05828 /* Nothing has been specified */ 05829 expiry = default_expiry; 05830 } 05831 } 05832 /* Look for brackets */ 05833 ast_copy_string(contact, get_header(req, "Contact"), sizeof(contact)); 05834 if (strchr(contact, '<') == NULL) { /* No <, check for ; and strip it */ 05835 char *ptr = strchr(contact, ';'); /* This is Header options, not URI options */ 05836 if (ptr) 05837 *ptr = '\0'; 05838 } 05839 c = get_in_brackets(contact); 05840 05841 /* if they did not specify Contact: or Expires:, they are querying 05842 what we currently have stored as their contact address, so return 05843 it 05844 */ 05845 if (ast_strlen_zero(c) && ast_strlen_zero(expires)) { 05846 /* If we have an active registration, tell them when the registration is going to expire */ 05847 if ((p->expire > -1) && !ast_strlen_zero(p->fullcontact)) { 05848 pvt->expiry = ast_sched_when(sched, p->expire); 05849 } 05850 return PARSE_REGISTER_QUERY; 05851 } else if (!strcasecmp(c, "*") || !expiry) { /* Unregister this peer */ 05852 /* This means remove all registrations and return OK */ 05853 memset(&p->addr, 0, sizeof(p->addr)); 05854 if (p->expire > -1) 05855 ast_sched_del(sched, p->expire); 05856 p->expire = -1; 05857 05858 destroy_association(p); 05859 05860 register_peer_exten(p, 0); 05861 p->fullcontact[0] = '\0'; 05862 p->useragent[0] = '\0'; 05863 p->sipoptions = 0; 05864 p->lastms = 0; 05865 05866 if (option_verbose > 2) 05867 ast_verbose(VERBOSE_PREFIX_3 "Unregistered SIP '%s'\n", p->name); 05868 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unregistered\r\n", p->name); 05869 return PARSE_REGISTER_UPDATE; 05870 } 05871 ast_copy_string(p->fullcontact, c, sizeof(p->fullcontact)); 05872 /* For the 200 OK, we should use the received contact */ 05873 snprintf(pvt->our_contact, sizeof(pvt->our_contact) - 1, "<%s>", c); 05874 /* Make sure it's a SIP URL */ 05875 if (strncasecmp(c, "sip:", 4)) { 05876 ast_log(LOG_NOTICE, "'%s' is not a valid SIP contact (missing sip:) trying to use anyway\n", c); 05877 } else 05878 c += 4; 05879 /* Ditch q */ 05880 n = strchr(c, ';'); 05881 if (n) { 05882 *n = '\0'; 05883 } 05884 /* Grab host */ 05885 n = strchr(c, '@'); 05886 if (!n) { 05887 n = c; 05888 c = NULL; 05889 } else { 05890 *n = '\0'; 05891 n++; 05892 } 05893 pt = strchr(n, ':'); 05894 if (pt) { 05895 *pt = '\0'; 05896 pt++; 05897 port = atoi(pt); 05898 } else 05899 port = DEFAULT_SIP_PORT; 05900 memcpy(&oldsin, &p->addr, sizeof(oldsin)); 05901 if (!(ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE)) { 05902 /* XXX This could block for a long time XXX */ 05903 hp = ast_gethostbyname(n, &ahp); 05904 if (!hp) { 05905 ast_log(LOG_WARNING, "Invalid host '%s'\n", n); 05906 return PARSE_REGISTER_FAILED; 05907 } 05908 p->addr.sin_family = AF_INET; 05909 memcpy(&p->addr.sin_addr, hp->h_addr, sizeof(p->addr.sin_addr)); 05910 p->addr.sin_port = htons(port); 05911 } else { 05912 /* Don't trust the contact field. Just use what they came to us 05913 with */ 05914 memcpy(&p->addr, &pvt->recv, sizeof(p->addr)); 05915 } 05916 05917 if (c) /* Overwrite the default username from config at registration */ 05918 ast_copy_string(p->username, c, sizeof(p->username)); 05919 else 05920 p->username[0] = '\0'; 05921 05922 if (p->expire > -1) 05923 ast_sched_del(sched, p->expire); 05924 if ((expiry < 1) || (expiry > max_expiry)) 05925 expiry = max_expiry; 05926 if (!ast_test_flag(p, SIP_REALTIME)) 05927 p->expire = ast_sched_add(sched, (expiry + 10) * 1000, expire_register, p); 05928 else 05929 p->expire = -1; 05930 pvt->expiry = expiry; 05931 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); 05932 if (!ast_test_flag((&p->flags_page2), SIP_PAGE2_RT_FROMCONTACT)) 05933 ast_db_put("SIP/Registry", p->name, data); 05934 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Registered\r\n", p->name); 05935 if (inaddrcmp(&p->addr, &oldsin)) { 05936 sip_poke_peer(p); 05937 if (option_verbose > 2) 05938 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); 05939 register_peer_exten(p, 1); 05940 } 05941 05942 /* Save SIP options profile */ 05943 p->sipoptions = pvt->sipoptions; 05944 05945 /* Save User agent */ 05946 useragent = get_header(req, "User-Agent"); 05947 if (useragent && strcasecmp(useragent, p->useragent)) { 05948 ast_copy_string(p->useragent, useragent, sizeof(p->useragent)); 05949 if (option_verbose > 3) { 05950 ast_verbose(VERBOSE_PREFIX_3 "Saved useragent \"%s\" for peer %s\n",p->useragent,p->name); 05951 } 05952 } 05953 return PARSE_REGISTER_UPDATE; 05954 }
|
|
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 7354 of file chan_sip.c. References sip_peer::lastms, and sip_peer::maxms. 07355 { 07356 int res = 0; 07357 if (peer->maxms) { 07358 if (peer->lastms < 0) { 07359 ast_copy_string(status, "UNREACHABLE", statuslen); 07360 } else if (peer->lastms > peer->maxms) { 07361 snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms); 07362 res = 1; 07363 } else if (peer->lastms) { 07364 snprintf(status, statuslen, "OK (%d ms)", peer->lastms); 07365 res = 1; 07366 } else { 07367 ast_copy_string(status, "UNKNOWN", statuslen); 07368 } 07369 } else { 07370 ast_copy_string(status, "Unmonitored", statuslen); 07371 /* Checking if port is 0 */ 07372 res = -1; 07373 } 07374 return res; 07375 }
|
|
print_codec_to_cli: Print codec list from preference to CLI/manager
Definition at line 7793 of file chan_sip.c. References ast_cli(), ast_codec_pref_index(), and ast_getformatname(). Referenced by _sip_show_peer(), and sip_show_settings(). 07794 { 07795 int x, codec; 07796 07797 for(x = 0; x < 32 ; x++) { 07798 codec = ast_codec_pref_index(pref, x); 07799 if (!codec) 07800 break; 07801 ast_cli(fd, "%s", ast_getformatname(codec)); 07802 if (x < 31 && ast_codec_pref_index(pref, x + 1)) 07803 ast_cli(fd, ","); 07804 } 07805 if (!x) 07806 ast_cli(fd, "none"); 07807 }
|
|
print_group: Print call group and pickup group ---
Definition at line 7610 of file chan_sip.c. References ast_cli(), and ast_print_group(). Referenced by _sip_show_peer(), and sip_show_user(). 07611 { 07612 char buf[256]; 07613 ast_cli(fd, crlf ? "%s\r\n" : "%s\n", ast_print_group(buf, sizeof(buf), group) ); 07614 }
|
|
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 } 03508 } 03509 } 03510 } 03511 /* RTP addresses and ports for audio and video */ 03512 sin.sin_family = AF_INET; 03513 memcpy(&sin.sin_addr, hp->h_addr, sizeof(sin.sin_addr)); 03514 03515 /* Setup audio port number */ 03516 sin.sin_port = htons(portno); 03517 if (p->rtp && sin.sin_port) { 03518 ast_rtp_set_peer(p->rtp, &sin); 03519 if (debug) { 03520 ast_verbose("Peer audio RTP is at port %s:%d\n", ast_inet_ntoa(iabuf,sizeof(iabuf), sin.sin_addr), ntohs(sin.sin_port)); 03521 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)); 03522 } 03523 } 03524 /* Check for Media-description-level-address for video */ 03525 if (pedanticsipchecking) { 03526 c = get_sdp_iterate(&destiterator, req, "c"); 03527 if (!ast_strlen_zero(c)) { 03528 if (sscanf(c, "IN IP4 %256s", host) != 1) { 03529 ast_log(LOG_WARNING, "Invalid secondary host in c= line, '%s'\n", c); 03530 } else { 03531 /* XXX This could block for a long time, and block the main thread! XXX */ 03532 hp = ast_gethostbyname(host, &ahp); 03533 if (!hp) { 03534 ast_log(LOG_WARNING, "Unable to lookup host in secondary c= line, '%s'\n", c); 03535 } 03536 } 03537 } 03538 } 03539 /* Setup video port number */ 03540 sin.sin_port = htons(vportno); 03541 if (p->vrtp && sin.sin_port) { 03542 ast_rtp_set_peer(p->vrtp, &sin); 03543 if (debug) { 03544 ast_verbose("Peer video RTP is at port %s:%d\n", ast_inet_ntoa(iabuf,sizeof(iabuf), sin.sin_addr), ntohs(sin.sin_port)); 03545 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)); 03546 } 03547 } 03548 03549 /* Next, scan through each "a=rtpmap:" line, noting each 03550 * specified RTP payload type (with corresponding MIME subtype): 03551 */ 03552 sdpLineNum_iterator_init(&iterator); 03553 while ((a = get_sdp_iterate(&iterator, req, "a"))[0] != '\0') { 03554 char* mimeSubtype = ast_strdupa(a); /* ensures we have enough space */ 03555 if (!strcasecmp(a, "sendonly")) { 03556 sendonly=1; 03557 continue; 03558 } 03559 if (!strcasecmp(a, "sendrecv")) { 03560 sendonly=0; 03561 } 03562 if (sscanf(a, "rtpmap: %u %[^/]/", &codec, mimeSubtype) != 2) continue; 03563 if (debug) 03564 ast_verbose("Found description format %s\n", mimeSubtype); 03565 /* Note: should really look at the 'freq' and '#chans' params too */ 03566 ast_rtp_set_rtpmap_type(p->rtp, codec, "audio", mimeSubtype); 03567 if (p->vrtp) 03568 ast_rtp_set_rtpmap_type(p->vrtp, codec, "video", mimeSubtype); 03569 } 03570 03571 /* Now gather all of the codecs that were asked for: */ 03572 ast_rtp_get_current_formats(p->rtp, 03573 &peercapability, &peernoncodeccapability); 03574 if (p->vrtp) 03575 ast_rtp_get_current_formats(p->vrtp, 03576 &vpeercapability, &vpeernoncodeccapability); 03577 p->jointcapability = p->capability & (peercapability | vpeercapability); 03578 p->peercapability = (peercapability | vpeercapability); 03579 p->noncodeccapability = noncodeccapability & peernoncodeccapability; 03580 03581 if (ast_test_flag(p, SIP_DTMF) == SIP_DTMF_AUTO) { 03582 ast_clear_flag(p, SIP_DTMF); 03583 if (p->noncodeccapability & AST_RTP_DTMF) { 03584 /* XXX Would it be reasonable to drop the DSP at this point? XXX */ 03585 ast_set_flag(p, SIP_DTMF_RFC2833); 03586 } else { 03587 ast_set_flag(p, SIP_DTMF_INBAND); 03588 } 03589 } 03590 03591 if (debug) { 03592 /* shame on whoever coded this.... */ 03593 const unsigned slen=512; 03594 char s1[slen], s2[slen], s3[slen], s4[slen]; 03595 03596 ast_verbose("Capabilities: us - %s, peer - audio=%s/video=%s, combined - %s\n", 03597 ast_getformatname_multiple(s1, slen, p->capability), 03598 ast_getformatname_multiple(s2, slen, peercapability), 03599 ast_getformatname_multiple(s3, slen, vpeercapability), 03600 ast_getformatname_multiple(s4, slen, p->jointcapability)); 03601 03602 ast_verbose("Non-codec capabilities: us - %s, peer - %s, combined - %s\n", 03603 ast_rtp_lookup_mime_multiple(s1, slen, noncodeccapability, 0), 03604 ast_rtp_lookup_mime_multiple(s2, slen, peernoncodeccapability, 0), 03605 ast_rtp_lookup_mime_multiple(s3, slen, p->noncodeccapability, 0)); 03606 } 03607 if (!p->jointcapability) { 03608 ast_log(LOG_NOTICE, "No compatible codecs!\n"); 03609 return -1; 03610 } 03611 03612 if (!p->owner) /* There's no open channel owning us */ 03613 return 0; 03614 03615 if (!(p->owner->nativeformats & p->jointcapability)) { 03616 const unsigned slen=512; 03617 char s1[slen], s2[slen]; 03618 ast_log(LOG_DEBUG, "Oooh, we need to change our formats since our peer supports only %s and not %s\n", 03619 ast_getformatname_multiple(s1, slen, p->jointcapability), 03620 ast_getformatname_multiple(s2, slen, p->owner->nativeformats)); 03621 p->owner->nativeformats = ast_codec_choose(&p->prefs, p->jointcapability, 1); 03622 ast_set_read_format(p->owner, p->owner->readformat); 03623 ast_set_write_format(p->owner, p->owner->writeformat); 03624 } 03625 if ((bridgepeer=ast_bridged_channel(p->owner))) { 03626 /* We have a bridge */ 03627 /* Turn on/off music on hold if we are holding/unholding */ 03628 struct ast_frame af = { AST_FRAME_NULL, }; 03629 if (sin.sin_addr.s_addr && !sendonly) { 03630 ast_moh_stop(bridgepeer); 03631 03632 /* Activate a re-invite */ 03633 ast_queue_frame(p->owner, &af); 03634 } else { 03635 /* No address for RTP, we're on hold */ 03636 03637 ast_moh_start(bridgepeer, NULL); 03638 if (sendonly) 03639 ast_rtp_stop(p->rtp); 03640 /* Activate a re-invite */ 03641 ast_queue_frame(p->owner, &af); 03642 } 03643 } 03644 03645 /* Manager Hold and Unhold events must be generated, if necessary */ 03646 if (sin.sin_addr.s_addr && !sendonly) { 03647 append_history(p, "Unhold", req->data); 03648 03649 if (callevents && ast_test_flag(p, SIP_CALL_ONHOLD)) { 03650 manager_event(EVENT_FLAG_CALL, "Unhold", 03651 "Channel: %s\r\n" 03652 "Uniqueid: %s\r\n", 03653 p->owner->name, 03654 p->owner->uniqueid); 03655 03656 } 03657 ast_clear_flag(p, SIP_CALL_ONHOLD); 03658 } else { 03659 /* No address for RTP, we're on hold */ 03660 append_history(p, "Hold", req->data); 03661 03662 if (callevents && !ast_test_flag(p, SIP_CALL_ONHOLD)) { 03663 manager_event(EVENT_FLAG_CALL, "Hold", 03664 "Channel: %s\r\n" 03665 "Uniqueid: %s\r\n", 03666 p->owner->name, 03667 p->owner->uniqueid); 03668 } 03669 ast_set_flag(p, SIP_CALL_ONHOLD); 03670 } 03671 03672 return 0; 03673 }
|
|
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 7249 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(). 07250 { 07251 char buf[1024]; 07252 struct ast_frame f; 07253 char *content_type; 07254 07255 content_type = get_header(req, "Content-Type"); 07256 if (strcmp(content_type, "text/plain")) { /* No text/plain attachment */ 07257 transmit_response(p, "415 Unsupported Media Type", req); /* Good enough, or? */ 07258 ast_set_flag(p, SIP_NEEDDESTROY); 07259 return; 07260 } 07261 07262 if (get_msg_text(buf, sizeof(buf), req)) { 07263 ast_log(LOG_WARNING, "Unable to retrieve text from %s\n", p->callid); 07264 transmit_response(p, "202 Accepted", req); 07265 ast_set_flag(p, SIP_NEEDDESTROY); 07266 return; 07267 } 07268 07269 if (p->owner) { 07270 if (sip_debug_test_pvt(p)) 07271 ast_verbose("Message received: '%s'\n", buf); 07272 memset(&f, 0, sizeof(f)); 07273 f.frametype = AST_FRAME_TEXT; 07274 f.subclass = 0; 07275 f.offset = 0; 07276 f.data = buf; 07277 f.datalen = strlen(buf); 07278 ast_queue_frame(p->owner, &f); 07279 transmit_response(p, "202 Accepted", req); /* We respond 202 accepted, since we relay the message */ 07280 } else { /* Message outside of a call, we do not support that */ 07281 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); 07282 transmit_response(p, "405 Method Not Allowed", req); /* Good enough, or? */ 07283 } 07284 ast_set_flag(p, SIP_NEEDDESTROY); 07285 return; 07286 }
|
|
reg_source_db: Get registration details from Asterisk DB ---
Definition at line 5668 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. 05669 { 05670 char data[256]; 05671 char iabuf[INET_ADDRSTRLEN]; 05672 struct in_addr in; 05673 int expiry; 05674 int port; 05675 char *scan, *addr, *port_str, *expiry_str, *username, *contact; 05676 05677 if (ast_test_flag(&(peer->flags_page2), SIP_PAGE2_RT_FROMCONTACT)) 05678 return; 05679 if (ast_db_get("SIP/Registry", peer->name, data, sizeof(data))) 05680 return; 05681 05682 scan = data; 05683 addr = strsep(&scan, ":"); 05684 port_str = strsep(&scan, ":"); 05685 expiry_str = strsep(&scan, ":"); 05686 username = strsep(&scan, ":"); 05687 contact = scan; /* Contact include sip: and has to be the last part of the database entry as long as we use : as a separator */ 05688 05689 if (!inet_aton(addr, &in)) 05690 return; 05691 05692 if (port_str) 05693 port = atoi(port_str); 05694 else 05695 return; 05696 05697 if (expiry_str) 05698 expiry = atoi(expiry_str); 05699 else 05700 return; 05701 05702 if (username) 05703 ast_copy_string(peer->username, username, sizeof(peer->username)); 05704 if (contact) 05705 ast_copy_string(peer->fullcontact, contact, sizeof(peer->fullcontact)); 05706 05707 if (option_verbose > 2) 05708 ast_verbose(VERBOSE_PREFIX_3 "SIP Seeding peer from astdb: '%s' at %s@%s:%d for %d\n", 05709 peer->name, peer->username, ast_inet_ntoa(iabuf, sizeof(iabuf), in), port, expiry); 05710 05711 memset(&peer->addr, 0, sizeof(peer->addr)); 05712 peer->addr.sin_family = AF_INET; 05713 peer->addr.sin_addr = in; 05714 peer->addr.sin_port = htons(port); 05715 if (sipsock < 0) { 05716 /* SIP isn't up yet, so schedule a poke only, pretty soon */ 05717 if (peer->pokeexpire > -1) 05718 ast_sched_del(sched, peer->pokeexpire); 05719 peer->pokeexpire = ast_sched_add(sched, thread_safe_rand() % 5000 + 1, sip_poke_peer_s, peer); 05720 } else 05721 sip_poke_peer(peer); 05722 if (peer->expire > -1) 05723 ast_sched_del(sched, peer->expire); 05724 peer->expire = ast_sched_add(sched, (expiry + 10) * 1000, expire_register, peer); 05725 register_peer_exten(peer, 1); 05726 }
|
|
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 6351 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(). 06352 { 06353 int res = -3; 06354 struct sip_peer *peer; 06355 char tmp[256]; 06356 char iabuf[INET_ADDRSTRLEN]; 06357 char *name, *c; 06358 char *t; 06359 char *domain; 06360 06361 /* Terminate URI */ 06362 t = uri; 06363 while(*t && (*t > 32) && (*t != ';')) 06364 t++; 06365 *t = '\0'; 06366 06367 ast_copy_string(tmp, get_header(req, "To"), sizeof(tmp)); 06368 if (pedanticsipchecking) 06369 ast_uri_decode(tmp); 06370 06371 c = get_in_brackets(tmp); 06372 /* Ditch ;user=phone */ 06373 name = strchr(c, ';'); 06374 if (name) 06375 *name = '\0'; 06376 06377 if (!strncmp(c, "sip:", 4)) { 06378 name = c + 4; 06379 } else { 06380 name = c; 06381 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)); 06382 } 06383 06384 /* Strip off the domain name */ 06385 if ((c = strchr(name, '@'))) { 06386 *c++ = '\0'; 06387 domain = c; 06388 if ((c = strchr(domain, ':'))) /* Remove :port */ 06389 *c = '\0'; 06390 if (!AST_LIST_EMPTY(&domain_list)) { 06391 if (!check_sip_domain(domain, NULL, 0)) { 06392 transmit_response(p, "404 Not found (unknown domain)", &p->initreq); 06393 return -3; 06394 } 06395 } 06396 } 06397 06398 ast_copy_string(p->exten, name, sizeof(p->exten)); 06399 build_contact(p); 06400 peer = find_peer(name, NULL, 1); 06401 if (!(peer && ast_apply_ha(peer->ha, sin))) { 06402 if (peer) 06403 ASTOBJ_UNREF(peer,sip_destroy_peer); 06404 } 06405 if (peer) { 06406 if (!ast_test_flag(peer, SIP_DYNAMIC)) { 06407 ast_log(LOG_ERROR, "Peer '%s' is trying to register, but not configured as host=dynamic\n", peer->name); 06408 } else { 06409 ast_copy_flags(p, peer, SIP_NAT); 06410 transmit_response(p, "100 Trying", req); 06411 if (!(res = check_auth(p, req, p->randdata, sizeof(p->randdata), peer->name, peer->secret, peer->md5secret, SIP_REGISTER, uri, 0, ignore))) { 06412 sip_cancel_destroy(p); 06413 switch (parse_register_contact(p, peer, req)) { 06414 case PARSE_REGISTER_FAILED: 06415 ast_log(LOG_WARNING, "Failed to parse contact info\n"); 06416 break; 06417 case PARSE_REGISTER_QUERY: 06418 transmit_response_with_date(p, "200 OK", req); 06419 peer->lastmsgssent = -1; 06420 res = 0; 06421 break; 06422 case PARSE_REGISTER_UPDATE: 06423 update_peer(peer, p->expiry); 06424 /* Say OK and ask subsystem to retransmit msg counter */ 06425 transmit_response_with_date(p, "200 OK", req); 06426 peer->lastmsgssent = -1; 06427 res = 0; 06428 break; 06429 } 06430 } 06431 } 06432 } 06433 if (!peer && autocreatepeer) { 06434 /* Create peer if we have autocreate mode enabled */ 06435 peer = temp_peer(name); 06436 if (peer) { 06437 ASTOBJ_CONTAINER_LINK(&peerl, peer); 06438 peer->lastmsgssent = -1; 06439 sip_cancel_destroy(p); 06440 switch (parse_register_contact(p, peer, req)) { 06441 case PARSE_REGISTER_FAILED: 06442 ast_log(LOG_WARNING, "Failed to parse contact info\n"); 06443 break; 06444 case PARSE_REGISTER_QUERY: 06445 transmit_response_with_date(p, "200 OK", req); 06446 peer->lastmsgssent = -1; 06447 res = 0; 06448 break; 06449 case PARSE_REGISTER_UPDATE: 06450 /* Say OK and ask subsystem to retransmit msg counter */ 06451 transmit_response_with_date(p, "200 OK", req); 06452 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Registered\r\n", peer->name); 06453 peer->lastmsgssent = -1; 06454 res = 0; 06455 break; 06456 } 06457 } 06458 } 06459 if (!res) { 06460 ast_device_state_changed("SIP/%s", peer->name); 06461 } 06462 if (res < 0) { 06463 switch (res) { 06464 case -1: 06465 /* Wrong password in authentication. Go away, don't try again until you fixed it */ 06466 transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq); 06467 break; 06468 case -2: 06469 /* Username and digest username does not match. 06470 Asterisk uses the From: username for authentication. We need the 06471 users to use the same authentication user name until we support 06472 proper authentication by digest auth name */ 06473 transmit_response(p, "403 Authentication user name does not match account name", &p->initreq); 06474 break; 06475 case -3: 06476 /* URI not found */ 06477 transmit_response(p, "404 Not found", &p->initreq); 06478 /* Set res back to -2 because we don't want to return an invalid domain message. That check already happened up above. */ 06479 res = -2; 06480 break; 06481 } 06482 if (option_debug > 1) { 06483 ast_log(LOG_DEBUG, "SIP REGISTER attempt failed for %s : %s\n", 06484 peer->name, 06485 (res == -1) ? "Bad password" : ((res == -2 ) ? "Bad digest user" : "Peer not found")); 06486 } 06487 } 06488 if (peer) 06489 ASTOBJ_UNREF(peer,sip_destroy_peer); 06490 06491 return res; 06492 }
|
|
Definition at line 5215 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. 05216 { 05217 switch(regstate) { 05218 case REG_STATE_FAILED: 05219 return "Failed"; 05220 case REG_STATE_UNREGISTERED: 05221 return "Unregistered"; 05222 case REG_STATE_REGSENT: 05223 return "Request Sent"; 05224 case REG_STATE_AUTHSENT: 05225 return "Auth. Sent"; 05226 case REG_STATE_REGISTERED: 05227 return "Registered"; 05228 case REG_STATE_REJECTED: 05229 return "Rejected"; 05230 case REG_STATE_TIMEOUT: 05231 return "Timeout"; 05232 case REG_STATE_NOAUTH: 05233 return "No Authentication"; 05234 default: 05235 return "Unknown"; 05236 } 05237 }
|
|
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 13086 of file chan_sip.c. References sip_reload(). 13087 { 13088 return sip_reload(0, 0, NULL); 13089 }
|
|
reload_config: Re-read SIP.conf config file ---
Definition at line 12299 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. 12300 { 12301 struct ast_config *cfg; 12302 struct ast_variable *v; 12303 struct sip_peer *peer; 12304 struct sip_user *user; 12305 struct ast_hostent ahp; 12306 char *cat; 12307 char *utype; 12308 struct hostent *hp; 12309 int format; 12310 char iabuf[INET_ADDRSTRLEN]; 12311 struct ast_flags dummy; 12312 int auto_sip_domains = 0; 12313 struct sockaddr_in old_bindaddr = bindaddr; 12314 12315 cfg = ast_config_load(config); 12316 12317 /* We *must* have a config file otherwise stop immediately */ 12318 if (!cfg) { 12319 ast_log(LOG_NOTICE, "Unable to load config %s\n", config); 12320 return -1; 12321 } 12322 12323 /* Reset IP addresses */ 12324 memset(&bindaddr, 0, sizeof(bindaddr)); 12325 memset(&localaddr, 0, sizeof(localaddr)); 12326 memset(&externip, 0, sizeof(externip)); 12327 memset(&prefs, 0 , sizeof(prefs)); 12328 sipdebug &= ~SIP_DEBUG_CONFIG; 12329 12330 /* Initialize some reasonable defaults at SIP reload */ 12331 ast_copy_string(default_context, DEFAULT_CONTEXT, sizeof(default_context)); 12332 default_subscribecontext[0] = '\0'; 12333 default_language[0] = '\0'; 12334 default_fromdomain[0] = '\0'; 12335 default_qualify = 0; 12336 allow_external_domains = 1; /* Allow external invites */ 12337 externhost[0] = '\0'; 12338 externexpire = 0; 12339 externrefresh = 10; 12340 ast_copy_string(default_useragent, DEFAULT_USERAGENT, sizeof(default_useragent)); 12341 ast_copy_string(default_notifymime, DEFAULT_NOTIFYMIME, sizeof(default_notifymime)); 12342 global_notifyringing = 1; 12343 ast_copy_string(global_realm, DEFAULT_REALM, sizeof(global_realm)); 12344 ast_copy_string(global_musicclass, "default", sizeof(global_musicclass)); 12345 ast_copy_string(default_callerid, DEFAULT_CALLERID, sizeof(default_callerid)); 12346 memset(&outboundproxyip, 0, sizeof(outboundproxyip)); 12347 outboundproxyip.sin_port = htons(DEFAULT_SIP_PORT); 12348 outboundproxyip.sin_family = AF_INET; /* Type of address: IPv4 */ 12349 videosupport = 0; 12350 compactheaders = 0; 12351 dumphistory = 0; 12352 recordhistory = 0; 12353 relaxdtmf = 0; 12354 callevents = 0; 12355 ourport = DEFAULT_SIP_PORT; 12356 global_rtptimeout = 0; 12357 global_rtpholdtimeout = 0; 12358 global_rtpkeepalive = 0; 12359 global_rtautoclear = 120; 12360 pedanticsipchecking = 0; 12361 global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT; 12362 global_regattempts_max = 0; 12363 ast_clear_flag(&global_flags, AST_FLAGS_ALL); 12364 ast_clear_flag(&global_flags_page2, AST_FLAGS_ALL); 12365 ast_set_flag(&global_flags, SIP_DTMF_RFC2833); 12366 ast_set_flag(&global_flags, SIP_NAT_RFC3581); 12367 ast_set_flag(&global_flags, SIP_CAN_REINVITE); 12368 ast_set_flag(&global_flags_page2, SIP_PAGE2_RTUPDATE); 12369 global_mwitime = DEFAULT_MWITIME; 12370 strcpy(global_vmexten, DEFAULT_VMEXTEN); 12371 srvlookup = 0; 12372 autocreatepeer = 0; 12373 regcontext[0] = '\0'; 12374 tos = 0; 12375 expiry = DEFAULT_EXPIRY; 12376 global_allowguest = 1; 12377 12378 /* Read the [general] config section of sip.conf (or from realtime config) */ 12379 v = ast_variable_browse(cfg, "general"); 12380 while(v) { 12381 if (handle_common_options(&global_flags, &dummy, v)) { 12382 v = v->next; 12383 continue; 12384 } 12385 12386 /* Create the interface list */ 12387 if (!strcasecmp(v->name, "context")) { 12388 ast_copy_string(default_context, v->value, sizeof(default_context)); 12389 } else if (!strcasecmp(v->name, "realm")) { 12390 ast_copy_string(global_realm, v->value, sizeof(global_realm)); 12391 } else if (!strcasecmp(v->name, "useragent")) { 12392 ast_copy_string(default_useragent, v->value, sizeof(default_useragent)); 12393 ast_log(LOG_DEBUG, "Setting User Agent Name to %s\n", 12394 default_useragent); 12395 } else if (!strcasecmp(v->name, "rtcachefriends")) { 12396 ast_set2_flag((&global_flags_page2), ast_true(v->value), SIP_PAGE2_RTCACHEFRIENDS); 12397 } else if (!strcasecmp(v->name, "rtupdate")) { 12398 ast_set2_flag((&global_flags_page2), ast_true(v->value), SIP_PAGE2_RTUPDATE); 12399 } else if (!strcasecmp(v->name, "ignoreregexpire")) { 12400 ast_set2_flag((&global_flags_page2), ast_true(v->value), SIP_PAGE2_IGNOREREGEXPIRE); 12401 } else if (!strcasecmp(v->name, "rtautoclear")) { 12402 int i = atoi(v->value); 12403 if (i > 0) 12404 global_rtautoclear = i; 12405 else 12406 i = 0; 12407 ast_set2_flag((&global_flags_page2), i || ast_true(v->value), SIP_PAGE2_RTAUTOCLEAR); 12408 } else if (!strcasecmp(v->name, "usereqphone")) { 12409 ast_set2_flag((&global_flags), ast_true(v->value), SIP_USEREQPHONE); 12410 } else if (!strcasecmp(v->name, "relaxdtmf")) { 12411 relaxdtmf = ast_true(v->value); 12412 } else if (!strcasecmp(v->name, "checkmwi")) { 12413 if ((sscanf(v->value, "%d", &global_mwitime) != 1) || (global_mwitime < 0)) { 12414 ast_log(LOG_WARNING, "'%s' is not a valid MWI time setting at line %d. Using default (10).\n", v->value, v->lineno); 12415 global_mwitime = DEFAULT_MWITIME; 12416 } 12417 } else if (!strcasecmp(v->name, "vmexten")) { 12418 ast_copy_string(global_vmexten, v->value, sizeof(global_vmexten)); 12419 } else if (!strcasecmp(v->name, "rtptimeout")) { 12420 if ((sscanf(v->value, "%d", &global_rtptimeout) != 1) || (global_rtptimeout < 0)) { 12421 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 12422 global_rtptimeout = 0; 12423 } 12424 } else if (!strcasecmp(v->name, "rtpholdtimeout")) { 12425 if ((sscanf(v->value, "%d", &global_rtpholdtimeout) != 1) || (global_rtpholdtimeout < 0)) { 12426 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 12427 global_rtpholdtimeout = 0; 12428 } 12429 } else if (!strcasecmp(v->name, "rtpkeepalive")) { 12430 if ((sscanf(v->value, "%d", &global_rtpkeepalive) != 1) || (global_rtpkeepalive < 0)) { 12431 ast_log(LOG_WARNING, "'%s' is not a valid RTP keepalive time at line %d. Using default.\n", v->value, v->lineno); 12432 global_rtpkeepalive = 0; 12433 } 12434 } else if (!strcasecmp(v->name, "videosupport")) { 12435 videosupport = ast_true(v->value); 12436 } else if (!strcasecmp(v->name, "compactheaders")) { 12437 compactheaders = ast_true(v->value); 12438 } else if (!strcasecmp(v->name, "notifymimetype")) { 12439 ast_copy_string(default_notifymime, v->value, sizeof(default_notifymime)); 12440 } else if (!strcasecmp(v->name, "notifyringing")) { 12441 global_notifyringing = ast_true(v->value); 12442 } else if (!strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) { 12443 ast_copy_string(global_musicclass, v->value, sizeof(global_musicclass)); 12444 } else if (!strcasecmp(v->name, "language")) { 12445 ast_copy_string(default_language, v->value, sizeof(default_language)); 12446 } else if (!strcasecmp(v->name, "regcontext")) { 12447 ast_copy_string(regcontext, v->value, sizeof(regcontext)); 12448 /* Create context if it doesn't exist already */ 12449 if (!ast_context_find(regcontext)) 12450 ast_context_create(NULL, regcontext, channeltype); 12451 } else if (!strcasecmp(v->name, "callerid")) { 12452 ast_copy_string(default_callerid, v->value, sizeof(default_callerid)); 12453 } else if (!strcasecmp(v->name, "fromdomain")) { 12454 ast_copy_string(default_fromdomain, v->value, sizeof(default_fromdomain)); 12455 } else if (!strcasecmp(v->name, "outboundproxy")) { 12456 if (ast_get_ip_or_srv(&outboundproxyip, v->value, "_sip._udp") < 0) 12457 ast_log(LOG_WARNING, "Unable to locate host '%s'\n", v->value); 12458 } else if (!strcasecmp(v->name, "outboundproxyport")) { 12459 /* Port needs to be after IP */ 12460 sscanf(v->value, "%d", &format); 12461 outboundproxyip.sin_port = htons(format); 12462 } else if (!strcasecmp(v->name, "autocreatepeer")) { 12463 autocreatepeer = ast_true(v->value); 12464 } else if (!strcasecmp(v->name, "srvlookup")) { 12465 srvlookup = ast_true(v->value); 12466 } else if (!strcasecmp(v->name, "pedantic")) { 12467 pedanticsipchecking = ast_true(v->value); 12468 } else if (!strcasecmp(v->name, "maxexpirey") || !strcasecmp(v->name, "maxexpiry")) { 12469 max_expiry = atoi(v->value); 12470 if (max_expiry < 1) 12471 max_expiry = DEFAULT_MAX_EXPIRY; 12472 } else if (!strcasecmp(v->name, "defaultexpiry") || !strcasecmp(v->name, "defaultexpirey")) { 12473 default_expiry = atoi(v->value); 12474 if (default_expiry < 1) 12475 default_expiry = DEFAULT_DEFAULT_EXPIRY; 12476 } else if (!strcasecmp(v->name, "sipdebug")) { 12477 if (ast_true(v->value)) 12478 sipdebug |= SIP_DEBUG_CONFIG; 12479 } else if (!strcasecmp(v->name, "dumphistory")) { 12480 dumphistory = ast_true(v->value); 12481 } else if (!strcasecmp(v->name, "recordhistory")) { 12482 recordhistory = ast_true(v->value); 12483 } else if (!strcasecmp(v->name, "registertimeout")) { 12484 global_reg_timeout = atoi(v->value); 12485 if (global_reg_timeout < 1) 12486 global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT; 12487 } else if (!strcasecmp(v->name, "registerattempts")) { 12488 global_regattempts_max = atoi(v->value); 12489 } else if (!strcasecmp(v->name, "bindaddr")) { 12490 if (!(hp = ast_gethostbyname(v->value, &ahp))) { 12491 ast_log(LOG_WARNING, "Invalid address: %s\n", v->value); 12492 } else { 12493 memcpy(&bindaddr.sin_addr, hp->h_addr, sizeof(bindaddr.sin_addr)); 12494 } 12495 } else if (!strcasecmp(v->name, "localnet")) { 12496 struct ast_ha *na; 12497 if (!(na = ast_append_ha("d", v->value, localaddr))) 12498 ast_log(LOG_WARNING, "Invalid localnet value: %s\n", v->value); 12499 else 12500 localaddr = na; 12501 } else if (!strcasecmp(v->name, "localmask")) { 12502 ast_log(LOG_WARNING, "Use of localmask is no long supported -- use localnet with mask syntax\n"); 12503 } else if (!strcasecmp(v->name, "externip")) { 12504 if (!(hp = ast_gethostbyname(v->value, &ahp))) 12505 ast_log(LOG_WARNING, "Invalid address for externip keyword: %s\n", v->value); 12506 else 12507 memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr)); 12508 externexpire = 0; 12509 } else if (!strcasecmp(v->name, "externhost")) { 12510 ast_copy_string(externhost, v->value, sizeof(externhost)); 12511 if (!(hp = ast_gethostbyname(externhost, &ahp))) 12512 ast_log(LOG_WARNING, "Invalid address for externhost keyword: %s\n", externhost); 12513 else 12514 memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr)); 12515 time(&externexpire); 12516 } else if (!strcasecmp(v->name, "externrefresh")) { 12517 if (sscanf(v->value, "%d", &externrefresh) != 1) { 12518 ast_log(LOG_WARNING, "Invalid externrefresh value '%s', must be an integer >0 at line %d\n", v->value, v->lineno); 12519 externrefresh = 10; 12520 } 12521 } else if (!strcasecmp(v->name, "allow")) { 12522 ast_parse_allow_disallow(&prefs, &global_capability, v->value, 1); 12523 } else if (!strcasecmp(v->name, "disallow")) { 12524 ast_parse_allow_disallow(&prefs, &global_capability, v->value, 0); 12525 } else if (!strcasecmp(v->name, "allowexternaldomains")) { 12526 allow_external_domains = ast_true(v->value); 12527 } else if (!strcasecmp(v->name, "autodomain")) { 12528 auto_sip_domains = ast_true(v->value); 12529 } else if (!strcasecmp(v->name, "domain")) { 12530 char *domain = ast_strdupa(v->value); 12531 char *context = strchr(domain, ','); 12532 12533 if (context) 12534 *context++ = '\0'; 12535 12536 if (ast_strlen_zero(domain)) 12537 ast_log(LOG_WARNING, "Empty domain specified at line %d\n", v->lineno); 12538 else if (ast_strlen_zero(context)) 12539 ast_log(LOG_WARNING, "Empty context specified at line %d for domain '%s'\n", v->lineno, domain); 12540 else 12541 add_sip_domain(ast_strip(domain), SIP_DOMAIN_CONFIG, context ? ast_strip(context) : ""); 12542 } else if (!strcasecmp(v->name, "register")) { 12543 sip_register(v->value, v->lineno); 12544 } else if (!strcasecmp(v->name, "tos")) { 12545 if (ast_str2tos(v->value, &tos)) 12546 ast_log(LOG_WARNING, "Invalid tos value at line %d, should be 'lowdelay', 'throughput', 'reliability', 'mincost', or 'none'\n", v->lineno); 12547 } else if (!strcasecmp(v->name, "bindport")) { 12548 if (sscanf(v->value, "%d", &ourport) == 1) { 12549 bindaddr.sin_port = htons(ourport); 12550 } else { 12551 ast_log(LOG_WARNING, "Invalid port number '%s' at line %d of %s\n", v->value, v->lineno, config); 12552 } 12553 } else if (!strcasecmp(v->name, "qualify")) { 12554 if (!strcasecmp(v->value, "no")) { 12555 default_qualify = 0; 12556 } else if (!strcasecmp(v->value, "yes")) { 12557 default_qualify = DEFAULT_MAXMS; 12558 } else if (sscanf(v->value, "%d", &default_qualify) != 1) { 12559 ast_log(LOG_WARNING, "Qualification default should be 'yes', 'no', or a number of milliseconds at line %d of sip.conf\n", v->lineno); 12560 default_qualify = 0; 12561 } 12562 } else if (!strcasecmp(v->name, "callevents")) { 12563 callevents = ast_true(v->value); 12564 } 12565 /* else if (strcasecmp(v->name,"type")) 12566 * ast_log(LOG_WARNING, "Ignoring %s\n", v->name); 12567 */ 12568 v = v->next; 12569 } 12570 12571 if (!allow_external_domains && AST_LIST_EMPTY(&domain_list)) { 12572 ast_log(LOG_WARNING, "To disallow external domains, you need to configure local SIP domains.\n"); 12573 allow_external_domains = 1; 12574 } 12575 12576 /* Build list of authentication to various SIP realms, i.e. service providers */ 12577 v = ast_variable_browse(cfg, "authentication"); 12578 while(v) { 12579 /* Format for authentication is auth = username:password@realm */ 12580 if (!strcasecmp(v->name, "auth")) { 12581 authl = add_realm_authentication(authl, v->value, v->lineno); 12582 } 12583 v = v->next; 12584 } 12585 12586 /* Load peers, users and friends */ 12587 cat = ast_category_browse(cfg, NULL); 12588 while(cat) { 12589 if (strcasecmp(cat, "general") && strcasecmp(cat, "authentication")) { 12590 utype = ast_variable_retrieve(cfg, cat, "type"); 12591 if (utype) { 12592 if (!strcasecmp(utype, "user") || !strcasecmp(utype, "friend")) { 12593 user = build_user(cat, ast_variable_browse(cfg, cat), 0); 12594 if (user) { 12595 ASTOBJ_CONTAINER_LINK(&userl,user); 12596 ASTOBJ_UNREF(user, sip_destroy_user); 12597 } 12598 } 12599 if (!strcasecmp(utype, "peer") || !strcasecmp(utype, "friend")) { 12600 peer = build_peer(cat, ast_variable_browse(cfg, cat), 0); 12601 if (peer) { 12602 ASTOBJ_CONTAINER_LINK(&peerl,peer); 12603 ASTOBJ_UNREF(peer, sip_destroy_peer); 12604 } 12605 } else if (strcasecmp(utype, "user")) { 12606 ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, "sip.conf"); 12607 } 12608 } else 12609 ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat); 12610 } 12611 cat = ast_category_browse(cfg, cat); 12612 } 12613 if (ast_find_ourip(&__ourip, bindaddr)) { 12614 ast_log(LOG_WARNING, "Unable to get own IP address, SIP disabled\n"); 12615 return 0; 12616 } 12617 if (!ntohs(bindaddr.sin_port)) 12618 bindaddr.sin_port = ntohs(DEFAULT_SIP_PORT); 12619 bindaddr.sin_family = AF_INET; 12620 ast_mutex_lock(&netlock); 12621 if ((sipsock > -1) && (memcmp(&old_bindaddr, &bindaddr, sizeof(struct sockaddr_in)))) { 12622 close(sipsock); 12623 sipsock = -1; 12624 } 12625 if (sipsock < 0) { 12626 sipsock = socket(AF_INET, SOCK_DGRAM, 0); 12627 if (sipsock < 0) { 12628 ast_log(LOG_WARNING, "Unable to create SIP socket: %s\n", strerror(errno)); 12629 } else { 12630 /* Allow SIP clients on the same host to access us: */ 12631 const int reuseFlag = 1; 12632 setsockopt(sipsock, SOL_SOCKET, SO_REUSEADDR, 12633 (const char*)&reuseFlag, 12634 sizeof reuseFlag); 12635 12636 if (bind(sipsock, (struct sockaddr *)&bindaddr, sizeof(bindaddr)) < 0) { 12637 ast_log(LOG_WARNING, "Failed to bind to %s:%d: %s\n", 12638 ast_inet_ntoa(iabuf, sizeof(iabuf), bindaddr.sin_addr), ntohs(bindaddr.sin_port), 12639 strerror(errno)); 12640 close(sipsock); 12641 sipsock = -1; 12642 } else { 12643 if (option_verbose > 1) { 12644 ast_verbose(VERBOSE_PREFIX_2 "SIP Listening on %s:%d\n", 12645 ast_inet_ntoa(iabuf, sizeof(iabuf), bindaddr.sin_addr), ntohs(bindaddr.sin_port)); 12646 ast_verbose(VERBOSE_PREFIX_2 "Using TOS bits %d\n", tos); 12647 } 12648 if (setsockopt(sipsock, IPPROTO_IP, IP_TOS, &tos, sizeof(tos))) 12649 ast_log(LOG_WARNING, "Unable to set TOS to %d\n", tos); 12650 } 12651 } 12652 } 12653 ast_mutex_unlock(&netlock); 12654 12655 /* Add default domains - host name, IP address and IP:port */ 12656 /* Only do this if user added any sip domain with "localdomains" */ 12657 /* In order to *not* break backwards compatibility */ 12658 /* Some phones address us at IP only, some with additional port number */ 12659 if (auto_sip_domains) { 12660 char temp[MAXHOSTNAMELEN]; 12661 12662 /* First our default IP address */ 12663 if (bindaddr.sin_addr.s_addr) { 12664 ast_inet_ntoa(temp, sizeof(temp), bindaddr.sin_addr); 12665 add_sip_domain(temp, SIP_DOMAIN_AUTO, NULL); 12666 } else { 12667 ast_log(LOG_NOTICE, "Can't add wildcard IP address to domain list, please add IP address to domain manually.\n"); 12668 } 12669 12670 /* Our extern IP address, if configured */ 12671 if (externip.sin_addr.s_addr) { 12672 ast_inet_ntoa(temp, sizeof(temp), externip.sin_addr); 12673 add_sip_domain(temp, SIP_DOMAIN_AUTO, NULL); 12674 } 12675 12676 /* Extern host name (NAT traversal support) */ 12677 if (!ast_strlen_zero(externhost)) 12678 add_sip_domain(externhost, SIP_DOMAIN_AUTO, NULL); 12679 12680 /* Our host name */ 12681 if (!gethostname(temp, sizeof(temp))) 12682 add_sip_domain(temp, SIP_DOMAIN_AUTO, NULL); 12683 } 12684 12685 /* Release configuration from memory */ 12686 ast_config_destroy(cfg); 12687 12688 /* Load the list of manual NOTIFY types to support */ 12689 if (notify_types) 12690 ast_config_destroy(notify_types); 12691 notify_types = ast_config_load(notify_config); 12692 12693 return 0; 12694 }
|
|
reply_digest: reply to authentication for outbound registrations ---
Definition at line 8919 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(). 08921 { 08922 char tmp[512]; 08923 char *c; 08924 char oldnonce[256]; 08925 08926 /* table of recognised keywords, and places where they should be copied */ 08927 const struct x { 08928 const char *key; 08929 char *dst; 08930 int dstlen; 08931 } *i, keys[] = { 08932 { "realm=", p->realm, sizeof(p->realm) }, 08933 { "nonce=", p->nonce, sizeof(p->nonce) }, 08934 { "opaque=", p->opaque, sizeof(p->opaque) }, 08935 { "qop=", p->qop, sizeof(p->qop) }, 08936 { "domain=", p->domain, sizeof(p->domain) }, 08937 { NULL, NULL, 0 }, 08938 }; 08939 08940 ast_copy_string(tmp, get_header(req, header), sizeof(tmp)); 08941 if (ast_strlen_zero(tmp)) 08942 return -1; 08943 if (strncasecmp(tmp, "Digest ", strlen("Digest "))) { 08944 ast_log(LOG_WARNING, "missing Digest.\n"); 08945 return -1; 08946 } 08947 c = tmp + strlen("Digest "); 08948 for (i = keys; i->key != NULL; i++) 08949 i->dst[0] = '\0'; /* init all to empty strings */ 08950 ast_copy_string(oldnonce, p->nonce, sizeof(oldnonce)); 08951 while (c && *(c = ast_skip_blanks(c))) { /* lookup for keys */ 08952 for (i = keys; i->key != NULL; i++) { 08953 char *src, *separator; 08954 if (strncasecmp(c, i->key, strlen(i->key)) != 0) 08955 continue; 08956 /* Found. Skip keyword, take text in quotes or up to the separator. */ 08957 c += strlen(i->key); 08958 if (*c == '\"') { 08959 src = ++c; 08960 separator = "\""; 08961 } else { 08962 src = c; 08963 separator = ","; 08964 } 08965 strsep(&c, separator); /* clear separator and move ptr */ 08966 ast_copy_string(i->dst, src, i->dstlen); 08967 break; 08968 } 08969 if (i->key == NULL) /* not found, try ',' */ 08970 strsep(&c, ","); 08971 } 08972 /* Reset nonce count */ 08973 if (strcmp(p->nonce, oldnonce)) 08974 p->noncecount = 0; 08975 08976 /* Save auth data for following registrations */ 08977 if (p->registry) { 08978 struct sip_registry *r = p->registry; 08979 08980 if (strcmp(r->nonce, p->nonce)) { 08981 ast_copy_string(r->realm, p->realm, sizeof(r->realm)); 08982 ast_copy_string(r->nonce, p->nonce, sizeof(r->nonce)); 08983 ast_copy_string(r->domain, p->domain, sizeof(r->domain)); 08984 ast_copy_string(r->opaque, p->opaque, sizeof(r->opaque)); 08985 ast_copy_string(r->qop, p->qop, sizeof(r->qop)); 08986 r->noncecount = 0; 08987 } 08988 } 08989 return build_reply_digest(p, sipmethod, digest, digest_len); 08990 }
|
|
reqprep: Initialize a SIP request response packet ---
Definition at line 4030 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. 04031 { 04032 struct sip_request *orig = &p->initreq; 04033 char stripped[80]; 04034 char tmp[80]; 04035 char newto[256]; 04036 char *c, *n; 04037 char *ot, *of; 04038 int is_strict = 0; /* Strict routing flag */ 04039 04040 memset(req, 0, sizeof(struct sip_request)); 04041 04042 snprintf(p->lastmsg, sizeof(p->lastmsg), "Tx: %s", sip_methods[sipmethod].text); 04043 04044 if (!seqno) { 04045 p->ocseq++; 04046 seqno = p->ocseq; 04047 } 04048 04049 if (newbranch) { 04050 p->branch ^= thread_safe_rand(); 04051 build_via(p, p->via, sizeof(p->via)); 04052 } 04053 04054 /* Check for strict or loose router */ 04055 if (p->route && !ast_strlen_zero(p->route->hop) && strstr(p->route->hop,";lr") == NULL) 04056 is_strict = 1; 04057 04058 if (sipmethod == SIP_CANCEL) { 04059 c = p->initreq.rlPart2; /* Use original URI */ 04060 } else if (sipmethod == SIP_ACK) { 04061 /* Use URI from Contact: in 200 OK (if INVITE) 04062 (we only have the contacturi on INVITEs) */ 04063 if (!ast_strlen_zero(p->okcontacturi)) 04064 c = is_strict ? p->route->hop : p->okcontacturi; 04065 else 04066 c = p->initreq.rlPart2; 04067 } else if (!ast_strlen_zero(p->okcontacturi)) { 04068 c = is_strict ? p->route->hop : p->okcontacturi; /* Use for BYE or REINVITE */ 04069 } else if (!ast_strlen_zero(p->uri)) { 04070 c = p->uri; 04071 } else { 04072 /* We have no URI, use To: or From: header as URI (depending on direction) */ 04073 c = get_header(orig, (ast_test_flag(p, SIP_OUTGOING)) ? "To" : "From"); 04074 ast_copy_string(stripped, c, sizeof(stripped)); 04075 c = get_in_brackets(stripped); 04076 n = strchr(c, ';'); 04077 if (n) 04078 *n = '\0'; 04079 } 04080 init_req(req, sipmethod, c); 04081 04082 snprintf(tmp, sizeof(tmp), "%d %s", seqno, sip_methods[sipmethod].text); 04083 04084 add_header(req, "Via", p->via); 04085 if (p->route) { 04086 set_destination(p, p->route->hop); 04087 if (is_strict) 04088 add_route(req, p->route->next); 04089 else 04090 add_route(req, p->route); 04091 } 04092 04093 ot = get_header(orig, "To"); 04094 of = get_header(orig, "From"); 04095 04096 /* Add tag *unless* this is a CANCEL, in which case we need to send it exactly 04097 as our original request, including tag (or presumably lack thereof) */ 04098 if (!strcasestr(ot, "tag=") && sipmethod != SIP_CANCEL) { 04099 /* Add the proper tag if we don't have it already. If they have specified 04100 their tag, use it. Otherwise, use our own tag */ 04101 if (ast_test_flag(p, SIP_OUTGOING) && !ast_strlen_zero(p->theirtag)) 04102 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->theirtag); 04103 else if (!ast_test_flag(p, SIP_OUTGOING)) 04104 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->tag); 04105 else 04106 snprintf(newto, sizeof(newto), "%s", ot); 04107 ot = newto; 04108 } 04109 04110 if (ast_test_flag(p, SIP_OUTGOING)) { 04111 add_header(req, "From", of); 04112 add_header(req, "To", ot); 04113 } else { 04114 add_header(req, "From", ot); 04115 add_header(req, "To", of); 04116 } 04117 add_header(req, "Contact", p->our_contact); 04118 copy_header(req, orig, "Call-ID"); 04119 add_header(req, "CSeq", tmp); 04120 04121 add_header(req, "User-Agent", default_useragent); 04122 add_header(req, "Max-Forwards", DEFAULT_MAX_FORWARDS); 04123 04124 if (p->rpid) 04125 add_header(req, "Remote-Party-ID", p->rpid); 04126 04127 return 0; 04128 }
|
|
respprep: Prepare SIP response packet ---
Definition at line 3982 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. 03983 { 03984 char newto[256], *ot; 03985 03986 memset(resp, 0, sizeof(*resp)); 03987 init_resp(resp, msg, req); 03988 copy_via_headers(p, resp, req, "Via"); 03989 if (msg[0] == '2') 03990 copy_all_header(resp, req, "Record-Route"); 03991 copy_header(resp, req, "From"); 03992 ot = get_header(req, "To"); 03993 if (!strcasestr(ot, "tag=") && strncmp(msg, "100", 3)) { 03994 /* Add the proper tag if we don't have it already. If they have specified 03995 their tag, use it. Otherwise, use our own tag */ 03996 if (!ast_strlen_zero(p->theirtag) && ast_test_flag(p, SIP_OUTGOING)) 03997 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->theirtag); 03998 else if (p->tag && !ast_test_flag(p, SIP_OUTGOING)) 03999 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->tag); 04000 else { 04001 ast_copy_string(newto, ot, sizeof(newto)); 04002 newto[sizeof(newto) - 1] = '\0'; 04003 } 04004 ot = newto; 04005 } 04006 add_header(resp, "To", ot); 04007 copy_header(resp, req, "Call-ID"); 04008 copy_header(resp, req, "CSeq"); 04009 add_header(resp, "User-Agent", default_useragent); 04010 add_header(resp, "Allow", ALLOWED_METHODS); 04011 if (msg[0] == '2' && (p->method == SIP_SUBSCRIBE || p->method == SIP_REGISTER)) { 04012 /* For registration responses, we also need expiry and 04013 contact info */ 04014 char tmp[256]; 04015 04016 snprintf(tmp, sizeof(tmp), "%d", p->expiry); 04017 add_header(resp, "Expires", tmp); 04018 if (p->expiry) { /* Only add contact if we have an expiry time */ 04019 char contact[256]; 04020 snprintf(contact, sizeof(contact), "%s;expires=%d", p->our_contact, p->expiry); 04021 add_header(resp, "Contact", contact); /* Not when we unregister */ 04022 } 04023 } else if (p->our_contact[0]) { 04024 add_header(resp, "Contact", p->our_contact); 04025 } 04026 return 0; 04027 }
|
|
restart_monitor: Start the channel monitor thread ---
Definition at line 11360 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. 11361 { 11362 /* If we're supposed to be stopped -- stay stopped */ 11363 if (monitor_thread == AST_PTHREADT_STOP) 11364 return 0; 11365 if (ast_mutex_lock(&monlock)) { 11366 ast_log(LOG_WARNING, "Unable to lock monitor\n"); 11367 return -1; 11368 } 11369 if (monitor_thread == pthread_self()) { 11370 ast_mutex_unlock(&monlock); 11371 ast_log(LOG_WARNING, "Cannot kill myself\n"); 11372 return -1; 11373 } 11374 if (monitor_thread != AST_PTHREADT_NULL) { 11375 /* Wake up the thread */ 11376 pthread_kill(monitor_thread, SIGURG); 11377 } else { 11378 /* Start a new monitor */ 11379 if (ast_pthread_create(&monitor_thread, NULL, do_monitor, NULL) < 0) { 11380 ast_mutex_unlock(&monlock); 11381 ast_log(LOG_ERROR, "Unable to start monitor thread.\n"); 11382 return -1; 11383 } 11384 } 11385 ast_mutex_unlock(&monlock); 11386 return 0; 11387 }
|
|
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 3886 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(). 03887 { 03888 char *h, *maddr, hostname[256]; 03889 char iabuf[INET_ADDRSTRLEN]; 03890 int port, hn; 03891 struct hostent *hp; 03892 struct ast_hostent ahp; 03893 int debug=sip_debug_test_pvt(p); 03894 03895 /* Parse uri to h (host) and port - uri is already just the part inside the <> */ 03896 /* general form we are expecting is sip[s]:username[:password]@host[:port][;...] */ 03897 03898 if (debug) 03899 ast_verbose("set_destination: Parsing <%s> for address/port to send to\n", uri); 03900 03901 /* Find and parse hostname */ 03902 h = strchr(uri, '@'); 03903 if (h) 03904 ++h; 03905 else { 03906 h = uri; 03907 if (strncmp(h, "sip:", 4) == 0) 03908 h += 4; 03909 else if (strncmp(h, "sips:", 5) == 0) 03910 h += 5; 03911 } 03912 hn = strcspn(h, ":;>") + 1; 03913 if (hn > sizeof(hostname)) 03914 hn = sizeof(hostname); 03915 ast_copy_string(hostname, h, hn); 03916 h += hn - 1; 03917 03918 /* Is "port" present? if not default to DEFAULT_SIP_PORT */ 03919 if (*h == ':') { 03920 /* Parse port */ 03921 ++h; 03922 port = strtol(h, &h, 10); 03923 } 03924 else 03925 port = DEFAULT_SIP_PORT; 03926 03927 /* Got the hostname:port - but maybe there's a "maddr=" to override address? */ 03928 maddr = strstr(h, "maddr="); 03929 if (maddr) { 03930 maddr += 6; 03931 hn = strspn(maddr, "0123456789.") + 1; 03932 if (hn > sizeof(hostname)) hn = sizeof(hostname); 03933 ast_copy_string(hostname, maddr, hn); 03934 } 03935 03936 hp = ast_gethostbyname(hostname, &ahp); 03937 if (hp == NULL) { 03938 ast_log(LOG_WARNING, "Can't find address for host '%s'\n", hostname); 03939 return; 03940 } 03941 p->sa.sin_family = AF_INET; 03942 memcpy(&p->sa.sin_addr, hp->h_addr, sizeof(p->sa.sin_addr)); 03943 p->sa.sin_port = htons(port); 03944 if (debug) 03945 ast_verbose("set_destination: set destination to %s, port %d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr), port); 03946 }
|
|
sip_addheader: Add a SIP header ---
Definition at line 12843 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(). 12844 { 12845 int no = 0; 12846 int ok = 0; 12847 char varbuf[128]; 12848 12849 if (ast_strlen_zero((char *)data)) { 12850 ast_log(LOG_WARNING, "This application requires the argument: Header\n"); 12851 return 0; 12852 } 12853 ast_mutex_lock(&chan->lock); 12854 12855 /* Check for headers */ 12856 while (!ok && no <= 50) { 12857 no++; 12858 snprintf(varbuf, sizeof(varbuf), "_SIPADDHEADER%02d", no); 12859 if (ast_strlen_zero(pbx_builtin_getvar_helper(chan, varbuf + 1))) 12860 ok = 1; 12861 } 12862 if (ok) { 12863 pbx_builtin_setvar_helper (chan, varbuf, (char *)data); 12864 if (sipdebug) 12865 ast_log(LOG_DEBUG,"SIP Header added \"%s\" as %s\n", (char *) data, varbuf); 12866 } else { 12867 ast_log(LOG_WARNING, "Too many SIP headers added, max 50\n"); 12868 } 12869 ast_mutex_unlock(&chan->lock); 12870 return 0; 12871 }
|
|
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 11486 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(). 11487 { 11488 char *host; 11489 char *tmp; 11490 11491 struct hostent *hp; 11492 struct ast_hostent ahp; 11493 struct sip_peer *p; 11494 11495 int res = AST_DEVICE_INVALID; 11496 11497 host = ast_strdupa(data); 11498 if ((tmp = strchr(host, '@'))) 11499 host = tmp + 1; 11500 11501 if (option_debug > 2) 11502 ast_log(LOG_DEBUG, "Checking device state for peer %s\n", host); 11503 11504 if ((p = find_peer(host, NULL, 1))) { 11505 if (p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) { 11506 /* we have an address for the peer */ 11507 /* if qualify is turned on, check the status */ 11508 if (p->maxms && (p->lastms > p->maxms)) { 11509 res = AST_DEVICE_UNAVAILABLE; 11510 } else { 11511 /* qualify is not on, or the peer is responding properly */ 11512 /* check call limit */ 11513 if (p->call_limit && (p->inUse == p->call_limit)) 11514 res = AST_DEVICE_BUSY; 11515 else if (p->call_limit && p->inUse) 11516 res = AST_DEVICE_INUSE; 11517 else if (p->call_limit) 11518 res = AST_DEVICE_NOT_INUSE; 11519 else 11520 res = AST_DEVICE_UNKNOWN; 11521 } 11522 } else { 11523 /* there is no address, it's unavailable */ 11524 res = AST_DEVICE_UNAVAILABLE; 11525 } 11526 ASTOBJ_UNREF(p,sip_destroy_peer); 11527 } else { 11528 hp = ast_gethostbyname(host, &ahp); 11529 if (hp) 11530 res = AST_DEVICE_UNKNOWN; 11531 } 11532 11533 return res; 11534 }
|
|
sip_do_debug: Turn on SIP debugging (CLI command)
Definition at line 8751 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. 08752 { 08753 int oldsipdebug = sipdebug & SIP_DEBUG_CONSOLE; 08754 if (argc != 2) { 08755 if (argc != 4) 08756 return RESULT_SHOWUSAGE; 08757 else if (strncmp(argv[2], "ip\0", 3) == 0) 08758 return sip_do_debug_ip(fd, argc, argv); 08759 else if (strncmp(argv[2], "peer\0", 5) == 0) 08760 return sip_do_debug_peer(fd, argc, argv); 08761 else return RESULT_SHOWUSAGE; 08762 } 08763 sipdebug |= SIP_DEBUG_CONSOLE; 08764 memset(&debugaddr, 0, sizeof(debugaddr)); 08765 if (oldsipdebug) 08766 ast_cli(fd, "SIP Debugging re-enabled\n"); 08767 else 08768 ast_cli(fd, "SIP Debugging enabled\n"); 08769 return RESULT_SUCCESS; 08770 }
|
|
sip_do_debug: Enable SIP Debugging in CLI ---
Definition at line 8695 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(). 08696 { 08697 struct hostent *hp; 08698 struct ast_hostent ahp; 08699 char iabuf[INET_ADDRSTRLEN]; 08700 int port = 0; 08701 char *p, *arg; 08702 08703 if (argc != 4) 08704 return RESULT_SHOWUSAGE; 08705 arg = argv[3]; 08706 p = strstr(arg, ":"); 08707 if (p) { 08708 *p = '\0'; 08709 p++; 08710 port = atoi(p); 08711 } 08712 hp = ast_gethostbyname(arg, &ahp); 08713 if (hp == NULL) { 08714 return RESULT_SHOWUSAGE; 08715 } 08716 debugaddr.sin_family = AF_INET; 08717 memcpy(&debugaddr.sin_addr, hp->h_addr, sizeof(debugaddr.sin_addr)); 08718 debugaddr.sin_port = htons(port); 08719 if (port == 0) 08720 ast_cli(fd, "SIP Debugging Enabled for IP: %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), debugaddr.sin_addr)); 08721 else 08722 ast_cli(fd, "SIP Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), debugaddr.sin_addr), port); 08723 sipdebug |= SIP_DEBUG_CONSOLE; 08724 return RESULT_SUCCESS; 08725 }
|
|
sip_do_debug_peer: Turn on SIP debugging with peer mask
Definition at line 8728 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(). 08729 { 08730 struct sip_peer *peer; 08731 char iabuf[INET_ADDRSTRLEN]; 08732 if (argc != 4) 08733 return RESULT_SHOWUSAGE; 08734 peer = find_peer(argv[3], NULL, 1); 08735 if (peer) { 08736 if (peer->addr.sin_addr.s_addr) { 08737 debugaddr.sin_family = AF_INET; 08738 memcpy(&debugaddr.sin_addr, &peer->addr.sin_addr, sizeof(debugaddr.sin_addr)); 08739 debugaddr.sin_port = peer->addr.sin_port; 08740 ast_cli(fd, "SIP Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), debugaddr.sin_addr), ntohs(debugaddr.sin_port)); 08741 sipdebug |= SIP_DEBUG_CONSOLE; 08742 } else 08743 ast_cli(fd, "Unable to get IP address of peer '%s'\n", argv[3]); 08744 ASTOBJ_UNREF(peer,sip_destroy_peer); 08745 } else 08746 ast_cli(fd, "No such peer '%s'\n", argv[3]); 08747 return RESULT_SUCCESS; 08748 }
|
|
sip_do_history: Enable SIP History logging (CLI) ---
Definition at line 8830 of file chan_sip.c. References ast_cli(), recordhistory, RESULT_SHOWUSAGE, and RESULT_SUCCESS. 08831 { 08832 if (argc != 2) { 08833 return RESULT_SHOWUSAGE; 08834 } 08835 recordhistory = 1; 08836 ast_cli(fd, "SIP History Recording Enabled (use 'sip show history')\n"); 08837 return RESULT_SUCCESS; 08838 }
|
|
sip_do_reload: Reload module
Definition at line 13038 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(). 13039 { 13040 clear_realm_authentication(authl); 13041 clear_sip_domains(); 13042 authl = NULL; 13043 13044 /* First, destroy all outstanding registry calls */ 13045 /* This is needed, since otherwise active registry entries will not be destroyed */ 13046 ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { 13047 ASTOBJ_RDLOCK(iterator); 13048 if (iterator->call) { 13049 if (option_debug > 2) 13050 ast_log(LOG_DEBUG, "Destroying active SIP dialog for registry %s@%s\n", iterator->username, iterator->hostname); 13051 /* This will also remove references to the registry */ 13052 sip_destroy(iterator->call); 13053 } 13054 ASTOBJ_UNLOCK(iterator); 13055 } while(0)); 13056 13057 ASTOBJ_CONTAINER_DESTROYALL(&userl, sip_destroy_user); 13058 ASTOBJ_CONTAINER_DESTROYALL(®l, sip_registry_destroy); 13059 ASTOBJ_CONTAINER_MARKALL(&peerl); 13060 reload_config(); 13061 /* Prune peers who still are supposed to be deleted */ 13062 ASTOBJ_CONTAINER_PRUNE_MARKED(&peerl, sip_destroy_peer); 13063 13064 sip_poke_all_peers(); 13065 sip_send_all_registers(); 13066 13067 return 0; 13068 }
|
|
sip_dtmfmode: change the DTMFmode for a SIP call (application) ---
Definition at line 12793 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(). 12794 { 12795 struct sip_pvt *p; 12796 char *mode; 12797 if (data) 12798 mode = (char *)data; 12799 else { 12800 ast_log(LOG_WARNING, "This application requires the argument: info, inband, rfc2833\n"); 12801 return 0; 12802 } 12803 ast_mutex_lock(&chan->lock); 12804 if (chan->type != channeltype) { 12805 ast_log(LOG_WARNING, "Call this application only on SIP incoming calls\n"); 12806 ast_mutex_unlock(&chan->lock); 12807 return 0; 12808 } 12809 p = chan->tech_pvt; 12810 if (!p) { 12811 ast_mutex_unlock(&chan->lock); 12812 return 0; 12813 } 12814 ast_mutex_lock(&p->lock); 12815 if (!strcasecmp(mode,"info")) { 12816 ast_clear_flag(p, SIP_DTMF); 12817 ast_set_flag(p, SIP_DTMF_INFO); 12818 } else if (!strcasecmp(mode,"rfc2833")) { 12819 ast_clear_flag(p, SIP_DTMF); 12820 ast_set_flag(p, SIP_DTMF_RFC2833); 12821 } else if (!strcasecmp(mode,"inband")) { 12822 ast_clear_flag(p, SIP_DTMF); 12823 ast_set_flag(p, SIP_DTMF_INBAND); 12824 } else 12825 ast_log(LOG_WARNING, "I don't know about this dtmf mode: %s\n",mode); 12826 if (ast_test_flag(p, SIP_DTMF) == SIP_DTMF_INBAND) { 12827 if (!p->vad) { 12828 p->vad = ast_dsp_new(); 12829 ast_dsp_set_features(p->vad, DSP_FEATURE_DTMF_DETECT); 12830 } 12831 } else { 12832 if (p->vad) { 12833 ast_dsp_free(p->vad); 12834 p->vad = NULL; 12835 } 12836 } 12837 ast_mutex_unlock(&p->lock); 12838 ast_mutex_unlock(&chan->lock); 12839 return 0; 12840 }
|
|
dump_history: Dump SIP history to debug log file at end of lifespan for SIP dialog
Definition at line 8576 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(). 08577 { 08578 int x; 08579 struct sip_history *hist; 08580 08581 if (!dialog) 08582 return; 08583 08584 ast_log(LOG_DEBUG, "\n---------- SIP HISTORY for '%s' \n", dialog->callid); 08585 if (dialog->subscribed) 08586 ast_log(LOG_DEBUG, " * Subscription\n"); 08587 else 08588 ast_log(LOG_DEBUG, " * SIP Call\n"); 08589 x = 0; 08590 hist = dialog->history; 08591 while(hist) { 08592 x++; 08593 ast_log(LOG_DEBUG, " %d. %s\n", x, hist->event); 08594 hist = hist->next; 08595 } 08596 if (!x) 08597 ast_log(LOG_DEBUG, "Call '%s' has no history\n", dialog->callid); 08598 ast_log(LOG_DEBUG, "\n---------- END SIP HISTORY for '%s' \n", dialog->callid); 08599 08600 }
|
|
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 12989 of file chan_sip.c. References sip_pvt::peercapability, and ast_channel::tech_pvt. 12990 { 12991 struct sip_pvt *p = chan->tech_pvt; 12992 return p->peercapability; 12993 }
|
|
sip_get_rtp_peer: Returns null if we can't reinvite (part of RTP interface)
Definition at line 12697 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. 12698 { 12699 struct sip_pvt *p; 12700 struct ast_rtp *rtp = NULL; 12701 p = chan->tech_pvt; 12702 if (!p) 12703 return NULL; 12704 ast_mutex_lock(&p->lock); 12705 if (p->rtp && ast_test_flag(p, SIP_CAN_REINVITE)) 12706 rtp = p->rtp; 12707 ast_mutex_unlock(&p->lock); 12708 return rtp; 12709 }
|
|
sip_get_vrtp_peer: Returns null if we can't reinvite video (part of RTP interface)
Definition at line 12712 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. 12713 { 12714 struct sip_pvt *p; 12715 struct ast_rtp *rtp = NULL; 12716 p = chan->tech_pvt; 12717 if (!p) 12718 return NULL; 12719 12720 ast_mutex_lock(&p->lock); 12721 if (p->vrtp && ast_test_flag(p, SIP_CAN_REINVITE)) 12722 rtp = p->vrtp; 12723 ast_mutex_unlock(&p->lock); 12724 return rtp; 12725 }
|
|
sip_getheader: Get a SIP header (dialplan app) ---
Definition at line 12874 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(). 12875 { 12876 static int dep_warning = 0; 12877 struct sip_pvt *p; 12878 char *argv, *varname = NULL, *header = NULL, *content; 12879 12880 if (!dep_warning) { 12881 ast_log(LOG_WARNING, "SIPGetHeader is deprecated, use the SIP_HEADER function instead.\n"); 12882 dep_warning = 1; 12883 } 12884 12885 argv = ast_strdupa(data); 12886 if (!argv) { 12887 ast_log(LOG_DEBUG, "Memory allocation failed\n"); 12888 return 0; 12889 } 12890 12891 if (strchr (argv, '=') ) { /* Pick out argumenet */ 12892 varname = strsep (&argv, "="); 12893 header = strsep (&argv, "\0"); 12894 } 12895 12896 if (!varname || !header) { 12897 ast_log(LOG_DEBUG, "SipGetHeader: Ignoring command, Syntax error in argument\n"); 12898 return 0; 12899 } 12900 12901 ast_mutex_lock(&chan->lock); 12902 if (chan->type != channeltype) { 12903 ast_log(LOG_WARNING, "Call this application only on incoming SIP calls\n"); 12904 ast_mutex_unlock(&chan->lock); 12905 return 0; 12906 } 12907 12908 p = chan->tech_pvt; 12909 content = get_header(&p->initreq, header); /* Get the header */ 12910 if (!ast_strlen_zero(content)) { 12911 pbx_builtin_setvar_helper(chan, varname, content); 12912 } else { 12913 ast_log(LOG_WARNING,"SIP Header %s not found for channel variable %s\n", header, varname); 12914 ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101); 12915 } 12916 12917 ast_mutex_unlock(&chan->lock); 12918 return 0; 12919 }
|
|
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 8852 of file chan_sip.c. References ast_cli(), RESULT_SHOWUSAGE, RESULT_SUCCESS, SIP_DEBUG_CONSOLE, and sipdebug. 08854 { 08855 if (argc != 3) 08856 return RESULT_SHOWUSAGE; 08857 sipdebug &= ~SIP_DEBUG_CONSOLE; 08858 ast_cli(fd, "SIP Debugging Disabled\n"); 08859 return RESULT_SUCCESS; 08860 }
|
|
sip_no_history: Disable SIP History logging (CLI) ---
Definition at line 8841 of file chan_sip.c. References ast_cli(), recordhistory, RESULT_SHOWUSAGE, and RESULT_SUCCESS. 08842 { 08843 if (argc != 3) { 08844 return RESULT_SHOWUSAGE; 08845 } 08846 recordhistory = 0; 08847 ast_cli(fd, "SIP History Recording Disabled\n"); 08848 return RESULT_SUCCESS; 08849 }
|
|
sip_notify: Send SIP notify to peer
Definition at line 8773 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. 08774 { 08775 struct ast_variable *varlist; 08776 int i; 08777 08778 if (argc < 4) 08779 return RESULT_SHOWUSAGE; 08780 08781 if (!notify_types) { 08782 ast_cli(fd, "No %s file found, or no types listed there\n", notify_config); 08783 return RESULT_FAILURE; 08784 } 08785 08786 varlist = ast_variable_browse(notify_types, argv[2]); 08787 08788 if (!varlist) { 08789 ast_cli(fd, "Unable to find notify type '%s'\n", argv[2]); 08790 return RESULT_FAILURE; 08791 } 08792 08793 for (i = 3; i < argc; i++) { 08794 struct sip_pvt *p; 08795 struct sip_request req; 08796 struct ast_variable *var; 08797 08798 p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY); 08799 if (!p) { 08800 ast_log(LOG_WARNING, "Unable to build sip pvt data for notify\n"); 08801 return RESULT_FAILURE; 08802 } 08803 08804 if (create_addr(p, argv[i])) { 08805 /* Maybe they're not registered, etc. */ 08806 sip_destroy(p); 08807 ast_cli(fd, "Could not create address for '%s'\n", argv[i]); 08808 continue; 08809 } 08810 08811 initreqprep(&req, p, SIP_NOTIFY); 08812 08813 for (var = varlist; var; var = var->next) 08814 add_header(&req, var->name, var->value); 08815 08816 add_blank_header(&req); 08817 /* Recalculate our side, and recalculate Call ID */ 08818 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 08819 memcpy(&p->ourip, &__ourip, sizeof(p->ourip)); 08820 build_via(p, p->via, sizeof(p->via)); 08821 build_callid(p->callid, sizeof(p->callid), p->ourip, p->fromdomain); 08822 ast_cli(fd, "Sending NOTIFY of type '%s' to '%s'\n", argv[2], argv[i]); 08823 transmit_sip_request(p, &req); 08824 sip_scheddestroy(p, 15000); 08825 } 08826 08827 return RESULT_SUCCESS; 08828 }
|
|
sip_park: Park a call ---
Definition at line 10070 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(). 10071 { 10072 struct sip_dual *d; 10073 struct ast_channel *chan1m, *chan2m; 10074 pthread_t th; 10075 chan1m = ast_channel_alloc(0); 10076 chan2m = ast_channel_alloc(0); 10077 if ((!chan2m) || (!chan1m)) { 10078 if (chan1m) 10079 ast_hangup(chan1m); 10080 if (chan2m) 10081 ast_hangup(chan2m); 10082 return -1; 10083 } 10084 snprintf(chan1m->name, sizeof(chan1m->name), "Parking/%s", chan1->name); 10085 /* Make formats okay */ 10086 chan1m->readformat = chan1->readformat; 10087 chan1m->writeformat = chan1->writeformat; 10088 ast_channel_masquerade(chan1m, chan1); 10089 /* Setup the extensions and such */ 10090 ast_copy_string(chan1m->context, chan1->context, sizeof(chan1m->context)); 10091 ast_copy_string(chan1m->exten, chan1->exten, sizeof(chan1m->exten)); 10092 chan1m->priority = chan1->priority; 10093 10094 /* We make a clone of the peer channel too, so we can play 10095 back the announcement */ 10096 snprintf(chan2m->name, sizeof (chan2m->name), "SIPPeer/%s",chan2->name); 10097 /* Make formats okay */ 10098 chan2m->readformat = chan2->readformat; 10099 chan2m->writeformat = chan2->writeformat; 10100 ast_channel_masquerade(chan2m, chan2); 10101 /* Setup the extensions and such */ 10102 ast_copy_string(chan2m->context, chan2->context, sizeof(chan2m->context)); 10103 ast_copy_string(chan2m->exten, chan2->exten, sizeof(chan2m->exten)); 10104 chan2m->priority = chan2->priority; 10105 ast_mutex_lock(&chan2m->lock); 10106 if (ast_do_masquerade(chan2m)) { 10107 ast_log(LOG_WARNING, "Masquerade failed :(\n"); 10108 ast_mutex_unlock(&chan2m->lock); 10109 ast_hangup(chan2m); 10110 return -1; 10111 } 10112 ast_mutex_unlock(&chan2m->lock); 10113 d = malloc(sizeof(struct sip_dual)); 10114 if (d) { 10115 memset(d, 0, sizeof(*d)); 10116 /* Save original request for followup */ 10117 copy_request(&d->req, req); 10118 d->chan1 = chan1m; 10119 d->chan2 = chan2m; 10120 if (!ast_pthread_create(&th, NULL, sip_park_thread, d)) 10121 return 0; 10122 free(d); 10123 } 10124 return -1; 10125 }
|
|
sip_park_thread: Park SIP call support function
Definition at line 10047 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(). 10048 { 10049 struct ast_channel *chan1, *chan2; 10050 struct sip_dual *d; 10051 struct sip_request req; 10052 int ext; 10053 int res; 10054 d = stuff; 10055 chan1 = d->chan1; 10056 chan2 = d->chan2; 10057 copy_request(&req, &d->req); 10058 free(d); 10059 ast_mutex_lock(&chan1->lock); 10060 ast_do_masquerade(chan1); 10061 ast_mutex_unlock(&chan1->lock); 10062 res = ast_park_call(chan1, chan2, 0, &ext); 10063 /* Then hangup */ 10064 ast_hangup(chan2); 10065 ast_log(LOG_DEBUG, "Parked on extension '%d'\n", ext); 10066 return NULL; 10067 }
|
|
sip_poke_all_peers: Send a poke to all known peers
Definition at line 13005 of file chan_sip.c. References ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_UNLOCK, ASTOBJ_WRLOCK, peerl, and sip_poke_peer(). Referenced by load_module(). 13006 { 13007 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 13008 ASTOBJ_WRLOCK(iterator); 13009 sip_poke_peer(iterator); 13010 ASTOBJ_UNLOCK(iterator); 13011 } while (0) 13012 ); 13013 }
|
|
sip_poke_noanswer: No answer to Qualify poke ---
Definition at line 11390 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(). 11391 { 11392 struct sip_peer *peer = data; 11393 11394 peer->pokeexpire = -1; 11395 if (peer->lastms > -1) { 11396 ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Last qualify: %d\n", peer->name, peer->lastms); 11397 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, -1); 11398 } 11399 if (peer->call) 11400 sip_destroy(peer->call); 11401 peer->call = NULL; 11402 peer->lastms = -1; 11403 ast_device_state_changed("SIP/%s", peer->name); 11404 /* Try again quickly */ 11405 peer->pokeexpire = ast_sched_add(sched, DEFAULT_FREQ_NOTOK, sip_poke_peer_s, peer); 11406 return 0; 11407 }
|
|
sip_poke_peer: Check availability of peer, also keep NAT open ---
Definition at line 11412 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(). 11413 { 11414 struct sip_pvt *p; 11415 if (!peer->maxms || !peer->addr.sin_addr.s_addr) { 11416 /* IF we have no IP, or this isn't to be monitored, return 11417 imeediately after clearing things out */ 11418 if (peer->pokeexpire > -1) 11419 ast_sched_del(sched, peer->pokeexpire); 11420 peer->lastms = 0; 11421 peer->pokeexpire = -1; 11422 peer->call = NULL; 11423 return 0; 11424 } 11425 if (peer->call > 0) { 11426 if (sipdebug) 11427 ast_log(LOG_NOTICE, "Still have a QUALIFY dialog active, deleting\n"); 11428 sip_destroy(peer->call); 11429 } 11430 p = peer->call = sip_alloc(NULL, NULL, 0, SIP_OPTIONS); 11431 if (!peer->call) { 11432 ast_log(LOG_WARNING, "Unable to allocate dialog for poking peer '%s'\n", peer->name); 11433 return -1; 11434 } 11435 memcpy(&p->sa, &peer->addr, sizeof(p->sa)); 11436 memcpy(&p->recv, &peer->addr, sizeof(p->sa)); 11437 ast_copy_flags(p, peer, SIP_FLAGS_TO_COPY); 11438 11439 /* Send OPTIONs to peer's fullcontact */ 11440 if (!ast_strlen_zero(peer->fullcontact)) { 11441 ast_copy_string (p->fullcontact, peer->fullcontact, sizeof(p->fullcontact)); 11442 } 11443 11444 if (!ast_strlen_zero(peer->tohost)) 11445 ast_copy_string(p->tohost, peer->tohost, sizeof(p->tohost)); 11446 else 11447 ast_inet_ntoa(p->tohost, sizeof(p->tohost), peer->addr.sin_addr); 11448 11449 /* Recalculate our side, and recalculate Call ID */ 11450 if (ast_sip_ouraddrfor(&p->sa.sin_addr,&p->ourip)) 11451 memcpy(&p->ourip, &__ourip, sizeof(p->ourip)); 11452 build_via(p, p->via, sizeof(p->via)); 11453 build_callid(p->callid, sizeof(p->callid), p->ourip, p->fromdomain); 11454 11455 if (peer->pokeexpire > -1) 11456 ast_sched_del(sched, peer->pokeexpire); 11457 p->peerpoke = peer; 11458 ast_set_flag(p, SIP_OUTGOING); 11459 #ifdef VOCAL_DATA_HACK 11460 ast_copy_string(p->username, "__VOCAL_DATA_SHOULD_READ_THE_SIP_SPEC__", sizeof(p->username)); 11461 transmit_invite(p, SIP_INVITE, 0, 2); 11462 #else 11463 transmit_invite(p, SIP_OPTIONS, 0, 2); 11464 #endif 11465 gettimeofday(&peer->ps, NULL); 11466 peer->pokeexpire = ast_sched_add(sched, DEFAULT_MAXMS * 2, sip_poke_noanswer, peer); 11467 11468 return 0; 11469 }
|
|
Definition at line 5659 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(). 05660 { 05661 struct sip_peer *peer = data; 05662 peer->pokeexpire = -1; 05663 sip_poke_peer(peer); 05664 return 0; 05665 }
|
|
sip_prune_realtime: Remove temporary realtime objects from memory (CLI) ---
Definition at line 7646 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. 07647 { 07648 struct sip_peer *peer; 07649 struct sip_user *user; 07650 int pruneuser = 0; 07651 int prunepeer = 0; 07652 int multi = 0; 07653 char *name = NULL; 07654 regex_t regexbuf; 07655 07656 switch (argc) { 07657 case 4: 07658 if (!strcasecmp(argv[3], "user")) 07659 return RESULT_SHOWUSAGE; 07660 if (!strcasecmp(argv[3], "peer")) 07661 return RESULT_SHOWUSAGE; 07662 if (!strcasecmp(argv[3], "like")) 07663 return RESULT_SHOWUSAGE; 07664 if (!strcasecmp(argv[3], "all")) { 07665 multi = 1; 07666 pruneuser = prunepeer = 1; 07667 } else { 07668 pruneuser = prunepeer = 1; 07669 name = argv[3]; 07670 } 07671 break; 07672 case 5: 07673 if (!strcasecmp(argv[4], "like")) 07674 return RESULT_SHOWUSAGE; 07675 if (!strcasecmp(argv[3], "all")) 07676 return RESULT_SHOWUSAGE; 07677 if (!strcasecmp(argv[3], "like")) { 07678 multi = 1; 07679 name = argv[4]; 07680 pruneuser = prunepeer = 1; 07681 } else if (!strcasecmp(argv[3], "user")) { 07682 pruneuser = 1; 07683 if (!strcasecmp(argv[4], "all")) 07684 multi = 1; 07685 else 07686 name = argv[4]; 07687 } else if (!strcasecmp(argv[3], "peer")) { 07688 prunepeer = 1; 07689 if (!strcasecmp(argv[4], "all")) 07690 multi = 1; 07691 else 07692 name = argv[4]; 07693 } else 07694 return RESULT_SHOWUSAGE; 07695 break; 07696 case 6: 07697 if (strcasecmp(argv[4], "like")) 07698 return RESULT_SHOWUSAGE; 07699 if (!strcasecmp(argv[3], "user")) { 07700 pruneuser = 1; 07701 name = argv[5]; 07702 } else if (!strcasecmp(argv[3], "peer")) { 07703 prunepeer = 1; 07704 name = argv[5]; 07705 } else 07706 return RESULT_SHOWUSAGE; 07707 break; 07708 default: 07709 return RESULT_SHOWUSAGE; 07710 } 07711 07712 if (multi && name) { 07713 if (regcomp(®exbuf, name, REG_EXTENDED | REG_NOSUB)) 07714 return RESULT_SHOWUSAGE; 07715 } 07716 07717 if (multi) { 07718 if (prunepeer) { 07719 int pruned = 0; 07720 07721 ASTOBJ_CONTAINER_WRLOCK(&peerl); 07722 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 07723 ASTOBJ_RDLOCK(iterator); 07724 if (name && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 07725 ASTOBJ_UNLOCK(iterator); 07726 continue; 07727 }; 07728 if (ast_test_flag((&iterator->flags_page2), SIP_PAGE2_RTCACHEFRIENDS)) { 07729 ASTOBJ_MARK(iterator); 07730 pruned++; 07731 } 07732 ASTOBJ_UNLOCK(iterator); 07733 } while (0) ); 07734 if (pruned) { 07735 ASTOBJ_CONTAINER_PRUNE_MARKED(&peerl, sip_destroy_peer); 07736 ast_cli(fd, "%d peers pruned.\n", pruned); 07737 } else 07738 ast_cli(fd, "No peers found to prune.\n"); 07739 ASTOBJ_CONTAINER_UNLOCK(&peerl); 07740 } 07741 if (pruneuser) { 07742 int pruned = 0; 07743 07744 ASTOBJ_CONTAINER_WRLOCK(&userl); 07745 ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do { 07746 ASTOBJ_RDLOCK(iterator); 07747 if (name && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 07748 ASTOBJ_UNLOCK(iterator); 07749 continue; 07750 }; 07751 if (ast_test_flag((&iterator->flags_page2), SIP_PAGE2_RTCACHEFRIENDS)) { 07752 ASTOBJ_MARK(iterator); 07753 pruned++; 07754 } 07755 ASTOBJ_UNLOCK(iterator); 07756 } while (0) ); 07757 if (pruned) { 07758 ASTOBJ_CONTAINER_PRUNE_MARKED(&userl, sip_destroy_user); 07759 ast_cli(fd, "%d users pruned.\n", pruned); 07760 } else 07761 ast_cli(fd, "No users found to prune.\n"); 07762 ASTOBJ_CONTAINER_UNLOCK(&userl); 07763 } 07764 } else { 07765 if (prunepeer) { 07766 if ((peer = ASTOBJ_CONTAINER_FIND_UNLINK(&peerl, name))) { 07767 if (!ast_test_flag((&peer->flags_page2), SIP_PAGE2_RTCACHEFRIENDS)) { 07768 ast_cli(fd, "Peer '%s' is not a Realtime peer, cannot be pruned.\n", name); 07769 ASTOBJ_CONTAINER_LINK(&peerl, peer); 07770 } else 07771 ast_cli(fd, "Peer '%s' pruned.\n", name); 07772 ASTOBJ_UNREF(peer, sip_destroy_peer); 07773 } else 07774 ast_cli(fd, "Peer '%s' not found.\n", name); 07775 } 07776 if (pruneuser) { 07777 if ((user = ASTOBJ_CONTAINER_FIND_UNLINK(&userl, name))) { 07778 if (!ast_test_flag((&user->flags_page2), SIP_PAGE2_RTCACHEFRIENDS)) { 07779 ast_cli(fd, "User '%s' is not a Realtime user, cannot be pruned.\n", name); 07780 ASTOBJ_CONTAINER_LINK(&userl, user); 07781 } else 07782 ast_cli(fd, "User '%s' pruned.\n", name); 07783 ASTOBJ_UNREF(user, sip_destroy_user); 07784 } else 07785 ast_cli(fd, "User '%s' not found.\n", name); 07786 } 07787 } 07788 07789 return RESULT_SUCCESS; 07790 }
|
|
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 5277 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(). 05278 { 05279 05280 /* if we are here, our registration timed out, so we'll just do it over */ 05281 struct sip_registry *r = ASTOBJ_REF((struct sip_registry *) data); 05282 struct sip_pvt *p; 05283 int res; 05284 05285 /* if we couldn't get a reference to the registry object, punt */ 05286 if (!r) 05287 return 0; 05288 05289 ast_log(LOG_NOTICE, " -- Registration for '%s@%s' timed out, trying again (Attempt #%d)\n", r->username, r->hostname, r->regattempts); 05290 if (r->call) { 05291 /* Unlink us, destroy old call. Locking is not relevant here because all this happens 05292 in the single SIP manager thread. */ 05293 p = r->call; 05294 if (p->registry) 05295 ASTOBJ_UNREF(p->registry, sip_registry_destroy); 05296 r->call = NULL; 05297 ast_set_flag(p, SIP_NEEDDESTROY); 05298 /* Pretend to ACK anything just in case */ 05299 __sip_pretend_ack(p); 05300 } 05301 /* If we have a limit, stop registration and give up */ 05302 if (global_regattempts_max && (r->regattempts > global_regattempts_max)) { 05303 /* Ok, enough is enough. Don't try any more */ 05304 /* We could add an external notification here... 05305 steal it from app_voicemail :-) */ 05306 ast_log(LOG_NOTICE, " -- Giving up forever trying to register '%s@%s'\n", r->username, r->hostname); 05307 r->regstate=REG_STATE_FAILED; 05308 } else { 05309 r->regstate=REG_STATE_UNREGISTERED; 05310 r->timeout = -1; 05311 res=transmit_register(r, SIP_REGISTER, NULL, NULL); 05312 } 05313 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)); 05314 ASTOBJ_UNREF(r,sip_registry_destroy); 05315 return 0; 05316 }
|
|
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 13071 of file chan_sip.c. References ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), restart_monitor(), and sip_reloading. Referenced by reload(). 13072 { 13073 13074 ast_mutex_lock(&sip_reload_lock); 13075 if (sip_reloading) { 13076 ast_verbose("Previous SIP reload not yet done\n"); 13077 } else 13078 sip_reloading = 1; 13079 ast_mutex_unlock(&sip_reload_lock); 13080 restart_monitor(); 13081 13082 return 0; 13083 }
|
|
sip_request: PBX interface function -build SIP pvt structure ---
Definition at line 11538 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. 11539 { 11540 int oldformat; 11541 struct sip_pvt *p; 11542 struct ast_channel *tmpc = NULL; 11543 char *ext, *host; 11544 char tmp[256]; 11545 char *dest = data; 11546 11547 oldformat = format; 11548 format &= ((AST_FORMAT_MAX_AUDIO << 1) - 1); 11549 if (!format) { 11550 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)); 11551 *cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; /* Can't find codec to connect to host */ 11552 return NULL; 11553 } 11554 p = sip_alloc(NULL, NULL, 0, SIP_INVITE); 11555 if (!p) { 11556 ast_log(LOG_ERROR, "Unable to build sip pvt data for '%s' (Out of memory)\n", (char *)data); 11557 *cause = AST_CAUSE_SWITCH_CONGESTION; 11558 return NULL; 11559 } 11560 11561 p->options = calloc(1, sizeof(*p->options)); 11562 if (!p->options) { 11563 sip_destroy(p); 11564 ast_log(LOG_ERROR, "Unable to build option SIP data structure - Out of memory\n"); 11565 *cause = AST_CAUSE_SWITCH_CONGESTION; 11566 return NULL; 11567 } 11568 11569 ast_copy_string(tmp, dest, sizeof(tmp)); 11570 host = strchr(tmp, '@'); 11571 if (host) { 11572 *host = '\0'; 11573 host++; 11574 ext = tmp; 11575 } else { 11576 ext = strchr(tmp, '/'); 11577 if (ext) { 11578 *ext++ = '\0'; 11579 host = tmp; 11580 } 11581 else { 11582 host = tmp; 11583 ext = NULL; 11584 } 11585 } 11586 11587 if (create_addr(p, host)) { 11588 *cause = AST_CAUSE_UNREGISTERED; 11589 sip_destroy(p); 11590 return NULL; 11591 } 11592 if (ast_strlen_zero(p->peername) && ext) 11593 ast_copy_string(p->peername, ext, sizeof(p->peername)); 11594 /* Recalculate our side, and recalculate Call ID */ 11595 if (ast_sip_ouraddrfor(&p->sa.sin_addr,&p->ourip)) 11596 memcpy(&p->ourip, &__ourip, sizeof(p->ourip)); 11597 build_via(p, p->via, sizeof(p->via)); 11598 build_callid(p->callid, sizeof(p->callid), p->ourip, p->fromdomain); 11599 11600 /* We have an extension to call, don't use the full contact here */ 11601 /* This to enable dialling registered peers with extension dialling, 11602 like SIP/peername/extension 11603 SIP/peername will still use the full contact */ 11604 if (ext) { 11605 ast_copy_string(p->username, ext, sizeof(p->username)); 11606 p->fullcontact[0] = 0; 11607 } 11608 #if 0 11609 printf("Setting up to call extension '%s' at '%s'\n", ext ? ext : "<none>", host); 11610 #endif 11611 p->prefcodec = format; 11612 ast_mutex_lock(&p->lock); 11613 tmpc = sip_new(p, AST_STATE_DOWN, host); /* Place the call */ 11614 ast_mutex_unlock(&p->lock); 11615 if (!tmpc) 11616 sip_destroy(p); 11617 ast_update_use_count(); 11618 restart_monitor(); 11619 return tmpc; 11620 }
|
|
sip_reregister: Update registration with SIP Proxy---
Definition at line 5242 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(). 05243 { 05244 /* if we are here, we know that we need to reregister. */ 05245 struct sip_registry *r= ASTOBJ_REF((struct sip_registry *) data); 05246 05247 /* if we couldn't get a reference to the registry object, punt */ 05248 if (!r) 05249 return 0; 05250 05251 if (r->call && recordhistory) { 05252 char tmp[80]; 05253 snprintf(tmp, sizeof(tmp), "Account: %s@%s", r->username, r->hostname); 05254 append_history(r->call, "RegistryRenew", tmp); 05255 } 05256 /* Since registry's are only added/removed by the the monitor thread, this 05257 may be overkill to reference/dereference at all here */ 05258 if (sipdebug) 05259 ast_log(LOG_NOTICE, " -- Re-registration for %s@%s\n", r->username, r->hostname); 05260 05261 r->expire = -1; 05262 __sip_do_register(r); 05263 ASTOBJ_UNREF(r, sip_registry_destroy); 05264 return 0; 05265 }
|
|
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 13016 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(). 13017 { 13018 int ms; 13019 int regspacing; 13020 if (!regobjs) 13021 return; 13022 regspacing = default_expiry * 1000/regobjs; 13023 if (regspacing > 100) 13024 regspacing = 100; 13025 ms = regspacing; 13026 ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { 13027 ASTOBJ_WRLOCK(iterator); 13028 if (iterator->expire > -1) 13029 ast_sched_del(sched, iterator->expire); 13030 ms += regspacing; 13031 iterator->expire = ast_sched_add(sched, ms, sip_reregister, iterator); 13032 ASTOBJ_UNLOCK(iterator); 13033 } while (0) 13034 ); 13035 }
|
|
sip_send_mwi_to_peer: Send message waiting indication ---
Definition at line 11187 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. 11188 { 11189 /* Called with peerl lock, but releases it */ 11190 struct sip_pvt *p; 11191 int newmsgs, oldmsgs; 11192 11193 /* Check for messages */ 11194 ast_app_messagecount(peer->mailbox, &newmsgs, &oldmsgs); 11195 11196 time(&peer->lastmsgcheck); 11197 11198 /* Return now if it's the same thing we told them last time */ 11199 if (((newmsgs << 8) | (oldmsgs)) == peer->lastmsgssent) { 11200 return 0; 11201 } 11202 11203 p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY); 11204 if (!p) { 11205 ast_log(LOG_WARNING, "Unable to build sip pvt data for MWI\n"); 11206 return -1; 11207 } 11208 peer->lastmsgssent = ((newmsgs << 8) | (oldmsgs)); 11209 if (create_addr_from_peer(p, peer)) { 11210 /* Maybe they're not registered, etc. */ 11211 sip_destroy(p); 11212 return 0; 11213 } 11214 /* Recalculate our side, and recalculate Call ID */ 11215 if (ast_sip_ouraddrfor(&p->sa.sin_addr,&p->ourip)) 11216 memcpy(&p->ourip, &__ourip, sizeof(p->ourip)); 11217 build_via(p, p->via, sizeof(p->via)); 11218 build_callid(p->callid, sizeof(p->callid), p->ourip, p->fromdomain); 11219 /* Send MWI */ 11220 ast_set_flag(p, SIP_OUTGOING); 11221 transmit_notify_with_mwi(p, newmsgs, oldmsgs, peer->vmexten); 11222 sip_scheddestroy(p, 15000); 11223 return 0; 11224 }
|
|
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 12728 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. 12729 { 12730 struct sip_pvt *p; 12731 12732 p = chan->tech_pvt; 12733 if (!p) 12734 return -1; 12735 ast_mutex_lock(&p->lock); 12736 if (rtp) 12737 ast_rtp_get_peer(rtp, &p->redirip); 12738 else 12739 memset(&p->redirip, 0, sizeof(p->redirip)); 12740 if (vrtp) 12741 ast_rtp_get_peer(vrtp, &p->vredirip); 12742 else 12743 memset(&p->vredirip, 0, sizeof(p->vredirip)); 12744 p->redircodecs = codecs; 12745 if (!ast_test_flag(p, SIP_GOTREFER)) { 12746 if (!p->pendinginvite) { 12747 if (option_debug > 2) { 12748 char iabuf[INET_ADDRSTRLEN]; 12749 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)); 12750 } 12751 transmit_reinvite_with_sdp(p); 12752 } else if (!ast_test_flag(p, SIP_PENDINGBYE)) { 12753 if (option_debug > 2) { 12754 char iabuf[INET_ADDRSTRLEN]; 12755 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)); 12756 } 12757 ast_set_flag(p, SIP_NEEDREINVITE); 12758 } 12759 } 12760 /* Reset lastrtprx timer */ 12761 time(&p->lastrtprx); 12762 time(&p->lastrtptx); 12763 ast_mutex_unlock(&p->lock); 12764 return 0; 12765 }
|
|
sip_show_channel: Show details of one call ---
Definition at line 8466 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. 08467 { 08468 struct sip_pvt *cur; 08469 char iabuf[INET_ADDRSTRLEN]; 08470 size_t len; 08471 int found = 0; 08472 08473 if (argc != 4) 08474 return RESULT_SHOWUSAGE; 08475 len = strlen(argv[3]); 08476 ast_mutex_lock(&iflock); 08477 cur = iflist; 08478 while(cur) { 08479 if (!strncasecmp(cur->callid, argv[3],len)) { 08480 ast_cli(fd,"\n"); 08481 if (cur->subscribed != NONE) 08482 ast_cli(fd, " * Subscription (type: %s)\n", subscription_type2str(cur->subscribed)); 08483 else 08484 ast_cli(fd, " * SIP Call\n"); 08485 ast_cli(fd, " Direction: %s\n", ast_test_flag(cur, SIP_OUTGOING)?"Outgoing":"Incoming"); 08486 ast_cli(fd, " Call-ID: %s\n", cur->callid); 08487 ast_cli(fd, " Our Codec Capability: %d\n", cur->capability); 08488 ast_cli(fd, " Non-Codec Capability: %d\n", cur->noncodeccapability); 08489 ast_cli(fd, " Their Codec Capability: %d\n", cur->peercapability); 08490 ast_cli(fd, " Joint Codec Capability: %d\n", cur->jointcapability); 08491 ast_cli(fd, " Format %s\n", ast_getformatname(cur->owner ? cur->owner->nativeformats : 0) ); 08492 ast_cli(fd, " Theoretical Address: %s:%d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), cur->sa.sin_addr), ntohs(cur->sa.sin_port)); 08493 ast_cli(fd, " Received Address: %s:%d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), cur->recv.sin_addr), ntohs(cur->recv.sin_port)); 08494 ast_cli(fd, " NAT Support: %s\n", nat2str(ast_test_flag(cur, SIP_NAT))); 08495 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)" ); 08496 ast_cli(fd, " Our Tag: %s\n", cur->tag); 08497 ast_cli(fd, " Their Tag: %s\n", cur->theirtag); 08498 ast_cli(fd, " SIP User agent: %s\n", cur->useragent); 08499 if (!ast_strlen_zero(cur->username)) 08500 ast_cli(fd, " Username: %s\n", cur->username); 08501 if (!ast_strlen_zero(cur->peername)) 08502 ast_cli(fd, " Peername: %s\n", cur->peername); 08503 if (!ast_strlen_zero(cur->uri)) 08504 ast_cli(fd, " Original uri: %s\n", cur->uri); 08505 if (!ast_strlen_zero(cur->cid_num)) 08506 ast_cli(fd, " Caller-ID: %s\n", cur->cid_num); 08507 ast_cli(fd, " Need Destroy: %d\n", ast_test_flag(cur, SIP_NEEDDESTROY)); 08508 ast_cli(fd, " Last Message: %s\n", cur->lastmsg); 08509 ast_cli(fd, " Promiscuous Redir: %s\n", ast_test_flag(cur, SIP_PROMISCREDIR) ? "Yes" : "No"); 08510 ast_cli(fd, " Route: %s\n", cur->route ? cur->route->hop : "N/A"); 08511 ast_cli(fd, " DTMF Mode: %s\n", dtmfmode2str(ast_test_flag(cur, SIP_DTMF))); 08512 ast_cli(fd, " SIP Options: "); 08513 if (cur->sipoptions) { 08514 int x; 08515 for (x=0 ; (x < (sizeof(sip_options) / sizeof(sip_options[0]))); x++) { 08516 if (cur->sipoptions & sip_options[x].id) 08517 ast_cli(fd, "%s ", sip_options[x].text); 08518 } 08519 } else 08520 ast_cli(fd, "(none)\n"); 08521 ast_cli(fd, "\n\n"); 08522 found++; 08523 } 08524 cur = cur->next; 08525 } 08526 ast_mutex_unlock(&iflock); 08527 if (!found) 08528 ast_cli(fd, "No such SIP Call ID starting with '%s'\n", argv[3]); 08529 return RESULT_SUCCESS; 08530 }
|
|
sip_show_channels: Show active SIP channels ---
Definition at line 8267 of file chan_sip.c. References __sip_show_channels(). 08268 { 08269 return __sip_show_channels(fd, argc, argv, 0); 08270 }
|
|
Definition at line 7823 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. 07824 { 07825 struct domain *d; 07826 07827 if (AST_LIST_EMPTY(&domain_list)) { 07828 ast_cli(fd, "SIP Domain support not enabled.\n\n"); 07829 return RESULT_SUCCESS; 07830 } else { 07831 ast_cli(fd, FORMAT, "Our local SIP domains:", "Context", "Set by"); 07832 AST_LIST_LOCK(&domain_list); 07833 AST_LIST_TRAVERSE(&domain_list, d, list) 07834 ast_cli(fd, FORMAT, d->domain, ast_strlen_zero(d->context) ? "(default)": d->context, 07835 domain_mode_to_text(d->mode)); 07836 AST_LIST_UNLOCK(&domain_list); 07837 ast_cli(fd, "\n"); 07838 return RESULT_SUCCESS; 07839 } 07840 }
|
|
sip_show_history: Show history details of one call ---
Definition at line 8533 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. 08534 { 08535 struct sip_pvt *cur; 08536 struct sip_history *hist; 08537 size_t len; 08538 int x; 08539 int found = 0; 08540 08541 if (argc != 4) 08542 return RESULT_SHOWUSAGE; 08543 if (!recordhistory) 08544 ast_cli(fd, "\n***Note: History recording is currently DISABLED. Use 'sip history' to ENABLE.\n"); 08545 len = strlen(argv[3]); 08546 ast_mutex_lock(&iflock); 08547 cur = iflist; 08548 while(cur) { 08549 if (!strncasecmp(cur->callid, argv[3], len)) { 08550 ast_cli(fd,"\n"); 08551 if (cur->subscribed != NONE) 08552 ast_cli(fd, " * Subscription\n"); 08553 else 08554 ast_cli(fd, " * SIP Call\n"); 08555 x = 0; 08556 hist = cur->history; 08557 while(hist) { 08558 x++; 08559 ast_cli(fd, "%d. %s\n", x, hist->event); 08560 hist = hist->next; 08561 } 08562 if (!x) 08563 ast_cli(fd, "Call '%s' has no history\n", cur->callid); 08564 found++; 08565 } 08566 cur = cur->next; 08567 } 08568 ast_mutex_unlock(&iflock); 08569 if (!found) 08570 ast_cli(fd, "No such SIP Call ID starting with '%s'\n", argv[3]); 08571 return RESULT_SUCCESS; 08572 }
|
|
sip_show_inuse: CLI Command to show calls within limits set by call_limit ---
Definition at line 7290 of file chan_sip.c. References ast_cli(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, FORMAT, FORMAT2, RESULT_SHOWUSAGE, and userl. 07290 { 07291 #define FORMAT "%-25.25s %-15.15s %-15.15s \n" 07292 #define FORMAT2 "%-25.25s %-15.15s %-15.15s \n" 07293 char ilimits[40]; 07294 char iused[40]; 07295 int showall = 0; 07296 07297 if (argc < 3) 07298 return RESULT_SHOWUSAGE; 07299 07300 if (argc == 4 && !strcmp(argv[3],"all")) 07301 showall = 1; 07302 07303 ast_cli(fd, FORMAT, "* User name", "In use", "Limit"); 07304 ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do { 07305 ASTOBJ_RDLOCK(iterator); 07306 if (iterator->call_limit) 07307 snprintf(ilimits, sizeof(ilimits), "%d", iterator->call_limit); 07308 else 07309 ast_copy_string(ilimits, "N/A", sizeof(ilimits)); 07310 snprintf(iused, sizeof(iused), "%d", iterator->inUse); 07311 if (showall || iterator->call_limit) 07312 ast_cli(fd, FORMAT2, iterator->name, iused, ilimits); 07313 ASTOBJ_UNLOCK(iterator); 07314 } while (0) ); 07315 07316 ast_cli(fd, FORMAT, "* Peer name", "In use", "Limit"); 07317 07318 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 07319 ASTOBJ_RDLOCK(iterator); 07320 if (iterator->call_limit) 07321 snprintf(ilimits, sizeof(ilimits), "%d", iterator->call_limit); 07322 else 07323 ast_copy_string(ilimits, "N/A", sizeof(ilimits)); 07324 snprintf(iused, sizeof(iused), "%d", iterator->inUse); 07325 if (showall || iterator->call_limit) 07326 ast_cli(fd, FORMAT2, iterator->name, iused, ilimits); 07327 ASTOBJ_UNLOCK(iterator); 07328 } while (0) ); 07329 07330 return RESULT_SUCCESS; 07331 #undef FORMAT 07332 #undef FORMAT2 07333 }
|
|
sip_show_objects: List all allocated SIP Objects ---
Definition at line 7596 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. 07597 { 07598 char tmp[256]; 07599 if (argc != 3) 07600 return RESULT_SHOWUSAGE; 07601 ast_cli(fd, "-= User objects: %d static, %d realtime =-\n\n", suserobjs, ruserobjs); 07602 ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), &userl); 07603 ast_cli(fd, "-= Peer objects: %d static, %d realtime, %d autocreate =-\n\n", speerobjs, rpeerobjs, apeerobjs); 07604 ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), &peerl); 07605 ast_cli(fd, "-= Registry objects: %d =-\n\n", regobjs); 07606 ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), ®l); 07607 return RESULT_SUCCESS; 07608 }
|
|
sip_show_peer: Show one peer in detail ---
Definition at line 7880 of file chan_sip.c. References _sip_show_peer(). 07881 { 07882 return _sip_show_peer(0, fd, NULL, NULL, argc, argv); 07883 }
|
|
sip_show_peers: CLI Show Peers command
Definition at line 7457 of file chan_sip.c. References _sip_show_peers(). 07458 { 07459 return _sip_show_peers(fd, NULL, NULL, NULL, argc, argv); 07460 }
|
|
sip_show_registry: Show SIP Registry (registrations with other SIP proxies ---
Definition at line 8132 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. 08133 { 08134 #define FORMAT2 "%-30.30s %-12.12s %8.8s %-20.20s\n" 08135 #define FORMAT "%-30.30s %-12.12s %8d %-20.20s\n" 08136 char host[80]; 08137 08138 if (argc != 3) 08139 return RESULT_SHOWUSAGE; 08140 ast_cli(fd, FORMAT2, "Host", "Username", "Refresh", "State"); 08141 ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { 08142 ASTOBJ_RDLOCK(iterator); 08143 snprintf(host, sizeof(host), "%s:%d", iterator->hostname, iterator->portno ? iterator->portno : DEFAULT_SIP_PORT); 08144 ast_cli(fd, FORMAT, host, iterator->username, iterator->refresh, regstate2str(iterator->regstate)); 08145 ASTOBJ_UNLOCK(iterator); 08146 } while(0)); 08147 return RESULT_SUCCESS; 08148 #undef FORMAT 08149 #undef FORMAT2 08150 }
|
|
sip_show_settings: List global settings for the SIP channel ---
Definition at line 8153 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. 08154 { 08155 char tmp[BUFSIZ]; 08156 int realtimepeers = 0; 08157 int realtimeusers = 0; 08158 08159 realtimepeers = ast_check_realtime("sippeers"); 08160 realtimeusers = ast_check_realtime("sipusers"); 08161 08162 if (argc != 3) 08163 return RESULT_SHOWUSAGE; 08164 ast_cli(fd, "\n\nGlobal Settings:\n"); 08165 ast_cli(fd, "----------------\n"); 08166 ast_cli(fd, " SIP Port: %d\n", ntohs(bindaddr.sin_port)); 08167 ast_cli(fd, " Bindaddress: %s\n", ast_inet_ntoa(tmp, sizeof(tmp), bindaddr.sin_addr)); 08168 ast_cli(fd, " Videosupport: %s\n", videosupport ? "Yes" : "No"); 08169 ast_cli(fd, " AutoCreatePeer: %s\n", autocreatepeer ? "Yes" : "No"); 08170 ast_cli(fd, " Allow unknown access: %s\n", global_allowguest ? "Yes" : "No"); 08171 ast_cli(fd, " Promsic. redir: %s\n", ast_test_flag(&global_flags, SIP_PROMISCREDIR) ? "Yes" : "No"); 08172 ast_cli(fd, " SIP domain support: %s\n", AST_LIST_EMPTY(&domain_list) ? "No" : "Yes"); 08173 ast_cli(fd, " Call to non-local dom.: %s\n", allow_external_domains ? "Yes" : "No"); 08174 ast_cli(fd, " URI user is phone no: %s\n", ast_test_flag(&global_flags, SIP_USEREQPHONE) ? "Yes" : "No"); 08175 ast_cli(fd, " Our auth realm %s\n", global_realm); 08176 ast_cli(fd, " Realm. auth: %s\n", authl ? "Yes": "No"); 08177 ast_cli(fd, " User Agent: %s\n", default_useragent); 08178 ast_cli(fd, " MWI checking interval: %d secs\n", global_mwitime); 08179 ast_cli(fd, " Reg. context: %s\n", ast_strlen_zero(regcontext) ? "(not set)" : regcontext); 08180 ast_cli(fd, " Caller ID: %s\n", default_callerid); 08181 ast_cli(fd, " From: Domain: %s\n", default_fromdomain); 08182 ast_cli(fd, " Record SIP history: %s\n", recordhistory ? "On" : "Off"); 08183 ast_cli(fd, " Call Events: %s\n", callevents ? "On" : "Off"); 08184 ast_cli(fd, " IP ToS: 0x%x\n", tos); 08185 #ifdef OSP_SUPPORT 08186 ast_cli(fd, " OSP Support: Yes\n"); 08187 #else 08188 ast_cli(fd, " OSP Support: No\n"); 08189 #endif 08190 if (!realtimepeers && !realtimeusers) 08191 ast_cli(fd, " SIP realtime: Disabled\n" ); 08192 else 08193 ast_cli(fd, " SIP realtime: Enabled\n" ); 08194 08195 ast_cli(fd, "\nGlobal Signalling Settings:\n"); 08196 ast_cli(fd, "---------------------------\n"); 08197 ast_cli(fd, " Codecs: "); 08198 print_codec_to_cli(fd, &prefs); 08199 ast_cli(fd, "\n"); 08200 ast_cli(fd, " Relax DTMF: %s\n", relaxdtmf ? "Yes" : "No"); 08201 ast_cli(fd, " Compact SIP headers: %s\n", compactheaders ? "Yes" : "No"); 08202 ast_cli(fd, " RTP Timeout: %d %s\n", global_rtptimeout, global_rtptimeout ? "" : "(Disabled)" ); 08203 ast_cli(fd, " RTP Hold Timeout: %d %s\n", global_rtpholdtimeout, global_rtpholdtimeout ? "" : "(Disabled)"); 08204 ast_cli(fd, " MWI NOTIFY mime type: %s\n", default_notifymime); 08205 ast_cli(fd, " DNS SRV lookup: %s\n", srvlookup ? "Yes" : "No"); 08206 ast_cli(fd, " Pedantic SIP support: %s\n", pedanticsipchecking ? "Yes" : "No"); 08207 ast_cli(fd, " Reg. max duration: %d secs\n", max_expiry); 08208 ast_cli(fd, " Reg. default duration: %d secs\n", default_expiry); 08209 ast_cli(fd, " Outbound reg. timeout: %d secs\n", global_reg_timeout); 08210 ast_cli(fd, " Outbound reg. attempts: %d\n", global_regattempts_max); 08211 ast_cli(fd, " Notify ringing state: %s\n", global_notifyringing ? "Yes" : "No"); 08212 ast_cli(fd, "\nDefault Settings:\n"); 08213 ast_cli(fd, "-----------------\n"); 08214 ast_cli(fd, " Context: %s\n", default_context); 08215 ast_cli(fd, " Nat: %s\n", nat2str(ast_test_flag(&global_flags, SIP_NAT))); 08216 ast_cli(fd, " DTMF: %s\n", dtmfmode2str(ast_test_flag(&global_flags, SIP_DTMF))); 08217 ast_cli(fd, " Qualify: %d\n", default_qualify); 08218 ast_cli(fd, " Use ClientCode: %s\n", ast_test_flag(&global_flags, SIP_USECLIENTCODE) ? "Yes" : "No"); 08219 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" ); 08220 ast_cli(fd, " Language: %s\n", ast_strlen_zero(default_language) ? "(Defaults to English)" : default_language); 08221 ast_cli(fd, " Musicclass: %s\n", global_musicclass); 08222 ast_cli(fd, " Voice Mail Extension: %s\n", global_vmexten); 08223 08224 08225 if (realtimepeers || realtimeusers) { 08226 ast_cli(fd, "\nRealtime SIP Settings:\n"); 08227 ast_cli(fd, "----------------------\n"); 08228 ast_cli(fd, " Realtime Peers: %s\n", realtimepeers ? "Yes" : "No"); 08229 ast_cli(fd, " Realtime Users: %s\n", realtimeusers ? "Yes" : "No"); 08230 ast_cli(fd, " Cache Friends: %s\n", ast_test_flag(&global_flags_page2, SIP_PAGE2_RTCACHEFRIENDS) ? "Yes" : "No"); 08231 ast_cli(fd, " Update: %s\n", ast_test_flag(&global_flags_page2, SIP_PAGE2_RTUPDATE) ? "Yes" : "No"); 08232 ast_cli(fd, " Ignore Reg. Expire: %s\n", ast_test_flag(&global_flags_page2, SIP_PAGE2_IGNOREREGEXPIRE) ? "Yes" : "No"); 08233 ast_cli(fd, " Auto Clear: %d\n", global_rtautoclear); 08234 } 08235 ast_cli(fd, "\n----\n"); 08236 return RESULT_SUCCESS; 08237 }
|
|
sip_show_subscriptions: Show active SIP subscriptions ---
Definition at line 8273 of file chan_sip.c. References __sip_show_channels(). 08274 { 08275 return __sip_show_channels(fd, argc, argv, 1); 08276 }
|
|
sip_show_user: Show one user in detail ---
Definition at line 8068 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. 08069 { 08070 char cbuf[256]; 08071 struct sip_user *user; 08072 struct ast_codec_pref *pref; 08073 struct ast_variable *v; 08074 int x = 0, codec = 0, load_realtime = 0; 08075 08076 if (argc < 4) 08077 return RESULT_SHOWUSAGE; 08078 08079 /* Load from realtime storage? */ 08080 load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? 1 : 0; 08081 08082 user = find_user(argv[3], load_realtime); 08083 if (user) { 08084 ast_cli(fd,"\n\n"); 08085 ast_cli(fd, " * Name : %s\n", user->name); 08086 ast_cli(fd, " Secret : %s\n", ast_strlen_zero(user->secret)?"<Not set>":"<Set>"); 08087 ast_cli(fd, " MD5Secret : %s\n", ast_strlen_zero(user->md5secret)?"<Not set>":"<Set>"); 08088 ast_cli(fd, " Context : %s\n", user->context); 08089 ast_cli(fd, " Language : %s\n", user->language); 08090 if (!ast_strlen_zero(user->accountcode)) 08091 ast_cli(fd, " Accountcode : %s\n", user->accountcode); 08092 ast_cli(fd, " AMA flags : %s\n", ast_cdr_flags2str(user->amaflags)); 08093 ast_cli(fd, " CallingPres : %s\n", ast_describe_caller_presentation(user->callingpres)); 08094 ast_cli(fd, " Call limit : %d\n", user->call_limit); 08095 ast_cli(fd, " Callgroup : "); 08096 print_group(fd, user->callgroup, 0); 08097 ast_cli(fd, " Pickupgroup : "); 08098 print_group(fd, user->pickupgroup, 0); 08099 ast_cli(fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), user->cid_name, user->cid_num, "<unspecified>")); 08100 ast_cli(fd, " ACL : %s\n", (user->ha?"Yes":"No")); 08101 ast_cli(fd, " Codec Order : ("); 08102 pref = &user->prefs; 08103 for(x = 0; x < 32 ; x++) { 08104 codec = ast_codec_pref_index(pref,x); 08105 if (!codec) 08106 break; 08107 ast_cli(fd, "%s", ast_getformatname(codec)); 08108 if (x < 31 && ast_codec_pref_index(pref,x+1)) 08109 ast_cli(fd, "|"); 08110 } 08111 08112 if (!x) 08113 ast_cli(fd, "none"); 08114 ast_cli(fd, ")\n"); 08115 08116 if (user->chanvars) { 08117 ast_cli(fd, " Variables :\n"); 08118 for (v = user->chanvars ; v ; v = v->next) 08119 ast_cli(fd, " %s = %s\n", v->name, v->value); 08120 } 08121 ast_cli(fd,"\n"); 08122 ASTOBJ_UNREF(user,sip_destroy_user); 08123 } else { 08124 ast_cli(fd,"User %s not found.\n", argv[3]); 08125 ast_cli(fd,"\n"); 08126 } 08127 08128 return RESULT_SUCCESS; 08129 }
|
|
sip_show_users: CLI Command 'SIP Show Users' ---
Definition at line 7378 of file chan_sip.c. References ast_cli(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, FORMAT, RESULT_SHOWUSAGE, and userl. 07379 { 07380 regex_t regexbuf; 07381 int havepattern = 0; 07382 07383 #define FORMAT "%-25.25s %-15.15s %-15.15s %-15.15s %-5.5s%-10.10s\n" 07384 07385 switch (argc) { 07386 case 5: 07387 if (!strcasecmp(argv[3], "like")) { 07388 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 07389 return RESULT_SHOWUSAGE; 07390 havepattern = 1; 07391 } else 07392 return RESULT_SHOWUSAGE; 07393 case 3: 07394 break; 07395 default: 07396 return RESULT_SHOWUSAGE; 07397 } 07398 07399 ast_cli(fd, FORMAT, "Username", "Secret", "Accountcode", "Def.Context", "ACL", "NAT"); 07400 ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do { 07401 ASTOBJ_RDLOCK(iterator); 07402 07403 if (havepattern && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 07404 ASTOBJ_UNLOCK(iterator); 07405 continue; 07406 } 07407 07408 ast_cli(fd, FORMAT, iterator->name, 07409 iterator->secret, 07410 iterator->accountcode, 07411 iterator->context, 07412 iterator->ha ? "Yes" : "No", 07413 nat2str(ast_test_flag(iterator, SIP_NAT))); 07414 ASTOBJ_UNLOCK(iterator); 07415 } while (0) 07416 ); 07417 07418 if (havepattern) 07419 regfree(®exbuf); 07420 07421 return RESULT_SUCCESS; 07422 #undef FORMAT 07423 }
|
|
sip_sipredirect: Transfer call before connect with a 302 redirect ---
Definition at line 12925 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(). 12926 { 12927 char *cdest; 12928 char *extension, *host, *port; 12929 char tmp[80]; 12930 12931 cdest = ast_strdupa(dest); 12932 if (!cdest) { 12933 ast_log(LOG_ERROR, "Problem allocating the memory\n"); 12934 return 0; 12935 } 12936 extension = strsep(&cdest, "@"); 12937 host = strsep(&cdest, ":"); 12938 port = strsep(&cdest, ":"); 12939 if (!extension) { 12940 ast_log(LOG_ERROR, "Missing mandatory argument: extension\n"); 12941 return 0; 12942 } 12943 12944 /* we'll issue the redirect message here */ 12945 if (!host) { 12946 char *localtmp; 12947 ast_copy_string(tmp, get_header(&p->initreq, "To"), sizeof(tmp)); 12948 if (!strlen(tmp)) { 12949 ast_log(LOG_ERROR, "Cannot retrieve the 'To' header from the original SIP request!\n"); 12950 return 0; 12951 } 12952 if ((localtmp = strstr(tmp, "sip:")) && (localtmp = strchr(localtmp, '@'))) { 12953 char lhost[80], lport[80]; 12954 memset(lhost, 0, sizeof(lhost)); 12955 memset(lport, 0, sizeof(lport)); 12956 localtmp++; 12957 /* This is okey because lhost and lport are as big as tmp */ 12958 sscanf(localtmp, "%[^<>:; ]:%[^<>:; ]", lhost, lport); 12959 if (!strlen(lhost)) { 12960 ast_log(LOG_ERROR, "Can't find the host address\n"); 12961 return 0; 12962 } 12963 host = ast_strdupa(lhost); 12964 if (!host) { 12965 ast_log(LOG_ERROR, "Problem allocating the memory\n"); 12966 return 0; 12967 } 12968 if (!ast_strlen_zero(lport)) { 12969 port = ast_strdupa(lport); 12970 if (!port) { 12971 ast_log(LOG_ERROR, "Problem allocating the memory\n"); 12972 return 0; 12973 } 12974 } 12975 } 12976 } 12977 12978 snprintf(p->our_contact, sizeof(p->our_contact), "Transfer <sip:%s@%s%s%s>", extension, host, port ? ":" : "", port ? port : ""); 12979 transmit_response_reliable(p, "302 Moved Temporarily", &p->initreq, 1); 12980 12981 /* this is all that we want to send to that SIP device */ 12982 ast_set_flag(p, SIP_ALREADYGONE); 12983 12984 /* hangup here */ 12985 return -1; 12986 }
|
|
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 11097 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(). 11098 { 11099 struct sip_request req; 11100 struct sockaddr_in sin = { 0, }; 11101 struct sip_pvt *p; 11102 int res; 11103 socklen_t len; 11104 int nounlock; 11105 int recount = 0; 11106 char iabuf[INET_ADDRSTRLEN]; 11107 11108 len = sizeof(sin); 11109 memset(&req, 0, sizeof(req)); 11110 res = recvfrom(sipsock, req.data, sizeof(req.data) - 1, 0, (struct sockaddr *)&sin, &len); 11111 if (res < 0) { 11112 #if !defined(__FreeBSD__) 11113 if (errno == EAGAIN) 11114 ast_log(LOG_NOTICE, "SIP: Received packet with bad UDP checksum\n"); 11115 else 11116 #endif 11117 if (errno != ECONNREFUSED) 11118 ast_log(LOG_WARNING, "Recv error: %s\n", strerror(errno)); 11119 return 1; 11120 } 11121 if (res == sizeof(req.data)) { 11122 ast_log(LOG_DEBUG, "Received packet exceeds buffer. Data is possibly lost\n"); 11123 } 11124 req.data[res] = '\0'; 11125 req.len = res; 11126 if(sip_debug_test_addr(&sin)) 11127 ast_set_flag(&req, SIP_PKT_DEBUG); 11128 if (pedanticsipchecking) 11129 req.len = lws2sws(req.data, req.len); /* Fix multiline headers */ 11130 if (ast_test_flag(&req, SIP_PKT_DEBUG)) { 11131 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); 11132 } 11133 parse_request(&req); 11134 req.method = find_sip_method(req.rlPart1); 11135 if (ast_test_flag(&req, SIP_PKT_DEBUG)) { 11136 ast_verbose("--- (%d headers %d lines)", req.headers, req.lines); 11137 if (req.headers + req.lines == 0) 11138 ast_verbose(" Nat keepalive "); 11139 ast_verbose("---\n"); 11140 } 11141 11142 if (req.headers < 2) { 11143 /* Must have at least two headers */ 11144 return 1; 11145 } 11146 11147 11148 /* Process request, with netlock held */ 11149 retrylock: 11150 ast_mutex_lock(&netlock); 11151 p = find_call(&req, &sin, req.method); 11152 if (p) { 11153 /* Go ahead and lock the owner if it has one -- we may need it */ 11154 if (p->owner && ast_mutex_trylock(&p->owner->lock)) { 11155 ast_log(LOG_DEBUG, "Failed to grab lock, trying again...\n"); 11156 ast_mutex_unlock(&p->lock); 11157 ast_mutex_unlock(&netlock); 11158 /* Sleep infintismly short amount of time */ 11159 usleep(1); 11160 goto retrylock; 11161 } 11162 memcpy(&p->recv, &sin, sizeof(p->recv)); 11163 if (recordhistory) { 11164 char tmp[80]; 11165 /* This is a response, note what it was for */ 11166 snprintf(tmp, sizeof(tmp), "%s / %s", req.data, get_header(&req, "CSeq")); 11167 append_history(p, "Rx", tmp); 11168 } 11169 nounlock = 0; 11170 if (handle_request(p, &req, &sin, &recount, &nounlock) == -1) { 11171 /* Request failed */ 11172 ast_log(LOG_DEBUG, "SIP message could not be handled, bad request: %-70.70s\n", p->callid[0] ? p->callid : "<no callid>"); 11173 } 11174 11175 if (p->owner && !nounlock) 11176 ast_mutex_unlock(&p->owner->lock); 11177 ast_mutex_unlock(&p->lock); 11178 } 11179 ast_mutex_unlock(&netlock); 11180 if (recount) 11181 ast_update_use_count(); 11182 11183 return 1; 11184 }
|
|
subscription_type2str: Show subscription type in string format
Definition at line 8240 of file chan_sip.c. References subscription_types, and type. Referenced by __sip_show_channels(), and sip_show_channel(). 08240 { 08241 int i; 08242 08243 for (i = 1; (i < (sizeof(subscription_types) / sizeof(subscription_types[0]))); i++) { 08244 if (subscription_types[i].type == subtype) { 08245 return subscription_types[i].text; 08246 } 08247 } 08248 return subscription_types[0].text; 08249 }
|
|
temp_peer: Create temporary peer (used in autocreatepeer mode) ---
Definition at line 11994 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(). 11995 { 11996 struct sip_peer *peer; 11997 11998 peer = malloc(sizeof(*peer)); 11999 if (!peer) 12000 return NULL; 12001 12002 memset(peer, 0, sizeof(*peer)); 12003 apeerobjs++; 12004 ASTOBJ_INIT(peer); 12005 12006 peer->expire = -1; 12007 peer->pokeexpire = -1; 12008 ast_copy_string(peer->name, name, sizeof(peer->name)); 12009 ast_copy_flags(peer, &global_flags, SIP_FLAGS_TO_COPY); 12010 strcpy(peer->context, default_context); 12011 strcpy(peer->subscribecontext, default_subscribecontext); 12012 strcpy(peer->language, default_language); 12013 strcpy(peer->musicclass, global_musicclass); 12014 peer->addr.sin_port = htons(DEFAULT_SIP_PORT); 12015 peer->addr.sin_family = AF_INET; 12016 peer->capability = global_capability; 12017 peer->rtptimeout = global_rtptimeout; 12018 peer->rtpholdtimeout = global_rtpholdtimeout; 12019 peer->rtpkeepalive = global_rtpkeepalive; 12020 ast_set_flag(peer, SIP_SELFDESTRUCT); 12021 ast_set_flag(peer, SIP_DYNAMIC); 12022 peer->prefs = prefs; 12023 reg_source_db(peer); 12024 12025 return peer; 12026 }
|
|
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 5565 of file chan_sip.c. References add_digit(), sip_pvt::ocseq, reqprep(), send_request(), and SIP_INFO. Referenced by sip_senddigit(). 05566 { 05567 struct sip_request req; 05568 reqprep(&req, p, SIP_INFO, 0, 1); 05569 add_digit(&req, digit); 05570 return send_request(p, &req, 1, p->ocseq); 05571 }
|
|
transmit_info_with_vidupdate: Send SIP INFO with video update request ---
Definition at line 5574 of file chan_sip.c. References add_vidupdate(), sip_pvt::ocseq, reqprep(), send_request(), and SIP_INFO. Referenced by sip_indicate(). 05575 { 05576 struct sip_request req; 05577 reqprep(&req, p, SIP_INFO, 0, 1); 05578 add_vidupdate(&req); 05579 return send_request(p, &req, 1, p->ocseq); 05580 }
|
|
transmit_invite: Build REFER/INVITE/OPTIONS message and transmit it ---
Definition at line 4865 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(). 04866 { 04867 struct sip_request req; 04868 04869 req.method = sipmethod; 04870 if (init) { 04871 /* Bump branch even on initial requests */ 04872 p->branch ^= thread_safe_rand(); 04873 build_via(p, p->via, sizeof(p->via)); 04874 if (init > 1) 04875 initreqprep(&req, p, sipmethod); 04876 else 04877 reqprep(&req, p, sipmethod, 0, 1); 04878 } else 04879 reqprep(&req, p, sipmethod, 0, 1); 04880 04881 if (p->options && p->options->auth) 04882 add_header(&req, p->options->authheader, p->options->auth); 04883 append_date(&req); 04884 if (sipmethod == SIP_REFER) { /* Call transfer */ 04885 if (!ast_strlen_zero(p->refer_to)) 04886 add_header(&req, "Refer-To", p->refer_to); 04887 if (!ast_strlen_zero(p->referred_by)) 04888 add_header(&req, "Referred-By", p->referred_by); 04889 } 04890 #ifdef OSP_SUPPORT 04891 if ((req.method != SIP_OPTIONS) && p->options && !ast_strlen_zero(p->options->osptoken)) { 04892 ast_log(LOG_DEBUG,"Adding OSP Token: %s\n", p->options->osptoken); 04893 add_header(&req, "P-OSP-Auth-Token", p->options->osptoken); 04894 } 04895 #endif 04896 if (p->options && !ast_strlen_zero(p->options->distinctive_ring)) 04897 { 04898 add_header(&req, "Alert-Info", p->options->distinctive_ring); 04899 } 04900 add_header(&req, "Allow", ALLOWED_METHODS); 04901 if (p->options && p->options->addsipheaders ) { 04902 struct ast_channel *ast; 04903 char *header = (char *) NULL; 04904 char *content = (char *) NULL; 04905 char *end = (char *) NULL; 04906 struct varshead *headp = (struct varshead *) NULL; 04907 struct ast_var_t *current; 04908 04909 ast = p->owner; /* The owner channel */ 04910 if (ast) { 04911 char *headdup; 04912 headp = &ast->varshead; 04913 if (!headp) 04914 ast_log(LOG_WARNING,"No Headp for the channel...ooops!\n"); 04915 else { 04916 AST_LIST_TRAVERSE(headp, current, entries) { 04917 /* SIPADDHEADER: Add SIP header to outgoing call */ 04918 if (!strncasecmp(ast_var_name(current), "SIPADDHEADER", strlen("SIPADDHEADER"))) { 04919 header = ast_var_value(current); 04920 headdup = ast_strdupa(header); 04921 /* Strip of the starting " (if it's there) */ 04922 if (*headdup == '"') 04923 headdup++; 04924 if ((content = strchr(headdup, ':'))) { 04925 *content = '\0'; 04926 content++; /* Move pointer ahead */ 04927 /* Skip white space */ 04928 while (*content == ' ') 04929 content++; 04930 /* Strip the ending " (if it's there) */ 04931 end = content + strlen(content) -1; 04932 if (*end == '"') 04933 *end = '\0'; 04934 04935 add_header(&req, headdup, content); 04936 if (sipdebug) 04937 ast_log(LOG_DEBUG, "Adding SIP Header \"%s\" with content :%s: \n", headdup, content); 04938 } 04939 } 04940 } 04941 } 04942 } 04943 } 04944 if (sdp && p->rtp) { 04945 ast_rtp_offered_from_local(p->rtp, 1); 04946 add_sdp(&req, p); 04947 } else { 04948 add_header_contentLength(&req, 0); 04949 add_blank_header(&req); 04950 } 04951 04952 if (!p->initreq.headers) { 04953 /* Use this as the basis */ 04954 copy_request(&p->initreq, &req); 04955 parse_request(&p->initreq); 04956 if (sip_debug_test_pvt(p)) 04957 ast_verbose("%d headers, %d lines\n", p->initreq.headers, p->initreq.lines); 04958 } 04959 p->lastinvite = p->ocseq; 04960 return send_request(p, &req, init ? 2 : 1, p->ocseq); 04961 }
|
|
transmit_message_with_text: Transmit text with SIP MESSAGE method ---
Definition at line 5511 of file chan_sip.c. References add_text(), sip_pvt::ocseq, reqprep(), send_request(), and SIP_MESSAGE. Referenced by sip_sendtext(). 05512 { 05513 struct sip_request req; 05514 reqprep(&req, p, SIP_MESSAGE, 0, 1); 05515 add_text(&req, text); 05516 return send_request(p, &req, 1, p->ocseq); 05517 }
|
|
transmit_notify_with_mwi: Notify user of messages waiting in voicemail ---
Definition at line 5136 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(). 05137 { 05138 struct sip_request req; 05139 char tmp[500]; 05140 char *t = tmp; 05141 size_t maxbytes = sizeof(tmp); 05142 char iabuf[INET_ADDRSTRLEN]; 05143 05144 initreqprep(&req, p, SIP_NOTIFY); 05145 add_header(&req, "Event", "message-summary"); 05146 add_header(&req, "Content-Type", default_notifymime); 05147 05148 ast_build_string(&t, &maxbytes, "Messages-Waiting: %s\r\n", newmsgs ? "yes" : "no"); 05149 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); 05150 ast_build_string(&t, &maxbytes, "Voice-Message: %d/%d (0/0)\r\n", newmsgs, oldmsgs); 05151 05152 if (t > tmp + sizeof(tmp)) 05153 ast_log(LOG_WARNING, "Buffer overflow detected!! (Please file a bug report)\n"); 05154 05155 add_header_contentLength(&req, strlen(tmp)); 05156 add_line(&req, tmp); 05157 05158 if (!p->initreq.headers) { /* Use this as the basis */ 05159 copy_request(&p->initreq, &req); 05160 parse_request(&p->initreq); 05161 if (sip_debug_test_pvt(p)) 05162 ast_verbose("%d headers, %d lines\n", p->initreq.headers, p->initreq.lines); 05163 determine_firstline_parts(&p->initreq); 05164 } 05165 05166 return send_request(p, &req, 1, p->ocseq); 05167 }
|
|
transmit_notify_with_sipfrag: Notify a transferring party of the status of trasnfer ---
Definition at line 5189 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(). 05190 { 05191 struct sip_request req; 05192 char tmp[20]; 05193 reqprep(&req, p, SIP_NOTIFY, 0, 1); 05194 snprintf(tmp, sizeof(tmp), "refer;id=%d", cseq); 05195 add_header(&req, "Event", tmp); 05196 add_header(&req, "Subscription-state", "terminated;reason=noresource"); 05197 add_header(&req, "Content-Type", "message/sipfrag;version=2.0"); 05198 05199 strcpy(tmp, "SIP/2.0 200 OK"); 05200 add_header_contentLength(&req, strlen(tmp)); 05201 add_line(&req, tmp); 05202 05203 if (!p->initreq.headers) { 05204 /* Use this as the basis */ 05205 copy_request(&p->initreq, &req); 05206 parse_request(&p->initreq); 05207 if (sip_debug_test_pvt(p)) 05208 ast_verbose("%d headers, %d lines\n", p->initreq.headers, p->initreq.lines); 05209 determine_firstline_parts(&p->initreq); 05210 } 05211 05212 return send_request(p, &req, 1, p->ocseq); 05213 }
|
|
transmit_refer: Transmit SIP REFER message ---
Definition at line 5520 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(). 05521 { 05522 struct sip_request req; 05523 char from[256]; 05524 char *of, *c; 05525 char referto[256]; 05526 05527 if (ast_test_flag(p, SIP_OUTGOING)) 05528 of = get_header(&p->initreq, "To"); 05529 else 05530 of = get_header(&p->initreq, "From"); 05531 ast_copy_string(from, of, sizeof(from)); 05532 of = get_in_brackets(from); 05533 ast_copy_string(p->from,of,sizeof(p->from)); 05534 if (strncmp(of, "sip:", 4)) { 05535 ast_log(LOG_NOTICE, "From address missing 'sip:', using it anyway\n"); 05536 } else 05537 of += 4; 05538 /* Get just the username part */ 05539 if ((c = strchr(dest, '@'))) { 05540 c = NULL; 05541 } else if ((c = strchr(of, '@'))) { 05542 *c = '\0'; 05543 c++; 05544 } 05545 if (c) { 05546 snprintf(referto, sizeof(referto), "<sip:%s@%s>", dest, c); 05547 } else { 05548 snprintf(referto, sizeof(referto), "<sip:%s>", dest); 05549 } 05550 05551 /* save in case we get 407 challenge */ 05552 ast_copy_string(p->refer_to, referto, sizeof(p->refer_to)); 05553 ast_copy_string(p->referred_by, p->our_contact, sizeof(p->referred_by)); 05554 05555 reqprep(&req, p, SIP_REFER, 0, 1); 05556 add_header(&req, "Refer-To", referto); 05557 if (!ast_strlen_zero(p->our_contact)) 05558 add_header(&req, "Referred-By", p->our_contact); 05559 add_blank_header(&req); 05560 return send_request(p, &req, 1, p->ocseq); 05561 }
|
|
transmit_register: Transmit register to SIP proxy or UA ---
Definition at line 5319 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(). 05320 { 05321 struct sip_request req; 05322 char from[256]; 05323 char to[256]; 05324 char tmp[80]; 05325 char via[80]; 05326 char addr[80]; 05327 struct sip_pvt *p; 05328 05329 /* exit if we are already in process with this registrar ?*/ 05330 if ( r == NULL || ((auth==NULL) && (r->regstate==REG_STATE_REGSENT || r->regstate==REG_STATE_AUTHSENT))) { 05331 ast_log(LOG_NOTICE, "Strange, trying to register %s@%s when registration already pending\n", r->username, r->hostname); 05332 return 0; 05333 } 05334 05335 if (r->call) { /* We have a registration */ 05336 if (!auth) { 05337 ast_log(LOG_WARNING, "Already have a REGISTER going on to %s@%s?? \n", r->username, r->hostname); 05338 return 0; 05339 } else { 05340 p = r->call; 05341 make_our_tag(p->tag, sizeof(p->tag)); /* create a new local tag for every register attempt */ 05342 p->theirtag[0]='\0'; /* forget their old tag, so we don't match tags when getting response */ 05343 } 05344 } else { 05345 /* Build callid for registration if we haven't registered before */ 05346 if (!r->callid_valid) { 05347 build_callid(r->callid, sizeof(r->callid), __ourip, default_fromdomain); 05348 r->callid_valid = 1; 05349 } 05350 /* Allocate SIP packet for registration */ 05351 p=sip_alloc( r->callid, NULL, 0, SIP_REGISTER); 05352 if (!p) { 05353 ast_log(LOG_WARNING, "Unable to allocate registration call\n"); 05354 return 0; 05355 } 05356 if (recordhistory) { 05357 char tmp[80]; 05358 snprintf(tmp, sizeof(tmp), "Account: %s@%s", r->username, r->hostname); 05359 append_history(p, "RegistryInit", tmp); 05360 } 05361 /* Find address to hostname */ 05362 if (create_addr(p, r->hostname)) { 05363 /* we have what we hope is a temporary network error, 05364 * probably DNS. We need to reschedule a registration try */ 05365 sip_destroy(p); 05366 if (r->timeout > -1) { 05367 ast_sched_del(sched, r->timeout); 05368 r->timeout = ast_sched_add(sched, global_reg_timeout*1000, sip_reg_timeout, r); 05369 ast_log(LOG_WARNING, "Still have a registration timeout for %s@%s (create_addr() error), %d\n", r->username, r->hostname, r->timeout); 05370 } else { 05371 r->timeout = ast_sched_add(sched, global_reg_timeout*1000, sip_reg_timeout, r); 05372 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); 05373 } 05374 r->regattempts++; 05375 return 0; 05376 } 05377 /* Copy back Call-ID in case create_addr changed it */ 05378 ast_copy_string(r->callid, p->callid, sizeof(r->callid)); 05379 if (r->portno) 05380 p->sa.sin_port = htons(r->portno); 05381 else /* Set registry port to the port set from the peer definition/srv or default */ 05382 r->portno = ntohs(p->sa.sin_port); 05383 ast_set_flag(p, SIP_OUTGOING); /* Registration is outgoing call */ 05384 r->call=p; /* Save pointer to SIP packet */ 05385 p->registry=ASTOBJ_REF(r); /* Add pointer to registry in packet */ 05386 if (!ast_strlen_zero(r->secret)) /* Secret (password) */ 05387 ast_copy_string(p->peersecret, r->secret, sizeof(p->peersecret)); 05388 if (!ast_strlen_zero(r->md5secret)) 05389 ast_copy_string(p->peermd5secret, r->md5secret, sizeof(p->peermd5secret)); 05390 /* User name in this realm 05391 - if authuser is set, use that, otherwise use username */ 05392 if (!ast_strlen_zero(r->authuser)) { 05393 ast_copy_string(p->peername, r->authuser, sizeof(p->peername)); 05394 ast_copy_string(p->authname, r->authuser, sizeof(p->authname)); 05395 } else { 05396 if (!ast_strlen_zero(r->username)) { 05397 ast_copy_string(p->peername, r->username, sizeof(p->peername)); 05398 ast_copy_string(p->authname, r->username, sizeof(p->authname)); 05399 ast_copy_string(p->fromuser, r->username, sizeof(p->fromuser)); 05400 } 05401 } 05402 if (!ast_strlen_zero(r->username)) 05403 ast_copy_string(p->username, r->username, sizeof(p->username)); 05404 /* Save extension in packet */ 05405 ast_copy_string(p->exten, r->contact, sizeof(p->exten)); 05406 05407 /* 05408 check which address we should use in our contact header 05409 based on whether the remote host is on the external or 05410 internal network so we can register through nat 05411 */ 05412 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 05413 memcpy(&p->ourip, &bindaddr.sin_addr, sizeof(p->ourip)); 05414 build_contact(p); 05415 } 05416 05417 /* set up a timeout */ 05418 if (auth == NULL) { 05419 if (r->timeout > -1) { 05420 ast_log(LOG_WARNING, "Still have a registration timeout, #%d - deleting it\n", r->timeout); 05421 ast_sched_del(sched, r->timeout); 05422 } 05423 r->timeout = ast_sched_add(sched, global_reg_timeout * 1000, sip_reg_timeout, r); 05424 ast_log(LOG_DEBUG, "Scheduled a registration timeout for %s id #%d \n", r->hostname, r->timeout); 05425 } 05426 05427 if (strchr(r->username, '@')) { 05428 snprintf(from, sizeof(from), "<sip:%s>;tag=%s", r->username, p->tag); 05429 if (!ast_strlen_zero(p->theirtag)) 05430 snprintf(to, sizeof(to), "<sip:%s>;tag=%s", r->username, p->theirtag); 05431 else 05432 snprintf(to, sizeof(to), "<sip:%s>", r->username); 05433 } else { 05434 snprintf(from, sizeof(from), "<sip:%s@%s>;tag=%s", r->username, p->tohost, p->tag); 05435 if (!ast_strlen_zero(p->theirtag)) 05436 snprintf(to, sizeof(to), "<sip:%s@%s>;tag=%s", r->username, p->tohost, p->theirtag); 05437 else 05438 snprintf(to, sizeof(to), "<sip:%s@%s>", r->username, p->tohost); 05439 } 05440 05441 /* Fromdomain is what we are registering to, regardless of actual 05442 host name from SRV */ 05443 if (!ast_strlen_zero(p->fromdomain)) 05444 snprintf(addr, sizeof(addr), "sip:%s", p->fromdomain); 05445 else 05446 snprintf(addr, sizeof(addr), "sip:%s", r->hostname); 05447 ast_copy_string(p->uri, addr, sizeof(p->uri)); 05448 05449 p->branch ^= thread_safe_rand(); 05450 05451 memset(&req, 0, sizeof(req)); 05452 init_req(&req, sipmethod, addr); 05453 05454 /* Add to CSEQ */ 05455 snprintf(tmp, sizeof(tmp), "%u %s", ++r->ocseq, sip_methods[sipmethod].text); 05456 p->ocseq = r->ocseq; 05457 05458 build_via(p, via, sizeof(via)); 05459 add_header(&req, "Via", via); 05460 add_header(&req, "From", from); 05461 add_header(&req, "To", to); 05462 add_header(&req, "Call-ID", p->callid); 05463 add_header(&req, "CSeq", tmp); 05464 add_header(&req, "User-Agent", default_useragent); 05465 add_header(&req, "Max-Forwards", DEFAULT_MAX_FORWARDS); 05466 05467 05468 if (auth) /* Add auth header */ 05469 add_header(&req, authheader, auth); 05470 else if (!ast_strlen_zero(r->nonce)) { 05471 char digest[1024]; 05472 05473 /* We have auth data to reuse, build a digest header! */ 05474 if (sipdebug) 05475 ast_log(LOG_DEBUG, " >>> Re-using Auth data for %s@%s\n", r->username, r->hostname); 05476 ast_copy_string(p->realm, r->realm, sizeof(p->realm)); 05477 ast_copy_string(p->nonce, r->nonce, sizeof(p->nonce)); 05478 ast_copy_string(p->domain, r->domain, sizeof(p->domain)); 05479 ast_copy_string(p->opaque, r->opaque, sizeof(p->opaque)); 05480 ast_copy_string(p->qop, r->qop, sizeof(p->qop)); 05481 p->noncecount = r->noncecount++; 05482 05483 memset(digest,0,sizeof(digest)); 05484 if(!build_reply_digest(p, sipmethod, digest, sizeof(digest))) 05485 add_header(&req, "Authorization", digest); 05486 else 05487 ast_log(LOG_NOTICE, "No authorization available for authentication of registration to %s@%s\n", r->username, r->hostname); 05488 05489 } 05490 05491 snprintf(tmp, sizeof(tmp), "%d", default_expiry); 05492 add_header(&req, "Expires", tmp); 05493 add_header(&req, "Contact", p->our_contact); 05494 add_header(&req, "Event", "registration"); 05495 add_header_contentLength(&req, 0); 05496 add_blank_header(&req); 05497 copy_request(&p->initreq, &req); 05498 parse_request(&p->initreq); 05499 if (sip_debug_test_pvt(p)) { 05500 ast_verbose("REGISTER %d headers, %d lines\n", p->initreq.headers, p->initreq.lines); 05501 } 05502 determine_firstline_parts(&p->initreq); 05503 r->regstate=auth?REG_STATE_AUTHSENT:REG_STATE_REGSENT; 05504 r->regattempts++; /* Another attempt */ 05505 if (option_debug > 3) 05506 ast_verbose("REGISTER attempt %d to %s@%s\n", r->regattempts, r->username, r->hostname); 05507 return send_request(p, &req, 2, p->ocseq); 05508 }
|
|
transmit_reinvite_with_sdp: Transmit reinvite with SDP :-) ---
Definition at line 4592 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(). 04593 { 04594 struct sip_request req; 04595 if (ast_test_flag(p, SIP_REINVITE_UPDATE)) 04596 reqprep(&req, p, SIP_UPDATE, 0, 1); 04597 else 04598 reqprep(&req, p, SIP_INVITE, 0, 1); 04599 04600 add_header(&req, "Allow", ALLOWED_METHODS); 04601 if (sipdebug) 04602 add_header(&req, "X-asterisk-info", "SIP re-invite (RTP bridge)"); 04603 ast_rtp_offered_from_local(p->rtp, 1); 04604 add_sdp(&req, p); 04605 /* Use this as the basis */ 04606 copy_request(&p->initreq, &req); 04607 parse_request(&p->initreq); 04608 if (sip_debug_test_pvt(p)) 04609 ast_verbose("%d headers, %d lines\n", p->initreq.headers, p->initreq.lines); 04610 p->lastinvite = p->ocseq; 04611 ast_set_flag(p, SIP_OUTGOING); 04612 return send_request(p, &req, 1, p->ocseq); 04613 }
|
|
transmit_request: transmit generic SIP request ---
Definition at line 5583 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(). 05584 { 05585 struct sip_request resp; 05586 reqprep(&resp, p, sipmethod, seqno, newbranch); 05587 add_header_contentLength(&resp, 0); 05588 add_blank_header(&resp); 05589 return send_request(p, &resp, reliable, seqno ? seqno : p->ocseq); 05590 }
|
|
transmit_request_with_auth: Transmit SIP request, auth added ---
Definition at line 5593 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(). 05594 { 05595 struct sip_request resp; 05596 05597 reqprep(&resp, p, sipmethod, seqno, newbranch); 05598 if (*p->realm) { 05599 char digest[1024]; 05600 05601 memset(digest, 0, sizeof(digest)); 05602 if(!build_reply_digest(p, sipmethod, digest, sizeof(digest))) { 05603 if (p->options && p->options->auth_type == PROXY_AUTH) 05604 add_header(&resp, "Proxy-Authorization", digest); 05605 else if (p->options && p->options->auth_type == WWW_AUTH) 05606 add_header(&resp, "Authorization", digest); 05607 else /* Default, to be backwards compatible (maybe being too careful, but leaving it for now) */ 05608 add_header(&resp, "Proxy-Authorization", digest); 05609 } else 05610 ast_log(LOG_WARNING, "No authentication available for call %s\n", p->callid); 05611 } 05612 /* If we are hanging up and know a cause for that, send it in clear text to make 05613 debugging easier. */ 05614 if (sipmethod == SIP_BYE) { 05615 if (p->owner && p->owner->hangupcause) { 05616 add_header(&resp, "X-Asterisk-HangupCause", ast_cause2str(p->owner->hangupcause)); 05617 } 05618 } 05619 05620 add_header_contentLength(&resp, 0); 05621 add_blank_header(&resp); 05622 return send_request(p, &resp, reliable, seqno ? seqno : p->ocseq); 05623 }
|
|
transmit_response: Transmit response, no retransmits
Definition at line 4152 of file chan_sip.c. References __transmit_response(). 04153 { 04154 return __transmit_response(p, msg, req, 0); 04155 }
|
|
transmit_response_reliable: Transmit response, Make sure you get a reply
Definition at line 4168 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(). 04169 { 04170 return __transmit_response(p, msg, req, fatal ? 2 : 1); 04171 }
|
|
transmit_response_with_allow: Append Accept header, content length before transmitting response ---
Definition at line 4198 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(). 04199 { 04200 struct sip_request resp; 04201 respprep(&resp, p, msg, req); 04202 add_header(&resp, "Accept", "application/sdp"); 04203 add_header_contentLength(&resp, 0); 04204 add_blank_header(&resp); 04205 return send_response(p, &resp, reliable, 0); 04206 }
|
|
Definition at line 4209 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(). 04210 { 04211 struct sip_request resp; 04212 char tmp[256]; 04213 int seqno = 0; 04214 04215 if (reliable && (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1)) { 04216 ast_log(LOG_WARNING, "Unable to determine sequence number from '%s'\n", get_header(req, "CSeq")); 04217 return -1; 04218 } 04219 /* Stale means that they sent us correct authentication, but 04220 based it on an old challenge (nonce) */ 04221 snprintf(tmp, sizeof(tmp), "Digest realm=\"%s\", nonce=\"%s\"%s", global_realm, randdata, stale ? ", stale=true" : ""); 04222 respprep(&resp, p, msg, req); 04223 add_header(&resp, header, tmp); 04224 add_header_contentLength(&resp, 0); 04225 add_blank_header(&resp); 04226 return send_response(p, &resp, reliable, seqno); 04227 }
|
|
transmit_response_with_date: Append date and content length before transmitting response ---
Definition at line 4187 of file chan_sip.c. References add_blank_header(), add_header_contentLength(), append_date(), respprep(), and send_response(). Referenced by register_verify(). 04188 { 04189 struct sip_request resp; 04190 respprep(&resp, p, msg, req); 04191 append_date(&resp); 04192 add_header_contentLength(&resp, 0); 04193 add_blank_header(&resp); 04194 return send_response(p, &resp, 0, 0); 04195 }
|
|
transmit_response_with_sdp: Used for 200 OK and 183 early media ---
Definition at line 4518 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(). 04519 { 04520 struct sip_request resp; 04521 int seqno; 04522 if (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1) { 04523 ast_log(LOG_WARNING, "Unable to get seqno from '%s'\n", get_header(req, "CSeq")); 04524 return -1; 04525 } 04526 respprep(&resp, p, msg, req); 04527 if (p->rtp) { 04528 ast_rtp_offered_from_local(p->rtp, 0); 04529 try_suggested_sip_codec(p); 04530 add_sdp(&resp, p); 04531 } else { 04532 ast_log(LOG_ERROR, "Can't add SDP to response, since we have no RTP session allocated. Call-ID %s\n", p->callid); 04533 } 04534 return send_response(p, &resp, retrans, seqno); 04535 }
|
|
transmit_response_with_unsupported: Transmit response, no retransmits
Definition at line 4158 of file chan_sip.c. References add_header(), append_date(), respprep(), and send_response(). Referenced by handle_request_invite(). 04159 { 04160 struct sip_request resp; 04161 respprep(&resp, p, msg, req); 04162 append_date(&resp); 04163 add_header(&resp, "Unsupported", unsupported); 04164 return send_response(p, &resp, 0, 0); 04165 }
|
|
transmit_sip_request: Transmit SIP request
Definition at line 5170 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(). 05171 { 05172 if (!p->initreq.headers) { 05173 /* Use this as the basis */ 05174 copy_request(&p->initreq, req); 05175 parse_request(&p->initreq); 05176 if (sip_debug_test_pvt(p)) 05177 ast_verbose("%d headers, %d lines\n", p->initreq.headers, p->initreq.lines); 05178 determine_firstline_parts(&p->initreq); 05179 } 05180 05181 return send_request(p, req, 0, p->ocseq); 05182 }
|
|
transmit_state_notify: Used in the SUBSCRIBE notification subsystem ----
Definition at line 4964 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(). 04965 { 04966 char tmp[4000], from[256], to[256]; 04967 char *t = tmp, *c, *a, *mfrom, *mto; 04968 size_t maxbytes = sizeof(tmp); 04969 struct sip_request req; 04970 char hint[AST_MAX_EXTENSION]; 04971 char *statestring = "terminated"; 04972 const struct cfsubscription_types *subscriptiontype; 04973 enum state { NOTIFY_OPEN, NOTIFY_INUSE, NOTIFY_CLOSED } local_state = NOTIFY_OPEN; 04974 char *pidfstate = "--"; 04975 char *pidfnote= "Ready"; 04976 04977 memset(from, 0, sizeof(from)); 04978 memset(to, 0, sizeof(to)); 04979 memset(tmp, 0, sizeof(tmp)); 04980 04981 switch (state) { 04982 case (AST_EXTENSION_RINGING | AST_EXTENSION_INUSE): 04983 if (global_notifyringing) 04984 statestring = "early"; 04985 else 04986 statestring = "confirmed"; 04987 local_state = NOTIFY_INUSE; 04988 pidfstate = "busy"; 04989 pidfnote = "Ringing"; 04990 break; 04991 case AST_EXTENSION_RINGING: 04992 statestring = "early"; 04993 local_state = NOTIFY_INUSE; 04994 pidfstate = "busy"; 04995 pidfnote = "Ringing"; 04996 break; 04997 case AST_EXTENSION_INUSE: 04998 statestring = "confirmed"; 04999 local_state = NOTIFY_INUSE; 05000 pidfstate = "busy"; 05001 pidfnote = "On the phone"; 05002 break; 05003 case AST_EXTENSION_BUSY: 05004 statestring = "confirmed"; 05005 local_state = NOTIFY_CLOSED; 05006 pidfstate = "busy"; 05007 pidfnote = "On the phone"; 05008 break; 05009 case AST_EXTENSION_UNAVAILABLE: 05010 statestring = "confirmed"; 05011 local_state = NOTIFY_CLOSED; 05012 pidfstate = "away"; 05013 pidfnote = "Unavailable"; 05014 break; 05015 case AST_EXTENSION_NOT_INUSE: 05016 default: 05017 /* Default setting */ 05018 break; 05019 } 05020 05021 subscriptiontype = find_subscription_type(p->subscribed); 05022 05023 /* Check which device/devices we are watching and if they are registered */ 05024 if (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, p->context, p->exten)) { 05025 /* If they are not registered, we will override notification and show no availability */ 05026 if (ast_device_state(hint) == AST_DEVICE_UNAVAILABLE) { 05027 local_state = NOTIFY_CLOSED; 05028 pidfstate = "away"; 05029 pidfnote = "Not online"; 05030 } 05031 } 05032 05033 ast_copy_string(from, get_header(&p->initreq, "From"), sizeof(from)); 05034 c = get_in_brackets(from); 05035 if (strncmp(c, "sip:", 4)) { 05036 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", c); 05037 return -1; 05038 } 05039 if ((a = strchr(c, ';'))) 05040 *a = '\0'; 05041 mfrom = c; 05042 05043 ast_copy_string(to, get_header(&p->initreq, "To"), sizeof(to)); 05044 c = get_in_brackets(to); 05045 if (strncmp(c, "sip:", 4)) { 05046 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", c); 05047 return -1; 05048 } 05049 if ((a = strchr(c, ';'))) 05050 *a = '\0'; 05051 mto = c; 05052 05053 reqprep(&req, p, SIP_NOTIFY, 0, 1); 05054 05055 05056 add_header(&req, "Event", subscriptiontype->event); 05057 add_header(&req, "Content-Type", subscriptiontype->mediatype); 05058 switch(state) { 05059 case AST_EXTENSION_DEACTIVATED: 05060 if (p->subscribed == TIMEOUT) 05061 add_header(&req, "Subscription-State", "terminated;reason=timeout"); 05062 else { 05063 add_header(&req, "Subscription-State", "terminated;reason=probation"); 05064 add_header(&req, "Retry-After", "60"); 05065 } 05066 break; 05067 case AST_EXTENSION_REMOVED: 05068 add_header(&req, "Subscription-State", "terminated;reason=noresource"); 05069 break; 05070 break; 05071 default: 05072 if (p->expiry) 05073 add_header(&req, "Subscription-State", "active"); 05074 else /* Expired */ 05075 add_header(&req, "Subscription-State", "terminated;reason=timeout"); 05076 } 05077 switch (p->subscribed) { 05078 case XPIDF_XML: 05079 case CPIM_PIDF_XML: 05080 ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\"?>\n"); 05081 ast_build_string(&t, &maxbytes, "<!DOCTYPE presence PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n"); 05082 ast_build_string(&t, &maxbytes, "<presence>\n"); 05083 ast_build_string(&t, &maxbytes, "<presentity uri=\"%s;method=SUBSCRIBE\" />\n", mfrom); 05084 ast_build_string(&t, &maxbytes, "<atom id=\"%s\">\n", p->exten); 05085 ast_build_string(&t, &maxbytes, "<address uri=\"%s;user=ip\" priority=\"0.800000\">\n", mto); 05086 ast_build_string(&t, &maxbytes, "<status status=\"%s\" />\n", (local_state == NOTIFY_OPEN) ? "open" : (local_state == NOTIFY_INUSE) ? "inuse" : "closed"); 05087 ast_build_string(&t, &maxbytes, "<msnsubstatus substatus=\"%s\" />\n", (local_state == NOTIFY_OPEN) ? "online" : (local_state == NOTIFY_INUSE) ? "onthephone" : "offline"); 05088 ast_build_string(&t, &maxbytes, "</address>\n</atom>\n</presence>\n"); 05089 break; 05090 case PIDF_XML: /* Eyebeam supports this format */ 05091 ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n"); 05092 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); 05093 ast_build_string(&t, &maxbytes, "<pp:person><status>\n"); 05094 if (pidfstate[0] != '-') 05095 ast_build_string(&t, &maxbytes, "<ep:activities><ep:%s/></ep:activities>\n", pidfstate); 05096 ast_build_string(&t, &maxbytes, "</status></pp:person>\n"); 05097 ast_build_string(&t, &maxbytes, "<note>%s</note>\n", pidfnote); /* Note */ 05098 ast_build_string(&t, &maxbytes, "<tuple id=\"%s\">\n", p->exten); /* Tuple start */ 05099 ast_build_string(&t, &maxbytes, "<contact priority=\"1\">%s</contact>\n", mto); 05100 if (pidfstate[0] == 'b') /* Busy? Still open ... */ 05101 ast_build_string(&t, &maxbytes, "<status><basic>open</basic></status>\n"); 05102 else 05103 ast_build_string(&t, &maxbytes, "<status><basic>%s</basic></status>\n", (local_state != NOTIFY_CLOSED) ? "open" : "closed"); 05104 ast_build_string(&t, &maxbytes, "</tuple>\n</presence>\n"); 05105 break; 05106 case DIALOG_INFO_XML: /* SNOM subscribes in this format */ 05107 ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\"?>\n"); 05108 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); 05109 if ((state & AST_EXTENSION_RINGING) && global_notifyringing) 05110 ast_build_string(&t, &maxbytes, "<dialog id=\"%s\" direction=\"recipient\">\n", p->exten); 05111 else 05112 ast_build_string(&t, &maxbytes, "<dialog id=\"%s\">\n", p->exten); 05113 ast_build_string(&t, &maxbytes, "<state>%s</state>\n", statestring); 05114 ast_build_string(&t, &maxbytes, "</dialog>\n</dialog-info>\n"); 05115 break; 05116 case NONE: 05117 default: 05118 break; 05119 } 05120 05121 if (t > tmp + sizeof(tmp)) 05122 ast_log(LOG_WARNING, "Buffer overflow detected!! (Please file a bug report)\n"); 05123 05124 add_header_contentLength(&req, strlen(tmp)); 05125 add_line(&req, tmp); 05126 05127 return send_request(p, &req, 1, p->ocseq); 05128 }
|
|
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 13269 of file chan_sip.c. References usecnt. 13270 { 13271 return usecnt; 13272 }
|
|
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 12769 of file chan_sip.c. Referenced by load_module(), and unload_module(). |
|
Definition at line 12771 of file chan_sip.c. Referenced by load_module(), and unload_module(). |
|
Definition at line 12783 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 9219 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 9118 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 12768 of file chan_sip.c. Referenced by load_module(). |
|
Definition at line 12775 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 12786 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 9135 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 7843 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 7425 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 13091 of file chan_sip.c. |
|
Initial value: "Usage: sip no debug\n" " Disables dumping of SIP packets for debugging purposes\n" Definition at line 9127 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 9131 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 9067 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 9109 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 9091 of file chan_sip.c. |
|
Initial value: "Usage: sip show channels\n" " Lists all currently active SIP channels.\n" Definition at line 9087 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 9062 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 9095 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 9082 of file chan_sip.c. |
|
Initial value: "Usage: sip show objects\n" " Shows status of known SIP objects\n" Definition at line 9148 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 9104 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 9099 of file chan_sip.c. |
|
Initial value: "Usage: sip show registry\n" " Lists all registration requests and status.\n" Definition at line 9114 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 9152 of file chan_sip.c. |
|
Initial value: "Usage: sip show subscriptions\n" " Shows active SIP subscriptions for extension states\n" Definition at line 9144 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 9077 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 9072 of file chan_sip.c. |
|
Definition at line 9198 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 9140 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 12996 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 9383 of file chan_sip.c. Referenced by load_module(), and unload_module(). |
|
|
Definition at line 9306 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 12767 of file chan_sip.c. Referenced by load_module(). |
|
Definition at line 12772 of file chan_sip.c. Referenced by load_module(). |
|
Definition at line 12784 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(). |