#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"
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 | |
char * | __get_header (struct sip_request *req, char *name, int *start) |
int | __sip_ack (struct sip_pvt *p, int seqno, int resp, int sipmethod) |
__sip_ack: Acknowledges receipt of a packet and stops retransmission --- | |
int | __sip_autodestruct (void *data) |
__sip_autodestruct: Kill a call (called by scheduler) --- | |
void | __sip_destroy (struct sip_pvt *p, int lockowner) |
__sip_destroy: Execute destrucion of call structure, release memory--- | |
int | __sip_do_register (struct sip_registry *r) |
__sip_do_register: Register with SIP proxy --- | |
int | __sip_pretend_ack (struct sip_pvt *p) |
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 --- | |
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) --- | |
int | __sip_show_channels (int fd, int argc, char *argv[], int subscriptions) |
int | __sip_xmit (struct sip_pvt *p, char *data, int len) |
__sip_xmit: Transmit SIP message --- | |
int | __transmit_response (struct sip_pvt *p, char *msg, struct sip_request *req, int reliable) |
__transmit_response: Base transmit response function | |
int | _sip_show_peer (int type, int fd, struct mansession *s, struct message *m, int argc, char *argv[]) |
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 | |
int | add_blank_header (struct sip_request *req) |
add_blank_header: Add blank header to SIP message | |
void | add_codec_to_sdp (const struct sip_pvt *p, int codec, int sample_rate, char **m_buf, size_t *m_size, char **a_buf, size_t *a_size, int debug) |
int | add_digit (struct sip_request *req, char digit) |
add_digit: add DTMF INFO tone to sip message --- | |
int | add_header (struct sip_request *req, const char *var, const char *value) |
add_header: Add header to SIP message | |
int | add_header_contentLength (struct sip_request *req, int len) |
add_header_contentLen: Add 'Content-Length' header to SIP message | |
int | add_line (struct sip_request *req, const char *line) |
add_line: Add content (not header) to SIP message | |
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) |
sip_auth * | add_realm_authentication (struct sip_auth *authlist, char *configuration, int lineno) |
add_realm_authentication: Add realm authentication in list --- | |
void | add_route (struct sip_request *req, struct sip_route *route) |
add_route: Add route header into request per learned route --- | |
int | add_sdp (struct sip_request *resp, struct sip_pvt *p) |
add_sdp: Add Session Description Protocol message --- | |
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 | |
int | add_text (struct sip_request *req, const char *text) |
add_text: Add text body to SIP message --- | |
int | add_vidupdate (struct sip_request *req) |
add_vidupdate: add XML encoded media control with update --- | |
void | append_date (struct sip_request *req) |
append_date: Append date to SIP message --- | |
int | append_history (struct sip_pvt *p, const char *event, const char *data) |
append_history: Append to SIP dialog history | |
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) | |
void | ast_quiet_chan (struct ast_channel *chan) |
ast_quiet_chan: Turn off generator data | |
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? --- | |
int | attempt_transfer (struct sip_pvt *p1, struct sip_pvt *p2) |
attempt_transfer: Attempt transfer of SIP call --- | |
int | auto_congest (void *nothing) |
auto_congest: Scheduled congestion on a call --- | |
void | build_callid (char *callid, int len, struct in_addr ourip, char *fromdomain) |
build_callid: Build SIP CALLID header --- | |
void | build_contact (struct sip_pvt *p) |
build_contact: Build contact header - the contact header we send out --- | |
sip_peer * | build_peer (const char *name, struct ast_variable *v, int realtime) |
build_peer: Build peer from config file --- | |
int | build_reply_digest (struct sip_pvt *p, int method, char *digest, int digest_len) |
build_reply_digest: Build reply digest --- | |
void | build_route (struct sip_pvt *p, struct sip_request *req, int backwards) |
build_route: Build route list from Record-Route header --- | |
void | build_rpid (struct sip_pvt *p) |
build_rpid: Build the Remote Party-ID & From using callingpres options --- | |
sip_user * | build_user (const char *name, struct ast_variable *v, int realtime) |
build_user: Initiate a SIP user structure from sip.conf --- | |
void | build_via (struct sip_pvt *p, char *buf, int len) |
build_via: Build a Via header for a request --- | |
int | cb_extensionstate (char *context, char *exten, int state, void *data) |
cb_extensionstate: Callback for the devicestate notification (SUBSCRIBE) support subsystem --- | |
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 --- | |
void | check_pendings (struct sip_pvt *p) |
check_pendings: Check pending actions on SIP call --- | |
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 | |
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 --- | |
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 --- | |
int | check_via (struct sip_pvt *p, struct sip_request *req) |
check Via: header for hostname, port and rport request/answer | |
int | clear_realm_authentication (struct sip_auth *authlist) |
clear_realm_authentication: Clear realm authentication list (at reload) --- | |
void | clear_sip_domains (void) |
clear_sip_domains: Clear our domain list (at reload) | |
char * | complete_sip_debug_peer (char *line, char *word, int pos, int state) |
complete_sip_debug_peer: Support routine for 'sip debug peer' CLI --- | |
char * | complete_sip_peer (char *word, int state, int flags2) |
complete_sip_peer: Do completion on peer name --- | |
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 --- | |
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 --- | |
char * | complete_sip_show_peer (char *line, char *word, int pos, int state) |
complete_sip_show_peer: Support routine for 'sip show peer' CLI --- | |
char * | complete_sip_show_user (char *line, char *word, int pos, int state) |
complete_sip_show_user: Support routine for 'sip show user' CLI --- | |
char * | complete_sip_user (char *word, int state, int flags2) |
complete_sip_user: Do completion on user name --- | |
char * | complete_sipch (char *line, char *word, int pos, int state) |
complete_sipch: Support routine for 'sip show channel' CLI --- | |
char * | complete_sipnotify (char *line, char *word, int pos, int state) |
complete_sipnotify: Support routine for 'sip notify' CLI --- | |
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 --- | |
int | copy_header (struct sip_request *req, struct sip_request *orig, char *field) |
copy_header: Copy one header field from one request to another | |
void | copy_request (struct sip_request *dst, struct sip_request *src) |
copy_request: copy SIP request (mostly used to save request for responses) --- | |
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 --- | |
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 | |
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. | |
void | destroy_association (struct sip_peer *peer) |
int | determine_firstline_parts (struct sip_request *req) |
determine_firstline_parts: parse first line of incoming SIP request | |
void * | do_monitor (void *data) |
do_monitor: The SIP monitoring thread --- | |
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 --- | |
int | do_register_auth (struct sip_pvt *p, struct sip_request *req, char *header, char *respheader) |
do_register_auth: Authenticate for outbound registration --- | |
const char * | domain_mode_to_text (const enum domain_mode mode) |
const char * | dtmfmode2str (int mode) |
dtmfmode2str: Convert DTMF mode to printable string --- | |
int | expire_register (void *data) |
expire_register: Expire registration of SIP peer --- | |
void | extract_uri (struct sip_pvt *p, struct sip_request *req) |
extract_uri: Check Contact: URI of SIP message --- | |
char * | find_alias (const char *name, char *_default) |
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 | |
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 | |
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 | |
const struct cfsubscription_types * | find_subscription_type (enum subscriptiontype subtype) |
find_subscription_type: Find subscription type in array | |
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) | |
void | free_old_route (struct sip_route *route) |
free_old_route: Remove route from route list --- | |
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 | |
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) | |
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 | |
char * | function_sippeer (struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) |
function_sippeer: ${SIPPEER()} Dialplan function - reads peer data | |
int | get_also_info (struct sip_pvt *p, struct sip_request *oreq) |
get_also_info: Call transfer support (old way, depreciated)-- | |
char * | get_calleridname (char *input, char *output, size_t outputsize) |
get_calleridname: Get caller id name from SIP headers --- | |
int | get_destination (struct sip_pvt *p, struct sip_request *oreq) |
get_destination: Find out who the call is for -- | |
char * | get_header (struct sip_request *req, char *name) |
get_header: Get header from SIP request --- | |
char * | get_in_brackets (char *tmp) |
get_in_brackets: Pick out text in brackets from character string --- | |
int | get_msg_text (char *buf, int len, struct sip_request *req) |
get_msg_text: Get text out of a SIP MESSAGE packet --- | |
int | get_rdnis (struct sip_pvt *p, struct sip_request *oreq) |
get_rdnis: get referring dnis --- | |
int | get_refer_info (struct sip_pvt *sip_pvt, struct sip_request *outgoing_req) |
get_refer_info: Call transfer support (the REFER method) --- | |
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 | |
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 | |
char * | get_sdp_by_line (char *line, char *name, int nameLen) |
get_sdp_by_line: Reads one line of SIP message body | |
char * | get_sdp_iterate (int *iterator, struct sip_request *req, char *name) |
sip_pvt * | get_sip_pvt_byid_locked (char *callid) |
get_sip_pvt_byid_locked: Lock interface lock and find matching pvt lock --- | |
char * | gettag (struct sip_request *req, char *header, char *tagbuf, int tagbufsize) |
gettag: Get tag from packet | |
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 --- | |
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) --- | |
int | handle_request_bye (struct sip_pvt *p, struct sip_request *req, int debug, int ignore) |
handle_request_bye: Handle incoming BYE request --- | |
int | handle_request_cancel (struct sip_pvt *p, struct sip_request *req, int debug, int ignore) |
handle_request_cancel: Handle incoming CANCEL request --- | |
void | handle_request_info (struct sip_pvt *p, struct sip_request *req) |
handle_request_info: Receive SIP INFO Message --- | |
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 | |
int | handle_request_message (struct sip_pvt *p, struct sip_request *req, int debug, int ignore) |
handle_request_message: Handle incoming MESSAGE request --- | |
int | handle_request_options (struct sip_pvt *p, struct sip_request *req, int debug) |
handle_request_options: Handle incoming OPTIONS request | |
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 --- | |
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 --- | |
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 --- | |
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 --- | |
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 --- | |
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) | |
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 --- | |
char * | hangup_cause2sip (int cause) |
hangup_cause2sip: Convert Asterisk hangup causes to SIP codes | |
int | hangup_sip2cause (int cause) |
hangup_sip2cause: Convert SIP hangup causes to Asterisk hangup causes --- | |
int | init_req (struct sip_request *req, int sipmethod, char *recip) |
init_req: Initialize SIP request --- | |
int | init_resp (struct sip_request *req, char *resp, struct sip_request *orig) |
init_resp: Initialize SIP response, based on SIP request --- | |
void | initreqprep (struct sip_request *req, struct sip_pvt *p, int sipmethod) |
initreqprep: Initiate new SIP request to peer/user --- | |
const char * | insecure2str (int port, int invite) |
insecure2str: Convert Insecure setting to printable string --- | |
char * | key () |
Returns the ASTERISK_GPL_KEY. | |
void | list_route (struct sip_route *route) |
list_route: List all routes - mostly for debugging --- | |
int | load_module () |
Initialize the module. | |
int | lws2sws (char *msgbuf, int len) |
lws2sws: Parse multiline SIP headers into one header | |
void | make_our_tag (char *tagbuf, size_t len) |
int | manager_sip_show_peer (struct mansession *s, struct message *m) |
manager_sip_show_peer: Show SIP peers in the manager API --- | |
int | manager_sip_show_peers (struct mansession *s, struct message *m) |
manager_sip_show_peers: Show SIP peers in the manager API --- | |
char * | nat2str (int nat) |
nat2str: Convert NAT setting to text string | |
void | parse_copy (struct sip_request *dst, struct sip_request *src) |
parse_copy: Copy SIP request, parse it | |
void | parse_moved_contact (struct sip_pvt *p, struct sip_request *req) |
parse_moved_contact: Parse 302 Moved temporalily response | |
int | parse_ok_contact (struct sip_pvt *pvt, struct sip_request *req) |
parse_ok_contact: Parse contact header for 200 OK on INVITE --- | |
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 --- | |
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 | |
int | peer_status (struct sip_peer *peer, char *status, int statuslen) |
peer_status: Report Peer status in character string | |
void | print_codec_to_cli (int fd, struct ast_codec_pref *pref) |
print_codec_to_cli: Print codec list from preference to CLI/manager | |
void | print_group (int fd, unsigned int group, int crlf) |
print_group: Print call group and pickup group --- | |
int | process_sdp (struct sip_pvt *p, struct sip_request *req) |
process_sdp: Process SIP SDP and activate RTP channels--- | |
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 | |
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 --- | |
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) | |
void | receive_message (struct sip_pvt *p, struct sip_request *req) |
receive_message: Receive SIP MESSAGE method messages --- | |
void | reg_source_db (struct sip_peer *peer) |
reg_source_db: Get registration details from Asterisk DB --- | |
void | register_peer_exten (struct sip_peer *peer, int onoff) |
register_peer_exten: Automatically add peer extension to dial plan --- | |
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 | |
char * | regstate2str (int regstate) |
int | reload (void) |
Reload stuff. | |
int | reload_config (void) |
reload_config: Re-read SIP.conf config file --- | |
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 --- | |
int | reqprep (struct sip_request *req, struct sip_pvt *p, int sipmethod, int seqno, int newbranch) |
reqprep: Initialize a SIP request response packet --- | |
int | respprep (struct sip_request *resp, struct sip_pvt *p, char *msg, struct sip_request *req) |
respprep: Prepare SIP response packet --- | |
int | restart_monitor (void) |
restart_monitor: Start the channel monitor thread --- | |
int | retrans_pkt (void *data) |
retrans_pkt: Retransmit SIP message if no answer --- | |
void | sdpLineNum_iterator_init (int *iterator) |
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 --- | |
int | send_response (struct sip_pvt *p, struct sip_request *req, int reliable, int seqno) |
send_response: Transmit response on SIP request--- | |
void | set_destination (struct sip_pvt *p, char *uri) |
set_destination: Set destination from SIP URI --- | |
int | sip_addheader (struct ast_channel *chan, void *data) |
sip_addheader: Add a SIP header --- | |
int | sip_addrcmp (char *name, struct sockaddr_in *sin) |
sip_addrcmp: Support routine for find_peer --- | |
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 --- | |
int | sip_answer (struct ast_channel *ast) |
sip_answer: Answer SIP call , send 200 OK on Invite Part of PBX interface | |
int | sip_call (struct ast_channel *ast, char *dest, int timeout) |
sip_call: Initiate SIP call from PBX used from the dial() application | |
int | sip_cancel_destroy (struct sip_pvt *p) |
sip_cancel_destroy: Cancel destruction of SIP call --- | |
int | sip_debug_test_addr (struct sockaddr_in *addr) |
sip_debug_test_addr: See if we pass debug IP filter | |
int | sip_debug_test_pvt (struct sip_pvt *p) |
sip_debug_test_pvt: Test PVT for debugging output | |
void | sip_destroy (struct sip_pvt *p) |
sip_destroy: Destroy SIP call structure --- | |
void | sip_destroy_peer (struct sip_peer *peer) |
sip_destroy_peer: Destroy peer object from memory | |
void | sip_destroy_user (struct sip_user *user) |
sip_destroy_user: Remove user object from in-memory storage --- | |
int | sip_devicestate (void *data) |
sip_devicestate: Part of PBX channel interface --- | |
int | sip_do_debug (int fd, int argc, char *argv[]) |
sip_do_debug: Turn on SIP debugging (CLI command) | |
int | sip_do_debug_ip (int fd, int argc, char *argv[]) |
sip_do_debug: Enable SIP Debugging in CLI --- | |
int | sip_do_debug_peer (int fd, int argc, char *argv[]) |
sip_do_debug_peer: Turn on SIP debugging with peer mask | |
int | sip_do_history (int fd, int argc, char *argv[]) |
sip_do_history: Enable SIP History logging (CLI) --- | |
int | sip_do_reload (void) |
sip_do_reload: Reload module | |
int | sip_dtmfmode (struct ast_channel *chan, void *data) |
sip_dtmfmode: change the DTMFmode for a SIP call (application) --- | |
void | sip_dump_history (struct sip_pvt *dialog) |
dump_history: Dump SIP history to debug log file at end of lifespan for SIP dialog | |
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 ---- | |
int | sip_get_codec (struct ast_channel *chan) |
sip_get_codec: Return SIP UA's codec (part of the RTP interface) --- | |
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) | |
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) | |
int | sip_getheader (struct ast_channel *chan, void *data) |
sip_getheader: Get a SIP header (dialplan app) --- | |
int | sip_hangup (struct ast_channel *ast) |
sip_hangup: Hangup SIP call Part of PBX interface, called from ast_hangup | |
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 | |
ast_channel * | sip_new (struct sip_pvt *i, int state, char *title) |
sip_new: Initiate a call in the SIP channel | |
int | sip_no_debug (int fd, int argc, char *argv[]) |
sip_no_debug: Disable SIP Debugging in CLI --- | |
int | sip_no_history (int fd, int argc, char *argv[]) |
sip_no_history: Disable SIP History logging (CLI) --- | |
int | sip_notify (int fd, int argc, char *argv[]) |
sip_notify: Send SIP notify to peer | |
int | sip_park (struct ast_channel *chan1, struct ast_channel *chan2, struct sip_request *req) |
sip_park: Park a call --- | |
void * | sip_park_thread (void *stuff) |
sip_park_thread: Park SIP call support function | |
void | sip_poke_all_peers (void) |
sip_poke_all_peers: Send a poke to all known peers | |
int | sip_poke_noanswer (void *data) |
sip_poke_noanswer: No answer to Qualify poke --- | |
int | sip_poke_peer (struct sip_peer *peer) |
sip_poke_peer: Check availability of peer, also keep NAT open --- | |
int | sip_poke_peer_s (void *data) |
int | sip_prune_realtime (int fd, int argc, char *argv[]) |
sip_prune_realtime: Remove temporary realtime objects from memory (CLI) --- | |
ast_frame * | sip_read (struct ast_channel *ast) |
sip_read: Read SIP RTP from channel | |
int | sip_reg_timeout (void *data) |
sip_reg_timeout: Registration timeout, register again | |
int | sip_register (char *value, int lineno) |
sip_register: Parse register=> line in sip.conf and add to registry | |
void | sip_registry_destroy (struct sip_registry *reg) |
sip_registry_destroy: Destroy registry object --- | |
int | sip_reload (int fd, int argc, char *argv[]) |
sip_reload: Force reload of module from cli --- | |
ast_channel * | sip_request_call (const char *type, int format, void *data, int *cause) |
sip_request: PBX interface function -build SIP pvt structure --- | |
int | sip_reregister (void *data) |
sip_reregister: Update registration with SIP Proxy--- | |
ast_frame * | sip_rtp_read (struct ast_channel *ast, struct sip_pvt *p) |
sip_rtp_read: Read RTP from network --- | |
int | sip_scheddestroy (struct sip_pvt *p, int ms) |
sip_scheddestroy: Schedule destruction of SIP call --- | |
void | sip_send_all_registers (void) |
sip_send_all_registers: Send all known registrations | |
int | sip_send_mwi_to_peer (struct sip_peer *peer) |
sip_send_mwi_to_peer: Send message waiting indication --- | |
int | sip_senddigit (struct ast_channel *ast, char digit) |
sip_senddigit: Send DTMF character on SIP channel | |
int | sip_sendtext (struct ast_channel *ast, const char *text) |
sip_sendtext: Send SIP MESSAGE text within a call --- | |
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 --- | |
int | sip_show_channel (int fd, int argc, char *argv[]) |
sip_show_channel: Show details of one call --- | |
int | sip_show_channels (int fd, int argc, char *argv[]) |
sip_show_channels: Show active SIP channels --- | |
int | sip_show_domains (int fd, int argc, char *argv[]) |
int | sip_show_history (int fd, int argc, char *argv[]) |
sip_show_history: Show history details of one call --- | |
int | sip_show_inuse (int fd, int argc, char *argv[]) |
sip_show_inuse: CLI Command to show calls within limits set by call_limit --- | |
int | sip_show_objects (int fd, int argc, char *argv[]) |
sip_show_objects: List all allocated SIP Objects --- | |
int | sip_show_peer (int fd, int argc, char *argv[]) |
sip_show_peer: Show one peer in detail --- | |
int | sip_show_peers (int fd, int argc, char *argv[]) |
sip_show_peers: CLI Show Peers command | |
int | sip_show_registry (int fd, int argc, char *argv[]) |
sip_show_registry: Show SIP Registry (registrations with other SIP proxies --- | |
int | sip_show_settings (int fd, int argc, char *argv[]) |
sip_show_settings: List global settings for the SIP channel --- | |
int | sip_show_subscriptions (int fd, int argc, char *argv[]) |
sip_show_subscriptions: Show active SIP subscriptions --- | |
int | sip_show_user (int fd, int argc, char *argv[]) |
sip_show_user: Show one user in detail --- | |
int | sip_show_users (int fd, int argc, char *argv[]) |
sip_show_users: CLI Command 'SIP Show Users' --- | |
int | sip_sipredirect (struct sip_pvt *p, const char *dest) |
sip_sipredirect: Transfer call before connect with a 302 redirect --- | |
int | sip_transfer (struct ast_channel *ast, const char *dest) |
sip_transfer: Transfer SIP call | |
int | sip_write (struct ast_channel *ast, struct ast_frame *frame) |
sip_write: Send frame to media channel (rtp) --- | |
int | sipsock_read (int *id, int fd, short events, void *ignore) |
sipsock_read: Read data from SIP socket --- | |
const char * | subscription_type2str (enum subscriptiontype subtype) |
subscription_type2str: Show subscription type in string format | |
sip_peer * | temp_peer (const char *name) |
temp_peer: Create temporary peer (used in autocreatepeer mode) --- | |
force_inline int | thread_safe_rand (void) |
Thread-safe random number generator. | |
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 --- | |
int | transmit_info_with_vidupdate (struct sip_pvt *p) |
transmit_info_with_vidupdate: Send SIP INFO with video update request --- | |
int | transmit_invite (struct sip_pvt *p, int sipmethod, int sendsdp, int init) |
transmit_invite: Build REFER/INVITE/OPTIONS message and transmit it --- | |
int | transmit_message_with_text (struct sip_pvt *p, const char *text) |
transmit_message_with_text: Transmit text with SIP MESSAGE method --- | |
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 --- | |
int | transmit_notify_with_sipfrag (struct sip_pvt *p, int cseq) |
transmit_notify_with_sipfrag: Notify a transferring party of the status of trasnfer --- | |
int | transmit_refer (struct sip_pvt *p, const char *dest) |
transmit_refer: Transmit SIP REFER message --- | |
int | transmit_register (struct sip_registry *r, int sipmethod, char *auth, char *authheader) |
transmit_register: Transmit register to SIP proxy or UA --- | |
int | transmit_reinvite_with_sdp (struct sip_pvt *p) |
transmit_reinvite_with_sdp: Transmit reinvite with SDP :-) --- | |
int | transmit_request (struct sip_pvt *p, int sipmethod, int inc, int reliable, int newbranch) |
transmit_request: transmit generic SIP request --- | |
int | transmit_request_with_auth (struct sip_pvt *p, int sipmethod, int inc, int reliable, int newbranch) |
transmit_request_with_auth: Transmit SIP request, auth added --- | |
int | transmit_response (struct sip_pvt *p, char *msg, struct sip_request *req) |
transmit_response: Transmit response, no retransmits | |
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 | |
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 --- | |
int | transmit_response_with_auth (struct sip_pvt *p, char *msg, struct sip_request *req, char *rand, int reliable, char *header, int stale) |
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 --- | |
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 --- | |
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 | |
int | transmit_sip_request (struct sip_pvt *p, struct sip_request *req) |
transmit_sip_request: Transmit SIP request | |
int | transmit_state_notify (struct sip_pvt *p, int state, int full, int substate) |
transmit_state_notify: Used in the SUBSCRIBE notification subsystem ---- | |
int | unload_module () |
Cleanup all module structures, sockets, etc. | |
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... | |
void | update_peer (struct sip_peer *p, int expiry) |
update_peer: Update peer data in database (if used) --- | |
int | usecount () |
Provides a usecount. | |
Variables | |
in_addr | __ourip |
const struct cfalias | aliases [] |
Structure for conversion between compressed SIP and "normal" SIP. | |
int | allow_external_domains |
int | apeerobjs = 0 |
char * | app_dtmfmode = "SIPDtmfMode" |
char * | app_sipaddheader = "SIPAddHeader" |
char * | app_sipgetheader = "SIPGetHeader" |
sip_auth * | authl |
int | autocreatepeer = 0 |
sockaddr_in | bindaddr = { 0, } |
int | callevents = 0 |
const char | channeltype [] = "SIP" |
ast_custom_function | checksipdomain_function |
int | compactheaders = 0 |
const char | config [] = "sip.conf" |
char | debug_usage [] |
sockaddr_in | debugaddr |
char | default_callerid [AST_MAX_EXTENSION] = DEFAULT_CALLERID |
char | default_context [AST_MAX_CONTEXT] = DEFAULT_CONTEXT |
int | default_expiry = DEFAULT_DEFAULT_EXPIRY |
char | default_fromdomain [AST_MAX_EXTENSION] = "" |
char | default_language [MAX_LANGUAGE] = "" |
char | default_notifymime [AST_MAX_EXTENSION] = DEFAULT_NOTIFYMIME |
int | default_qualify = 0 |
char | default_subscribecontext [AST_MAX_CONTEXT] |
char | default_useragent [AST_MAX_EXTENSION] = DEFAULT_USERAGENT |
const char | desc [] = "Session Initiation Protocol (SIP)" |
char * | descrip_dtmfmode = "SIPDtmfMode(inband|info|rfc2833): Changes the dtmfmode for a SIP call\n" |
char * | descrip_sipaddheader |
char * | descrip_sipgetheader |
int | dumphistory = 0 |
int | expiry = DEFAULT_EXPIRY |
time_t | externexpire = 0 |
char | externhost [MAXHOSTNAMELEN] = "" |
sockaddr_in | externip |
int | externrefresh = 10 |
int | global_allowguest = 1 |
int | global_capability = AST_FORMAT_ULAW | AST_FORMAT_ALAW | AST_FORMAT_GSM | AST_FORMAT_H263 |
Codecs that we support by default:. | |
ast_flags | global_flags = {0} |
ast_flags | global_flags_page2 = {0} |
char | global_musicclass [MAX_MUSICCLASS] = "" |
int | global_mwitime = DEFAULT_MWITIME |
int | global_notifyringing = 1 |
char | global_realm [MAXHOSTNAMELEN] = DEFAULT_REALM |
int | global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT |
int | global_regattempts_max = 0 |
int | global_rtautoclear = 120 |
int | global_rtpholdtimeout = 0 |
int | global_rtpkeepalive = 0 |
int | global_rtptimeout = 0 |
char | global_vmexten [AST_MAX_EXTENSION] = DEFAULT_VMEXTEN |
char | history_usage [] |
sip_pvt * | iflist |
sip_pvt: PVT structures are used for each SIP conversation, ie. a call | |
io_context * | io |
ast_ha * | localaddr |
char | mandescr_show_peer [] |
char | mandescr_show_peers [] |
int | max_expiry = DEFAULT_MAX_EXPIRY |
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. | |
ast_cli_entry | my_clis [] |
char | no_debug_usage [] |
char | no_history_usage [] |
int | noncodeccapability = AST_RTP_DTMF |
const char | notify_config [] = "sip_notify.conf" |
ast_config * | notify_types |
char | notify_usage [] |
int | ourport |
sockaddr_in | outboundproxyip |
int | pedanticsipchecking = 0 |
ast_peer_list | peerl |
The peer list: Peers and Friends ---. | |
ast_codec_pref | prefs |
char | prune_realtime_usage [] |
int | recordhistory = 0 |
char | regcontext [AST_MAX_CONTEXT] = "" |
ast_register_list | regl |
The register list: Other SIP proxys we register with and call ---. | |
int | regobjs = 0 |
int | relaxdtmf = 0 |
int | rpeerobjs = 0 |
int | ruserobjs = 0 |
sched_context * | sched |
char | show_channel_usage [] |
char | show_channels_usage [] |
char | show_domains_usage [] |
char | show_history_usage [] |
char | show_inuse_usage [] |
char | show_objects_usage [] |
char | show_peer_usage [] |
char | show_peers_usage [] |
char | show_reg_usage [] |
char | show_settings_usage [] |
char | show_subscriptions_usage [] |
char | show_user_usage [] |
char | show_users_usage [] |
ast_custom_function | sip_header_function |
enum sipmethod | sip_method_list |
const struct cfsip_methods | sip_methods [] |
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. | |
char | sip_reload_usage [] |
int | sip_reloading = 0 |
ast_rtp_protocol | sip_rtp |
sip_rtp: Interface structure with callbacks used to connect to rtp module -- | |
const struct ast_channel_tech | sip_tech |
Definition of this channel for PBX channel registration. | |
ast_custom_function | sipchaninfo_function |
int | sipdebug = 0 |
ast_custom_function | sippeer_function |
int | sipsock = -1 |
int | speerobjs = 0 |
int | srvlookup = 0 |
const struct cfsubscription_types | subscription_types [] |
int | suserobjs = 0 |
char * | synopsis_dtmfmode = "Change the dtmfmode for a SIP call" |
char * | synopsis_sipaddheader = "Add a SIP header to the outbound call" |
char * | synopsis_sipgetheader = "Get a SIP header from an incoming call" |
int | tos = 0 |
int | usecnt = 0 |
ast_user_list | userl |
The user list: Users and friends ---. | |
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. |
|
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. |
|
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. |
|
Definition at line 104 of file chan_sip.c. Referenced by initreqprep(), reqprep(), and transmit_register(). |
|
Definition at line 129 of file chan_sip.c. |
|
Definition at line 382 of file chan_sip.c. |
|
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. |
|
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(), reload_config(), 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. Referenced by handle_response_register(). |
|
Definition at line 115 of file chan_sip.c. Referenced by handle_response_register(). |
|
Definition at line 108 of file chan_sip.c. Referenced by handle_response_register(). |
|
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 7798 of file chan_sip.c. |
|
sip_show_domains: CLI command to list local domains
Definition at line 7798 of file chan_sip.c. |
|
sip_show_domains: CLI command to list local domains
Definition at line 7798 of file chan_sip.c. |
|
sip_show_domains: CLI command to list local domains
Definition at line 7798 of file chan_sip.c. |
|
sip_show_domains: CLI command to list local domains
Definition at line 7798 of file chan_sip.c. |
|
sip_show_domains: CLI command to list local domains
Definition at line 7798 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. |
|
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 regstate2str(), and transmit_register(). |
|
Definition at line 809 of file chan_sip.c. Referenced by regstate2str(). |
|
Definition at line 808 of file chan_sip.c. Referenced by regstate2str(). |
|
Definition at line 805 of file chan_sip.c. Referenced by regstate2str(). |
|
Definition at line 803 of file chan_sip.c. Referenced by regstate2str(), and transmit_register(). |
|
Definition at line 806 of file chan_sip.c. Referenced by regstate2str(). |
|
Definition at line 807 of file chan_sip.c. Referenced by regstate2str(). |
|
Definition at line 802 of file chan_sip.c. Referenced by regstate2str(). |
|
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. |
|
Definition at line 414 of file chan_sip.c. |
|
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 dtmfmode2str(), and handle_common_options(). |
|
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(), 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 dtmfmode2str(), handle_common_options(), process_sdp(), reload_config(), sip_dtmfmode(), and sip_senddigit(). |
|
Is this a dynamic peer? Definition at line 527 of file chan_sip.c. Referenced by _sip_show_peer(), 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_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(), 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 parse_request(). |
|
Max amount of lines in SIP attachment (like SDP) Definition at line 439 of file chan_sip.c. Referenced by 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(), 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(), sip_show_settings(), and sip_show_users(). |
|
Definition at line 539 of file chan_sip.c. Referenced by 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 handle_common_options(), nat2str(), and reload_config(). |
|
Definition at line 538 of file chan_sip.c. Referenced by check_user_full(), check_via(), create_addr_from_peer(), handle_common_options(), nat2str(), 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 add_sdp(), 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_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(). |
|
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(), handle_common_options(), and initreqprep(). |
|
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 5779 of file chan_sip.c. Referenced by parse_register_contact(). 05779 { 05780 PARSE_REGISTER_FAILED, 05781 PARSE_REGISTER_UPDATE, 05782 PARSE_REGISTER_QUERY, 05783 };
|
|
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. Referenced by __sip_reliable_xmit(), check_auth(), check_user(), check_user_full(), do_proxy_auth(), handle_response(), handle_response_peerpoke(), init_req(), initreqprep(), reply_digest(), reqprep(), transmit_invite(), transmit_register(), transmit_request(), and transmit_request_with_auth(). 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. Referenced by transmit_state_notify(). 00158 { 00159 NONE = 0, 00160 TIMEOUT, 00161 XPIDF_XML, 00162 DIALOG_INFO_XML, 00163 CPIM_PIDF_XML, 00164 PIDF_XML 00165 };
|
|
Definition at line 2892 of file chan_sip.c. References find_alias(), sip_request::header, sip_request::headers, and name. Referenced by build_route(), copy_all_header(), copy_via_headers(), get_header(), and handle_response_register(). 02893 { 02894 int pass; 02895 02896 /* 02897 * Technically you can place arbitrary whitespace both before and after the ':' in 02898 * a header, although RFC3261 clearly says you shouldn't before, and place just 02899 * one afterwards. If you shouldn't do it, what absolute idiot decided it was 02900 * a good idea to say you can do it, and if you can do it, why in the hell would. 02901 * you say you shouldn't. 02902 * Anyways, pedanticsipchecking controls whether we allow spaces before ':', 02903 * and we always allow spaces after that for compatibility. 02904 */ 02905 for (pass = 0; name && pass < 2;pass++) { 02906 int x, len = strlen(name); 02907 for (x=*start; x<req->headers; x++) { 02908 if (!strncasecmp(req->header[x], name, len)) { 02909 char *r = req->header[x] + len; /* skip name */ 02910 if (pedanticsipchecking) 02911 r = ast_skip_blanks(r); 02912 02913 if (*r == ':') { 02914 *start = x+1; 02915 return ast_skip_blanks(r+1); 02916 } 02917 } 02918 } 02919 if (pass == 0) /* Try aliases */ 02920 name = find_alias(name, NULL); 02921 } 02922 02923 /* Don't return NULL, so get_header is always a valid pointer */ 02924 return ""; 02925 }
|
|
__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, sipdebug, 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 cur = p->packets; 01366 while(cur) { 01367 if ((cur->seqno == seqno) && ((ast_test_flag(cur, FLAG_RESPONSE)) == resp) && 01368 ((ast_test_flag(cur, FLAG_RESPONSE)) || 01369 (!strncasecmp(msg, cur->data, strlen(msg)) && (cur->data[strlen(msg)] < 33)))) { 01370 ast_mutex_lock(&p->lock); 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 ast_mutex_unlock(&p->lock); 01388 res = 0; 01389 break; 01390 } 01391 prev = cur; 01392 cur = cur->next; 01393 } 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, sip_pvt::owner, sip_destroy(), 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::autokillid, sip_registry::call, sip_pvt::callid, sip_pvt::chanvars, free, free_old_route(), sip_pvt::history, iflist, sip_pvt::initid, sip_pvt::lock, ast_channel::lock, LOG_DEBUG, LOG_WARNING, ast_channel::name, sip_pkt::next, sip_pvt::next, sip_history::next, sip_pvt::options, sip_pvt::owner, sip_pvt::packets, sip_pvt::registry, sip_pkt::retransid, sip_pvt::route, sip_pvt::rpid, sip_pvt::rpid_from, sip_pvt::rtp, sched, sip_debug_test_pvt(), sip_dump_history(), sip_registry_destroy(), sip_pvt::stateid, ast_channel::tech_pvt, and sip_pvt::vrtp. 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 5251 of file chan_sip.c. References SIP_REGISTER, and transmit_register(). Referenced by sip_reregister(). 05252 { 05253 int res; 05254 05255 res = transmit_register(r, SIP_REGISTER, NULL, NULL); 05256 return res; 05257 }
|
|
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, 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(), sip_pkt::retransid, sched, sip_pkt::seqno, sipmethod, 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 8258 of file chan_sip.c. References ast_cli(), ast_extension_state2str(), ast_getformatname(), ast_inet_ntoa(), ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, sip_pvt::callid, sip_pvt::cid_num, sip_pvt::exten, FORMAT, FORMAT2, FORMAT3, sip_pvt::icseq, sip_pvt::lastmsg, sip_pvt::laststate, ast_channel::nativeformats, sip_pvt::next, NONE, sip_pvt::ocseq, sip_pvt::owner, sip_pvt::sa, SIP_CALL_ONHOLD, SIP_NEEDDESTROY, subscription_type2str(), and sip_pvt::username. Referenced by sip_show_channels(), and sip_show_subscriptions(). 08259 { 08260 #define FORMAT3 "%-15.15s %-10.10s %-11.11s %-15.15s %-13.13s %-15.15s\n" 08261 #define FORMAT2 "%-15.15s %-10.10s %-11.11s %-11.11s %-4.4s %-7.7s %-15.15s\n" 08262 #define FORMAT "%-15.15s %-10.10s %-11.11s %5.5d/%5.5d %-4.4s %-3.3s %-3.3s %-15.15s\n" 08263 struct sip_pvt *cur; 08264 char iabuf[INET_ADDRSTRLEN]; 08265 int numchans = 0; 08266 if (argc != 3) 08267 return RESULT_SHOWUSAGE; 08268 ast_mutex_lock(&iflock); 08269 cur = iflist; 08270 if (!subscriptions) 08271 ast_cli(fd, FORMAT2, "Peer", "User/ANR", "Call ID", "Seq (Tx/Rx)", "Format", "Hold", "Last Message"); 08272 else 08273 ast_cli(fd, FORMAT3, "Peer", "User", "Call ID", "Extension", "Last state", "Type"); 08274 while (cur) { 08275 if (cur->subscribed == NONE && !subscriptions) { 08276 ast_cli(fd, FORMAT, ast_inet_ntoa(iabuf, sizeof(iabuf), cur->sa.sin_addr), 08277 ast_strlen_zero(cur->username) ? ( ast_strlen_zero(cur->cid_num) ? "(None)" : cur->cid_num ) : cur->username, 08278 cur->callid, 08279 cur->ocseq, cur->icseq, 08280 ast_getformatname(cur->owner ? cur->owner->nativeformats : 0), 08281 ast_test_flag(cur, SIP_CALL_ONHOLD) ? "Yes" : "No", 08282 ast_test_flag(cur, SIP_NEEDDESTROY) ? "(d)" : "", 08283 cur->lastmsg ); 08284 numchans++; 08285 } 08286 if (cur->subscribed != NONE && subscriptions) { 08287 ast_cli(fd, FORMAT3, ast_inet_ntoa(iabuf, sizeof(iabuf), cur->sa.sin_addr), 08288 ast_strlen_zero(cur->username) ? ( ast_strlen_zero(cur->cid_num) ? "(None)" : cur->cid_num ) : cur->username, 08289 cur->callid, cur->exten, ast_extension_state2str(cur->laststate), 08290 subscription_type2str(cur->subscribed)); 08291 numchans++; 08292 } 08293 cur = cur->next; 08294 } 08295 ast_mutex_unlock(&iflock); 08296 if (!subscriptions) 08297 ast_cli(fd, "%d active SIP channel%s\n", numchans, (numchans != 1) ? "s" : ""); 08298 else 08299 ast_cli(fd, "%d active SIP subscription%s\n", numchans, (numchans != 1) ? "s" : ""); 08300 return RESULT_SUCCESS; 08301 #undef FORMAT 08302 #undef FORMAT2 08303 #undef FORMAT3 08304 }
|
|
__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, 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 4119 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(). 04120 { 04121 struct sip_request resp; 04122 int seqno = 0; 04123 04124 if (reliable && (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1)) { 04125 ast_log(LOG_WARNING, "Unable to determine sequence number from '%s'\n", get_header(req, "CSeq")); 04126 return -1; 04127 } 04128 respprep(&resp, p, msg, req); 04129 add_header_contentLength(&resp, 0); 04130 /* If we are cancelling an incoming invite for some reason, add information 04131 about the reason why we are doing this in clear text */ 04132 if (p->owner && p->owner->hangupcause) { 04133 add_header(&resp, "X-Asterisk-HangupCause", ast_cause2str(p->owner->hangupcause)); 04134 } 04135 add_blank_header(&resp); 04136 return send_response(p, &resp, reliable, seqno); 04137 }
|
|
Definition at line 7861 of file chan_sip.c. References sip_peer::accountcode, sip_peer::addr, sip_peer::amaflags, ast_callerid_merge(), ast_cdr_flags2str(), ast_cli(), ast_codec_pref_index(), ast_describe_caller_presentation(), ast_getformatname(), ast_getformatname_multiple(), ast_inet_ntoa(), ast_sched_when(), ast_strlen_zero(), ast_test_flag, astman_get_header(), 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, mansession::fd, find_peer(), sip_peer::fromdomain, sip_peer::fromuser, sip_peer::fullcontact, sip_peer::ha, cfsip_options::id, 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, s, sched, 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, type, 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(). 07862 { 07863 char status[30] = ""; 07864 char cbuf[256]; 07865 char iabuf[INET_ADDRSTRLEN]; 07866 struct sip_peer *peer; 07867 char codec_buf[512]; 07868 struct ast_codec_pref *pref; 07869 struct ast_variable *v; 07870 struct sip_auth *auth; 07871 int x = 0, codec = 0, load_realtime = 0; 07872 07873 if (argc < 4) 07874 return RESULT_SHOWUSAGE; 07875 07876 load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? 1 : 0; 07877 peer = find_peer(argv[3], NULL, load_realtime); 07878 if (s) { /* Manager */ 07879 if (peer) 07880 ast_cli(s->fd, "Response: Success\r\n"); 07881 else { 07882 snprintf (cbuf, sizeof(cbuf), "Peer %s not found.\n", argv[3]); 07883 astman_send_error(s, m, cbuf); 07884 return 0; 07885 } 07886 } 07887 if (peer && type==0 ) { /* Normal listing */ 07888 ast_cli(fd,"\n\n"); 07889 ast_cli(fd, " * Name : %s\n", peer->name); 07890 ast_cli(fd, " Secret : %s\n", ast_strlen_zero(peer->secret)?"<Not set>":"<Set>"); 07891 ast_cli(fd, " MD5Secret : %s\n", ast_strlen_zero(peer->md5secret)?"<Not set>":"<Set>"); 07892 auth = peer->auth; 07893 while(auth) { 07894 ast_cli(fd, " Realm-auth : Realm %-15.15s User %-10.20s ", auth->realm, auth->username); 07895 ast_cli(fd, "%s\n", !ast_strlen_zero(auth->secret)?"<Secret set>":(!ast_strlen_zero(auth->md5secret)?"<MD5secret set>" : "<Not set>")); 07896 auth = auth->next; 07897 } 07898 ast_cli(fd, " Context : %s\n", peer->context); 07899 ast_cli(fd, " Subscr.Cont. : %s\n", ast_strlen_zero(peer->subscribecontext)?"<Not set>":peer->subscribecontext); 07900 ast_cli(fd, " Language : %s\n", peer->language); 07901 if (!ast_strlen_zero(peer->accountcode)) 07902 ast_cli(fd, " Accountcode : %s\n", peer->accountcode); 07903 ast_cli(fd, " AMA flags : %s\n", ast_cdr_flags2str(peer->amaflags)); 07904 ast_cli(fd, " CallingPres : %s\n", ast_describe_caller_presentation(peer->callingpres)); 07905 if (!ast_strlen_zero(peer->fromuser)) 07906 ast_cli(fd, " FromUser : %s\n", peer->fromuser); 07907 if (!ast_strlen_zero(peer->fromdomain)) 07908 ast_cli(fd, " FromDomain : %s\n", peer->fromdomain); 07909 ast_cli(fd, " Callgroup : "); 07910 print_group(fd, peer->callgroup, 0); 07911 ast_cli(fd, " Pickupgroup : "); 07912 print_group(fd, peer->pickupgroup, 0); 07913 ast_cli(fd, " Mailbox : %s\n", peer->mailbox); 07914 ast_cli(fd, " VM Extension : %s\n", peer->vmexten); 07915 ast_cli(fd, " LastMsgsSent : %d\n", peer->lastmsgssent); 07916 ast_cli(fd, " Call limit : %d\n", peer->call_limit); 07917 ast_cli(fd, " Dynamic : %s\n", (ast_test_flag(peer, SIP_DYNAMIC)?"Yes":"No")); 07918 ast_cli(fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>")); 07919 ast_cli(fd, " Expire : %d\n", peer->expire); 07920 ast_cli(fd, " Insecure : %s\n", insecure2str(ast_test_flag(peer, SIP_INSECURE_PORT), ast_test_flag(peer, SIP_INSECURE_INVITE))); 07921 ast_cli(fd, " Nat : %s\n", nat2str(ast_test_flag(peer, SIP_NAT))); 07922 ast_cli(fd, " ACL : %s\n", (peer->ha?"Yes":"No")); 07923 ast_cli(fd, " CanReinvite : %s\n", (ast_test_flag(peer, SIP_CAN_REINVITE)?"Yes":"No")); 07924 ast_cli(fd, " PromiscRedir : %s\n", (ast_test_flag(peer, SIP_PROMISCREDIR)?"Yes":"No")); 07925 ast_cli(fd, " User=Phone : %s\n", (ast_test_flag(peer, SIP_USEREQPHONE)?"Yes":"No")); 07926 ast_cli(fd, " Trust RPID : %s\n", (ast_test_flag(peer, SIP_TRUSTRPID) ? "Yes" : "No")); 07927 ast_cli(fd, " Send RPID : %s\n", (ast_test_flag(peer, SIP_SENDRPID) ? "Yes" : "No")); 07928 07929 /* - is enumerated */ 07930 ast_cli(fd, " DTMFmode : %s\n", dtmfmode2str(ast_test_flag(peer, SIP_DTMF))); 07931 ast_cli(fd, " LastMsg : %d\n", peer->lastmsg); 07932 ast_cli(fd, " ToHost : %s\n", peer->tohost); 07933 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)); 07934 ast_cli(fd, " Defaddr->IP : %s Port %d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port)); 07935 ast_cli(fd, " Def. Username: %s\n", peer->username); 07936 ast_cli(fd, " SIP Options : "); 07937 if (peer->sipoptions) { 07938 for (x=0 ; (x < (sizeof(sip_options) / sizeof(sip_options[0]))); x++) { 07939 if (peer->sipoptions & sip_options[x].id) 07940 ast_cli(fd, "%s ", sip_options[x].text); 07941 } 07942 } else 07943 ast_cli(fd, "(none)"); 07944 07945 ast_cli(fd, "\n"); 07946 ast_cli(fd, " Codecs : "); 07947 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability); 07948 ast_cli(fd, "%s\n", codec_buf); 07949 ast_cli(fd, " Codec Order : ("); 07950 print_codec_to_cli(fd, &peer->prefs); 07951 07952 ast_cli(fd, ")\n"); 07953 07954 ast_cli(fd, " Status : "); 07955 peer_status(peer, status, sizeof(status)); 07956 ast_cli(fd, "%s\n",status); 07957 ast_cli(fd, " Useragent : %s\n", peer->useragent); 07958 ast_cli(fd, " Reg. Contact : %s\n", peer->fullcontact); 07959 if (peer->chanvars) { 07960 ast_cli(fd, " Variables :\n"); 07961 for (v = peer->chanvars ; v ; v = v->next) 07962 ast_cli(fd, " %s = %s\n", v->name, v->value); 07963 } 07964 ast_cli(fd,"\n"); 07965 ASTOBJ_UNREF(peer,sip_destroy_peer); 07966 } else if (peer && type == 1) { /* manager listing */ 07967 char *actionid = astman_get_header(m,"ActionID"); 07968 07969 ast_cli(fd, "Channeltype: SIP\r\n"); 07970 if (actionid) 07971 ast_cli(fd, "ActionID: %s\r\n", actionid); 07972 ast_cli(fd, "ObjectName: %s\r\n", peer->name); 07973 ast_cli(fd, "ChanObjectType: peer\r\n"); 07974 ast_cli(fd, "SecretExist: %s\r\n", ast_strlen_zero(peer->secret)?"N":"Y"); 07975 ast_cli(fd, "MD5SecretExist: %s\r\n", ast_strlen_zero(peer->md5secret)?"N":"Y"); 07976 ast_cli(fd, "Context: %s\r\n", peer->context); 07977 ast_cli(fd, "Language: %s\r\n", peer->language); 07978 if (!ast_strlen_zero(peer->accountcode)) 07979 ast_cli(fd, "Accountcode: %s\r\n", peer->accountcode); 07980 ast_cli(fd, "AMAflags: %s\r\n", ast_cdr_flags2str(peer->amaflags)); 07981 ast_cli(fd, "CID-CallingPres: %s\r\n", ast_describe_caller_presentation(peer->callingpres)); 07982 if (!ast_strlen_zero(peer->fromuser)) 07983 ast_cli(fd, "SIP-FromUser: %s\r\n", peer->fromuser); 07984 if (!ast_strlen_zero(peer->fromdomain)) 07985 ast_cli(fd, "SIP-FromDomain: %s\r\n", peer->fromdomain); 07986 ast_cli(fd, "Callgroup: "); 07987 print_group(fd, peer->callgroup, 1); 07988 ast_cli(fd, "Pickupgroup: "); 07989 print_group(fd, peer->pickupgroup, 1); 07990 ast_cli(fd, "VoiceMailbox: %s\r\n", peer->mailbox); 07991 ast_cli(fd, "LastMsgsSent: %d\r\n", peer->lastmsgssent); 07992 ast_cli(fd, "Call limit: %d\r\n", peer->call_limit); 07993 ast_cli(fd, "Dynamic: %s\r\n", (ast_test_flag(peer, SIP_DYNAMIC)?"Y":"N")); 07994 ast_cli(fd, "Callerid: %s\r\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "")); 07995 ast_cli(fd, "RegExpire: %ld seconds\r\n", ast_sched_when(sched,peer->expire)); 07996 ast_cli(fd, "SIP-AuthInsecure: %s\r\n", insecure2str(ast_test_flag(peer, SIP_INSECURE_PORT), ast_test_flag(peer, SIP_INSECURE_INVITE))); 07997 ast_cli(fd, "SIP-NatSupport: %s\r\n", nat2str(ast_test_flag(peer, SIP_NAT))); 07998 ast_cli(fd, "ACL: %s\r\n", (peer->ha?"Y":"N")); 07999 ast_cli(fd, "SIP-CanReinvite: %s\r\n", (ast_test_flag(peer, SIP_CAN_REINVITE)?"Y":"N")); 08000 ast_cli(fd, "SIP-PromiscRedir: %s\r\n", (ast_test_flag(peer, SIP_PROMISCREDIR)?"Y":"N")); 08001 ast_cli(fd, "SIP-UserPhone: %s\r\n", (ast_test_flag(peer, SIP_USEREQPHONE)?"Y":"N")); 08002 08003 /* - is enumerated */ 08004 ast_cli(fd, "SIP-DTMFmode %s\r\n", dtmfmode2str(ast_test_flag(peer, SIP_DTMF))); 08005 ast_cli(fd, "SIPLastMsg: %d\r\n", peer->lastmsg); 08006 ast_cli(fd, "ToHost: %s\r\n", peer->tohost); 08007 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)); 08008 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)); 08009 ast_cli(fd, "Default-Username: %s\r\n", peer->username); 08010 ast_cli(fd, "Codecs: "); 08011 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability); 08012 ast_cli(fd, "%s\r\n", codec_buf); 08013 ast_cli(fd, "CodecOrder: "); 08014 pref = &peer->prefs; 08015 for(x = 0; x < 32 ; x++) { 08016 codec = ast_codec_pref_index(pref,x); 08017 if (!codec) 08018 break; 08019 ast_cli(fd, "%s", ast_getformatname(codec)); 08020 if (x < 31 && ast_codec_pref_index(pref,x+1)) 08021 ast_cli(fd, ","); 08022 } 08023 08024 ast_cli(fd, "\r\n"); 08025 ast_cli(fd, "Status: "); 08026 peer_status(peer, status, sizeof(status)); 08027 ast_cli(fd, "%s\r\n", status); 08028 ast_cli(fd, "SIP-Useragent: %s\r\n", peer->useragent); 08029 ast_cli(fd, "Reg-Contact : %s\r\n", peer->fullcontact); 08030 if (peer->chanvars) { 08031 for (v = peer->chanvars ; v ; v = v->next) { 08032 ast_cli(fd, "ChanVariable:\n"); 08033 ast_cli(fd, " %s,%s\r\n", v->name, v->value); 08034 } 08035 } 08036 08037 ASTOBJ_UNREF(peer,sip_destroy_peer); 08038 08039 } else { 08040 ast_cli(fd,"Peer %s not found.\n", argv[3]); 08041 ast_cli(fd,"\n"); 08042 } 08043 08044 return RESULT_SUCCESS; 08045 }
|
|
_sip_show_peers: Execute sip show peers command
Definition at line 7439 of file chan_sip.c. References ast_cli(), ast_strlen_zero(), astman_get_header(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, FORMAT2, name, peer_status(), peerl, and s. Referenced by manager_sip_show_peers(), and sip_show_peers(). 07440 { 07441 regex_t regexbuf; 07442 int havepattern = 0; 07443 07444 #define FORMAT2 "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8s %-10s\n" 07445 #define FORMAT "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8d %-10s\n" 07446 07447 char name[256]; 07448 char iabuf[INET_ADDRSTRLEN]; 07449 int total_peers = 0; 07450 int peers_online = 0; 07451 int peers_offline = 0; 07452 char *id; 07453 char idtext[256] = ""; 07454 07455 if (s) { /* Manager - get ActionID */ 07456 id = astman_get_header(m,"ActionID"); 07457 if (!ast_strlen_zero(id)) 07458 snprintf(idtext,256,"ActionID: %s\r\n",id); 07459 } 07460 07461 switch (argc) { 07462 case 5: 07463 if (!strcasecmp(argv[3], "like")) { 07464 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 07465 return RESULT_SHOWUSAGE; 07466 havepattern = 1; 07467 } else 07468 return RESULT_SHOWUSAGE; 07469 case 3: 07470 break; 07471 default: 07472 return RESULT_SHOWUSAGE; 07473 } 07474 07475 if (!s) { /* Normal list */ 07476 ast_cli(fd, FORMAT2, "Name/username", "Host", "Dyn", "Nat", "ACL", "Port", "Status"); 07477 } 07478 07479 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 07480 char status[20] = ""; 07481 char srch[2000]; 07482 char pstatus; 07483 07484 ASTOBJ_RDLOCK(iterator); 07485 07486 if (havepattern && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 07487 ASTOBJ_UNLOCK(iterator); 07488 continue; 07489 } 07490 07491 if (!ast_strlen_zero(iterator->username) && !s) 07492 snprintf(name, sizeof(name), "%s/%s", iterator->name, iterator->username); 07493 else 07494 ast_copy_string(name, iterator->name, sizeof(name)); 07495 07496 pstatus = peer_status(iterator, status, sizeof(status)); 07497 if (pstatus) 07498 peers_online++; 07499 else { 07500 if (pstatus == 0) 07501 peers_offline++; 07502 else { /* Unmonitored */ 07503 /* Checking if port is 0 */ 07504 if ( ntohs(iterator->addr.sin_port) == 0 ) { 07505 peers_offline++; 07506 } else { 07507 peers_online++; 07508 } 07509 } 07510 } 07511 07512 snprintf(srch, sizeof(srch), FORMAT, name, 07513 iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), iterator->addr.sin_addr) : "(Unspecified)", 07514 ast_test_flag(iterator, SIP_DYNAMIC) ? " D " : " ", /* Dynamic or not? */ 07515 (ast_test_flag(iterator, SIP_NAT) & SIP_NAT_ROUTE) ? " N " : " ", /* NAT=yes? */ 07516 iterator->ha ? " A " : " ", /* permit/deny */ 07517 ntohs(iterator->addr.sin_port), status); 07518 07519 if (!s) {/* Normal CLI list */ 07520 ast_cli(fd, FORMAT, name, 07521 iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), iterator->addr.sin_addr) : "(Unspecified)", 07522 ast_test_flag(iterator, SIP_DYNAMIC) ? " D " : " ", /* Dynamic or not? */ 07523 (ast_test_flag(iterator, SIP_NAT) & SIP_NAT_ROUTE) ? " N " : " ", /* NAT=yes? */ 07524 iterator->ha ? " A " : " ", /* permit/deny */ 07525 07526 ntohs(iterator->addr.sin_port), status); 07527 } else { /* Manager format */ 07528 /* The names here need to be the same as other channels */ 07529 ast_cli(fd, 07530 "Event: PeerEntry\r\n%s" 07531 "Channeltype: SIP\r\n" 07532 "ObjectName: %s\r\n" 07533 "ChanObjectType: peer\r\n" /* "peer" or "user" */ 07534 "IPaddress: %s\r\n" 07535 "IPport: %d\r\n" 07536 "Dynamic: %s\r\n" 07537 "Natsupport: %s\r\n" 07538 "ACL: %s\r\n" 07539 "Status: %s\r\n\r\n", 07540 idtext, 07541 iterator->name, 07542 iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), iterator->addr.sin_addr) : "-none-", 07543 ntohs(iterator->addr.sin_port), 07544 ast_test_flag(iterator, SIP_DYNAMIC) ? "yes" : "no", /* Dynamic or not? */ 07545 (ast_test_flag(iterator, SIP_NAT) & SIP_NAT_ROUTE) ? "yes" : "no", /* NAT=yes? */ 07546 iterator->ha ? "yes" : "no", /* permit/deny */ 07547 status); 07548 } 07549 07550 ASTOBJ_UNLOCK(iterator); 07551 07552 total_peers++; 07553 } while(0) ); 07554 07555 if (!s) { 07556 ast_cli(fd,"%d sip peers [%d online , %d offline]\n",total_peers,peers_online,peers_offline); 07557 } 07558 07559 if (havepattern) 07560 regfree(®exbuf); 07561 07562 if (total) 07563 *total = total_peers; 07564 07565 07566 return RESULT_SUCCESS; 07567 #undef FORMAT 07568 #undef FORMAT2 07569 }
|
|
add_blank_header: Add blank header to SIP message
Definition at line 3708 of file chan_sip.c. References ast_log(), sip_request::data, sip_request::header, sip_request::headers, sip_request::len, sip_request::lines, and LOG_WARNING. 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(). 03709 { 03710 if (req->headers == SIP_MAX_HEADERS) { 03711 ast_log(LOG_WARNING, "Out of SIP header space\n"); 03712 return -1; 03713 } 03714 if (req->lines) { 03715 ast_log(LOG_WARNING, "Can't add more headers when lines have been added\n"); 03716 return -1; 03717 } 03718 if (req->len >= sizeof(req->data) - 4) { 03719 ast_log(LOG_WARNING, "Out of space, can't add anymore\n"); 03720 return -1; 03721 } 03722 req->header[req->headers] = req->data + req->len; 03723 snprintf(req->header[req->headers], sizeof(req->data) - req->len, "\r\n"); 03724 req->len += strlen(req->header[req->headers]); 03725 req->headers++; 03726 return 0; 03727 }
|
|
Definition at line 4260 of file chan_sip.c. References ast_build_string(), ast_getformatname(), ast_rtp_lookup_code(), ast_rtp_lookup_mime_subtype(), ast_verbose(), and sip_pvt::rtp. Referenced by add_sdp(). 04263 { 04264 int rtp_code; 04265 04266 if (debug) 04267 ast_verbose("Adding codec 0x%x (%s) to SDP\n", codec, ast_getformatname(codec)); 04268 if ((rtp_code = ast_rtp_lookup_code(p->rtp, 1, codec)) == -1) 04269 return; 04270 04271 ast_build_string(m_buf, m_size, " %d", rtp_code); 04272 ast_build_string(a_buf, a_size, "a=rtpmap:%d %s/%d\r\n", rtp_code, 04273 ast_rtp_lookup_mime_subtype(1, codec), 04274 sample_rate); 04275 if (codec == AST_FORMAT_G729A) 04276 /* Indicate that we don't support VAD (G.729 annex B) */ 04277 ast_build_string(a_buf, a_size, "a=fmtp:%d annexb=no\r\n", rtp_code); 04278 }
|
|
add_digit: add DTMF INFO tone to sip message ---
Definition at line 4229 of file chan_sip.c. References add_header(), add_header_contentLength(), and add_line(). Referenced by transmit_info_with_digit(). 04230 { 04231 char tmp[256]; 04232 04233 snprintf(tmp, sizeof(tmp), "Signal=%c\r\nDuration=250\r\n", digit); 04234 add_header(req, "Content-Type", "application/dtmf-relay"); 04235 add_header_contentLength(req, strlen(tmp)); 04236 add_line(req, tmp); 04237 return 0; 04238 }
|
|
|
add_header_contentLen: Add 'Content-Length' header to SIP message
Definition at line 3699 of file chan_sip.c. References add_header(). Referenced by __transmit_response(), add_digit(), add_sdp(), add_text(), add_vidupdate(), transmit_invite(), transmit_notify_with_mwi(), transmit_notify_with_sipfrag(), transmit_register(), transmit_request(), transmit_request_with_auth(), transmit_response_with_allow(), transmit_response_with_auth(), transmit_response_with_date(), and transmit_state_notify(). 03700 { 03701 char clen[10]; 03702 03703 snprintf(clen, sizeof(clen), "%d", len); 03704 return add_header(req, "Content-Length", clen); 03705 }
|
|
add_line: Add content (not header) to SIP message
Definition at line 3730 of file chan_sip.c. References ast_log(), sip_request::data, sip_request::len, sip_request::line, sip_request::lines, and LOG_WARNING. Referenced by add_digit(), add_sdp(), add_text(), add_vidupdate(), transmit_notify_with_mwi(), transmit_notify_with_sipfrag(), and transmit_state_notify(). 03731 { 03732 if (req->lines == SIP_MAX_LINES) { 03733 ast_log(LOG_WARNING, "Out of SIP line space\n"); 03734 return -1; 03735 } 03736 if (!req->lines) { 03737 /* Add extra empty return */ 03738 snprintf(req->data + req->len, sizeof(req->data) - req->len, "\r\n"); 03739 req->len += strlen(req->data + req->len); 03740 } 03741 if (req->len >= sizeof(req->data) - 4) { 03742 ast_log(LOG_WARNING, "Out of space, can't add anymore\n"); 03743 return -1; 03744 } 03745 req->line[req->lines] = req->data + req->len; 03746 snprintf(req->line[req->lines], sizeof(req->data) - req->len, "%s", line); 03747 req->len += strlen(req->line[req->lines]); 03748 req->lines++; 03749 return 0; 03750 }
|
|
Definition at line 4280 of file chan_sip.c. References ast_build_string(), ast_rtp_lookup_code(), ast_rtp_lookup_mime_subtype(), ast_verbose(), and sip_pvt::rtp. Referenced by add_sdp(). 04283 { 04284 int rtp_code; 04285 04286 if (debug) 04287 ast_verbose("Adding non-codec 0x%x (%s) to SDP\n", format, ast_rtp_lookup_mime_subtype(0, format)); 04288 if ((rtp_code = ast_rtp_lookup_code(p->rtp, 0, format)) == -1) 04289 return; 04290 04291 ast_build_string(m_buf, m_size, " %d", rtp_code); 04292 ast_build_string(a_buf, a_size, "a=rtpmap:%d %s/%d\r\n", rtp_code, 04293 ast_rtp_lookup_mime_subtype(0, format), 04294 sample_rate); 04295 if (format == AST_RTP_DTMF) 04296 /* Indicate we support DTMF and FLASH... */ 04297 ast_build_string(a_buf, a_size, "a=fmtp:%d 0-16\r\n", rtp_code); 04298 }
|
|
add_realm_authentication: Add realm authentication in list ---
Definition at line 11762 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, sip_auth::secret, strsep(), and sip_auth::username. Referenced by build_peer(), and reload_config(). 11763 { 11764 char authcopy[256]; 11765 char *username=NULL, *realm=NULL, *secret=NULL, *md5secret=NULL; 11766 char *stringp; 11767 struct sip_auth *auth; 11768 struct sip_auth *b = NULL, *a = authlist; 11769 11770 if (ast_strlen_zero(configuration)) 11771 return authlist; 11772 11773 ast_log(LOG_DEBUG, "Auth config :: %s\n", configuration); 11774 11775 ast_copy_string(authcopy, configuration, sizeof(authcopy)); 11776 stringp = authcopy; 11777 11778 username = stringp; 11779 realm = strrchr(stringp, '@'); 11780 if (realm) { 11781 *realm = '\0'; 11782 realm++; 11783 } 11784 if (ast_strlen_zero(username) || ast_strlen_zero(realm)) { 11785 ast_log(LOG_WARNING, "Format for authentication entry is user[:secret]@realm at line %d\n", lineno); 11786 return authlist; 11787 } 11788 stringp = username; 11789 username = strsep(&stringp, ":"); 11790 if (username) { 11791 secret = strsep(&stringp, ":"); 11792 if (!secret) { 11793 stringp = username; 11794 md5secret = strsep(&stringp,"#"); 11795 } 11796 } 11797 auth = malloc(sizeof(struct sip_auth)); 11798 if (auth) { 11799 memset(auth, 0, sizeof(struct sip_auth)); 11800 ast_copy_string(auth->realm, realm, sizeof(auth->realm)); 11801 ast_copy_string(auth->username, username, sizeof(auth->username)); 11802 if (secret) 11803 ast_copy_string(auth->secret, secret, sizeof(auth->secret)); 11804 if (md5secret) 11805 ast_copy_string(auth->md5secret, md5secret, sizeof(auth->md5secret)); 11806 } else { 11807 ast_log(LOG_ERROR, "Allocation of auth structure failed, Out of memory\n"); 11808 return authlist; 11809 } 11810 11811 /* Add authentication to authl */ 11812 if (!authlist) { /* No existing list */ 11813 return auth; 11814 } 11815 while(a) { 11816 b = a; 11817 a = a->next; 11818 } 11819 b->next = auth; /* Add structure add end of list */ 11820 11821 if (option_verbose > 2) 11822 ast_verbose("Added authentication for realm %s\n", realm); 11823 11824 return authlist; 11825 11826 }
|
|
add_route: Add route header into request per learned route ---
Definition at line 3848 of file chan_sip.c. References add_header(), sip_route::hop, and sip_route::next. Referenced by reqprep(). 03849 { 03850 char r[256], *p; 03851 int n, rem = sizeof(r); 03852 03853 if (!route) return; 03854 03855 p = r; 03856 while (route) { 03857 n = strlen(route->hop); 03858 if ((n+3)>rem) break; 03859 if (p != r) { 03860 *p++ = ','; 03861 --rem; 03862 } 03863 *p++ = '<'; 03864 ast_copy_string(p, route->hop, rem); p += n; 03865 *p++ = '>'; 03866 rem -= (n+2); 03867 route = route->next; 03868 } 03869 *p = '\0'; 03870 add_header(req, "Route", r); 03871 }
|
|
add_sdp: Add Session Description Protocol message ---
Definition at line 4301 of file chan_sip.c. References add_codec_to_sdp(), add_header(), add_header_contentLength(), add_line(), add_noncodec_to_sdp(), ast_build_string(), ast_codec_pref_index(), AST_FORMAT_MAX_VIDEO, ast_inet_ntoa(), ast_log(), ast_rtp_get_us(), ast_test_flag, ast_verbose(), sip_pvt::jointcapability, sip_pvt::lastrtprx, sip_pvt::lastrtptx, LOG_WARNING, sip_pvt::noncodeccapability, 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(), SIP_NOVIDEO, videosupport, sip_pvt::vredirip, and sip_pvt::vrtp. Referenced by transmit_connect_with_sdp(), transmit_invite(), transmit_modify_with_sdp(), transmit_reinvite_with_sdp(), and transmit_response_with_sdp(). 04302 { 04303 int len = 0; 04304 int pref_codec; 04305 int alreadysent = 0; 04306 struct sockaddr_in sin; 04307 struct sockaddr_in vsin; 04308 char v[256]; 04309 char s[256]; 04310 char o[256]; 04311 char c[256]; 04312 char t[256]; 04313 char m_audio[256]; 04314 char m_video[256]; 04315 char a_audio[1024]; 04316 char a_video[1024]; 04317 char *m_audio_next = m_audio; 04318 char *m_video_next = m_video; 04319 size_t m_audio_left = sizeof(m_audio); 04320 size_t m_video_left = sizeof(m_video); 04321 char *a_audio_next = a_audio; 04322 char *a_video_next = a_video; 04323 size_t a_audio_left = sizeof(a_audio); 04324 size_t a_video_left = sizeof(a_video); 04325 char iabuf[INET_ADDRSTRLEN]; 04326 int x; 04327 int capability; 04328 struct sockaddr_in dest; 04329 struct sockaddr_in vdest = { 0, }; 04330 int debug; 04331 04332 debug = sip_debug_test_pvt(p); 04333 04334 len = 0; 04335 if (!p->rtp) { 04336 ast_log(LOG_WARNING, "No way to add SDP without an RTP structure\n"); 04337 return -1; 04338 } 04339 capability = p->jointcapability; 04340 04341 if (!p->sessionid) { 04342 p->sessionid = getpid(); 04343 p->sessionversion = p->sessionid; 04344 } else 04345 p->sessionversion++; 04346 ast_rtp_get_us(p->rtp, &sin); 04347 if (p->vrtp) 04348 ast_rtp_get_us(p->vrtp, &vsin); 04349 04350 if (p->redirip.sin_addr.s_addr) { 04351 dest.sin_port = p->redirip.sin_port; 04352 dest.sin_addr = p->redirip.sin_addr; 04353 if (p->redircodecs) 04354 capability = p->redircodecs; 04355 } else { 04356 dest.sin_addr = p->ourip; 04357 dest.sin_port = sin.sin_port; 04358 } 04359 04360 /* Determine video destination */ 04361 if (p->vrtp) { 04362 if (p->vredirip.sin_addr.s_addr) { 04363 vdest.sin_port = p->vredirip.sin_port; 04364 vdest.sin_addr = p->vredirip.sin_addr; 04365 } else { 04366 vdest.sin_addr = p->ourip; 04367 vdest.sin_port = vsin.sin_port; 04368 } 04369 } 04370 if (debug){ 04371 ast_verbose("We're at %s port %d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip), ntohs(sin.sin_port)); 04372 if (p->vrtp) 04373 ast_verbose("Video is at %s port %d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip), ntohs(vsin.sin_port)); 04374 } 04375 04376 /* We break with the "recommendation" and send our IP, in order that our 04377 peer doesn't have to ast_gethostbyname() us */ 04378 04379 snprintf(v, sizeof(v), "v=0\r\n"); 04380 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)); 04381 snprintf(s, sizeof(s), "s=session\r\n"); 04382 snprintf(c, sizeof(c), "c=IN IP4 %s\r\n", ast_inet_ntoa(iabuf, sizeof(iabuf), dest.sin_addr)); 04383 snprintf(t, sizeof(t), "t=0 0\r\n"); 04384 04385 ast_build_string(&m_audio_next, &m_audio_left, "m=audio %d RTP/AVP", ntohs(dest.sin_port)); 04386 ast_build_string(&m_video_next, &m_video_left, "m=video %d RTP/AVP", ntohs(vdest.sin_port)); 04387 04388 /* Prefer the codec we were requested to use, first, no matter what */ 04389 if (capability & p->prefcodec) { 04390 if (p->prefcodec <= AST_FORMAT_MAX_AUDIO) 04391 add_codec_to_sdp(p, p->prefcodec, 8000, 04392 &m_audio_next, &m_audio_left, 04393 &a_audio_next, &a_audio_left, 04394 debug); 04395 else 04396 add_codec_to_sdp(p, p->prefcodec, 90000, 04397 &m_video_next, &m_video_left, 04398 &a_video_next, &a_video_left, 04399 debug); 04400 alreadysent |= p->prefcodec; 04401 } 04402 04403 /* Start by sending our preferred codecs */ 04404 for (x = 0; x < 32; x++) { 04405 if (!(pref_codec = ast_codec_pref_index(&p->prefs, x))) 04406 break; 04407 04408 if (!(capability & pref_codec)) 04409 continue; 04410 04411 if (alreadysent & pref_codec) 04412 continue; 04413 04414 if (pref_codec <= AST_FORMAT_MAX_AUDIO) 04415 add_codec_to_sdp(p, pref_codec, 8000, 04416 &m_audio_next, &m_audio_left, 04417 &a_audio_next, &a_audio_left, 04418 debug); 04419 else 04420 add_codec_to_sdp(p, pref_codec, 90000, 04421 &m_video_next, &m_video_left, 04422 &a_video_next, &a_video_left, 04423 debug); 04424 alreadysent |= pref_codec; 04425 } 04426 04427 /* Now send any other common codecs, and non-codec formats: */ 04428 for (x = 1; x <= ((videosupport && p->vrtp) ? AST_FORMAT_MAX_VIDEO : AST_FORMAT_MAX_AUDIO); x <<= 1) { 04429 if (!(capability & x)) 04430 continue; 04431 04432 if (alreadysent & x) 04433 continue; 04434 04435 if (x <= AST_FORMAT_MAX_AUDIO) 04436 add_codec_to_sdp(p, x, 8000, 04437 &m_audio_next, &m_audio_left, 04438 &a_audio_next, &a_audio_left, 04439 debug); 04440 else 04441 add_codec_to_sdp(p, x, 90000, 04442 &m_video_next, &m_video_left, 04443 &a_video_next, &a_video_left, 04444 debug); 04445 } 04446 04447 for (x = 1; x <= AST_RTP_MAX; x <<= 1) { 04448 if (!(p->noncodeccapability & x)) 04449 continue; 04450 04451 add_noncodec_to_sdp(p, x, 8000, 04452 &m_audio_next, &m_audio_left, 04453 &a_audio_next, &a_audio_left, 04454 debug); 04455 } 04456 04457 ast_build_string(&a_audio_next, &a_audio_left, "a=silenceSupp:off - - - -\r\n"); 04458 04459 if ((m_audio_left < 2) || (m_video_left < 2) || (a_audio_left == 0) || (a_video_left == 0)) 04460 ast_log(LOG_WARNING, "SIP SDP may be truncated due to undersized buffer!!\n"); 04461 04462 ast_build_string(&m_audio_next, &m_audio_left, "\r\n"); 04463 ast_build_string(&m_video_next, &m_video_left, "\r\n"); 04464 04465 len = strlen(v) + strlen(s) + strlen(o) + strlen(c) + strlen(t) + strlen(m_audio) + strlen(a_audio); 04466 if ((p->vrtp) && (!ast_test_flag(p, SIP_NOVIDEO)) && (capability & VIDEO_CODEC_MASK)) /* only if video response is appropriate */ 04467 len += strlen(m_video) + strlen(a_video); 04468 04469 add_header(resp, "Content-Type", "application/sdp"); 04470 add_header_contentLength(resp, len); 04471 add_line(resp, v); 04472 add_line(resp, o); 04473 add_line(resp, s); 04474 add_line(resp, c); 04475 add_line(resp, t); 04476 add_line(resp, m_audio); 04477 add_line(resp, a_audio); 04478 if ((p->vrtp) && (!ast_test_flag(p, SIP_NOVIDEO)) && (capability & VIDEO_CODEC_MASK)) { /* only if video response is appropriate */ 04479 add_line(resp, m_video); 04480 add_line(resp, a_video); 04481 } 04482 04483 /* Update lastrtprx when we send our SDP */ 04484 time(&p->lastrtprx); 04485 time(&p->lastrtptx); 04486 04487 return 0; 04488 }
|
|
add_sip_domain: Add SIP domain to list of domains we are responsible for
Definition at line 11695 of file chan_sip.c. References AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), ast_strlen_zero(), calloc, LOG_DEBUG, LOG_ERROR, and LOG_WARNING. Referenced by reload_config(). 11696 { 11697 struct domain *d; 11698 11699 if (ast_strlen_zero(domain)) { 11700 ast_log(LOG_WARNING, "Zero length domain.\n"); 11701 return 1; 11702 } 11703 11704 d = calloc(1, sizeof(*d)); 11705 if (!d) { 11706 ast_log(LOG_ERROR, "Allocation of domain structure failed, Out of memory\n"); 11707 return 0; 11708 } 11709 11710 ast_copy_string(d->domain, domain, sizeof(d->domain)); 11711 11712 if (!ast_strlen_zero(context)) 11713 ast_copy_string(d->context, context, sizeof(d->context)); 11714 11715 d->mode = mode; 11716 11717 AST_LIST_LOCK(&domain_list); 11718 AST_LIST_INSERT_TAIL(&domain_list, d, list); 11719 AST_LIST_UNLOCK(&domain_list); 11720 11721 if (sipdebug) 11722 ast_log(LOG_DEBUG, "Added local SIP domain '%s'\n", domain); 11723 11724 return 1; 11725 }
|
|
add_text: Add text body to SIP message ---
Definition at line 4218 of file chan_sip.c. References add_header(), add_header_contentLength(), add_line(), and text. Referenced by transmit_message_with_text(). 04219 { 04220 /* XXX Convert \n's to \r\n's XXX */ 04221 add_header(req, "Content-Type", "text/plain"); 04222 add_header_contentLength(req, strlen(text)); 04223 add_line(req, text); 04224 return 0; 04225 }
|
|
add_vidupdate: add XML encoded media control with update ---
Definition at line 4242 of file chan_sip.c. References add_header(), add_header_contentLength(), and add_line(). Referenced by transmit_info_with_vidupdate(). 04243 { 04244 const char *xml_is_a_huge_waste_of_space = 04245 "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\r\n" 04246 " <media_control>\r\n" 04247 " <vc_primitive>\r\n" 04248 " <to_encoder>\r\n" 04249 " <picture_fast_update>\r\n" 04250 " </picture_fast_update>\r\n" 04251 " </to_encoder>\r\n" 04252 " </vc_primitive>\r\n" 04253 " </media_control>\r\n"; 04254 add_header(req, "Content-Type", "application/media_control+xml"); 04255 add_header_contentLength(req, strlen(xml_is_a_huge_waste_of_space)); 04256 add_line(req, xml_is_a_huge_waste_of_space); 04257 return 0; 04258 }
|
|
append_date: Append date to SIP message ---
Definition at line 4162 of file chan_sip.c. References add_header(). 04163 { 04164 char tmpdat[256]; 04165 struct tm tm; 04166 time_t t; 04167 04168 time(&t); 04169 gmtime_r(&t, &tm); 04170 strftime(tmpdat, sizeof(tmpdat), "%a, %d %b %Y %T GMT", &tm); 04171 add_header(req, "Date", tmpdat); 04172 }
|
|
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, sip_history::next, and recordhistory. 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 10104 of file chan_sip.c. References ast_channel::_state, ast_deactivate_generator(), and ast_channel::generatordata. Referenced by attempt_transfer(). 10105 { 10106 if (chan && chan->_state == AST_STATE_UP) { 10107 if (chan->generatordata) 10108 ast_deactivate_generator(chan); 10109 } 10110 }
|
|
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, 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 10113 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(), ast_channel::cdr, LOG_NOTICE, LOG_WARNING, and sip_pvt::owner. 10114 { 10115 int res = 0; 10116 struct ast_channel 10117 *chana = NULL, 10118 *chanb = NULL, 10119 *bridgea = NULL, 10120 *bridgeb = NULL, 10121 *peera = NULL, 10122 *peerb = NULL, 10123 *peerc = NULL, 10124 *peerd = NULL; 10125 10126 if (!p1->owner || !p2->owner) { 10127 ast_log(LOG_WARNING, "Transfer attempted without dual ownership?\n"); 10128 return -1; 10129 } 10130 chana = p1->owner; 10131 chanb = p2->owner; 10132 bridgea = ast_bridged_channel(chana); 10133 bridgeb = ast_bridged_channel(chanb); 10134 10135 if (bridgea) { 10136 peera = chana; 10137 peerb = chanb; 10138 peerc = bridgea; 10139 peerd = bridgeb; 10140 } else if (bridgeb) { 10141 peera = chanb; 10142 peerb = chana; 10143 peerc = bridgeb; 10144 peerd = bridgea; 10145 } 10146 10147 if (peera && peerb && peerc && (peerb != peerc)) { 10148 ast_quiet_chan(peera); 10149 ast_quiet_chan(peerb); 10150 ast_quiet_chan(peerc); 10151 ast_quiet_chan(peerd); 10152 10153 if (peera->cdr && peerb->cdr) { 10154 peerb->cdr = ast_cdr_append(peerb->cdr, peera->cdr); 10155 } else if (peera->cdr) { 10156 peerb->cdr = peera->cdr; 10157 } 10158 peera->cdr = NULL; 10159 10160 if (peerb->cdr && peerc->cdr) { 10161 peerb->cdr = ast_cdr_append(peerb->cdr, peerc->cdr); 10162 } else if (peerc->cdr) { 10163 peerb->cdr = peerc->cdr; 10164 } 10165 peerc->cdr = NULL; 10166 10167 if (ast_channel_masquerade(peerb, peerc)) { 10168 ast_log(LOG_WARNING, "Failed to masquerade %s into %s\n", peerb->name, peerc->name); 10169 res = -1; 10170 } 10171 return res; 10172 } else { 10173 ast_log(LOG_NOTICE, "Transfer attempted with no appropriate bridged calls to transfer\n"); 10174 if (chana) 10175 ast_softhangup_nolock(chana, AST_SOFTHANGUP_DEV); 10176 if (chanb) 10177 ast_softhangup_nolock(chanb, AST_SOFTHANGUP_DEV); 10178 return -1; 10179 } 10180 return 0; 10181 }
|
|
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. Referenced by sip_call(). 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 2997 of file chan_sip.c. References ast_inet_ntoa(), ast_strlen_zero(), thread_safe_rand(), and val. Referenced by sip_alloc(), sip_notify(), sip_poke_peer(), sip_request_call(), sip_send_mwi_to_peer(), and transmit_register(). 02998 { 02999 int res; 03000 int val; 03001 int x; 03002 char iabuf[INET_ADDRSTRLEN]; 03003 for (x=0; x<4; x++) { 03004 val = thread_safe_rand(); 03005 res = snprintf(callid, len, "%08x", val); 03006 len -= res; 03007 callid += res; 03008 } 03009 if (!ast_strlen_zero(fromdomain)) 03010 snprintf(callid, len, "@%s", fromdomain); 03011 else 03012 /* It's not important that we really use our right IP here... */ 03013 snprintf(callid, len, "@%s", ast_inet_ntoa(iabuf, sizeof(iabuf), ourip)); 03014 }
|
|
build_contact: Build contact header - the contact header we send out ---
Definition at line 4617 of file chan_sip.c. References ast_inet_ntoa(), 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(), initreqprep(), register_verify(), and transmit_register(). 04618 { 04619 char iabuf[INET_ADDRSTRLEN]; 04620 04621 /* Construct Contact: header */ 04622 if (ourport != 5060) /* Needs to be 5060, according to the RFC */ 04623 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); 04624 else 04625 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)); 04626 }
|
|
build_peer: Build peer from config file ---
Definition at line 11992 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_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_flags, global_flags_page2, global_musicclass, 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, name, ast_variable::next, peerl, sip_peer::pickupgroup, sip_peer::pokeexpire, sip_peer::prefs, reg_source_db(), sip_peer::regexten, rpeerobjs, sip_peer::rtpholdtimeout, sip_peer::rtpkeepalive, sip_peer::rtptimeout, sched, 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. 11993 { 11994 struct sip_peer *peer = NULL; 11995 struct ast_ha *oldha = NULL; 11996 int obproxyfound=0; 11997 int found=0; 11998 int format=0; /* Ama flags */ 11999 time_t regseconds; 12000 char *varname = NULL, *varval = NULL; 12001 struct ast_variable *tmpvar = NULL; 12002 struct ast_flags peerflags = {(0)}; 12003 struct ast_flags mask = {(0)}; 12004 12005 12006 if (!realtime) 12007 /* Note we do NOT use find_peer here, to avoid realtime recursion */ 12008 /* We also use a case-sensitive comparison (unlike find_peer) so 12009 that case changes made to the peer name will be properly handled 12010 during reload 12011 */ 12012 peer = ASTOBJ_CONTAINER_FIND_UNLINK_FULL(&peerl, name, name, 0, 0, strcmp); 12013 12014 if (peer) { 12015 /* Already in the list, remove it and it will be added back (or FREE'd) */ 12016 found++; 12017 } else { 12018 peer = malloc(sizeof(*peer)); 12019 if (peer) { 12020 memset(peer, 0, sizeof(*peer)); 12021 if (realtime) 12022 rpeerobjs++; 12023 else 12024 speerobjs++; 12025 ASTOBJ_INIT(peer); 12026 peer->expire = -1; 12027 peer->pokeexpire = -1; 12028 } else { 12029 ast_log(LOG_WARNING, "Can't allocate SIP peer memory\n"); 12030 } 12031 } 12032 /* Note that our peer HAS had its reference count incrased */ 12033 if (!peer) 12034 return NULL; 12035 12036 peer->lastmsgssent = -1; 12037 if (!found) { 12038 if (name) 12039 ast_copy_string(peer->name, name, sizeof(peer->name)); 12040 peer->addr.sin_port = htons(DEFAULT_SIP_PORT); 12041 peer->addr.sin_family = AF_INET; 12042 peer->defaddr.sin_family = AF_INET; 12043 } 12044 /* If we have channel variables, remove them (reload) */ 12045 if (peer->chanvars) { 12046 ast_variables_destroy(peer->chanvars); 12047 peer->chanvars = NULL; 12048 } 12049 strcpy(peer->context, default_context); 12050 strcpy(peer->subscribecontext, default_subscribecontext); 12051 strcpy(peer->vmexten, global_vmexten); 12052 strcpy(peer->language, default_language); 12053 strcpy(peer->musicclass, global_musicclass); 12054 ast_copy_flags(peer, &global_flags, SIP_USEREQPHONE); 12055 peer->secret[0] = '\0'; 12056 peer->md5secret[0] = '\0'; 12057 peer->cid_num[0] = '\0'; 12058 peer->cid_name[0] = '\0'; 12059 peer->fromdomain[0] = '\0'; 12060 peer->fromuser[0] = '\0'; 12061 peer->regexten[0] = '\0'; 12062 peer->mailbox[0] = '\0'; 12063 peer->callgroup = 0; 12064 peer->pickupgroup = 0; 12065 peer->rtpkeepalive = global_rtpkeepalive; 12066 peer->maxms = default_qualify; 12067 peer->prefs = prefs; 12068 oldha = peer->ha; 12069 peer->ha = NULL; 12070 peer->addr.sin_family = AF_INET; 12071 ast_copy_flags(peer, &global_flags, SIP_FLAGS_TO_COPY); 12072 peer->capability = global_capability; 12073 peer->rtptimeout = global_rtptimeout; 12074 peer->rtpholdtimeout = global_rtpholdtimeout; 12075 while(v) { 12076 if (handle_common_options(&peerflags, &mask, v)) { 12077 v = v->next; 12078 continue; 12079 } 12080 12081 if (realtime && !strcasecmp(v->name, "regseconds")) { 12082 if (sscanf(v->value, "%ld", (time_t *)®seconds) != 1) 12083 regseconds = 0; 12084 } else if (realtime && !strcasecmp(v->name, "ipaddr") && !ast_strlen_zero(v->value) ) { 12085 inet_aton(v->value, &(peer->addr.sin_addr)); 12086 } else if (realtime && !strcasecmp(v->name, "name")) 12087 ast_copy_string(peer->name, v->value, sizeof(peer->name)); 12088 else if (realtime && !strcasecmp(v->name, "fullcontact")) { 12089 ast_copy_string(peer->fullcontact, v->value, sizeof(peer->fullcontact)); 12090 ast_set_flag((&peer->flags_page2), SIP_PAGE2_RT_FROMCONTACT); 12091 } else if (!strcasecmp(v->name, "secret")) 12092 ast_copy_string(peer->secret, v->value, sizeof(peer->secret)); 12093 else if (!strcasecmp(v->name, "md5secret")) 12094 ast_copy_string(peer->md5secret, v->value, sizeof(peer->md5secret)); 12095 else if (!strcasecmp(v->name, "auth")) 12096 peer->auth = add_realm_authentication(peer->auth, v->value, v->lineno); 12097 else if (!strcasecmp(v->name, "callerid")) { 12098 ast_callerid_split(v->value, peer->cid_name, sizeof(peer->cid_name), peer->cid_num, sizeof(peer->cid_num)); 12099 } else if (!strcasecmp(v->name, "context")) { 12100 ast_copy_string(peer->context, v->value, sizeof(peer->context)); 12101 } else if (!strcasecmp(v->name, "subscribecontext")) { 12102 ast_copy_string(peer->subscribecontext, v->value, sizeof(peer->subscribecontext)); 12103 } else if (!strcasecmp(v->name, "fromdomain")) 12104 ast_copy_string(peer->fromdomain, v->value, sizeof(peer->fromdomain)); 12105 else if (!strcasecmp(v->name, "usereqphone")) 12106 ast_set2_flag(peer, ast_true(v->value), SIP_USEREQPHONE); 12107 else if (!strcasecmp(v->name, "fromuser")) 12108 ast_copy_string(peer->fromuser, v->value, sizeof(peer->fromuser)); 12109 else if (!strcasecmp(v->name, "host") || !strcasecmp(v->name, "outboundproxy")) { 12110 if (!strcasecmp(v->value, "dynamic")) { 12111 if (!strcasecmp(v->name, "outboundproxy") || obproxyfound) { 12112 ast_log(LOG_WARNING, "You can't have a dynamic outbound proxy, you big silly head at line %d.\n", v->lineno); 12113 } else { 12114 /* They'll register with us */ 12115 ast_set_flag(peer, SIP_DYNAMIC); 12116 if (!found) { 12117 /* Initialize stuff iff we're not found, otherwise 12118 we keep going with what we had */ 12119 memset(&peer->addr.sin_addr, 0, 4); 12120 if (peer->addr.sin_port) { 12121 /* If we've already got a port, make it the default rather than absolute */ 12122 peer->defaddr.sin_port = peer->addr.sin_port; 12123 peer->addr.sin_port = 0; 12124 } 12125 } 12126 } 12127 } else { 12128 /* Non-dynamic. Make sure we become that way if we're not */ 12129 if (peer->expire > -1) 12130 ast_sched_del(sched, peer->expire); 12131 peer->expire = -1; 12132 ast_clear_flag(peer, SIP_DYNAMIC); 12133 if (!obproxyfound || !strcasecmp(v->name, "outboundproxy")) { 12134 if (ast_get_ip_or_srv(&peer->addr, v->value, "_sip._udp")) { 12135 ASTOBJ_UNREF(peer, sip_destroy_peer); 12136 return NULL; 12137 } 12138 } 12139 if (!strcasecmp(v->name, "outboundproxy")) 12140 obproxyfound=1; 12141 else { 12142 ast_copy_string(peer->tohost, v->value, sizeof(peer->tohost)); 12143 if (!peer->addr.sin_port) 12144 peer->addr.sin_port = htons(DEFAULT_SIP_PORT); 12145 } 12146 } 12147 } else if (!strcasecmp(v->name, "defaultip")) { 12148 if (ast_get_ip(&peer->defaddr, v->value)) { 12149 ASTOBJ_UNREF(peer, sip_destroy_peer); 12150 return NULL; 12151 } 12152 } else if (!strcasecmp(v->name, "permit") || !strcasecmp(v->name, "deny")) { 12153 peer->ha = ast_append_ha(v->name, v->value, peer->ha); 12154 } else if (!strcasecmp(v->name, "port")) { 12155 if (!realtime && ast_test_flag(peer, SIP_DYNAMIC)) 12156 peer->defaddr.sin_port = htons(atoi(v->value)); 12157 else 12158 peer->addr.sin_port = htons(atoi(v->value)); 12159 } else if (!strcasecmp(v->name, "callingpres")) { 12160 peer->callingpres = ast_parse_caller_presentation(v->value); 12161 if (peer->callingpres == -1) 12162 peer->callingpres = atoi(v->value); 12163 } else if (!strcasecmp(v->name, "username")) { 12164 ast_copy_string(peer->username, v->value, sizeof(peer->username)); 12165 } else if (!strcasecmp(v->name, "language")) { 12166 ast_copy_string(peer->language, v->value, sizeof(peer->language)); 12167 } else if (!strcasecmp(v->name, "regexten")) { 12168 ast_copy_string(peer->regexten, v->value, sizeof(peer->regexten)); 12169 } else if (!strcasecmp(v->name, "call-limit") || !strcasecmp(v->name, "incominglimit")) { 12170 peer->call_limit = atoi(v->value); 12171 if (peer->call_limit < 0) 12172 peer->call_limit = 0; 12173 } else if (!strcasecmp(v->name, "amaflags")) { 12174 format = ast_cdr_amaflags2int(v->value); 12175 if (format < 0) { 12176 ast_log(LOG_WARNING, "Invalid AMA Flags for peer: %s at line %d\n", v->value, v->lineno); 12177 } else { 12178 peer->amaflags = format; 12179 } 12180 } else if (!strcasecmp(v->name, "accountcode")) { 12181 ast_copy_string(peer->accountcode, v->value, sizeof(peer->accountcode)); 12182 } else if (!strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) { 12183 ast_copy_string(peer->musicclass, v->value, sizeof(peer->musicclass)); 12184 } else if (!strcasecmp(v->name, "mailbox")) { 12185 ast_copy_string(peer->mailbox, v->value, sizeof(peer->mailbox)); 12186 } else if (!strcasecmp(v->name, "vmexten")) { 12187 ast_copy_string(peer->vmexten, v->value, sizeof(peer->vmexten)); 12188 } else if (!strcasecmp(v->name, "callgroup")) { 12189 peer->callgroup = ast_get_group(v->value); 12190 } else if (!strcasecmp(v->name, "pickupgroup")) { 12191 peer->pickupgroup = ast_get_group(v->value); 12192 } else if (!strcasecmp(v->name, "allow")) { 12193 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1); 12194 } else if (!strcasecmp(v->name, "disallow")) { 12195 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0); 12196 } else if (!strcasecmp(v->name, "rtptimeout")) { 12197 if ((sscanf(v->value, "%d", &peer->rtptimeout) != 1) || (peer->rtptimeout < 0)) { 12198 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 12199 peer->rtptimeout = global_rtptimeout; 12200 } 12201 } else if (!strcasecmp(v->name, "rtpholdtimeout")) { 12202 if ((sscanf(v->value, "%d", &peer->rtpholdtimeout) != 1) || (peer->rtpholdtimeout < 0)) { 12203 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 12204 peer->rtpholdtimeout = global_rtpholdtimeout; 12205 } 12206 } else if (!strcasecmp(v->name, "rtpkeepalive")) { 12207 if ((sscanf(v->value, "%d", &peer->rtpkeepalive) != 1) || (peer->rtpkeepalive < 0)) { 12208 ast_log(LOG_WARNING, "'%s' is not a valid RTP keepalive time at line %d. Using default.\n", v->value, v->lineno); 12209 peer->rtpkeepalive = global_rtpkeepalive; 12210 } 12211 } else if (!strcasecmp(v->name, "setvar")) { 12212 /* Set peer channel variable */ 12213 varname = ast_strdupa(v->value); 12214 if (varname && (varval = strchr(varname,'='))) { 12215 *varval = '\0'; 12216 varval++; 12217 if ((tmpvar = ast_variable_new(varname, varval))) { 12218 tmpvar->next = peer->chanvars; 12219 peer->chanvars = tmpvar; 12220 } 12221 } 12222 } else if (!strcasecmp(v->name, "qualify")) { 12223 if (!strcasecmp(v->value, "no")) { 12224 peer->maxms = 0; 12225 } else if (!strcasecmp(v->value, "yes")) { 12226 peer->maxms = DEFAULT_MAXMS; 12227 } else if (sscanf(v->value, "%d", &peer->maxms) != 1) { 12228 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); 12229 peer->maxms = 0; 12230 } 12231 } 12232 /* else if (strcasecmp(v->name,"type")) 12233 * ast_log(LOG_WARNING, "Ignoring %s\n", v->name); 12234 */ 12235 v=v->next; 12236 } 12237 if (!ast_test_flag((&global_flags_page2), SIP_PAGE2_IGNOREREGEXPIRE) && ast_test_flag(peer, SIP_DYNAMIC) && realtime) { 12238 time_t nowtime; 12239 12240 time(&nowtime); 12241 if ((nowtime - regseconds) > 0) { 12242 destroy_association(peer); 12243 memset(&peer->addr, 0, sizeof(peer->addr)); 12244 if (option_debug) 12245 ast_log(LOG_DEBUG, "Bah, we're expired (%d/%d/%d)!\n", (int)(nowtime - regseconds), (int)regseconds, (int)nowtime); 12246 } 12247 } 12248 ast_copy_flags(peer, &peerflags, mask.flags); 12249 if (!found && ast_test_flag(peer, SIP_DYNAMIC) && !ast_test_flag(peer, SIP_REALTIME)) 12250 reg_source_db(peer); 12251 ASTOBJ_UNMARK(peer); 12252 ast_free_ha(oldha); 12253 return peer; 12254 }
|
|
build_reply_digest: Build reply digest ---
Definition at line 8976 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_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, sip_methods, text, thread_safe_rand(), sip_pvt::uri, sip_auth::username, and sip_pvt::username. Referenced by reply_digest(), transmit_register(), and transmit_request_with_auth(). 08977 { 08978 char a1[256]; 08979 char a2[256]; 08980 char a1_hash[256]; 08981 char a2_hash[256]; 08982 char resp[256]; 08983 char resp_hash[256]; 08984 char uri[256]; 08985 char cnonce[80]; 08986 char iabuf[INET_ADDRSTRLEN]; 08987 char *username; 08988 char *secret; 08989 char *md5secret; 08990 struct sip_auth *auth = (struct sip_auth *) NULL; /* Realm authentication */ 08991 08992 if (!ast_strlen_zero(p->domain)) 08993 ast_copy_string(uri, p->domain, sizeof(uri)); 08994 else if (!ast_strlen_zero(p->uri)) 08995 ast_copy_string(uri, p->uri, sizeof(uri)); 08996 else 08997 snprintf(uri, sizeof(uri), "sip:%s@%s",p->username, ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr)); 08998 08999 snprintf(cnonce, sizeof(cnonce), "%08x", thread_safe_rand()); 09000 09001 /* Check if we have separate auth credentials */ 09002 if ((auth = find_realm_authentication(authl, p->realm))) { 09003 username = auth->username; 09004 secret = auth->secret; 09005 md5secret = auth->md5secret; 09006 if (sipdebug) 09007 ast_log(LOG_DEBUG,"Using realm %s authentication for call %s\n", p->realm, p->callid); 09008 } else { 09009 /* No authentication, use peer or register= config */ 09010 username = p->authname; 09011 secret = p->peersecret; 09012 md5secret = p->peermd5secret; 09013 } 09014 if (ast_strlen_zero(username)) /* We have no authentication */ 09015 return -1; 09016 09017 09018 /* Calculate SIP digest response */ 09019 snprintf(a1,sizeof(a1),"%s:%s:%s", username, p->realm, secret); 09020 snprintf(a2,sizeof(a2),"%s:%s", sip_methods[method].text, uri); 09021 if (!ast_strlen_zero(md5secret)) 09022 ast_copy_string(a1_hash, md5secret, sizeof(a1_hash)); 09023 else 09024 ast_md5_hash(a1_hash,a1); 09025 ast_md5_hash(a2_hash,a2); 09026 09027 p->noncecount++; 09028 if (!ast_strlen_zero(p->qop)) 09029 snprintf(resp,sizeof(resp),"%s:%s:%08x:%s:%s:%s", a1_hash, p->nonce, p->noncecount, cnonce, "auth", a2_hash); 09030 else 09031 snprintf(resp,sizeof(resp),"%s:%s:%s", a1_hash, p->nonce, a2_hash); 09032 ast_md5_hash(resp_hash, resp); 09033 /* XXX We hard code our qop to "auth" for now. XXX */ 09034 if (!ast_strlen_zero(p->qop)) 09035 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); 09036 else 09037 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); 09038 09039 return 0; 09040 }
|
|
build_route: Build route list from Record-Route header ---
Definition at line 5962 of file chan_sip.c. References __get_header(), ast_log(), ast_strlen_zero(), free_old_route(), get_header(), sip_route::hop, list_route(), LOG_DEBUG, malloc, sip_route::next, sip_pvt::route, sip_pvt::route_persistant, and sip_debug_test_pvt(). Referenced by handle_request_invite(), and handle_response_invite(). 05963 { 05964 struct sip_route *thishop, *head, *tail; 05965 int start = 0; 05966 int len; 05967 char *rr, *contact, *c; 05968 05969 /* Once a persistant route is set, don't fool with it */ 05970 if (p->route && p->route_persistant) { 05971 ast_log(LOG_DEBUG, "build_route: Retaining previous route: <%s>\n", p->route->hop); 05972 return; 05973 } 05974 05975 if (p->route) { 05976 free_old_route(p->route); 05977 p->route = NULL; 05978 } 05979 05980 p->route_persistant = backwards; 05981 05982 /* We build up head, then assign it to p->route when we're done */ 05983 head = NULL; tail = head; 05984 /* 1st we pass through all the hops in any Record-Route headers */ 05985 for (;;) { 05986 /* Each Record-Route header */ 05987 rr = __get_header(req, "Record-Route", &start); 05988 if (*rr == '\0') break; 05989 for (;;) { 05990 /* Each route entry */ 05991 /* Find < */ 05992 rr = strchr(rr, '<'); 05993 if (!rr) break; /* No more hops */ 05994 ++rr; 05995 len = strcspn(rr, ">") + 1; 05996 /* Make a struct route */ 05997 thishop = malloc(sizeof(*thishop) + len); 05998 if (thishop) { 05999 ast_copy_string(thishop->hop, rr, len); 06000 ast_log(LOG_DEBUG, "build_route: Record-Route hop: <%s>\n", thishop->hop); 06001 /* Link in */ 06002 if (backwards) { 06003 /* Link in at head so they end up in reverse order */ 06004 thishop->next = head; 06005 head = thishop; 06006 /* If this was the first then it'll be the tail */ 06007 if (!tail) tail = thishop; 06008 } else { 06009 thishop->next = NULL; 06010 /* Link in at the end */ 06011 if (tail) 06012 tail->next = thishop; 06013 else 06014 head = thishop; 06015 tail = thishop; 06016 } 06017 } 06018 rr += len; 06019 } 06020 } 06021 06022 /* Only append the contact if we are dealing with a strict router */ 06023 if (!head || (!ast_strlen_zero(head->hop) && strstr(head->hop,";lr") == NULL) ) { 06024 /* 2nd append the Contact: if there is one */ 06025 /* Can be multiple Contact headers, comma separated values - we just take the first */ 06026 contact = get_header(req, "Contact"); 06027 if (!ast_strlen_zero(contact)) { 06028 ast_log(LOG_DEBUG, "build_route: Contact hop: %s\n", contact); 06029 /* Look for <: delimited address */ 06030 c = strchr(contact, '<'); 06031 if (c) { 06032 /* Take to > */ 06033 ++c; 06034 len = strcspn(c, ">") + 1; 06035 } else { 06036 /* No <> - just take the lot */ 06037 c = contact; 06038 len = strlen(contact) + 1; 06039 } 06040 thishop = malloc(sizeof(*thishop) + len); 06041 if (thishop) { 06042 ast_copy_string(thishop->hop, c, len); 06043 thishop->next = NULL; 06044 /* Goes at the end */ 06045 if (tail) 06046 tail->next = thishop; 06047 else 06048 head = thishop; 06049 } 06050 } 06051 } 06052 06053 /* Store as new route */ 06054 p->route = head; 06055 06056 /* For debugging dump what we ended up with */ 06057 if (sip_debug_test_pvt(p)) 06058 list_route(p->route); 06059 }
|
|
build_rpid: Build the Remote Party-ID & From using callingpres options ---
Definition at line 4629 of file chan_sip.c. References ast_inet_ntoa(), ast_log(), 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_strlen_zero(), sip_pvt::callingpres, ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, 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. Referenced by initreqprep(). 04630 { 04631 int send_pres_tags = 1; 04632 const char *privacy=NULL; 04633 const char *screen=NULL; 04634 char buf[256]; 04635 const char *clid = default_callerid; 04636 const char *clin = NULL; 04637 char iabuf[INET_ADDRSTRLEN]; 04638 const char *fromdomain; 04639 04640 if (p->rpid || p->rpid_from) 04641 return; 04642 04643 if (p->owner && p->owner->cid.cid_num) 04644 clid = p->owner->cid.cid_num; 04645 if (p->owner && p->owner->cid.cid_name) 04646 clin = p->owner->cid.cid_name; 04647 if (ast_strlen_zero(clin)) 04648 clin = clid; 04649 04650 switch (p->callingpres) { 04651 case AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED: 04652 privacy = "off"; 04653 screen = "no"; 04654 break; 04655 case AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN: 04656 privacy = "off"; 04657 screen = "pass"; 04658 break; 04659 case AST_PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN: 04660 privacy = "off"; 04661 screen = "fail"; 04662 break; 04663 case AST_PRES_ALLOWED_NETWORK_NUMBER: 04664 privacy = "off"; 04665 screen = "yes"; 04666 break; 04667 case AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED: 04668 privacy = "full"; 04669 screen = "no"; 04670 break; 04671 case AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN: 04672 privacy = "full"; 04673 screen = "pass"; 04674 break; 04675 case AST_PRES_PROHIB_USER_NUMBER_FAILED_SCREEN: 04676 privacy = "full"; 04677 screen = "fail"; 04678 break; 04679 case AST_PRES_PROHIB_NETWORK_NUMBER: 04680 privacy = "full"; 04681 screen = "pass"; 04682 break; 04683 case AST_PRES_NUMBER_NOT_AVAILABLE: 04684 send_pres_tags = 0; 04685 break; 04686 default: 04687 ast_log(LOG_WARNING, "Unsupported callingpres (%d)\n", p->callingpres); 04688 if ((p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED) 04689 privacy = "full"; 04690 else 04691 privacy = "off"; 04692 screen = "no"; 04693 break; 04694 } 04695 04696 fromdomain = ast_strlen_zero(p->fromdomain) ? ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip) : p->fromdomain; 04697 04698 snprintf(buf, sizeof(buf), "\"%s\" <sip:%s@%s>", clin, clid, fromdomain); 04699 if (send_pres_tags) 04700 snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), ";privacy=%s;screen=%s", privacy, screen); 04701 p->rpid = strdup(buf); 04702 04703 snprintf(buf, sizeof(buf), "\"%s\" <sip:%s@%s>;tag=%s", clin, 04704 ast_strlen_zero(p->fromuser) ? clid : p->fromuser, 04705 fromdomain, p->tag); 04706 p->rpid_from = strdup(buf); 04707 }
|
|
build_user: Initiate a SIP user structure from sip.conf ---
Definition at line 11859 of file chan_sip.c. References sip_user::accountcode, sip_user::amaflags, 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, sip_user::call_limit, sip_user::callgroup, sip_user::callingpres, sip_user::capability, sip_user::chanvars, sip_user::cid_name, sip_user::cid_num, sip_user::context, default_context, default_language, ast_flags::flags, global_flags, global_musicclass, sip_user::ha, handle_common_options(), sip_user::language, ast_variable::lineno, LOG_WARNING, malloc, sip_user::md5secret, sip_user::musicclass, ast_variable::name, name, ast_variable::next, sip_user::pickupgroup, sip_user::prefs, sip_user::secret, SIP_FLAGS_TO_COPY, sip_user::subscribecontext, suserobjs, and ast_variable::value. Referenced by realtime_user(), reload_config(), and set_config(). 11860 { 11861 struct sip_user *user; 11862 int format; 11863 struct ast_ha *oldha = NULL; 11864 char *varname = NULL, *varval = NULL; 11865 struct ast_variable *tmpvar = NULL; 11866 struct ast_flags userflags = {(0)}; 11867 struct ast_flags mask = {(0)}; 11868 11869 11870 user = (struct sip_user *)malloc(sizeof(struct sip_user)); 11871 if (!user) { 11872 return NULL; 11873 } 11874 memset(user, 0, sizeof(struct sip_user)); 11875 suserobjs++; 11876 ASTOBJ_INIT(user); 11877 ast_copy_string(user->name, name, sizeof(user->name)); 11878 oldha = user->ha; 11879 user->ha = NULL; 11880 ast_copy_flags(user, &global_flags, SIP_FLAGS_TO_COPY); 11881 user->capability = global_capability; 11882 user->prefs = prefs; 11883 /* set default context */ 11884 strcpy(user->context, default_context); 11885 strcpy(user->language, default_language); 11886 strcpy(user->musicclass, global_musicclass); 11887 while(v) { 11888 if (handle_common_options(&userflags, &mask, v)) { 11889 v = v->next; 11890 continue; 11891 } 11892 11893 if (!strcasecmp(v->name, "context")) { 11894 ast_copy_string(user->context, v->value, sizeof(user->context)); 11895 } else if (!strcasecmp(v->name, "subscribecontext")) { 11896 ast_copy_string(user->subscribecontext, v->value, sizeof(user->subscribecontext)); 11897 } else if (!strcasecmp(v->name, "setvar")) { 11898 varname = ast_strdupa(v->value); 11899 if (varname && (varval = strchr(varname,'='))) { 11900 *varval = '\0'; 11901 varval++; 11902 if ((tmpvar = ast_variable_new(varname, varval))) { 11903 tmpvar->next = user->chanvars; 11904 user->chanvars = tmpvar; 11905 } 11906 } 11907 } else if (!strcasecmp(v->name, "permit") || 11908 !strcasecmp(v->name, "deny")) { 11909 user->ha = ast_append_ha(v->name, v->value, user->ha); 11910 } else if (!strcasecmp(v->name, "secret")) { 11911 ast_copy_string(user->secret, v->value, sizeof(user->secret)); 11912 } else if (!strcasecmp(v->name, "md5secret")) { 11913 ast_copy_string(user->md5secret, v->value, sizeof(user->md5secret)); 11914 } else if (!strcasecmp(v->name, "callerid")) { 11915 ast_callerid_split(v->value, user->cid_name, sizeof(user->cid_name), user->cid_num, sizeof(user->cid_num)); 11916 } else if (!strcasecmp(v->name, "callgroup")) { 11917 user->callgroup = ast_get_group(v->value); 11918 } else if (!strcasecmp(v->name, "pickupgroup")) { 11919 user->pickupgroup = ast_get_group(v->value); 11920 } else if (!strcasecmp(v->name, "language")) { 11921 ast_copy_string(user->language, v->value, sizeof(user->language)); 11922 } else if (!strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) { 11923 ast_copy_string(user->musicclass, v->value, sizeof(user->musicclass)); 11924 } else if (!strcasecmp(v->name, "accountcode")) { 11925 ast_copy_string(user->accountcode, v->value, sizeof(user->accountcode)); 11926 } else if (!strcasecmp(v->name, "call-limit") || !strcasecmp(v->name, "incominglimit")) { 11927 user->call_limit = atoi(v->value); 11928 if (user->call_limit < 0) 11929 user->call_limit = 0; 11930 } else if (!strcasecmp(v->name, "amaflags")) { 11931 format = ast_cdr_amaflags2int(v->value); 11932 if (format < 0) { 11933 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno); 11934 } else { 11935 user->amaflags = format; 11936 } 11937 } else if (!strcasecmp(v->name, "allow")) { 11938 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1); 11939 } else if (!strcasecmp(v->name, "disallow")) { 11940 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 0); 11941 } else if (!strcasecmp(v->name, "callingpres")) { 11942 user->callingpres = ast_parse_caller_presentation(v->value); 11943 if (user->callingpres == -1) 11944 user->callingpres = atoi(v->value); 11945 } 11946 /*else if (strcasecmp(v->name,"type")) 11947 * ast_log(LOG_WARNING, "Ignoring %s\n", v->name); 11948 */ 11949 v = v->next; 11950 } 11951 ast_copy_flags(user, &userflags, mask.flags); 11952 ast_free_ha(oldha); 11953 return user; 11954 }
|
|
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, ourport, and SIP_NAT. 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 6305 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, option_debug, sip_cancel_destroy(), sip_scheddestroy(), sip_pvt::stateid, transmit_state_notify(), sip_pvt::username, VERBOSE_PREFIX_1, and VERBOSE_PREFIX_2. Referenced by handle_request_subscribe(). 06306 { 06307 struct sip_pvt *p = data; 06308 06309 switch(state) { 06310 case AST_EXTENSION_DEACTIVATED: /* Retry after a while */ 06311 case AST_EXTENSION_REMOVED: /* Extension is gone */ 06312 if (p->autokillid > -1) 06313 sip_cancel_destroy(p); /* Remove subscription expiry for renewals */ 06314 sip_scheddestroy(p, 15000); /* Delete subscription in 15 secs */ 06315 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); 06316 p->stateid = -1; 06317 p->subscribed = NONE; 06318 append_history(p, "Subscribestatus", state == AST_EXTENSION_REMOVED ? "HintRemoved" : "Deactivated"); 06319 break; 06320 default: /* Tell user */ 06321 p->laststate = state; 06322 break; 06323 } 06324 transmit_state_notify(p, state, 1, 1); 06325 06326 if (option_debug > 1) 06327 ast_verbose(VERBOSE_PREFIX_1 "Extension Changed %s new state %s for Notify User %s\n", exten, ast_extension_state2str(state), p->username); 06328 return 0; 06329 }
|
|
check_auth: Check user authorization from peer definition ---
Definition at line 6080 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(), sipmethod, text, thread_safe_rand(), and transmit_response_with_auth(). Referenced by check_user_full(), and register_verify(). 06081 { 06082 int res = -1; 06083 char *response = "407 Proxy Authentication Required"; 06084 char *reqheader = "Proxy-Authorization"; 06085 char *respheader = "Proxy-Authenticate"; 06086 char *authtoken; 06087 #ifdef OSP_SUPPORT 06088 char *osptoken; 06089 #endif 06090 /* Always OK if no secret */ 06091 if (ast_strlen_zero(secret) && ast_strlen_zero(md5secret) 06092 #ifdef OSP_SUPPORT 06093 && !ast_test_flag(p, SIP_OSPAUTH) 06094 && global_allowguest != 2 06095 #endif 06096 ) 06097 return 0; 06098 if (sipmethod == SIP_REGISTER || sipmethod == SIP_SUBSCRIBE) { 06099 /* On a REGISTER, we have to use 401 and its family of headers instead of 407 and its family 06100 of headers -- GO SIP! Whoo hoo! Two things that do the same thing but are used in 06101 different circumstances! What a surprise. */ 06102 response = "401 Unauthorized"; 06103 reqheader = "Authorization"; 06104 respheader = "WWW-Authenticate"; 06105 } 06106 #ifdef OSP_SUPPORT 06107 else { 06108 ast_log (LOG_DEBUG, "Checking OSP Authentication!\n"); 06109 osptoken = get_header (req, "P-OSP-Auth-Token"); 06110 switch (ast_test_flag (p, SIP_OSPAUTH)) { 06111 case SIP_OSPAUTH_NO: 06112 break; 06113 case SIP_OSPAUTH_GATEWAY: 06114 if (ast_strlen_zero (osptoken)) { 06115 if (ast_strlen_zero (secret) && ast_strlen_zero (md5secret)) { 06116 return (0); 06117 } 06118 } 06119 else { 06120 return (check_osptoken (p, osptoken)); 06121 } 06122 break; 06123 case SIP_OSPAUTH_PROXY: 06124 if (ast_strlen_zero (osptoken)) { 06125 return (0); 06126 } 06127 else { 06128 return (check_osptoken (p, osptoken)); 06129 } 06130 break; 06131 case SIP_OSPAUTH_EXCLUSIVE: 06132 if (ast_strlen_zero (osptoken)) { 06133 return (-1); 06134 } 06135 else { 06136 return (check_osptoken (p, osptoken)); 06137 } 06138 break; 06139 default: 06140 return (-1); 06141 } 06142 } 06143 #endif 06144 authtoken = get_header(req, reqheader); 06145 if (ignore && !ast_strlen_zero(randdata) && ast_strlen_zero(authtoken)) { 06146 /* This is a retransmitted invite/register/etc, don't reconstruct authentication 06147 information */ 06148 if (!ast_strlen_zero(randdata)) { 06149 if (!reliable) { 06150 /* Resend message if this was NOT a reliable delivery. Otherwise the 06151 retransmission should get it */ 06152 transmit_response_with_auth(p, response, req, randdata, reliable, respheader, 0); 06153 /* Schedule auto destroy in 15 seconds */ 06154 sip_scheddestroy(p, 15000); 06155 } 06156 res = 1; 06157 } 06158 } else if (ast_strlen_zero(randdata) || ast_strlen_zero(authtoken)) { 06159 snprintf(randdata, randlen, "%08x", thread_safe_rand()); 06160 transmit_response_with_auth(p, response, req, randdata, reliable, respheader, 0); 06161 /* Schedule auto destroy in 15 seconds */ 06162 sip_scheddestroy(p, 15000); 06163 res = 1; 06164 } else { 06165 /* Whoever came up with the authentication section of SIP can suck my %&#$&* for not putting 06166 an example in the spec of just what it is you're doing a hash on. */ 06167 char a1[256]; 06168 char a2[256]; 06169 char a1_hash[256]; 06170 char a2_hash[256]; 06171 char resp[256]; 06172 char resp_hash[256]=""; 06173 char tmp[256]; 06174 char *c; 06175 char *z; 06176 char *ua_hash =""; 06177 char *resp_uri =""; 06178 char *nonce = ""; 06179 char *digestusername = ""; 06180 int wrongnonce = 0; 06181 char *usednonce = randdata; 06182 06183 /* Find their response among the mess that we'r sent for comparison */ 06184 ast_copy_string(tmp, authtoken, sizeof(tmp)); 06185 c = tmp; 06186 06187 while(c) { 06188 c = ast_skip_blanks(c); 06189 if (!*c) 06190 break; 06191 if (!strncasecmp(c, "response=", strlen("response="))) { 06192 c+= strlen("response="); 06193 if ((*c == '\"')) { 06194 ua_hash=++c; 06195 if ((c = strchr(c,'\"'))) 06196 *c = '\0'; 06197 06198 } else { 06199 ua_hash=c; 06200 if ((c = strchr(c,','))) 06201 *c = '\0'; 06202 } 06203 06204 } else if (!strncasecmp(c, "uri=", strlen("uri="))) { 06205 c+= strlen("uri="); 06206 if ((*c == '\"')) { 06207 resp_uri=++c; 06208 if ((c = strchr(c,'\"'))) 06209 *c = '\0'; 06210 } else { 06211 resp_uri=c; 06212 if ((c = strchr(c,','))) 06213 *c = '\0'; 06214 } 06215 06216 } else if (!strncasecmp(c, "username=", strlen("username="))) { 06217 c+= strlen("username="); 06218 if ((*c == '\"')) { 06219 digestusername=++c; 06220 if((c = strchr(c,'\"'))) 06221 *c = '\0'; 06222 } else { 06223 digestusername=c; 06224 if((c = strchr(c,','))) 06225 *c = '\0'; 06226 } 06227 } else if (!strncasecmp(c, "nonce=", strlen("nonce="))) { 06228 c+= strlen("nonce="); 06229 if ((*c == '\"')) { 06230 nonce=++c; 06231 if ((c = strchr(c,'\"'))) 06232 *c = '\0'; 06233 } else { 06234 nonce=c; 06235 if ((c = strchr(c,','))) 06236 *c = '\0'; 06237 } 06238 06239 } else 06240 if ((z = strchr(c,' ')) || (z = strchr(c,','))) c=z; 06241 if (c) 06242 c++; 06243 } 06244 /* Verify that digest username matches the username we auth as */ 06245 if (strcmp(username, digestusername)) { 06246 /* Oops, we're trying something here */ 06247 return -2; 06248 } 06249 06250 /* Verify nonce from request matches our nonce. If not, send 401 with new nonce */ 06251 if (strncasecmp(randdata, nonce, randlen)) { 06252 wrongnonce = 1; 06253 usednonce = nonce; 06254 } 06255 06256 snprintf(a1, sizeof(a1), "%s:%s:%s", username, global_realm, secret); 06257 06258 if (!ast_strlen_zero(resp_uri)) 06259 snprintf(a2, sizeof(a2), "%s:%s", sip_methods[sipmethod].text, resp_uri); 06260 else 06261 snprintf(a2, sizeof(a2), "%s:%s", sip_methods[sipmethod].text, uri); 06262 06263 if (!ast_strlen_zero(md5secret)) 06264 snprintf(a1_hash, sizeof(a1_hash), "%s", md5secret); 06265 else 06266 ast_md5_hash(a1_hash, a1); 06267 06268 ast_md5_hash(a2_hash, a2); 06269 06270 snprintf(resp, sizeof(resp), "%s:%s:%s", a1_hash, usednonce, a2_hash); 06271 ast_md5_hash(resp_hash, resp); 06272 06273 if (wrongnonce) { 06274 06275 snprintf(randdata, randlen, "%08x", thread_safe_rand()); 06276 if (ua_hash && !strncasecmp(ua_hash, resp_hash, strlen(resp_hash))) { 06277 if (sipdebug) 06278 ast_log(LOG_NOTICE, "stale nonce received from '%s'\n", get_header(req, "To")); 06279 /* We got working auth token, based on stale nonce . */ 06280 transmit_response_with_auth(p, response, req, randdata, reliable, respheader, 1); 06281 } else { 06282 /* Everything was wrong, so give the device one more try with a new challenge */ 06283 if (sipdebug) 06284 ast_log(LOG_NOTICE, "Bad authentication received from '%s'\n", get_header(req, "To")); 06285 transmit_response_with_auth(p, response, req, randdata, reliable, respheader, 0); 06286 } 06287 06288 /* Schedule auto destroy in 15 seconds */ 06289 sip_scheddestroy(p, 15000); 06290 return 1; 06291 } 06292 /* resp_hash now has the expected response, compare the two */ 06293 if (ua_hash && !strncasecmp(ua_hash, resp_hash, strlen(resp_hash))) { 06294 /* Auth is OK */ 06295 res = 0; 06296 } 06297 } 06298 /* Failure */ 06299 return res; 06300 }
|
|
check_pendings: Check pending actions on SIP call ---
Definition at line 9411 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(). 09412 { 09413 /* Go ahead and send bye at this point */ 09414 if (ast_test_flag(p, SIP_PENDINGBYE)) { 09415 transmit_request_with_auth(p, SIP_BYE, 0, 1, 1); 09416 ast_set_flag(p, SIP_NEEDDESTROY); 09417 ast_clear_flag(p, SIP_NEEDREINVITE); 09418 } else if (ast_test_flag(p, SIP_NEEDREINVITE)) { 09419 ast_log(LOG_DEBUG, "Sending pending reinvite on '%s'\n", p->callid); 09420 /* Didn't get to reinvite yet, so do it now */ 09421 transmit_reinvite_with_sdp(p); 09422 ast_clear_flag(p, SIP_NEEDREINVITE); 09423 } 09424 }
|
|
check_sip_domain: Check if domain part of uri is local to our server
Definition at line 11728 of file chan_sip.c. References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_strlen_zero(), domain::context, domain::domain, and result. Referenced by func_check_sipdomain(), get_destination(), and register_verify(). 11729 { 11730 struct domain *d; 11731 int result = 0; 11732 11733 AST_LIST_LOCK(&domain_list); 11734 AST_LIST_TRAVERSE(&domain_list, d, list) { 11735 if (strcasecmp(d->domain, domain)) 11736 continue; 11737 11738 if (len && !ast_strlen_zero(d->context)) 11739 ast_copy_string(context, d->context, len); 11740 11741 result = 1; 11742 break; 11743 } 11744 AST_LIST_UNLOCK(&domain_list); 11745 11746 return result; 11747 }
|
|
check_user: Find user ---
Definition at line 7195 of file chan_sip.c. References check_user_full(), and sipmethod. Referenced by handle_request_invite(). 07196 { 07197 return check_user_full(p, req, sipmethod, uri, reliable, sin, ignore, NULL, 0); 07198 }
|
|
check_user_full: Check if matching user or peer is defined ---
Definition at line 6932 of file chan_sip.c. References sip_peer::accountcode, sip_user::accountcode, sip_pvt::accountcode, sip_peer::amaflags, sip_user::amaflags, sip_pvt::amaflags, ast_apply_ha(), ast_copy_flags, ast_inet_ntoa(), ast_log(), 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, sip_pvt::authname, build_contact(), sip_peer::call_limit, sip_user::call_limit, sip_peer::callgroup, sip_user::callgroup, sip_pvt::callgroup, sip_peer::callingpres, sip_user::callingpres, sip_pvt::callingpres, sip_peer::capability, sip_user::capability, sip_pvt::capability, sip_peer::chanvars, sip_pvt::chanvars, sip_user::chanvars, check_auth(), sip_peer::cid_name, sip_user::cid_name, sip_pvt::cid_name, sip_peer::cid_num, sip_user::cid_num, sip_pvt::cid_num, sip_peer::context, sip_pvt::context, sip_user::context, sip_pvt::exten, find_peer(), find_user(), sip_pvt::from, sip_peer::fullcontact, sip_pvt::fullcontact, get_calleridname(), get_header(), get_in_brackets(), get_rpid_num(), global_allowguest, global_flags, sip_user::ha, sip_pvt::jointcapability, sip_peer::language, sip_user::language, sip_pvt::language, sip_peer::lastms, LOG_DEBUG, LOG_NOTICE, sip_peer::mailbox, sip_peer::maxms, sip_peer::md5secret, sip_user::md5secret, sip_user::musicclass, sip_pvt::musicclass, ast_variable::next, sip_pvt::noncodeccapability, sip_pvt::our_contact, sip_pvt::peercapability, sip_pvt::peermd5secret, sip_pvt::peername, sip_pvt::peersecret, sip_peer::pickupgroup, sip_user::pickupgroup, sip_pvt::pickupgroup, sip_peer::prefs, sip_user::prefs, sip_pvt::prefs, sip_pvt::randdata, sip_pvt::recv, sip_pvt::rtp, sip_peer::secret, sip_user::secret, SIP_CALL_LIMIT, sip_cancel_destroy(), sip_debug_test_addr(), sip_destroy_peer(), sip_destroy_user(), SIP_DTMF, SIP_FLAGS_TO_COPY, SIP_INSECURE_INVITE, SIP_NAT, SIP_NAT_ROUTE, SIP_OSPAUTH, SIP_TRUSTRPID, sipmethod, sip_peer::sipoptions, sip_user::sipoptions, sip_pvt::sipoptions, sip_peer::subscribecontext, sip_user::subscribecontext, sip_pvt::subscribecontext, sip_pvt::timer_t1, sip_peer::username, sip_pvt::username, and sip_pvt::vrtp. Referenced by check_user(), and handle_request_subscribe(). 06933 { 06934 struct sip_user *user = NULL; 06935 struct sip_peer *peer; 06936 char *of, from[256], *c; 06937 char *rpid,rpid_num[50]; 06938 char iabuf[INET_ADDRSTRLEN]; 06939 int res = 0; 06940 char *t; 06941 char calleridname[50]; 06942 int debug=sip_debug_test_addr(sin); 06943 struct ast_variable *tmpvar = NULL, *v = NULL; 06944 06945 /* Terminate URI */ 06946 t = uri; 06947 while(*t && (*t > 32) && (*t != ';')) 06948 t++; 06949 *t = '\0'; 06950 of = get_header(req, "From"); 06951 if (pedanticsipchecking) 06952 ast_uri_decode(of); 06953 06954 ast_copy_string(from, of, sizeof(from)); 06955 06956 memset(calleridname,0,sizeof(calleridname)); 06957 get_calleridname(from, calleridname, sizeof(calleridname)); 06958 if (calleridname[0]) 06959 ast_copy_string(p->cid_name, calleridname, sizeof(p->cid_name)); 06960 06961 rpid = get_header(req, "Remote-Party-ID"); 06962 memset(rpid_num,0,sizeof(rpid_num)); 06963 if (!ast_strlen_zero(rpid)) 06964 p->callingpres = get_rpid_num(rpid,rpid_num, sizeof(rpid_num)); 06965 06966 of = get_in_brackets(from); 06967 if (ast_strlen_zero(p->exten)) { 06968 t = uri; 06969 if (!strncmp(t, "sip:", 4)) 06970 t+= 4; 06971 ast_copy_string(p->exten, t, sizeof(p->exten)); 06972 t = strchr(p->exten, '@'); 06973 if (t) 06974 *t = '\0'; 06975 if (ast_strlen_zero(p->our_contact)) 06976 build_contact(p); 06977 } 06978 /* save the URI part of the From header */ 06979 ast_copy_string(p->from, of, sizeof(p->from)); 06980 if (strncmp(of, "sip:", 4)) { 06981 ast_log(LOG_NOTICE, "From address missing 'sip:', using it anyway\n"); 06982 } else 06983 of += 4; 06984 /* Get just the username part */ 06985 if ((c = strchr(of, '@'))) { 06986 *c = '\0'; 06987 if ((c = strchr(of, ':'))) 06988 *c = '\0'; 06989 ast_copy_string(p->cid_num, of, sizeof(p->cid_num)); 06990 ast_shrink_phone_number(p->cid_num); 06991 } 06992 if (ast_strlen_zero(of)) 06993 return 0; 06994 06995 if (!mailbox) /* If it's a mailbox SUBSCRIBE, don't check users */ 06996 user = find_user(of, 1); 06997 06998 /* Find user based on user name in the from header */ 06999 if (user && ast_apply_ha(user->ha, sin)) { 07000 ast_copy_flags(p, user, SIP_FLAGS_TO_COPY); 07001 /* copy channel vars */ 07002 for (v = user->chanvars ; v ; v = v->next) { 07003 if ((tmpvar = ast_variable_new(v->name, v->value))) { 07004 tmpvar->next = p->chanvars; 07005 p->chanvars = tmpvar; 07006 } 07007 } 07008 p->prefs = user->prefs; 07009 /* replace callerid if rpid found, and not restricted */ 07010 if (!ast_strlen_zero(rpid_num) && ast_test_flag(p, SIP_TRUSTRPID)) { 07011 if (*calleridname) 07012 ast_copy_string(p->cid_name, calleridname, sizeof(p->cid_name)); 07013 ast_copy_string(p->cid_num, rpid_num, sizeof(p->cid_num)); 07014 ast_shrink_phone_number(p->cid_num); 07015 } 07016 07017 if (p->rtp) { 07018 ast_log(LOG_DEBUG, "Setting NAT on RTP to %d\n", (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE)); 07019 ast_rtp_setnat(p->rtp, (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE)); 07020 } 07021 if (p->vrtp) { 07022 ast_log(LOG_DEBUG, "Setting NAT on VRTP to %d\n", (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE)); 07023 ast_rtp_setnat(p->vrtp, (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE)); 07024 } 07025 if (!(res = check_auth(p, req, p->randdata, sizeof(p->randdata), user->name, user->secret, user->md5secret, sipmethod, uri, reliable, ignore))) { 07026 sip_cancel_destroy(p); 07027 ast_copy_flags(p, user, SIP_FLAGS_TO_COPY); 07028 /* Copy SIP extensions profile from INVITE */ 07029 if (p->sipoptions) 07030 user->sipoptions = p->sipoptions; 07031 07032 /* If we have a call limit, set flag */ 07033 if (user->call_limit) 07034 ast_set_flag(p, SIP_CALL_LIMIT); 07035 if (!ast_strlen_zero(user->context)) 07036 ast_copy_string(p->context, user->context, sizeof(p->context)); 07037 if (!ast_strlen_zero(user->cid_num) && !ast_strlen_zero(p->cid_num)) { 07038 ast_copy_string(p->cid_num, user->cid_num, sizeof(p->cid_num)); 07039 ast_shrink_phone_number(p->cid_num); 07040 } 07041 if (!ast_strlen_zero(user->cid_name) && !ast_strlen_zero(p->cid_num)) 07042 ast_copy_string(p->cid_name, user->cid_name, sizeof(p->cid_name)); 07043 ast_copy_string(p->username, user->name, sizeof(p->username)); 07044 ast_copy_string(p->peersecret, user->secret, sizeof(p->peersecret)); 07045 ast_copy_string(p->subscribecontext, user->subscribecontext, sizeof(p->subscribecontext)); 07046 ast_copy_string(p->peermd5secret, user->md5secret, sizeof(p->peermd5secret)); 07047 ast_copy_string(p->accountcode, user->accountcode, sizeof(p->accountcode)); 07048 ast_copy_string(p->language, user->language, sizeof(p->language)); 07049 ast_copy_string(p->musicclass, user->musicclass, sizeof(p->musicclass)); 07050 p->amaflags = user->amaflags; 07051 p->callgroup = user->callgroup; 07052 p->pickupgroup = user->pickupgroup; 07053 p->callingpres = user->callingpres; 07054 p->capability = user->capability; 07055 p->jointcapability = user->capability; 07056 if (p->peercapability) 07057 p->jointcapability &= p->peercapability; 07058 if ((ast_test_flag(p, SIP_DTMF) == SIP_DTMF_RFC2833) || (ast_test_flag(p, SIP_DTMF) == SIP_DTMF_AUTO)) 07059 p->noncodeccapability |= AST_RTP_DTMF; 07060 else 07061 p->noncodeccapability &= ~AST_RTP_DTMF; 07062 } 07063 if (user && debug) 07064 ast_verbose("Found user '%s'\n", user->name); 07065 } else { 07066 if (user) { 07067 if (!mailbox && debug) 07068 ast_verbose("Found user '%s', but fails host access\n", user->name); 07069 ASTOBJ_UNREF(user,sip_destroy_user); 07070 } 07071 user = NULL; 07072 } 07073 07074 if (!user) { 07075 /* If we didn't find a user match, check for peers */ 07076 if (sipmethod == SIP_SUBSCRIBE) 07077 /* For subscribes, match on peer name only */ 07078 peer = find_peer(of, NULL, 1); 07079 else 07080 /* Look for peer based on the IP address we received data from */ 07081 /* If peer is registered from this IP address or have this as a default 07082 IP address, this call is from the peer 07083 */ 07084 peer = find_peer(NULL, &p->recv, 1); 07085 07086 if (peer) { 07087 if (debug) 07088 ast_verbose("Found peer '%s'\n", peer->name); 07089 /* Take the peer */ 07090 ast_copy_flags(p, peer, SIP_FLAGS_TO_COPY); 07091 07092 /* Copy SIP extensions profile to peer */ 07093 if (p->sipoptions) 07094 peer->sipoptions = p->sipoptions; 07095 07096 /* replace callerid if rpid found, and not restricted */ 07097 if (!ast_strlen_zero(rpid_num) && ast_test_flag(p, SIP_TRUSTRPID)) { 07098 if (*calleridname) 07099 ast_copy_string(p->cid_name, calleridname, sizeof(p->cid_name)); 07100 ast_copy_string(p->cid_num, rpid_num, sizeof(p->cid_num)); 07101 ast_shrink_phone_number(p->cid_num); 07102 } 07103 if (p->rtp) { 07104 ast_log(LOG_DEBUG, "Setting NAT on RTP to %d\n", (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE)); 07105 ast_rtp_setnat(p->rtp, (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE)); 07106 } 07107 if (p->vrtp) { 07108 ast_log(LOG_DEBUG, "Setting NAT on VRTP to %d\n", (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE)); 07109 ast_rtp_setnat(p->vrtp, (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE)); 07110 } 07111 ast_copy_string(p->peersecret, peer->secret, sizeof(p->peersecret)); 07112 p->peersecret[sizeof(p->peersecret)-1] = '\0'; 07113 ast_copy_string(p->subscribecontext, peer->subscribecontext, sizeof(p->subscribecontext)); 07114 ast_copy_string(p->peermd5secret, peer->md5secret, sizeof(p->peermd5secret)); 07115 p->peermd5secret[sizeof(p->peermd5secret)-1] = '\0'; 07116 p->callingpres = peer->callingpres; 07117 if (peer->maxms && peer->lastms) 07118 p->timer_t1 = peer->lastms; 07119 if (ast_test_flag(peer, SIP_INSECURE_INVITE)) { 07120 /* Pretend there is no required authentication */ 07121 p->peersecret[0] = '\0'; 07122 p->peermd5secret[0] = '\0'; 07123 } 07124 if (!(res = check_auth(p, req, p->randdata, sizeof(p->randdata), peer->name, p->peersecret, p->peermd5secret, sipmethod, uri, reliable, ignore))) { 07125 ast_copy_flags(p, peer, SIP_FLAGS_TO_COPY); 07126 /* If we have a call limit, set flag */ 07127 if (peer->call_limit) 07128 ast_set_flag(p, SIP_CALL_LIMIT); 07129 ast_copy_string(p->peername, peer->name, sizeof(p->peername)); 07130 ast_copy_string(p->authname, peer->name, sizeof(p->authname)); 07131 /* copy channel vars */ 07132 for (v = peer->chanvars ; v ; v = v->next) { 07133 if ((tmpvar = ast_variable_new(v->name, v->value))) { 07134 tmpvar->next = p->chanvars; 07135 p->chanvars = tmpvar; 07136 } 07137 } 07138 if (mailbox) 07139 snprintf(mailbox, mailboxlen, ",%s,", peer->mailbox); 07140 if (!ast_strlen_zero(peer->username)) { 07141 ast_copy_string(p->username, peer->username, sizeof(p->username)); 07142 /* Use the default username for authentication on outbound calls */ 07143 ast_copy_string(p->authname, peer->username, sizeof(p->authname)); 07144 } 07145 if (!ast_strlen_zero(peer->cid_num) && !ast_strlen_zero(p->cid_num)) { 07146 ast_copy_string(p->cid_num, peer->cid_num, sizeof(p->cid_num)); 07147 ast_shrink_phone_number(p->cid_num); 07148 } 07149 if (!ast_strlen_zero(peer->cid_name) && !ast_strlen_zero(p->cid_name)) 07150 ast_copy_string(p->cid_name, peer->cid_name, sizeof(p->cid_name)); 07151 ast_copy_string(p->fullcontact, peer->fullcontact, sizeof(p->fullcontact)); 07152 if (!ast_strlen_zero(peer->context)) 07153 ast_copy_string(p->context, peer->context, sizeof(p->context)); 07154 ast_copy_string(p->peersecret, peer->secret, sizeof(p->peersecret)); 07155 ast_copy_string(p->peermd5secret, peer->md5secret, sizeof(p->peermd5secret)); 07156 ast_copy_string(p->language, peer->language, sizeof(p->language)); 07157 ast_copy_string(p->accountcode, peer->accountcode, sizeof(p->accountcode)); 07158 p->amaflags = peer->amaflags; 07159 p->callgroup = peer->callgroup; 07160 p->pickupgroup = peer->pickupgroup; 07161 p->capability = peer->capability; 07162 p->prefs = peer->prefs; 07163 p->jointcapability = peer->capability; 07164 if (p->peercapability) 07165 p->jointcapability &= p->peercapability; 07166 if ((ast_test_flag(p, SIP_DTMF) == SIP_DTMF_RFC2833) || (ast_test_flag(p, SIP_DTMF) == SIP_DTMF_AUTO)) 07167 p->noncodeccapability |= AST_RTP_DTMF; 07168 else 07169 p->noncodeccapability &= ~AST_RTP_DTMF; 07170 } 07171 ASTOBJ_UNREF(peer,sip_destroy_peer); 07172 } else { 07173 if (debug) 07174 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)); 07175 07176 /* do we allow guests? */ 07177 if (!global_allowguest) 07178 res = -1; /* we don't want any guests, authentication will fail */ 07179 #ifdef OSP_SUPPORT 07180 else if (global_allowguest == 2) { 07181 ast_copy_flags(p, &global_flags, SIP_OSPAUTH); 07182 res = check_auth(p, req, p->randdata, sizeof(p->randdata), "", "", "", sipmethod, uri, reliable, ignore); 07183 } 07184 #endif 07185 } 07186 07187 } 07188 07189 if (user) 07190 ASTOBJ_UNREF(user,sip_destroy_user); 07191 return res; 07192 }
|
|
check Via: header for hostname, port and rport request/answer
Definition at line 6808 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(). 06809 { 06810 char via[256]; 06811 char iabuf[INET_ADDRSTRLEN]; 06812 char *c, *pt; 06813 struct hostent *hp; 06814 struct ast_hostent ahp; 06815 06816 ast_copy_string(via, get_header(req, "Via"), sizeof(via)); 06817 06818 /* Check for rport */ 06819 c = strstr(via, ";rport"); 06820 if (c && (c[6] != '=')) /* rport query, not answer */ 06821 ast_set_flag(p, SIP_NAT_ROUTE); 06822 06823 c = strchr(via, ';'); 06824 if (c) 06825 *c = '\0'; 06826 06827 c = strchr(via, ' '); 06828 if (c) { 06829 *c = '\0'; 06830 c = ast_skip_blanks(c+1); 06831 if (strcasecmp(via, "SIP/2.0/UDP")) { 06832 ast_log(LOG_WARNING, "Don't know how to respond via '%s'\n", via); 06833 return -1; 06834 } 06835 pt = strchr(c, ':'); 06836 if (pt) 06837 *pt++ = '\0'; /* remember port pointer */ 06838 hp = ast_gethostbyname(c, &ahp); 06839 if (!hp) { 06840 ast_log(LOG_WARNING, "'%s' is not a valid host\n", c); 06841 return -1; 06842 } 06843 memset(&p->sa, 0, sizeof(p->sa)); 06844 p->sa.sin_family = AF_INET; 06845 memcpy(&p->sa.sin_addr, hp->h_addr, sizeof(p->sa.sin_addr)); 06846 p->sa.sin_port = htons(pt ? atoi(pt) : DEFAULT_SIP_PORT); 06847 06848 if (sip_debug_test_pvt(p)) { 06849 c = (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE) ? "NAT" : "non-NAT"; 06850 ast_verbose("Sending to %s : %d (%s)\n", ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr), ntohs(p->sa.sin_port), c); 06851 } 06852 } 06853 return 0; 06854 }
|
|
clear_realm_authentication: Clear realm authentication list (at reload) ---
Definition at line 11829 of file chan_sip.c. References free, and sip_auth::next. Referenced by sip_destroy_peer(), sip_do_reload(), and unload_module(). 11830 { 11831 struct sip_auth *a = authlist; 11832 struct sip_auth *b; 11833 11834 while (a) { 11835 b = a; 11836 a = a->next; 11837 free(b); 11838 } 11839 11840 return 1; 11841 }
|
|
clear_sip_domains: Clear our domain list (at reload)
Definition at line 11750 of file chan_sip.c. References AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, and free. Referenced by sip_do_reload(), and unload_module(). 11751 { 11752 struct domain *d; 11753 11754 AST_LIST_LOCK(&domain_list); 11755 while ((d = AST_LIST_REMOVE_HEAD(&domain_list, list))) 11756 free(d); 11757 AST_LIST_UNLOCK(&domain_list); 11758 }
|
|
complete_sip_debug_peer: Support routine for 'sip debug peer' CLI ---
Definition at line 8358 of file chan_sip.c. References complete_sip_peer(). 08359 { 08360 if (pos == 3) 08361 return complete_sip_peer(word, state, 0); 08362 08363 return NULL; 08364 }
|
|
complete_sip_peer: Do completion on peer name ---
Definition at line 8329 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(). 08330 { 08331 char *result = NULL; 08332 int wordlen = strlen(word); 08333 int which = 0; 08334 08335 ASTOBJ_CONTAINER_TRAVERSE(&peerl, !result, do { 08336 /* locking of the object is not required because only the name and flags are being compared */ 08337 if (!strncasecmp(word, iterator->name, wordlen)) { 08338 if (flags2 && !ast_test_flag((&iterator->flags_page2), flags2)) 08339 continue; 08340 if (++which > state) { 08341 result = strdup(iterator->name); 08342 } 08343 } 08344 } while(0) ); 08345 return result; 08346 }
|
|
complete_sip_prune_realtime_peer: Support routine for 'sip prune realtime peer' CLI ---
Definition at line 8429 of file chan_sip.c. References complete_sip_peer(), and SIP_PAGE2_RTCACHEFRIENDS. 08430 { 08431 if (pos == 4) 08432 return complete_sip_peer(word, state, SIP_PAGE2_RTCACHEFRIENDS); 08433 return NULL; 08434 }
|
|
complete_sip_prune_realtime_user: Support routine for 'sip prune realtime user' CLI ---
Definition at line 8437 of file chan_sip.c. References complete_sip_user(), and SIP_PAGE2_RTCACHEFRIENDS. 08438 { 08439 if (pos == 4) 08440 return complete_sip_user(word, state, SIP_PAGE2_RTCACHEFRIENDS); 08441 08442 return NULL; 08443 }
|
|
complete_sip_show_peer: Support routine for 'sip show peer' CLI ---
Definition at line 8349 of file chan_sip.c. References complete_sip_peer(). 08350 { 08351 if (pos == 3) 08352 return complete_sip_peer(word, state, 0); 08353 08354 return NULL; 08355 }
|
|
complete_sip_show_user: Support routine for 'sip show user' CLI ---
Definition at line 8387 of file chan_sip.c. References complete_sip_user(). 08388 { 08389 if (pos == 3) 08390 return complete_sip_user(word, state, 0); 08391 08392 return NULL; 08393 }
|
|
complete_sip_user: Do completion on user name ---
Definition at line 8367 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(). 08368 { 08369 char *result = NULL; 08370 int wordlen = strlen(word); 08371 int which = 0; 08372 08373 ASTOBJ_CONTAINER_TRAVERSE(&userl, !result, do { 08374 /* locking of the object is not required because only the name and flags are being compared */ 08375 if (!strncasecmp(word, iterator->name, wordlen)) { 08376 if (flags2 && !ast_test_flag(&(iterator->flags_page2), flags2)) 08377 continue; 08378 if (++which > state) { 08379 result = strdup(iterator->name); 08380 } 08381 } 08382 } while(0) ); 08383 return result; 08384 }
|
|
complete_sipch: Support routine for 'sip show channel' CLI ---
Definition at line 8307 of file chan_sip.c. References ast_mutex_lock(), ast_mutex_unlock(), sip_pvt::callid, sip_pvt::next, and strdup. 08308 { 08309 int which=0; 08310 struct sip_pvt *cur; 08311 char *c = NULL; 08312 08313 ast_mutex_lock(&iflock); 08314 cur = iflist; 08315 while(cur) { 08316 if (!strncasecmp(word, cur->callid, strlen(word))) { 08317 if (++which > state) { 08318 c = strdup(cur->callid); 08319 break; 08320 } 08321 } 08322 cur = cur->next; 08323 } 08324 ast_mutex_unlock(&iflock); 08325 return c; 08326 }
|
|
complete_sipnotify: Support routine for 'sip notify' CLI ---
Definition at line 8396 of file chan_sip.c. References ast_category_browse(), complete_sip_peer(), notify_types, and strdup. 08397 { 08398 char *c = NULL; 08399 08400 if (pos == 2) { 08401 int which = 0; 08402 char *cat; 08403 08404 /* do completion for notify type */ 08405 08406 if (!notify_types) 08407 return NULL; 08408 08409 cat = ast_category_browse(notify_types, NULL); 08410 while(cat) { 08411 if (!strncasecmp(word, cat, strlen(word))) { 08412 if (++which > state) { 08413 c = strdup(cat); 08414 break; 08415 } 08416 } 08417 cat = ast_category_browse(notify_types, cat); 08418 } 08419 return c; 08420 } 08421 08422 if (pos > 2) 08423 return complete_sip_peer(word, state, 0); 08424 08425 return NULL; 08426 }
|
|
copy_all_header: Copy all headers from one request to another ---
Definition at line 3766 of file chan_sip.c. References __get_header(), add_header(), and ast_strlen_zero(). Referenced by respprep(). 03767 { 03768 char *tmp; 03769 int start = 0; 03770 int copied = 0; 03771 for (;;) { 03772 tmp = __get_header(orig, field, &start); 03773 if (!ast_strlen_zero(tmp)) { 03774 /* Add what we're responding to */ 03775 add_header(req, field, tmp); 03776 copied++; 03777 } else 03778 break; 03779 } 03780 return copied ? 0 : -1; 03781 }
|
|
copy_header: Copy one header field from one request to another
Definition at line 3753 of file chan_sip.c. References add_header(), ast_log(), ast_strlen_zero(), get_header(), and LOG_NOTICE. Referenced by reqprep(), and respprep(). 03754 { 03755 char *tmp; 03756 tmp = get_header(orig, field); 03757 if (!ast_strlen_zero(tmp)) { 03758 /* Add what we're responding to */ 03759 return add_header(req, field, tmp); 03760 } 03761 ast_log(LOG_NOTICE, "No field '%s' present to copy\n", field); 03762 return -1; 03763 }
|
|
copy_request: copy SIP request (mostly used to save request for responses) ---
Definition at line 4491 of file chan_sip.c. References sip_request::headers, and sip_request::lines. 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(). 04492 { 04493 long offset; 04494 int x; 04495 offset = ((void *)dst) - ((void *)src); 04496 /* First copy stuff */ 04497 memcpy(dst, src, sizeof(*dst)); 04498 /* Now fix pointer arithmetic */ 04499 for (x=0; x < src->headers; x++) 04500 dst->header[x] += offset; 04501 for (x=0; x < src->lines; x++) 04502 dst->line[x] += offset; 04503 }
|
|
copy_via_headers: Copy SIP VIA Headers from the request to the response ---
Definition at line 3789 of file chan_sip.c. References __get_header(), add_header(), ast_inet_ntoa(), ast_log(), ast_strlen_zero(), ast_test_flag, LOG_NOTICE, sip_pvt::recv, and SIP_NAT. Referenced by respprep(). 03790 { 03791 char tmp[256], *oh, *end; 03792 int start = 0; 03793 int copied = 0; 03794 char iabuf[INET_ADDRSTRLEN]; 03795 03796 for (;;) { 03797 oh = __get_header(orig, field, &start); 03798 if (!ast_strlen_zero(oh)) { 03799 if (!copied) { /* Only check for empty rport in topmost via header */ 03800 char *rport; 03801 char new[256]; 03802 03803 /* Find ;rport; (empty request) */ 03804 rport = strstr(oh, ";rport"); 03805 if (rport && *(rport+6) == '=') 03806 rport = NULL; /* We already have a parameter to rport */ 03807 03808 if (rport && (ast_test_flag(p, SIP_NAT) == SIP_NAT_ALWAYS)) { 03809 /* We need to add received port - rport */ 03810 ast_copy_string(tmp, oh, sizeof(tmp)); 03811 03812 rport = strstr(tmp, ";rport"); 03813 03814 if (rport) { 03815 end = strchr(rport + 1, ';'); 03816 if (end) 03817 memmove(rport, end, strlen(end) + 1); 03818 else 03819 *rport = '\0'; 03820 } 03821 03822 /* Add rport to first VIA header if requested */ 03823 /* Whoo hoo! Now we can indicate port address translation too! Just 03824 another RFC (RFC3581). I'll leave the original comments in for 03825 posterity. */ 03826 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)); 03827 } else { 03828 /* We should *always* add a received to the topmost via */ 03829 snprintf(new, sizeof(new), "%s;received=%s", oh, ast_inet_ntoa(iabuf, sizeof(iabuf), p->recv.sin_addr)); 03830 } 03831 add_header(req, field, new); 03832 } else { 03833 /* Add the following via headers untouched */ 03834 add_header(req, field, oh); 03835 } 03836 copied++; 03837 } else 03838 break; 03839 } 03840 if (!copied) { 03841 ast_log(LOG_NOTICE, "No header field '%s' present to copy\n", field); 03842 return -1; 03843 } 03844 return 0; 03845 }
|
|
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(), find_peer(), hp, LOG_WARNING, sip_pvt::recv, sip_pvt::sa, sip_destroy_peer(), sip_pvt::timer_t1, and sip_pvt::tohost. Referenced by cache_get_callno_locked(), iax2_call(), iax2_provision(), iax2_request(), oh323_request(), sip_notify(), sip_request_call(), and transmit_register(). 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_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_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 13240 of file chan_sip.c. 13241 { 13242 return (char *) desc; 13243 }
|
|
Definition at line 5606 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(). 05607 { 05608 if (!ast_test_flag((&global_flags_page2), SIP_PAGE2_IGNOREREGEXPIRE)) { 05609 if (ast_test_flag(&(peer->flags_page2), SIP_PAGE2_RT_FROMCONTACT)) { 05610 ast_update_realtime("sippeers", "name", peer->name, "fullcontact", "", "ipaddr", "", "port", "", "regseconds", "0", "username", "", NULL); 05611 } else { 05612 ast_db_del("SIP/Registry", peer->name); 05613 } 05614 } 05615 }
|
|
determine_firstline_parts: parse first line of incoming SIP request
Definition at line 4525 of file chan_sip.c. References sip_request::header, 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(). 04526 { 04527 char *e, *cmd; 04528 int len; 04529 04530 cmd = ast_skip_blanks(req->header[0]); 04531 if (!*cmd) 04532 return -1; 04533 req->rlPart1 = cmd; 04534 e = ast_skip_nonblanks(cmd); 04535 /* Get the command */ 04536 if (*e) 04537 *e++ = '\0'; 04538 e = ast_skip_blanks(e); 04539 if ( !*e ) 04540 return -1; 04541 04542 if ( !strcasecmp(cmd, "SIP/2.0") ) { 04543 /* We have a response */ 04544 req->rlPart2 = e; 04545 len = strlen( req->rlPart2 ); 04546 if ( len < 2 ) { 04547 return -1; 04548 } 04549 ast_trim_blanks(e); 04550 } else { 04551 /* We have a request */ 04552 if ( *e == '<' ) { 04553 e++; 04554 if ( !*e ) { 04555 return -1; 04556 } 04557 } 04558 req->rlPart2 = e; /* URI */ 04559 if ( ( e= strrchr( req->rlPart2, 'S' ) ) == NULL ) { 04560 return -1; 04561 } 04562 /* XXX maybe trim_blanks() ? */ 04563 while( isspace( *(--e) ) ) {} 04564 if ( *e == '>' ) { 04565 *e = '\0'; 04566 } else { 04567 *(++e)= '\0'; 04568 } 04569 } 04570 return 1; 04571 }
|
|
do_monitor: The SIP monitoring thread ---
Definition at line 11195 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_strlen_zero(), ast_test_flag, ast_verbose(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_REF, ASTOBJ_UNLOCK, ASTOBJ_UNREF, ASTOBJ_WRLOCK, global_mwitime, 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, sched, sip_destroy_peer(), sip_do_reload(), SIP_NEEDDESTROY, sip_reloading, sip_send_mwi_to_peer(), sipsock, sipsock_read(), and VERBOSE_PREFIX_1. Referenced by restart_monitor(). 11196 { 11197 int res; 11198 struct sip_pvt *sip; 11199 struct sip_peer *peer = NULL; 11200 time_t t; 11201 int fastrestart =0; 11202 int lastpeernum = -1; 11203 int curpeernum; 11204 int reloading; 11205 11206 /* Add an I/O event to our UDP socket */ 11207 if (sipsock > -1) 11208 ast_io_add(io, sipsock, sipsock_read, AST_IO_IN, NULL); 11209 11210 /* This thread monitors all the frame relay interfaces which are not yet in use 11211 (and thus do not have a separate thread) indefinitely */ 11212 /* From here on out, we die whenever asked */ 11213 for(;;) { 11214 /* Check for a reload request */ 11215 ast_mutex_lock(&sip_reload_lock); 11216 reloading = sip_reloading; 11217 sip_reloading = 0; 11218 ast_mutex_unlock(&sip_reload_lock); 11219 if (reloading) { 11220 if (option_verbose > 0) 11221 ast_verbose(VERBOSE_PREFIX_1 "Reloading SIP\n"); 11222 sip_do_reload(); 11223 } 11224 /* Check for interfaces needing to be killed */ 11225 ast_mutex_lock(&iflock); 11226 restartsearch: 11227 time(&t); 11228 sip = iflist; 11229 while(sip) { 11230 ast_mutex_lock(&sip->lock); 11231 if (sip->rtp && sip->owner && (sip->owner->_state == AST_STATE_UP) && !sip->redirip.sin_addr.s_addr) { 11232 if (sip->lastrtptx && sip->rtpkeepalive && t > sip->lastrtptx + sip->rtpkeepalive) { 11233 /* Need to send an empty RTP packet */ 11234 time(&sip->lastrtptx); 11235 ast_rtp_sendcng(sip->rtp, 0); 11236 } 11237 if (sip->lastrtprx && (sip->rtptimeout || sip->rtpholdtimeout) && t > sip->lastrtprx + sip->rtptimeout) { 11238 /* Might be a timeout now -- see if we're on hold */ 11239 struct sockaddr_in sin; 11240 ast_rtp_get_peer(sip->rtp, &sin); 11241 if (sin.sin_addr.s_addr || 11242 (sip->rtpholdtimeout && 11243 (t > sip->lastrtprx + sip->rtpholdtimeout))) { 11244 /* Needs a hangup */ 11245 if (sip->rtptimeout) { 11246 while(sip->owner && ast_mutex_trylock(&sip->owner->lock)) { 11247 ast_mutex_unlock(&sip->lock); 11248 usleep(1); 11249 ast_mutex_lock(&sip->lock); 11250 } 11251 if (sip->owner) { 11252 ast_log(LOG_NOTICE, "Disconnecting call '%s' for lack of RTP activity in %ld seconds\n", sip->owner->name, (long)(t - sip->lastrtprx)); 11253 /* Issue a softhangup */ 11254 ast_softhangup(sip->owner, AST_SOFTHANGUP_DEV); 11255 ast_mutex_unlock(&sip->owner->lock); 11256 } 11257 } 11258 } 11259 } 11260 } 11261 if (ast_test_flag(sip, SIP_NEEDDESTROY) && !sip->packets && !sip->owner) { 11262 ast_mutex_unlock(&sip->lock); 11263 __sip_destroy(sip, 1); 11264 goto restartsearch; 11265 } 11266 ast_mutex_unlock(&sip->lock); 11267 sip = sip->next; 11268 } 11269 ast_mutex_unlock(&iflock); 11270 /* Don't let anybody kill us right away. Nobody should lock the interface list 11271 and wait for the monitor list, but the other way around is okay. */ 11272 ast_mutex_lock(&monlock); 11273 /* Lock the network interface */ 11274 ast_mutex_lock(&netlock); 11275 /* Okay, now that we know what to do, release the network lock */ 11276 ast_mutex_unlock(&netlock); 11277 /* And from now on, we're okay to be killed, so release the monitor lock as well */ 11278 ast_mutex_unlock(&monlock); 11279 pthread_testcancel(); 11280 /* Wait for sched or io */ 11281 res = ast_sched_wait(sched); 11282 if ((res < 0) || (res > 1000)) 11283 res = 1000; 11284 /* If we might need to send more mailboxes, don't wait long at all.*/ 11285 if (fastrestart) 11286 res = 1; 11287 res = ast_io_wait(io, res); 11288 if (res > 20) 11289 ast_log(LOG_DEBUG, "chan_sip: ast_io_wait ran %d all at once\n", res); 11290 ast_mutex_lock(&monlock); 11291 if (res >= 0) { 11292 res = ast_sched_runq(sched); 11293 if (res >= 20) 11294 ast_log(LOG_DEBUG, "chan_sip: ast_sched_runq ran %d all at once\n", res); 11295 } 11296 11297 /* needs work to send mwi to realtime peers */ 11298 time(&t); 11299 fastrestart = 0; 11300 curpeernum = 0; 11301 peer = NULL; 11302 ASTOBJ_CONTAINER_TRAVERSE(&peerl, !peer, do { 11303 if ((curpeernum > lastpeernum) && !ast_strlen_zero(iterator->mailbox) && ((t - iterator->lastmsgcheck) > global_mwitime)) { 11304 fastrestart = 1; 11305 lastpeernum = curpeernum; 11306 peer = ASTOBJ_REF(iterator); 11307 }; 11308 curpeernum++; 11309 } while (0) 11310 ); 11311 if (peer) { 11312 ASTOBJ_WRLOCK(peer); 11313 sip_send_mwi_to_peer(peer); 11314 ASTOBJ_UNLOCK(peer); 11315 ASTOBJ_UNREF(peer,sip_destroy_peer); 11316 } else { 11317 /* Reset where we come from */ 11318 lastpeernum = -1; 11319 } 11320 ast_mutex_unlock(&monlock); 11321 } 11322 /* Never reached */ 11323 return NULL; 11324 11325 }
|
|
do_proxy_auth: Add authentication on outbound SIP packet ---
Definition at line 8869 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, sipmethod, cfsip_methods::text, and transmit_invite(). Referenced by handle_response(), and handle_response_invite(). 08870 { 08871 char digest[1024]; 08872 08873 if (!p->options) { 08874 p->options = calloc(1, sizeof(*p->options)); 08875 if (!p->options) { 08876 ast_log(LOG_ERROR, "Out of memory\n"); 08877 return -2; 08878 } 08879 } 08880 08881 p->authtries++; 08882 if (option_debug > 1) 08883 ast_log(LOG_DEBUG, "Auth attempt %d on %s\n", p->authtries, sip_methods[sipmethod].text); 08884 memset(digest, 0, sizeof(digest)); 08885 if (reply_digest(p, req, header, sipmethod, digest, sizeof(digest) )) { 08886 /* No way to authenticate */ 08887 return -1; 08888 } 08889 /* Now we have a reply digest */ 08890 p->options->auth = digest; 08891 p->options->authheader = respheader; 08892 return transmit_invite(p, sipmethod, sipmethod == SIP_INVITE, init); 08893 }
|
|
do_register_auth: Authenticate for outbound registration ---
Definition at line 8845 of file chan_sip.c. References append_history(), ast_verbose(), sip_pvt::authtries, sip_registry::hostname, sip_pvt::registry, reply_digest(), sip_debug_test_pvt(), SIP_REGISTER, and transmit_register(). Referenced by handle_response_register(). 08846 { 08847 char digest[1024]; 08848 p->authtries++; 08849 memset(digest,0,sizeof(digest)); 08850 if (reply_digest(p, req, header, SIP_REGISTER, digest, sizeof(digest))) { 08851 /* There's nothing to use for authentication */ 08852 /* No digest challenge in request */ 08853 if (sip_debug_test_pvt(p) && p->registry) 08854 ast_verbose("No authentication challenge, sending blank registration to domain/host name %s\n", p->registry->hostname); 08855 /* No old challenge */ 08856 return -1; 08857 } 08858 if (recordhistory) { 08859 char tmp[80]; 08860 snprintf(tmp, sizeof(tmp), "Try: %d", p->authtries); 08861 append_history(p, "RegistryAuth", tmp); 08862 } 08863 if (sip_debug_test_pvt(p) && p->registry) 08864 ast_verbose("Responding to challenge, registration to domain/host name %s\n", p->registry->hostname); 08865 return transmit_register(p->registry, SIP_REGISTER, digest, respheader); 08866 }
|
|
Definition at line 7785 of file chan_sip.c. References SIP_DOMAIN_AUTO, and SIP_DOMAIN_CONFIG. Referenced by sip_show_domains(). 07786 { 07787 switch (mode) { 07788 case SIP_DOMAIN_AUTO: 07789 return "[Automatic]"; 07790 case SIP_DOMAIN_CONFIG: 07791 return "[Configured]"; 07792 } 07793 07794 return ""; 07795 }
|
|
dtmfmode2str: Convert DTMF mode to printable string ---
Definition at line 7593 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(). 07594 { 07595 switch (mode) { 07596 case SIP_DTMF_RFC2833: 07597 return "rfc2833"; 07598 case SIP_DTMF_INFO: 07599 return "info"; 07600 case SIP_DTMF_INBAND: 07601 return "inband"; 07602 case SIP_DTMF_AUTO: 07603 return "auto"; 07604 } 07605 return "<error>"; 07606 }
|
|
expire_register: Expire registration of SIP peer ---
Definition at line 5618 of file chan_sip.c. References sip_peer::addr, ast_device_state_changed(), ast_test_flag, ASTOBJ_CONTAINER_UNLINK, ASTOBJ_UNREF, destroy_association(), EVENT_FLAG_SYSTEM, sip_peer::expire, sip_peer::flags_page2, manager_event(), peerl, register_peer_exten(), sip_destroy_peer(), SIP_PAGE2_RTAUTOCLEAR, and SIP_SELFDESTRUCT. Referenced by parse_register_contact(), realtime_peer(), and reg_source_db(). 05619 { 05620 struct sip_peer *peer = data; 05621 05622 memset(&peer->addr, 0, sizeof(peer->addr)); 05623 05624 destroy_association(peer); 05625 05626 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name); 05627 register_peer_exten(peer, 0); 05628 peer->expire = -1; 05629 ast_device_state_changed("SIP/%s", peer->name); 05630 if (ast_test_flag(peer, SIP_SELFDESTRUCT) || ast_test_flag((&peer->flags_page2), SIP_PAGE2_RTAUTOCLEAR)) { 05631 peer = ASTOBJ_CONTAINER_UNLINK(&peerl, peer); 05632 ASTOBJ_UNREF(peer, sip_destroy_peer); 05633 } 05634 05635 return 0; 05636 }
|
|
extract_uri: Check Contact: URI of SIP message ---
Definition at line 4603 of file chan_sip.c. References ast_strlen_zero(), get_header(), get_in_brackets(), and sip_pvt::uri. Referenced by handle_request(), and handle_request_invite(). 04604 { 04605 char stripped[256]; 04606 char *c, *n; 04607 ast_copy_string(stripped, get_header(req, "Contact"), sizeof(stripped)); 04608 c = get_in_brackets(stripped); 04609 n = strchr(c, ';'); 04610 if (n) 04611 *n = '\0'; 04612 if (!ast_strlen_zero(c)) 04613 ast_copy_string(p->uri, c, sizeof(p->uri)); 04614 }
|
|
Definition at line 2883 of file chan_sip.c. References aliases, name, and cfalias::shortname. Referenced by __get_header(), and setup_incoming_call(). 02884 { 02885 int x; 02886 for (x=0;x<sizeof(aliases) / sizeof(aliases[0]); x++) 02887 if (!strcasecmp(aliases[x].fullname, name)) 02888 return aliases[x].shortname; 02889 return _default; 02890 }
|
|
find_call: Connect incoming SIP message to current dialog or create new dialog structure
Definition at line 3115 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(), sip_pvt::lock, LOG_DEBUG, sip_request::method, sip_pvt::next, option_debug, pedanticsipchecking, sip_alloc(), sip_methods, SIP_PKT_WITH_TOTAG, SIP_RESPONSE, sip_pvt::tag, and sip_pvt::theirtag. Referenced by sipsock_read(). 03116 { 03117 struct sip_pvt *p; 03118 char *callid; 03119 char *tag = ""; 03120 char totag[128]; 03121 char fromtag[128]; 03122 03123 callid = get_header(req, "Call-ID"); 03124 03125 if (pedanticsipchecking) { 03126 /* In principle Call-ID's uniquely identify a call, but with a forking SIP proxy 03127 we need more to identify a branch - so we have to check branch, from 03128 and to tags to identify a call leg. 03129 For Asterisk to behave correctly, you need to turn on pedanticsipchecking 03130 in sip.conf 03131 */ 03132 if (gettag(req, "To", totag, sizeof(totag))) 03133 ast_set_flag(req, SIP_PKT_WITH_TOTAG); /* Used in handle_request/response */ 03134 gettag(req, "From", fromtag, sizeof(fromtag)); 03135 03136 if (req->method == SIP_RESPONSE) 03137 tag = totag; 03138 else 03139 tag = fromtag; 03140 03141 03142 if (option_debug > 4 ) 03143 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); 03144 } 03145 03146 ast_mutex_lock(&iflock); 03147 p = iflist; 03148 while(p) { /* In pedantic, we do not want packets with bad syntax to be connected to a PVT */ 03149 int found = 0; 03150 if (req->method == SIP_REGISTER) 03151 found = (!strcmp(p->callid, callid)); 03152 else 03153 found = (!strcmp(p->callid, callid) && 03154 (!pedanticsipchecking || !tag || ast_strlen_zero(p->theirtag) || !strcmp(p->theirtag, tag))) ; 03155 03156 if (option_debug > 4) 03157 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); 03158 03159 /* If we get a new request within an existing to-tag - check the to tag as well */ 03160 if (pedanticsipchecking && found && req->method != SIP_RESPONSE) { /* SIP Request */ 03161 if (p->tag[0] == '\0' && totag[0]) { 03162 /* We have no to tag, but they have. Wrong dialog */ 03163 found = 0; 03164 } else if (totag[0]) { /* Both have tags, compare them */ 03165 if (strcmp(totag, p->tag)) { 03166 found = 0; /* This is not our packet */ 03167 } 03168 } 03169 if (!found && option_debug > 4) 03170 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); 03171 } 03172 03173 03174 if (found) { 03175 /* Found the call */ 03176 ast_mutex_lock(&p->lock); 03177 ast_mutex_unlock(&iflock); 03178 return p; 03179 } 03180 p = p->next; 03181 } 03182 ast_mutex_unlock(&iflock); 03183 p = sip_alloc(callid, sin, 1, intended_method); 03184 if (p) 03185 ast_mutex_lock(&p->lock); 03186 return p; 03187 }
|
|
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 11844 of file chan_sip.c. References sip_auth::next, and sip_auth::realm. Referenced by build_reply_digest(). 11845 { 11846 struct sip_auth *a = authlist; /* First entry in auth list */ 11847 11848 while (a) { 11849 if (!strcasecmp(a->realm, realm)){ 11850 break; 11851 } 11852 a = a->next; 11853 } 11854 11855 return a; 11856 }
|
|
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 8232 of file chan_sip.c. References subscription_types. Referenced by transmit_state_notify(). 08232 { 08233 int i; 08234 08235 for (i = 1; (i < (sizeof(subscription_types) / sizeof(subscription_types[0]))); i++) { 08236 if (subscription_types[i].type == subtype) { 08237 return &subscription_types[i]; 08238 } 08239 } 08240 return &subscription_types[0]; 08241 }
|
|
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, name, 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 5938 of file chan_sip.c. References free, and sip_route::next. Referenced by __sip_destroy(), and build_route(). 05939 { 05940 struct sip_route *next; 05941 while (route) { 05942 next = route->next; 05943 free(route); 05944 route = next; 05945 } 05946 }
|
|
function_check_sipdomain: Dial plan function to check if domain is local
Definition at line 9186 of file chan_sip.c. References ast_log(), ast_strlen_zero(), check_sip_domain(), and LOG_WARNING. 09187 { 09188 if (ast_strlen_zero(data)) { 09189 ast_log(LOG_WARNING, "CHECKSIPDOMAIN requires an argument - A domain name\n"); 09190 return buf; 09191 } 09192 if (check_sip_domain(data, NULL, 0)) 09193 ast_copy_string(buf, data, len); 09194 else 09195 buf[0] = '\0'; 09196 return buf; 09197 }
|
|
func_header_read: Read SIP header (dialplan function)
Definition at line 9139 of file chan_sip.c. References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_strlen_zero(), get_header(), sip_pvt::initreq, ast_channel::lock, LOG_WARNING, ast_channel::tech_pvt, and ast_channel::type. 09140 { 09141 struct sip_pvt *p; 09142 char *content; 09143 09144 if (!data) { 09145 ast_log(LOG_WARNING, "This function requires a header name.\n"); 09146 return NULL; 09147 } 09148 09149 ast_mutex_lock(&chan->lock); 09150 if (chan->type != channeltype) { 09151 ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n"); 09152 ast_mutex_unlock(&chan->lock); 09153 return NULL; 09154 } 09155 09156 p = chan->tech_pvt; 09157 09158 /* If there is no private structure, this channel is no longer alive */ 09159 if (!p) { 09160 ast_mutex_unlock(&chan->lock); 09161 return NULL; 09162 } 09163 09164 content = get_header(&p->initreq, data); 09165 09166 if (ast_strlen_zero(content)) { 09167 ast_mutex_unlock(&chan->lock); 09168 return NULL; 09169 } 09170 09171 ast_copy_string(buf, content, len); 09172 ast_mutex_unlock(&chan->lock); 09173 09174 return buf; 09175 }
|
|
function_sipchaninfo_read: ${SIPCHANINFO()} Dialplan function - reads sip channel data
Definition at line 9310 of file chan_sip.c. References ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), 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. 09311 { 09312 struct sip_pvt *p; 09313 char iabuf[INET_ADDRSTRLEN]; 09314 09315 *buf = 0; 09316 09317 if (!data) { 09318 ast_log(LOG_WARNING, "This function requires a parameter name.\n"); 09319 return NULL; 09320 } 09321 09322 ast_mutex_lock(&chan->lock); 09323 if (chan->type != channeltype) { 09324 ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n"); 09325 ast_mutex_unlock(&chan->lock); 09326 return NULL; 09327 } 09328 09329 /* ast_verbose("function_sipchaninfo_read: %s\n", data); */ 09330 p = chan->tech_pvt; 09331 09332 /* If there is no private structure, this channel is no longer alive */ 09333 if (!p) { 09334 ast_mutex_unlock(&chan->lock); 09335 return NULL; 09336 } 09337 09338 if (!strcasecmp(data, "peerip")) { 09339 ast_copy_string(buf, p->sa.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr) : "", len); 09340 } else if (!strcasecmp(data, "recvip")) { 09341 ast_copy_string(buf, p->recv.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), p->recv.sin_addr) : "", len); 09342 } else if (!strcasecmp(data, "from")) { 09343 ast_copy_string(buf, p->from, len); 09344 } else if (!strcasecmp(data, "uri")) { 09345 ast_copy_string(buf, p->uri, len); 09346 } else if (!strcasecmp(data, "useragent")) { 09347 ast_copy_string(buf, p->useragent, len); 09348 } else if (!strcasecmp(data, "peername")) { 09349 ast_copy_string(buf, p->peername, len); 09350 } else { 09351 ast_mutex_unlock(&chan->lock); 09352 return NULL; 09353 } 09354 ast_mutex_unlock(&chan->lock); 09355 09356 return buf; 09357 }
|
|
function_sippeer: ${SIPPEER()} Dialplan function - reads peer data
Definition at line 9212 of file chan_sip.c. References 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. 09213 { 09214 char *ret = NULL; 09215 struct sip_peer *peer; 09216 char *peername, *colname; 09217 char iabuf[INET_ADDRSTRLEN]; 09218 09219 if (!(peername = ast_strdupa(data))) { 09220 ast_log(LOG_ERROR, "Memory Error!\n"); 09221 return ret; 09222 } 09223 09224 if ((colname = strchr(peername, ':'))) { 09225 *colname = '\0'; 09226 colname++; 09227 } else { 09228 colname = "ip"; 09229 } 09230 if (!(peer = find_peer(peername, NULL, 1))) 09231 return ret; 09232 09233 if (!strcasecmp(colname, "ip")) { 09234 ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), peer->addr.sin_addr) : "", len); 09235 } else if (!strcasecmp(colname, "status")) { 09236 peer_status(peer, buf, sizeof(buf)); 09237 } else if (!strcasecmp(colname, "language")) { 09238 ast_copy_string(buf, peer->language, len); 09239 } else if (!strcasecmp(colname, "regexten")) { 09240 ast_copy_string(buf, peer->regexten, len); 09241 } else if (!strcasecmp(colname, "limit")) { 09242 snprintf(buf, len, "%d", peer->call_limit); 09243 } else if (!strcasecmp(colname, "curcalls")) { 09244 snprintf(buf, len, "%d", peer->inUse); 09245 } else if (!strcasecmp(colname, "useragent")) { 09246 ast_copy_string(buf, peer->useragent, len); 09247 } else if (!strcasecmp(colname, "mailbox")) { 09248 ast_copy_string(buf, peer->mailbox, len); 09249 } else if (!strcasecmp(colname, "context")) { 09250 ast_copy_string(buf, peer->context, len); 09251 } else if (!strcasecmp(colname, "expire")) { 09252 snprintf(buf, len, "%d", peer->expire); 09253 } else if (!strcasecmp(colname, "dynamic")) { 09254 ast_copy_string(buf, (ast_test_flag(peer, SIP_DYNAMIC) ? "yes" : "no"), len); 09255 } else if (!strcasecmp(colname, "callerid_name")) { 09256 ast_copy_string(buf, peer->cid_name, len); 09257 } else if (!strcasecmp(colname, "callerid_num")) { 09258 ast_copy_string(buf, peer->cid_num, len); 09259 } else if (!strcasecmp(colname, "codecs")) { 09260 ast_getformatname_multiple(buf, len -1, peer->capability); 09261 } else if (!strncasecmp(colname, "codec[", 6)) { 09262 char *codecnum, *ptr; 09263 int index = 0, codec = 0; 09264 09265 codecnum = strchr(colname, '['); 09266 *codecnum = '\0'; 09267 codecnum++; 09268 if ((ptr = strchr(codecnum, ']'))) { 09269 *ptr = '\0'; 09270 } 09271 index = atoi(codecnum); 09272 if((codec = ast_codec_pref_index(&peer->prefs, index))) { 09273 ast_copy_string(buf, ast_getformatname(codec), len); 09274 } 09275 } 09276 ret = buf; 09277 09278 ASTOBJ_UNREF(peer, sip_destroy_peer); 09279 09280 return ret; 09281 }
|
|
get_also_info: Call transfer support (old way, depreciated)--
Definition at line 6766 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(). 06767 { 06768 char tmp[256], *c, *a; 06769 struct sip_request *req; 06770 06771 req = oreq; 06772 if (!req) 06773 req = &p->initreq; 06774 ast_copy_string(tmp, get_header(req, "Also"), sizeof(tmp)); 06775 06776 c = get_in_brackets(tmp); 06777 06778 06779 if (strncmp(c, "sip:", 4)) { 06780 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", c); 06781 return -1; 06782 } 06783 c += 4; 06784 if ((a = strchr(c, '@'))) 06785 *a = '\0'; 06786 if ((a = strchr(c, ';'))) 06787 *a = '\0'; 06788 06789 if (sip_debug_test_pvt(p)) { 06790 ast_verbose("Looking for %s in %s\n", c, p->context); 06791 } 06792 if (ast_exists_extension(NULL, p->context, c, 1, NULL)) { 06793 /* This is an unsupervised transfer */ 06794 ast_log(LOG_DEBUG,"Assigning Extension %s to REFER-TO\n", c); 06795 ast_copy_string(p->refer_to, c, sizeof(p->refer_to)); 06796 ast_copy_string(p->referred_by, "", sizeof(p->referred_by)); 06797 ast_copy_string(p->refer_contact, "", sizeof(p->refer_contact)); 06798 p->refer_call = NULL; 06799 return 0; 06800 } else if (ast_canmatch_extension(NULL, p->context, c, 1, NULL)) { 06801 return 1; 06802 } 06803 06804 return -1; 06805 }
|
|
get_calleridname: Get caller id name from SIP headers ---
Definition at line 6857 of file chan_sip.c. Referenced by check_user_full(). 06858 { 06859 char *end = strchr(input,'<'); 06860 char *tmp = strchr(input,'\"'); 06861 int bytes = 0; 06862 int maxbytes = outputsize - 1; 06863 06864 if (!end || (end == input)) return NULL; 06865 /* move away from "<" */ 06866 end--; 06867 /* we found "name" */ 06868 if (tmp && tmp < end) { 06869 end = strchr(tmp+1, '\"'); 06870 if (!end) return NULL; 06871 bytes = (int) (end - tmp); 06872 /* protect the output buffer */ 06873 if (bytes > maxbytes) 06874 bytes = maxbytes; 06875 ast_copy_string(output, tmp + 1, bytes); 06876 } else { 06877 /* we didn't find "name" */ 06878 /* clear the empty characters in the begining*/ 06879 input = ast_skip_blanks(input); 06880 /* clear the empty characters in the end */ 06881 while(*end && (*end < 33) && end > input) 06882 end--; 06883 if (end >= input) { 06884 bytes = (int) (end - input) + 2; 06885 /* protect the output buffer */ 06886 if (bytes > maxbytes) { 06887 bytes = maxbytes; 06888 } 06889 ast_copy_string(output, input, bytes); 06890 } 06891 else 06892 return NULL; 06893 } 06894 return output; 06895 }
|
|
get_destination: Find out who the call is for --
Definition at line 6504 of file chan_sip.c. References allow_external_domains, ast_canmatch_extension(), ast_exists_extension(), AST_LIST_EMPTY, ast_log(), 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, sip_request::rlPart2, sip_debug_test_pvt(), SIP_INVITE, and sip_methods. Referenced by handle_request_invite(), handle_request_options(), and handle_request_subscribe(). 06505 { 06506 char tmp[256] = "", *uri, *a; 06507 char tmpf[256], *from; 06508 struct sip_request *req; 06509 06510 req = oreq; 06511 if (!req) 06512 req = &p->initreq; 06513 if (req->rlPart2) 06514 ast_copy_string(tmp, req->rlPart2, sizeof(tmp)); 06515 uri = get_in_brackets(tmp); 06516 06517 ast_copy_string(tmpf, get_header(req, "From"), sizeof(tmpf)); 06518 06519 from = get_in_brackets(tmpf); 06520 06521 if (strncmp(uri, "sip:", 4)) { 06522 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", uri); 06523 return -1; 06524 } 06525 uri += 4; 06526 if (!ast_strlen_zero(from)) { 06527 if (strncmp(from, "sip:", 4)) { 06528 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", from); 06529 return -1; 06530 } 06531 from += 4; 06532 } else 06533 from = NULL; 06534 06535 if (pedanticsipchecking) { 06536 ast_uri_decode(uri); 06537 ast_uri_decode(from); 06538 } 06539 06540 /* Get the target domain */ 06541 if ((a = strchr(uri, '@'))) { 06542 char *colon; 06543 *a = '\0'; 06544 a++; 06545 colon = strchr(a, ':'); /* Remove :port */ 06546 if (colon) 06547 *colon = '\0'; 06548 ast_copy_string(p->domain, a, sizeof(p->domain)); 06549 } 06550 /* Skip any options */ 06551 if ((a = strchr(uri, ';'))) { 06552 *a = '\0'; 06553 } 06554 06555 if (!AST_LIST_EMPTY(&domain_list)) { 06556 char domain_context[AST_MAX_EXTENSION]; 06557 06558 domain_context[0] = '\0'; 06559 if (!check_sip_domain(p->domain, domain_context, sizeof(domain_context))) { 06560 if (!allow_external_domains && (req->method == SIP_INVITE || req->method == SIP_REFER)) { 06561 ast_log(LOG_DEBUG, "Got SIP %s to non-local domain '%s'; refusing request.\n", sip_methods[req->method].text, p->domain); 06562 return -2; 06563 } 06564 } 06565 /* If we have a context defined, overwrite the original context */ 06566 if (!ast_strlen_zero(domain_context)) 06567 ast_copy_string(p->context, domain_context, sizeof(p->context)); 06568 } 06569 06570 if (from) { 06571 if ((a = strchr(from, ';'))) 06572 *a = '\0'; 06573 if ((a = strchr(from, '@'))) { 06574 *a = '\0'; 06575 ast_copy_string(p->fromdomain, a + 1, sizeof(p->fromdomain)); 06576 } else 06577 ast_copy_string(p->fromdomain, from, sizeof(p->fromdomain)); 06578 } 06579 if (sip_debug_test_pvt(p)) 06580 ast_verbose("Looking for %s in %s (domain %s)\n", uri, p->context, p->domain); 06581 06582 /* Return 0 if we have a matching extension */ 06583 if (ast_exists_extension(NULL, p->context, uri, 1, from) || 06584 !strcmp(uri, ast_pickup_ext())) { 06585 if (!oreq) 06586 ast_copy_string(p->exten, uri, sizeof(p->exten)); 06587 return 0; 06588 } 06589 06590 /* Return 1 for overlap dialling support */ 06591 if (ast_canmatch_extension(NULL, p->context, uri, 1, from) || 06592 !strncmp(uri, ast_pickup_ext(),strlen(uri))) { 06593 return 1; 06594 } 06595 06596 return -1; 06597 }
|
|
|
get_in_brackets: Pick out text in brackets from character string ---
Definition at line 1532 of file chan_sip.c. References ast_log(), and LOG_WARNING. 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 7201 of file chan_sip.c. References sip_request::line, and sip_request::lines. Referenced by receive_message(). 07202 { 07203 int x; 07204 int y; 07205 07206 buf[0] = '\0'; 07207 y = len - strlen(buf) - 5; 07208 if (y < 0) 07209 y = 0; 07210 for (x=0;x<req->lines;x++) { 07211 strncat(buf, req->line[x], y); /* safe */ 07212 y -= strlen(req->line[x]) + 1; 07213 if (y < 0) 07214 y = 0; 07215 if (y != 0) 07216 strcat(buf, "\n"); /* safe */ 07217 } 07218 return 0; 07219 }
|
|
get_rdnis: get referring dnis ---
Definition at line 6476 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(). 06477 { 06478 char tmp[256], *c, *a; 06479 struct sip_request *req; 06480 06481 req = oreq; 06482 if (!req) 06483 req = &p->initreq; 06484 ast_copy_string(tmp, get_header(req, "Diversion"), sizeof(tmp)); 06485 if (ast_strlen_zero(tmp)) 06486 return 0; 06487 c = get_in_brackets(tmp); 06488 if (strncmp(c, "sip:", 4)) { 06489 ast_log(LOG_WARNING, "Huh? Not an RDNIS SIP header (%s)?\n", c); 06490 return -1; 06491 } 06492 c += 4; 06493 if ((a = strchr(c, '@')) || (a = strchr(c, ';'))) { 06494 *a = '\0'; 06495 } 06496 if (sip_debug_test_pvt(p)) 06497 ast_verbose("RDNIS is %s\n", c); 06498 ast_copy_string(p->rdnis, c, sizeof(p->rdnis)); 06499 06500 return 0; 06501 }
|
|
get_refer_info: Call transfer support (the REFER method) ---
Definition at line 6629 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(), 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(). 06630 { 06631 06632 char *p_refer_to = NULL, *p_referred_by = NULL, *h_refer_to = NULL, *h_referred_by = NULL, *h_contact = NULL; 06633 char *replace_callid = "", *refer_to = NULL, *referred_by = NULL, *ptr = NULL; 06634 struct sip_request *req = NULL; 06635 struct sip_pvt *sip_pvt_ptr = NULL; 06636 struct ast_channel *chan = NULL, *peer = NULL; 06637 06638 req = outgoing_req; 06639 06640 if (!req) { 06641 req = &sip_pvt->initreq; 06642 } 06643 06644 if (!( (p_refer_to = get_header(req, "Refer-To")) && (h_refer_to = ast_strdupa(p_refer_to)) )) { 06645 ast_log(LOG_WARNING, "No Refer-To Header That's illegal\n"); 06646 return -1; 06647 } 06648 06649 refer_to = get_in_brackets(h_refer_to); 06650 06651 if (!( (p_referred_by = get_header(req, "Referred-By")) && (h_referred_by = ast_strdupa(p_referred_by)) )) { 06652 ast_log(LOG_WARNING, "No Referrred-By Header That's not illegal\n"); 06653 return -1; 06654 } else { 06655 if (pedanticsipchecking) { 06656 ast_uri_decode(h_referred_by); 06657 } 06658 referred_by = get_in_brackets(h_referred_by); 06659 } 06660 h_contact = get_header(req, "Contact"); 06661 06662 if (strncmp(refer_to, "sip:", 4)) { 06663 ast_log(LOG_WARNING, "Refer-to: Huh? Not a SIP header (%s)?\n", refer_to); 06664 return -1; 06665 } 06666 06667 if (strncmp(referred_by, "sip:", 4)) { 06668 ast_log(LOG_WARNING, "Referred-by: Huh? Not a SIP header (%s) Ignoring?\n", referred_by); 06669 referred_by = NULL; 06670 } 06671 06672 if (refer_to) 06673 refer_to += 4; 06674 06675 if (referred_by) 06676 referred_by += 4; 06677 06678 if ((ptr = strchr(refer_to, '?'))) { 06679 /* Search for arguments */ 06680 *ptr = '\0'; 06681 ptr++; 06682 if (!strncasecmp(ptr, "REPLACES=", 9)) { 06683 char *p; 06684 replace_callid = ast_strdupa(ptr + 9); 06685 /* someday soon to support invite/replaces properly! 06686 replaces_header = ast_strdupa(replace_callid); 06687 -anthm 06688 */ 06689 ast_uri_decode(replace_callid); 06690 if ((ptr = strchr(replace_callid, '%'))) 06691 *ptr = '\0'; 06692 if ((ptr = strchr(replace_callid, ';'))) 06693 *ptr = '\0'; 06694 /* Skip leading whitespace XXX memmove behaviour with overlaps ? */ 06695 p = ast_skip_blanks(replace_callid); 06696 if (p != replace_callid) 06697 memmove(replace_callid, p, strlen(p)); 06698 } 06699 } 06700 06701 if ((ptr = strchr(refer_to, '@'))) /* Skip domain (should be saved in SIPDOMAIN) */ 06702 *ptr = '\0'; 06703 if ((ptr = strchr(refer_to, ';'))) 06704 *ptr = '\0'; 06705 06706 if (referred_by) { 06707 if ((ptr = strchr(referred_by, '@'))) 06708 *ptr = '\0'; 06709 if ((ptr = strchr(referred_by, ';'))) 06710 *ptr = '\0'; 06711 } 06712 06713 if (sip_debug_test_pvt(sip_pvt)) { 06714 ast_verbose("Transfer to %s in %s\n", refer_to, sip_pvt->context); 06715 if (referred_by) 06716 ast_verbose("Transfer from %s in %s\n", referred_by, sip_pvt->context); 06717 } 06718 if (!ast_strlen_zero(replace_callid)) { 06719 /* This is a supervised transfer */ 06720 ast_log(LOG_DEBUG,"Assigning Replace-Call-ID Info %s to REPLACE_CALL_ID\n",replace_callid); 06721 06722 ast_copy_string(sip_pvt->refer_to, "", sizeof(sip_pvt->refer_to)); 06723 ast_copy_string(sip_pvt->referred_by, "", sizeof(sip_pvt->referred_by)); 06724 ast_copy_string(sip_pvt->refer_contact, "", sizeof(sip_pvt->refer_contact)); 06725 sip_pvt->refer_call = NULL; 06726 if ((sip_pvt_ptr = get_sip_pvt_byid_locked(replace_callid))) { 06727 sip_pvt->refer_call = sip_pvt_ptr; 06728 if (sip_pvt->refer_call == sip_pvt) { 06729 ast_log(LOG_NOTICE, "Supervised transfer attempted to transfer into same call id (%s == %s)!\n", replace_callid, sip_pvt->callid); 06730 sip_pvt->refer_call = NULL; 06731 } else 06732 return 0; 06733 } else { 06734 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); 06735 /* XXX The refer_to could contain a call on an entirely different machine, requiring an 06736 INVITE with a replaces header -anthm XXX */ 06737 /* The only way to find out is to use the dialplan - oej */ 06738 } 06739 } else if (ast_exists_extension(NULL, sip_pvt->context, refer_to, 1, NULL) || !strcmp(refer_to, ast_parking_ext())) { 06740 /* This is an unsupervised transfer (blind transfer) */ 06741 06742 ast_log(LOG_DEBUG,"Unsupervised transfer to (Refer-To): %s\n", refer_to); 06743 if (referred_by) 06744 ast_log(LOG_DEBUG,"Transferred by (Referred-by: ) %s \n", referred_by); 06745 ast_log(LOG_DEBUG,"Transfer Contact Info %s (REFER_CONTACT)\n", h_contact); 06746 ast_copy_string(sip_pvt->refer_to, refer_to, sizeof(sip_pvt->refer_to)); 06747 if (referred_by) 06748 ast_copy_string(sip_pvt->referred_by, referred_by, sizeof(sip_pvt->referred_by)); 06749 if (h_contact) { 06750 ast_copy_string(sip_pvt->refer_contact, h_contact, sizeof(sip_pvt->refer_contact)); 06751 } 06752 sip_pvt->refer_call = NULL; 06753 if ((chan = sip_pvt->owner) && (peer = ast_bridged_channel(sip_pvt->owner))) { 06754 pbx_builtin_setvar_helper(chan, "BLINDTRANSFER", peer->name); 06755 pbx_builtin_setvar_helper(peer, "BLINDTRANSFER", chan->name); 06756 } 06757 return 0; 06758 } else if (ast_canmatch_extension(NULL, sip_pvt->context, refer_to, 1, NULL)) { 06759 return 1; 06760 } 06761 06762 return -1; 06763 }
|
|
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 6901 of file chan_sip.c. Referenced by check_user_full(). 06902 { 06903 char *start; 06904 char *end; 06905 06906 start = strchr(input,':'); 06907 if (!start) { 06908 output[0] = '\0'; 06909 return 0; 06910 } 06911 start++; 06912 06913 /* we found "number" */ 06914 ast_copy_string(output,start,maxlen); 06915 output[maxlen-1] = '\0'; 06916 06917 end = strchr(output,'@'); 06918 if (end) 06919 *end = '\0'; 06920 else 06921 output[0] = '\0'; 06922 if (strstr(input,"privacy=full") || strstr(input,"privacy=uri")) 06923 return AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED; 06924 06925 return 0; 06926 }
|
|
get_sdp: Gets all kind of SIP message bodies, including SDP, but the name wrongly applies _only_ sdp
Definition at line 2849 of file chan_sip.c. References get_sdp_by_line(), sip_request::line, sip_request::lines, and name. Referenced by handle_request_info(), and process_sdp(). 02850 { 02851 int x; 02852 int len = strlen(name); 02853 char *r; 02854 02855 for (x=0; x<req->lines; x++) { 02856 r = get_sdp_by_line(req->line[x], name, len); 02857 if (r[0] != '\0') 02858 return r; 02859 } 02860 return ""; 02861 }
|
|
get_sdp_by_line: Reads one line of SIP message body
Definition at line 2839 of file chan_sip.c. References name. Referenced by get_sdp(), and get_sdp_iterate(). 02840 { 02841 if (strncasecmp(line, name, nameLen) == 0 && line[nameLen] == '=') { 02842 return ast_skip_blanks(line + nameLen + 1); 02843 } 02844 return ""; 02845 }
|
|
Definition at line 2869 of file chan_sip.c. References get_sdp_by_line(), sip_request::line, sip_request::lines, and name. Referenced by process_sdp(). 02871 { 02872 int len = strlen(name); 02873 char *r; 02874 02875 while (*iterator < req->lines) { 02876 r = get_sdp_by_line(req->line[(*iterator)++], name, len); 02877 if (r[0] != '\0') 02878 return r; 02879 } 02880 return ""; 02881 }
|
|
get_sip_pvt_byid_locked: Lock interface lock and find matching pvt lock ---
Definition at line 6600 of file chan_sip.c. References ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), sip_pvt::callid, ast_channel::lock, sip_pvt::lock, sip_pvt::next, and sip_pvt::owner. Referenced by get_refer_info(). 06601 { 06602 struct sip_pvt *sip_pvt_ptr = NULL; 06603 06604 /* Search interfaces and find the match */ 06605 ast_mutex_lock(&iflock); 06606 sip_pvt_ptr = iflist; 06607 while(sip_pvt_ptr) { 06608 if (!strcmp(sip_pvt_ptr->callid, callid)) { 06609 /* Go ahead and lock it (and its owner) before returning */ 06610 ast_mutex_lock(&sip_pvt_ptr->lock); 06611 if (sip_pvt_ptr->owner) { 06612 while(ast_mutex_trylock(&sip_pvt_ptr->owner->lock)) { 06613 ast_mutex_unlock(&sip_pvt_ptr->lock); 06614 usleep(1); 06615 ast_mutex_lock(&sip_pvt_ptr->lock); 06616 if (!sip_pvt_ptr->owner) 06617 break; 06618 } 06619 } 06620 break; 06621 } 06622 sip_pvt_ptr = sip_pvt_ptr->next; 06623 } 06624 ast_mutex_unlock(&iflock); 06625 return sip_pvt_ptr; 06626 }
|
|
gettag: Get tag from packet
Definition at line 10184 of file chan_sip.c. References get_header(), and strcasestr(). Referenced by find_call(), handle_request(), and handle_response(). 10185 { 10186 10187 char *thetag, *sep; 10188 10189 10190 if (!tagbuf) 10191 return NULL; 10192 tagbuf[0] = '\0'; /* reset the buffer */ 10193 thetag = get_header(req, header); 10194 thetag = strcasestr(thetag, ";tag="); 10195 if (thetag) { 10196 thetag += 5; 10197 ast_copy_string(tagbuf, thetag, tagbufsize); 10198 sep = strchr(tagbuf, ';'); 10199 if (sep) 10200 *sep = '\0'; 10201 } 10202 return thetag; 10203 }
|
|
handle_common_options: Handle flag-type options common to users and peers ---
Definition at line 11586 of file chan_sip.c. References ast_clear_flag, ast_false(), ast_log(), ast_set2_flag, ast_set_flag, ast_true(), global_allowguest, ast_variable::lineno, LOG_WARNING, ast_variable::name, 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(). 11587 { 11588 int res = 0; 11589 11590 if (!strcasecmp(v->name, "trustrpid")) { 11591 ast_set_flag(mask, SIP_TRUSTRPID); 11592 ast_set2_flag(flags, ast_true(v->value), SIP_TRUSTRPID); 11593 res = 1; 11594 } else if (!strcasecmp(v->name, "sendrpid")) { 11595 ast_set_flag(mask, SIP_SENDRPID); 11596 ast_set2_flag(flags, ast_true(v->value), SIP_SENDRPID); 11597 res = 1; 11598 } else if (!strcasecmp(v->name, "useclientcode")) { 11599 ast_set_flag(mask, SIP_USECLIENTCODE); 11600 ast_set2_flag(flags, ast_true(v->value), SIP_USECLIENTCODE); 11601 res = 1; 11602 } else if (!strcasecmp(v->name, "dtmfmode")) { 11603 ast_set_flag(mask, SIP_DTMF); 11604 ast_clear_flag(flags, SIP_DTMF); 11605 if (!strcasecmp(v->value, "inband")) 11606 ast_set_flag(flags, SIP_DTMF_INBAND); 11607 else if (!strcasecmp(v->value, "rfc2833")) 11608 ast_set_flag(flags, SIP_DTMF_RFC2833); 11609 else if (!strcasecmp(v->value, "info")) 11610 ast_set_flag(flags, SIP_DTMF_INFO); 11611 else if (!strcasecmp(v->value, "auto")) 11612 ast_set_flag(flags, SIP_DTMF_AUTO); 11613 else { 11614 ast_log(LOG_WARNING, "Unknown dtmf mode '%s' on line %d, using rfc2833\n", v->value, v->lineno); 11615 ast_set_flag(flags, SIP_DTMF_RFC2833); 11616 } 11617 } else if (!strcasecmp(v->name, "nat")) { 11618 ast_set_flag(mask, SIP_NAT); 11619 ast_clear_flag(flags, SIP_NAT); 11620 if (!strcasecmp(v->value, "never")) 11621 ast_set_flag(flags, SIP_NAT_NEVER); 11622 else if (!strcasecmp(v->value, "route")) 11623 ast_set_flag(flags, SIP_NAT_ROUTE); 11624 else if (ast_true(v->value)) 11625 ast_set_flag(flags, SIP_NAT_ALWAYS); 11626 else 11627 ast_set_flag(flags, SIP_NAT_RFC3581); 11628 } else if (!strcasecmp(v->name, "canreinvite")) { 11629 ast_set_flag(mask, SIP_REINVITE); 11630 ast_clear_flag(flags, SIP_REINVITE); 11631 if (!strcasecmp(v->value, "update")) 11632 ast_set_flag(flags, SIP_REINVITE_UPDATE | SIP_CAN_REINVITE); 11633 else 11634 ast_set2_flag(flags, ast_true(v->value), SIP_CAN_REINVITE); 11635 } else if (!strcasecmp(v->name, "insecure")) { 11636 ast_set_flag(mask, SIP_INSECURE_PORT | SIP_INSECURE_INVITE); 11637 ast_clear_flag(flags, SIP_INSECURE_PORT | SIP_INSECURE_INVITE); 11638 if (!strcasecmp(v->value, "very")) 11639 ast_set_flag(flags, SIP_INSECURE_PORT | SIP_INSECURE_INVITE); 11640 else if (ast_true(v->value)) 11641 ast_set_flag(flags, SIP_INSECURE_PORT); 11642 else if (!ast_false(v->value)) { 11643 char buf[64]; 11644 char *word, *next; 11645 11646 ast_copy_string(buf, v->value, sizeof(buf)); 11647 next = buf; 11648 while ((word = strsep(&next, ","))) { 11649 if (!strcasecmp(word, "port")) 11650 ast_set_flag(flags, SIP_INSECURE_PORT); 11651 else if (!strcasecmp(word, "invite")) 11652 ast_set_flag(flags, SIP_INSECURE_INVITE); 11653 else 11654 ast_log(LOG_WARNING, "Unknown insecure mode '%s' on line %d\n", v->value, v->lineno); 11655 } 11656 } 11657 } else if (!strcasecmp(v->name, "progressinband")) { 11658 ast_set_flag(mask, SIP_PROG_INBAND); 11659 ast_clear_flag(flags, SIP_PROG_INBAND); 11660 if (ast_true(v->value)) 11661 ast_set_flag(flags, SIP_PROG_INBAND_YES); 11662 else if (strcasecmp(v->value, "never")) 11663 ast_set_flag(flags, SIP_PROG_INBAND_NO); 11664 } else if (!strcasecmp(v->name, "allowguest")) { 11665 #ifdef OSP_SUPPORT 11666 if (!strcasecmp(v->value, "osp")) 11667 global_allowguest = 2; 11668 else 11669 #endif 11670 if (ast_true(v->value)) 11671 global_allowguest = 1; 11672 else 11673 global_allowguest = 0; 11674 #ifdef OSP_SUPPORT 11675 } else if (!strcasecmp(v->name, "ospauth")) { 11676 ast_set_flag(mask, SIP_OSPAUTH); 11677 ast_clear_flag(flags, SIP_OSPAUTH); 11678 if (!strcasecmp(v->value, "proxy")) 11679 ast_set_flag(flags, SIP_OSPAUTH_PROXY); 11680 else if (!strcasecmp(v->value, "gateway")) 11681 ast_set_flag(flags, SIP_OSPAUTH_GATEWAY); 11682 else if(!strcasecmp (v->value, "exclusive")) 11683 ast_set_flag(flags, SIP_OSPAUTH_EXCLUSIVE); 11684 #endif 11685 } else if (!strcasecmp(v->name, "promiscredir")) { 11686 ast_set_flag(mask, SIP_PROMISCREDIR); 11687 ast_set2_flag(flags, ast_true(v->value), SIP_PROMISCREDIR); 11688 res = 1; 11689 } 11690 11691 return res; 11692 }
|
|
handle_request: Handle SIP requests (methods) ---
Definition at line 10865 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(), 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, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, LOG_WARNING, sip_pvt::method, sip_request::method, sip_pvt::ocseq, option_debug, 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_SUBSCRIBE, sip_pvt::theirtag, transmit_response(), transmit_response_reliable(), transmit_response_with_allow(), and sip_pvt::useragent. Referenced by mgcpsock_read(), and sipsock_read(). 10866 { 10867 /* Called with p->lock held, as well as p->owner->lock if appropriate, keeping things 10868 relatively static */ 10869 struct sip_request resp; 10870 char *cmd; 10871 char *cseq; 10872 char *useragent; 10873 int seqno; 10874 int len; 10875 int ignore=0; 10876 int respid; 10877 int res = 0; 10878 char iabuf[INET_ADDRSTRLEN]; 10879 int debug = sip_debug_test_pvt(p); 10880 char *e; 10881 int error = 0; 10882 10883 /* Clear out potential response */ 10884 memset(&resp, 0, sizeof(resp)); 10885 10886 /* Get Method and Cseq */ 10887 cseq = get_header(req, "Cseq"); 10888 cmd = req->header[0]; 10889 10890 /* Must have Cseq */ 10891 if (ast_strlen_zero(cmd) || ast_strlen_zero(cseq)) { 10892 ast_log(LOG_ERROR, "Missing Cseq. Dropping this SIP message, it's incomplete.\n"); 10893 error = 1; 10894 } 10895 if (!error && sscanf(cseq, "%d%n", &seqno, &len) != 1) { 10896 ast_log(LOG_ERROR, "No seqno in '%s'. Dropping incomplete message.\n", cmd); 10897 error = 1; 10898 } 10899 if (error) { 10900 if (!p->initreq.header) /* New call */ 10901 ast_set_flag(p, SIP_NEEDDESTROY); /* Make sure we destroy this dialog */ 10902 return -1; 10903 } 10904 /* Get the command XXX */ 10905 10906 cmd = req->rlPart1; 10907 e = req->rlPart2; 10908 10909 /* Save useragent of the client */ 10910 useragent = get_header(req, "User-Agent"); 10911 if (!ast_strlen_zero(useragent)) 10912 ast_copy_string(p->useragent, useragent, sizeof(p->useragent)); 10913 10914 /* Find out SIP method for incoming request */ 10915 if (req->method == SIP_RESPONSE) { /* Response to our request */ 10916 /* Response to our request -- Do some sanity checks */ 10917 if (!p->initreq.headers) { 10918 ast_log(LOG_DEBUG, "That's odd... Got a response on a call we dont know about. Cseq %d Cmd %s\n", seqno, cmd); 10919 ast_set_flag(p, SIP_NEEDDESTROY); 10920 return 0; 10921 } else if (p->ocseq && (p->ocseq < seqno)) { 10922 ast_log(LOG_DEBUG, "Ignoring out of order response %d (expecting %d)\n", seqno, p->ocseq); 10923 return -1; 10924 } else if (p->ocseq && (p->ocseq != seqno)) { 10925 /* ignore means "don't do anything with it" but still have to 10926 respond appropriately */ 10927 ignore=1; 10928 } 10929 10930 e = ast_skip_blanks(e); 10931 if (sscanf(e, "%d %n", &respid, &len) != 1) { 10932 ast_log(LOG_WARNING, "Invalid response: '%s'\n", e); 10933 } else { 10934 /* More SIP ridiculousness, we have to ignore bogus contacts in 100 etc responses */ 10935 if ((respid == 200) || ((respid >= 300) && (respid <= 399))) 10936 extract_uri(p, req); 10937 handle_response(p, respid, e + len, req, ignore, seqno); 10938 } 10939 return 0; 10940 } 10941 10942 /* New SIP request coming in 10943 (could be new request in existing SIP dialog as well...) 10944 */ 10945 10946 p->method = req->method; /* Find out which SIP method they are using */ 10947 if (option_debug > 2) 10948 ast_log(LOG_DEBUG, "**** Received %s (%d) - Command in SIP %s\n", sip_methods[p->method].text, sip_methods[p->method].id, cmd); 10949 10950 if (p->icseq && (p->icseq > seqno)) { 10951 if (option_debug) 10952 ast_log(LOG_DEBUG, "Ignoring too old SIP packet packet %d (expecting >= %d)\n", seqno, p->icseq); 10953 if (req->method != SIP_ACK) 10954 transmit_response(p, "503 Server error", req); /* We must respond according to RFC 3261 sec 12.2 */ 10955 return -1; 10956 } else if (p->icseq && (p->icseq == seqno) && req->method != SIP_ACK &&(p->method != SIP_CANCEL|| ast_test_flag(p, SIP_ALREADYGONE))) { 10957 /* ignore means "don't do anything with it" but still have to 10958 respond appropriately. We do this if we receive a repeat of 10959 the last sequence number */ 10960 ignore=2; 10961 if (option_debug > 2) 10962 ast_log(LOG_DEBUG, "Ignoring SIP message because of retransmit (%s Seqno %d, ours %d)\n", sip_methods[p->method].text, p->icseq, seqno); 10963 } 10964 10965 if (seqno >= p->icseq) 10966 /* Next should follow monotonically (but not necessarily 10967 incrementally -- thanks again to the genius authors of SIP -- 10968 increasing */ 10969 p->icseq = seqno; 10970 10971 /* Find their tag if we haven't got it */ 10972 if (ast_strlen_zero(p->theirtag)) { 10973 gettag(req, "From", p->theirtag, sizeof(p->theirtag)); 10974 } 10975 snprintf(p->lastmsg, sizeof(p->lastmsg), "Rx: %s", cmd); 10976 10977 if (pedanticsipchecking) { 10978 /* If this is a request packet without a from tag, it's not 10979 correct according to RFC 3261 */ 10980 /* Check if this a new request in a new dialog with a totag already attached to it, 10981 RFC 3261 - section 12.2 - and we don't want to mess with recovery */ 10982 if (!p->initreq.headers && ast_test_flag(req, SIP_PKT_WITH_TOTAG)) { 10983 /* If this is a first request and it got a to-tag, it is not for us */ 10984 if (!ignore && req->method == SIP_INVITE) { 10985 transmit_response_reliable(p, "481 Call/Transaction Does Not Exist", req, 1); 10986 /* Will cease to exist after ACK */ 10987 } else { 10988 transmit_response(p, "481 Call/Transaction Does Not Exist", req); 10989 ast_set_flag(p, SIP_NEEDDESTROY); 10990 } 10991 return res; 10992 } 10993 } 10994 10995 /* Handle various incoming SIP methods in requests */ 10996 switch (p->method) { 10997 case SIP_OPTIONS: 10998 res = handle_request_options(p, req, debug); 10999 break; 11000 case SIP_INVITE: 11001 res = handle_request_invite(p, req, debug, ignore, seqno, sin, recount, e); 11002 break; 11003 case SIP_REFER: 11004 res = handle_request_refer(p, req, debug, ignore, seqno, nounlock); 11005 break; 11006 case SIP_CANCEL: 11007 res = handle_request_cancel(p, req, debug, ignore); 11008 break; 11009 case SIP_BYE: 11010 res = handle_request_bye(p, req, debug, ignore); 11011 break; 11012 case SIP_MESSAGE: 11013 res = handle_request_message(p, req, debug, ignore); 11014 break; 11015 case SIP_SUBSCRIBE: 11016 res = handle_request_subscribe(p, req, debug, ignore, sin, seqno, e); 11017 break; 11018 case SIP_REGISTER: 11019 res = handle_request_register(p, req, debug, ignore, sin, e); 11020 break; 11021 case SIP_INFO: 11022 if (!ignore) { 11023 if (debug) 11024 ast_verbose("Receiving INFO!\n"); 11025 handle_request_info(p, req); 11026 } else { /* if ignoring, transmit response */ 11027 transmit_response(p, "200 OK", req); 11028 } 11029 break; 11030 case SIP_NOTIFY: 11031 /* XXX we get NOTIFY's from some servers. WHY?? Maybe we should 11032 look into this someday XXX */ 11033 transmit_response(p, "200 OK", req); 11034 if (!p->lastinvite) 11035 ast_set_flag(p, SIP_NEEDDESTROY); 11036 break; 11037 case SIP_ACK: 11038 /* Make sure we don't ignore this */ 11039 if (seqno == p->pendinginvite) { 11040 p->pendinginvite = 0; 11041 __sip_ack(p, seqno, FLAG_RESPONSE, 0); 11042 if (!ast_strlen_zero(get_header(req, "Content-Type"))) { 11043 if (process_sdp(p, req)) 11044 return -1; 11045 } 11046 check_pendings(p); 11047 } 11048 if (!p->lastinvite && ast_strlen_zero(p->randdata)) 11049 ast_set_flag(p, SIP_NEEDDESTROY); 11050 break; 11051 default: 11052 transmit_response_with_allow(p, "501 Method Not Implemented", req, 0); 11053 ast_log(LOG_NOTICE, "Unknown SIP command '%s' from '%s'\n", 11054 cmd, ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr)); 11055 /* If this is some new method, and we don't have a call, destroy it now */ 11056 if (!p->initreq.headers) 11057 ast_set_flag(p, SIP_NEEDDESTROY); 11058 break; 11059 } 11060 return res; 11061 }
|
|
handle_request_bye: Handle incoming BYE request ---
Definition at line 10585 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(), sip_pvt::context, copy_request(), default_context, get_also_info(), get_header(), sip_pvt::initreq, LOG_NOTICE, LOG_WARNING, sip_pvt::owner, sip_pvt::pendinginvite, sip_pvt::recv, sip_pvt::refer_to, sip_pvt::rtp, SIP_ALREADYGONE, SIP_NEEDDESTROY, SIP_OUTGOING, transmit_response(), transmit_response_reliable(), and sip_pvt::vrtp. Referenced by handle_request(). 10586 { 10587 struct ast_channel *c=NULL; 10588 int res; 10589 struct ast_channel *bridged_to; 10590 char iabuf[INET_ADDRSTRLEN]; 10591 10592 if (p->pendinginvite && !ast_test_flag(p, SIP_OUTGOING) && !ignore) 10593 transmit_response_reliable(p, "487 Request Terminated", &p->initreq, 1); 10594 10595 copy_request(&p->initreq, req); 10596 check_via(p, req); 10597 ast_set_flag(p, SIP_ALREADYGONE); 10598 if (p->rtp) { 10599 /* Immediately stop RTP */ 10600 ast_rtp_stop(p->rtp); 10601 } 10602 if (p->vrtp) { 10603 /* Immediately stop VRTP */ 10604 ast_rtp_stop(p->vrtp); 10605 } 10606 if (!ast_strlen_zero(get_header(req, "Also"))) { 10607 ast_log(LOG_NOTICE, "Client '%s' using deprecated BYE/Also transfer method. Ask vendor to support REFER instead\n", 10608 ast_inet_ntoa(iabuf, sizeof(iabuf), p->recv.sin_addr)); 10609 if (ast_strlen_zero(p->context)) 10610 strcpy(p->context, default_context); 10611 res = get_also_info(p, req); 10612 if (!res) { 10613 c = p->owner; 10614 if (c) { 10615 bridged_to = ast_bridged_channel(c); 10616 if (bridged_to) { 10617 /* Don't actually hangup here... */ 10618 ast_moh_stop(bridged_to); 10619 ast_async_goto(bridged_to, p->context, p->refer_to,1); 10620 } else 10621 ast_queue_hangup(p->owner); 10622 } 10623 } else { 10624 ast_log(LOG_WARNING, "Invalid transfer information from '%s'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), p->recv.sin_addr)); 10625 if (p->owner) 10626 ast_queue_hangup(p->owner); 10627 } 10628 } else if (p->owner) 10629 ast_queue_hangup(p->owner); 10630 else 10631 ast_set_flag(p, SIP_NEEDDESTROY); 10632 transmit_response(p, "200 OK", req); 10633 10634 return 1; 10635 }
|
|
handle_request_cancel: Handle incoming CANCEL request ---
Definition at line 10556 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(). 10557 { 10558 10559 check_via(p, req); 10560 ast_set_flag(p, SIP_ALREADYGONE); 10561 if (p->rtp) { 10562 /* Immediately stop RTP */ 10563 ast_rtp_stop(p->rtp); 10564 } 10565 if (p->vrtp) { 10566 /* Immediately stop VRTP */ 10567 ast_rtp_stop(p->vrtp); 10568 } 10569 if (p->owner) 10570 ast_queue_hangup(p->owner); 10571 else 10572 ast_set_flag(p, SIP_NEEDDESTROY); 10573 if (p->initreq.len > 0) { 10574 if (!ignore) 10575 transmit_response_reliable(p, "487 Request Terminated", &p->initreq, 1); 10576 transmit_response(p, "200 OK", req); 10577 return 1; 10578 } else { 10579 transmit_response(p, "481 Call Leg Does Not Exist", req); 10580 return 0; 10581 } 10582 }
|
|
handle_request_info: Receive SIP INFO Message ---
Definition at line 8585 of file chan_sip.c. References ast_bridged_channel(), ast_cdr_setuserfield(), AST_CONTROL_VIDUPDATE, 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, get_header(), get_sdp(), LOG_WARNING, sip_pvt::owner, SIP_NEEDDESTROY, SIP_USECLIENTCODE, ast_frame::subclass, and transmit_response(). Referenced by handle_request(). 08586 { 08587 char buf[1024]; 08588 unsigned int event; 08589 char *c; 08590 08591 /* Need to check the media/type */ 08592 if (!strcasecmp(get_header(req, "Content-Type"), "application/dtmf-relay") || 08593 !strcasecmp(get_header(req, "Content-Type"), "application/vnd.nortelnetworks.digits")) { 08594 08595 /* Try getting the "signal=" part */ 08596 if (ast_strlen_zero(c = get_sdp(req, "Signal")) && ast_strlen_zero(c = get_sdp(req, "d"))) { 08597 ast_log(LOG_WARNING, "Unable to retrieve DTMF signal from INFO message from %s\n", p->callid); 08598 transmit_response(p, "200 OK", req); /* Should return error */ 08599 return; 08600 } else { 08601 ast_copy_string(buf, c, sizeof(buf)); 08602 } 08603 08604 if (!p->owner) { /* not a PBX call */ 08605 transmit_response(p, "481 Call leg/transaction does not exist", req); 08606 ast_set_flag(p, SIP_NEEDDESTROY); 08607 return; 08608 } 08609 08610 if (ast_strlen_zero(buf)) { 08611 transmit_response(p, "200 OK", req); 08612 return; 08613 } 08614 08615 if (buf[0] == '*') 08616 event = 10; 08617 else if (buf[0] == '#') 08618 event = 11; 08619 else if ((buf[0] >= 'A') && (buf[0] <= 'D')) 08620 event = 12 + buf[0] - 'A'; 08621 else 08622 event = atoi(buf); 08623 if (event == 16) { 08624 /* send a FLASH event */ 08625 struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_FLASH, }; 08626 ast_queue_frame(p->owner, &f); 08627 if (sipdebug) 08628 ast_verbose("* DTMF-relay event received: FLASH\n"); 08629 } else { 08630 /* send a DTMF event */ 08631 struct ast_frame f = { AST_FRAME_DTMF, }; 08632 if (event < 10) { 08633 f.subclass = '0' + event; 08634 } else if (event < 11) { 08635 f.subclass = '*'; 08636 } else if (event < 12) { 08637 f.subclass = '#'; 08638 } else if (event < 16) { 08639 f.subclass = 'A' + (event - 12); 08640 } 08641 ast_queue_frame(p->owner, &f); 08642 if (sipdebug) 08643 ast_verbose("* DTMF-relay event received: %c\n", f.subclass); 08644 } 08645 transmit_response(p, "200 OK", req); 08646 return; 08647 } else if (!strcasecmp(get_header(req, "Content-Type"), "application/media_control+xml")) { 08648 /* Eh, we'll just assume it's a fast picture update for now */ 08649 if (p->owner) 08650 ast_queue_control(p->owner, AST_CONTROL_VIDUPDATE); 08651 transmit_response(p, "200 OK", req); 08652 return; 08653 } else if ((c = get_header(req, "X-ClientCode"))) { 08654 /* Client code (from SNOM phone) */ 08655 if (ast_test_flag(p, SIP_USECLIENTCODE)) { 08656 if (p->owner && p->owner->cdr) 08657 ast_cdr_setuserfield(p->owner, c); 08658 if (p->owner && ast_bridged_channel(p->owner) && ast_bridged_channel(p->owner)->cdr) 08659 ast_cdr_setuserfield(ast_bridged_channel(p->owner), c); 08660 transmit_response(p, "200 OK", req); 08661 } else { 08662 transmit_response(p, "403 Unauthorized", req); 08663 } 08664 return; 08665 } 08666 /* Other type of INFO message, not really understood by Asterisk */ 08667 /* if (get_msg_text(buf, sizeof(buf), req)) { */ 08668 08669 ast_log(LOG_WARNING, "Unable to parse INFO message from %s. Content %s\n", p->callid, buf); 08670 transmit_response(p, "415 Unsupported media type", req); 08671 return; 08672 }
|
|
handle_request_invite: Handle incoming INVITE request
Definition at line 10230 of file chan_sip.c. References ast_channel::_state, ast_channel_setwhentohangup(), ast_clear_flag, ast_hangup(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_PBX_CALL_LIMIT, AST_PBX_FAILED, ast_pbx_result, 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, sip_pvt::sipoptions, sip_pvt::tag, sip_pvt::theirtag, transmit_response(), transmit_response_reliable(), transmit_response_with_sdp(), transmit_response_with_unsupported(), update_call_counter(), and sip_pvt::username. Referenced by handle_request(). 10231 { 10232 int res = 1; 10233 struct ast_channel *c=NULL; 10234 int gotdest; 10235 struct ast_frame af = { AST_FRAME_NULL, }; 10236 char *supported; 10237 char *required; 10238 unsigned int required_profile = 0; 10239 10240 /* Find out what they support */ 10241 if (!p->sipoptions) { 10242 supported = get_header(req, "Supported"); 10243 if (supported) 10244 parse_sip_options(p, supported); 10245 } 10246 required = get_header(req, "Required"); 10247 if (!ast_strlen_zero(required)) { 10248 required_profile = parse_sip_options(NULL, required); 10249 if (required_profile) { /* They require something */ 10250 /* At this point we support no extensions, so fail */ 10251 transmit_response_with_unsupported(p, "420 Bad extension", req, required); 10252 if (!p->lastinvite) 10253 ast_set_flag(p, SIP_NEEDDESTROY); 10254 return -1; 10255 10256 } 10257 } 10258 10259 /* Check if this is a loop */ 10260 /* This happens since we do not properly support SIP domain 10261 handling yet... -oej */ 10262 if (ast_test_flag(p, SIP_OUTGOING) && p->owner && (p->owner->_state != AST_STATE_UP)) { 10263 /* This is a call to ourself. Send ourselves an error code and stop 10264 processing immediately, as SIP really has no good mechanism for 10265 being able to call yourself */ 10266 transmit_response(p, "482 Loop Detected", req); 10267 /* We do NOT destroy p here, so that our response will be accepted */ 10268 return 0; 10269 } 10270 if (!ignore) { 10271 /* Use this as the basis */ 10272 if (debug) 10273 ast_verbose("Using INVITE request as basis request - %s\n", p->callid); 10274 sip_cancel_destroy(p); 10275 /* This call is no longer outgoing if it ever was */ 10276 ast_clear_flag(p, SIP_OUTGOING); 10277 /* This also counts as a pending invite */ 10278 p->pendinginvite = seqno; 10279 copy_request(&p->initreq, req); 10280 check_via(p, req); 10281 if (p->owner) { 10282 /* Handle SDP here if we already have an owner */ 10283 if (!strcasecmp(get_header(req, "Content-Type"), "application/sdp")) { 10284 if (process_sdp(p, req)) { 10285 transmit_response(p, "488 Not acceptable here", req); 10286 if (!p->lastinvite) 10287 ast_set_flag(p, SIP_NEEDDESTROY); 10288 return -1; 10289 } 10290 } else { 10291 p->jointcapability = p->capability; 10292 ast_log(LOG_DEBUG, "Hm.... No sdp for the moment\n"); 10293 } 10294 } 10295 } else if (debug) 10296 ast_verbose("Ignoring this INVITE request\n"); 10297 if (!p->lastinvite && !ignore && !p->owner) { 10298 /* Handle authentication if this is our first invite */ 10299 res = check_user(p, req, SIP_INVITE, e, 1, sin, ignore); 10300 if (res) { 10301 if (res < 0) { 10302 ast_log(LOG_NOTICE, "Failed to authenticate user %s\n", get_header(req, "From")); 10303 if (ignore) 10304 transmit_response(p, "403 Forbidden", req); 10305 else 10306 transmit_response_reliable(p, "403 Forbidden", req, 1); 10307 ast_set_flag(p, SIP_NEEDDESTROY); 10308 p->theirtag[0] = '\0'; /* Forget their to-tag, we'll get a new one */ 10309 } 10310 return 0; 10311 } 10312 /* Process the SDP portion */ 10313 if (!ast_strlen_zero(get_header(req, "Content-Type"))) { 10314 if (process_sdp(p, req)) { 10315 transmit_response(p, "488 Not acceptable here", req); 10316 ast_set_flag(p, SIP_NEEDDESTROY); 10317 return -1; 10318 } 10319 } else { 10320 p->jointcapability = p->capability; 10321 ast_log(LOG_DEBUG, "Hm.... No sdp for the moment\n"); 10322 } 10323 /* Queue NULL frame to prod ast_rtp_bridge if appropriate */ 10324 if (p->owner) 10325 ast_queue_frame(p->owner, &af); 10326 /* Initialize the context if it hasn't been already */ 10327 if (ast_strlen_zero(p->context)) 10328 strcpy(p->context, default_context); 10329 /* Check number of concurrent calls -vs- incoming limit HERE */ 10330 ast_log(LOG_DEBUG, "Checking SIP call limits for device %s\n", p->username); 10331 res = update_call_counter(p, INC_CALL_LIMIT); 10332 if (res) { 10333 if (res < 0) { 10334 ast_log(LOG_NOTICE, "Failed to place call for user %s, too many calls\n", p->username); 10335 if (ignore) 10336 transmit_response(p, "480 Temporarily Unavailable (Call limit)", req); 10337 else 10338 transmit_response_reliable(p, "480 Temporarily Unavailable (Call limit) ", req, 1); 10339 ast_set_flag(p, SIP_NEEDDESTROY); 10340 } 10341 return 0; 10342 } 10343 /* Get destination right away */ 10344 gotdest = get_destination(p, NULL); 10345 10346 get_rdnis(p, NULL); 10347 extract_uri(p, req); 10348 build_contact(p); 10349 10350 if (gotdest) { 10351 if (gotdest < 0) { 10352 if (ignore) 10353 transmit_response(p, "404 Not Found", req); 10354 else 10355 transmit_response_reliable(p, "404 Not Found", req, 1); 10356 update_call_counter(p, DEC_CALL_LIMIT); 10357 } else { 10358 if (ignore) 10359 transmit_response(p, "484 Address Incomplete", req); 10360 else 10361 transmit_response_reliable(p, "484 Address Incomplete", req, 1); 10362 update_call_counter(p, DEC_CALL_LIMIT); 10363 } 10364 ast_set_flag(p, SIP_NEEDDESTROY); 10365 } else { 10366 /* If no extension was specified, use the s one */ 10367 if (ast_strlen_zero(p->exten)) 10368 ast_copy_string(p->exten, "s", sizeof(p->exten)); 10369 /* Initialize tag */ 10370 make_our_tag(p->tag, sizeof(p->tag)); 10371 /* First invitation */ 10372 c = sip_new(p, AST_STATE_DOWN, ast_strlen_zero(p->username) ? NULL : p->username ); 10373 *recount = 1; 10374 /* Save Record-Route for any later requests we make on this dialogue */ 10375 build_route(p, req, 0); 10376 if (c) { 10377 /* Pre-lock the call */ 10378 ast_mutex_lock(&c->lock); 10379 } 10380 } 10381 10382 } else { 10383 if (option_debug > 1 && sipdebug) 10384 ast_log(LOG_DEBUG, "Got a SIP re-invite for call %s\n", p->callid); 10385 c = p->owner; 10386 } 10387 if (!ignore && p) 10388 p->lastinvite = seqno; 10389 if (c) { 10390 #ifdef OSP_SUPPORT 10391 ast_channel_setwhentohangup (c, p->osptimelimit); 10392 #endif 10393 switch(c->_state) { 10394 case AST_STATE_DOWN: 10395 transmit_response(p, "100 Trying", req); 10396 ast_setstate(c, AST_STATE_RING); 10397 if (strcmp(p->exten, ast_pickup_ext())) { 10398 enum ast_pbx_result res; 10399 10400 res = ast_pbx_start(c); 10401 10402 switch (res) { 10403 case AST_PBX_FAILED: 10404 ast_log(LOG_WARNING, "Failed to start PBX :(\n"); 10405 if (ignore) 10406 transmit_response(p, "503 Unavailable", req); 10407 else 10408 transmit_response_reliable(p, "503 Unavailable", req, 1); 10409 break; 10410 case AST_PBX_CALL_LIMIT: 10411 ast_log(LOG_WARNING, "Failed to start PBX (call limit reached) \n"); 10412 if (ignore) 10413 transmit_response(p, "480 Temporarily Unavailable", req); 10414 else 10415 transmit_response_reliable(p, "480 Temporarily Unavailable", req, 1); 10416 break; 10417 case AST_PBX_SUCCESS: 10418 /* nothing to do */ 10419 break; 10420 } 10421 10422 if (res) { 10423 ast_log(LOG_WARNING, "Failed to start PBX :(\n"); 10424 /* Unlock locks so ast_hangup can do its magic */ 10425 ast_mutex_unlock(&c->lock); 10426 ast_mutex_unlock(&p->lock); 10427 ast_hangup(c); 10428 ast_mutex_lock(&p->lock); 10429 c = NULL; 10430 } 10431 } else { 10432 ast_mutex_unlock(&c->lock); 10433 if (ast_pickup_call(c)) { 10434 ast_log(LOG_NOTICE, "Nothing to pick up\n"); 10435 if (ignore) 10436 transmit_response(p, "503 Unavailable", req); 10437 else 10438 transmit_response_reliable(p, "503 Unavailable", req, 1); 10439 ast_set_flag(p, SIP_ALREADYGONE); 10440 /* Unlock locks so ast_hangup can do its magic */ 10441 ast_mutex_unlock(&p->lock); 10442 ast_hangup(c); 10443 ast_mutex_lock(&p->lock); 10444 c = NULL; 10445 } else { 10446 ast_mutex_unlock(&p->lock); 10447 ast_setstate(c, AST_STATE_DOWN); 10448 ast_hangup(c); 10449 ast_mutex_lock(&p->lock); 10450 c = NULL; 10451 } 10452 } 10453 break; 10454 case AST_STATE_RING: 10455 transmit_response(p, "100 Trying", req); 10456 break; 10457 case AST_STATE_RINGING: 10458 transmit_response(p, "180 Ringing", req); 10459 break; 10460 case AST_STATE_UP: 10461 transmit_response_with_sdp(p, "200 OK", req, 1); 10462 break; 10463 default: 10464 ast_log(LOG_WARNING, "Don't know how to handle INVITE in state %d\n", c->_state); 10465 transmit_response(p, "100 Trying", req); 10466 } 10467 } else { 10468 if (p && !ast_test_flag(p, SIP_NEEDDESTROY) && !ignore) { 10469 if (!p->jointcapability) { 10470 if (ignore) 10471 transmit_response(p, "488 Not Acceptable Here (codec error)", req); 10472 else 10473 transmit_response_reliable(p, "488 Not Acceptable Here (codec error)", req, 1); 10474 ast_set_flag(p, SIP_NEEDDESTROY); 10475 } else { 10476 ast_log(LOG_NOTICE, "Unable to create/find channel\n"); 10477 if (ignore) 10478 transmit_response(p, "503 Unavailable", req); 10479 else 10480 transmit_response_reliable(p, "503 Unavailable", req, 1); 10481 ast_set_flag(p, SIP_NEEDDESTROY); 10482 } 10483 } 10484 } 10485 return res; 10486 }
|
|
handle_request_message: Handle incoming MESSAGE request ---
Definition at line 10638 of file chan_sip.c. References ast_verbose(), receive_message(), and transmit_response(). Referenced by handle_request(). 10639 { 10640 if (!ignore) { 10641 if (debug) 10642 ast_verbose("Receiving message!\n"); 10643 receive_message(p, req); 10644 } else { 10645 transmit_response(p, "202 Accepted", req); 10646 } 10647 return 1; 10648 }
|
|
handle_request_options: Handle incoming OPTIONS request
Definition at line 10206 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(). 10207 { 10208 int res; 10209 10210 res = get_destination(p, req); 10211 build_contact(p); 10212 /* XXX Should we authenticate OPTIONS? XXX */ 10213 if (ast_strlen_zero(p->context)) 10214 strcpy(p->context, default_context); 10215 if (res < 0) 10216 transmit_response_with_allow(p, "404 Not Found", req, 0); 10217 else if (res > 0) 10218 transmit_response_with_allow(p, "484 Address Incomplete", req, 0); 10219 else 10220 transmit_response_with_allow(p, "200 OK", req, 0); 10221 /* Destroy if this OPTIONS was the opening request, but not if 10222 it's in the middle of a normal call flow. */ 10223 if (!p->lastinvite) 10224 ast_set_flag(p, SIP_NEEDDESTROY); 10225 10226 return res; 10227 }
|
|
handle_request_refer: Handle incoming REFER request ---
Definition at line 10489 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(). 10490 { 10491 struct ast_channel *c=NULL; 10492 int res; 10493 struct ast_channel *transfer_to; 10494 10495 if (option_debug > 2) 10496 ast_log(LOG_DEBUG, "SIP call transfer received for call %s (REFER)!\n", p->callid); 10497 if (ast_strlen_zero(p->context)) 10498 strcpy(p->context, default_context); 10499 res = get_refer_info(p, req); 10500 if (res < 0) 10501 transmit_response_with_allow(p, "404 Not Found", req, 1); 10502 else if (res > 0) 10503 transmit_response_with_allow(p, "484 Address Incomplete", req, 1); 10504 else { 10505 int nobye = 0; 10506 if (!ignore) { 10507 if (p->refer_call) { 10508 ast_log(LOG_DEBUG,"202 Accepted (supervised)\n"); 10509 attempt_transfer(p, p->refer_call); 10510 if (p->refer_call->owner) 10511 ast_mutex_unlock(&p->refer_call->owner->lock); 10512 ast_mutex_unlock(&p->refer_call->lock); 10513 p->refer_call = NULL; 10514 ast_set_flag(p, SIP_GOTREFER); 10515 } else { 10516 ast_log(LOG_DEBUG,"202 Accepted (blind)\n"); 10517 c = p->owner; 10518 if (c) { 10519 transfer_to = ast_bridged_channel(c); 10520 if (transfer_to) { 10521 ast_log(LOG_DEBUG, "Got SIP blind transfer, applying to '%s'\n", transfer_to->name); 10522 ast_moh_stop(transfer_to); 10523 if (!strcmp(p->refer_to, ast_parking_ext())) { 10524 /* Must release c's lock now, because it will not longer 10525 be accessible after the transfer! */ 10526 *nounlock = 1; 10527 ast_mutex_unlock(&c->lock); 10528 sip_park(transfer_to, c, req); 10529 nobye = 1; 10530 } else { 10531 /* Must release c's lock now, because it will not longer 10532 be accessible after the transfer! */ 10533 *nounlock = 1; 10534 ast_mutex_unlock(&c->lock); 10535 ast_async_goto(transfer_to,p->context, p->refer_to,1); 10536 } 10537 } else { 10538 ast_log(LOG_DEBUG, "Got SIP blind transfer but nothing to transfer to.\n"); 10539 ast_queue_hangup(p->owner); 10540 } 10541 } 10542 ast_set_flag(p, SIP_GOTREFER); 10543 } 10544 transmit_response(p, "202 Accepted", req); 10545 transmit_notify_with_sipfrag(p, seqno); 10546 /* Always increment on a BYE */ 10547 if (!nobye) { 10548 transmit_request_with_auth(p, SIP_BYE, 0, 1, 1); 10549 ast_set_flag(p, SIP_ALREADYGONE); 10550 } 10551 } 10552 } 10553 return res; 10554 }
|
|
handle_request_register: Handle incoming REGISTER request ---
Definition at line 10843 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(). 10844 { 10845 int res = 0; 10846 char iabuf[INET_ADDRSTRLEN]; 10847 10848 /* Use this as the basis */ 10849 if (debug) 10850 ast_verbose("Using latest REGISTER request as basis request\n"); 10851 copy_request(&p->initreq, req); 10852 check_via(p, req); 10853 if ((res = register_verify(p, sin, req, e, ignore)) < 0) 10854 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")); 10855 if (res < 1) { 10856 /* Destroy the session, but keep us around for just a bit in case they don't 10857 get our 200 OK */ 10858 sip_scheddestroy(p, 15*1000); 10859 } 10860 return res; 10861 }
|
|
handle_request_subscribe: Handle incoming SUBSCRIBE request ---
Definition at line 10650 of file chan_sip.c. References append_history(), ast_clear_flag, 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(), default_context, sip_pvt::expiry, sip_pvt::exten, get_destination(), get_header(), sip_request::headers, sip_pvt::initreq, sip_pvt::lastinvite, sip_pvt::lock, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, make_our_tag(), sip_request::method, sip_pvt::next, option_debug, sip_cancel_destroy(), sip_methods, SIP_NEEDDESTROY, SIP_OUTGOING, sip_scheddestroy(), SIP_SUBSCRIBE, sipdebug, sip_pvt::stateid, sip_pvt::subscribecontext, sip_pvt::tag, transmit_response(), transmit_state_notify(), sip_pvt::useragent, and sip_pvt::username. Referenced by handle_request(). 10651 { 10652 int gotdest; 10653 int res = 0; 10654 int firststate = AST_EXTENSION_REMOVED; 10655 10656 if (p->initreq.headers) { 10657 /* We already have a dialog */ 10658 if (p->initreq.method != SIP_SUBSCRIBE) { 10659 /* This is a SUBSCRIBE within another SIP dialog, which we do not support */ 10660 /* For transfers, this could happen, but since we haven't seen it happening, let us just refuse this */ 10661 transmit_response(p, "403 Forbidden (within dialog)", req); 10662 /* Do not destroy session, since we will break the call if we do */ 10663 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); 10664 return 0; 10665 } else { 10666 if (debug) 10667 ast_log(LOG_DEBUG, "Got a re-subscribe on existing subscription %s\n", p->callid); 10668 } 10669 } 10670 if (!ignore && !p->initreq.headers) { 10671 /* Use this as the basis */ 10672 if (debug) 10673 ast_verbose("Using latest SUBSCRIBE request as basis request\n"); 10674 /* This call is no longer outgoing if it ever was */ 10675 ast_clear_flag(p, SIP_OUTGOING); 10676 copy_request(&p->initreq, req); 10677 check_via(p, req); 10678 } else if (debug && ignore) 10679 ast_verbose("Ignoring this SUBSCRIBE request\n"); 10680 10681 if (!p->lastinvite) { 10682 char mailboxbuf[256]=""; 10683 int found = 0; 10684 char *mailbox = NULL; 10685 int mailboxsize = 0; 10686 10687 char *event = get_header(req, "Event"); /* Get Event package name */ 10688 char *accept = get_header(req, "Accept"); 10689 10690 if (!strcmp(event, "message-summary") && !strcmp(accept, "application/simple-message-summary")) { 10691 mailbox = mailboxbuf; 10692 mailboxsize = sizeof(mailboxbuf); 10693 } 10694 /* Handle authentication if this is our first subscribe */ 10695 res = check_user_full(p, req, SIP_SUBSCRIBE, e, 0, sin, ignore, mailbox, mailboxsize); 10696 if (res) { 10697 if (res < 0) { 10698 ast_log(LOG_NOTICE, "Failed to authenticate user %s for SUBSCRIBE\n", get_header(req, "From")); 10699 ast_set_flag(p, SIP_NEEDDESTROY); 10700 } 10701 return 0; 10702 } 10703 /* Initialize the context if it hasn't been already */ 10704 if (!ast_strlen_zero(p->subscribecontext)) 10705 ast_copy_string(p->context, p->subscribecontext, sizeof(p->context)); 10706 else if (ast_strlen_zero(p->context)) 10707 strcpy(p->context, default_context); 10708 /* Get destination right away */ 10709 gotdest = get_destination(p, NULL); 10710 build_contact(p); 10711 if (gotdest) { 10712 if (gotdest < 0) 10713 transmit_response(p, "404 Not Found", req); 10714 else 10715 transmit_response(p, "484 Address Incomplete", req); /* Overlap dialing on SUBSCRIBE?? */ 10716 ast_set_flag(p, SIP_NEEDDESTROY); 10717 } else { 10718 10719 /* Initialize tag for new subscriptions */ 10720 if (ast_strlen_zero(p->tag)) 10721 make_our_tag(p->tag, sizeof(p->tag)); 10722 10723 if (!strcmp(event, "presence") || !strcmp(event, "dialog")) { /* Presence, RFC 3842 */ 10724 10725 /* Header from Xten Eye-beam Accept: multipart/related, application/rlmi+xml, application/pidf+xml, application/xpidf+xml */ 10726 if (strstr(accept, "application/pidf+xml")) { 10727 p->subscribed = PIDF_XML; /* RFC 3863 format */ 10728 } else if (strstr(accept, "application/dialog-info+xml")) { 10729 p->subscribed = DIALOG_INFO_XML; 10730 /* IETF draft: draft-ietf-sipping-dialog-package-05.txt */ 10731 } else if (strstr(accept, "application/cpim-pidf+xml")) { 10732 p->subscribed = CPIM_PIDF_XML; /* RFC 3863 format */ 10733 } else if (strstr(accept, "application/xpidf+xml")) { 10734 p->subscribed = XPIDF_XML; /* Early pre-RFC 3863 format with MSN additions (Microsoft Messenger) */ 10735 } else if (strstr(p->useragent, "Polycom")) { 10736 p->subscribed = XPIDF_XML; /* Polycoms subscribe for "event: dialog" but don't include an "accept:" header */ 10737 } else { 10738 /* Can't find a format for events that we know about */ 10739 transmit_response(p, "489 Bad Event", req); 10740 ast_set_flag(p, SIP_NEEDDESTROY); 10741 return 0; 10742 } 10743 } else if (!strcmp(event, "message-summary") && !strcmp(accept, "application/simple-message-summary")) { 10744 /* Looks like they actually want a mailbox status */ 10745 10746 /* At this point, we should check if they subscribe to a mailbox that 10747 has the same extension as the peer or the mailbox id. If we configure 10748 the context to be the same as a SIP domain, we could check mailbox 10749 context as well. To be able to securely accept subscribes on mailbox 10750 IDs, not extensions, we need to check the digest auth user to make 10751 sure that the user has access to the mailbox. 10752 10753 Since we do not act on this subscribe anyway, we might as well 10754 accept any authenticated peer with a mailbox definition in their 10755 config section. 10756 10757 */ 10758 if (!ast_strlen_zero(mailbox)) { 10759 found++; 10760 } 10761 10762 if (found){ 10763 transmit_response(p, "200 OK", req); 10764 ast_set_flag(p, SIP_NEEDDESTROY); 10765 } else { 10766 transmit_response(p, "404 Not found", req); 10767 ast_set_flag(p, SIP_NEEDDESTROY); 10768 } 10769 return 0; 10770 } else { /* At this point, Asterisk does not understand the specified event */ 10771 transmit_response(p, "489 Bad Event", req); 10772 if (option_debug > 1) 10773 ast_log(LOG_DEBUG, "Received SIP subscribe for unknown event package: %s\n", event); 10774 ast_set_flag(p, SIP_NEEDDESTROY); 10775 return 0; 10776 } 10777 if (p->subscribed != NONE) 10778 p->stateid = ast_extension_state_add(p->context, p->exten, cb_extensionstate, p); 10779 } 10780 } 10781 10782 if (!ignore && p) 10783 p->lastinvite = seqno; 10784 if (p && !ast_test_flag(p, SIP_NEEDDESTROY)) { 10785 p->expiry = atoi(get_header(req, "Expires")); 10786 10787 /* The next 4 lines can be removed if the SNOM Expires bug is fixed */ 10788 if (p->subscribed == DIALOG_INFO_XML) { 10789 if (p->expiry > max_expiry) 10790 p->expiry = max_expiry; 10791 } 10792 if (sipdebug || option_debug > 1) 10793 ast_log(LOG_DEBUG, "Adding subscription for extension %s context %s for peer %s\n", p->exten, p->context, p->username); 10794 if (p->autokillid > -1) 10795 sip_cancel_destroy(p); /* Remove subscription expiry for renewals */ 10796 sip_scheddestroy(p, (p->expiry + 10) * 1000); /* Set timer for destruction of call at expiration */ 10797 10798 if ((firststate = ast_extension_state(NULL, p->context, p->exten)) < 0) { 10799 ast_log(LOG_ERROR, "Got SUBSCRIBE for extensions without hint. Please add hint to %s in context %s\n", p->exten, p->context); 10800 transmit_response(p, "404 Not found", req); 10801 ast_set_flag(p, SIP_NEEDDESTROY); 10802 return 0; 10803 } else { 10804 struct sip_pvt *p_old; 10805 10806 transmit_response(p, "200 OK", req); 10807 transmit_state_notify(p, firststate, 1, 1); /* Send first notification */ 10808 append_history(p, "Subscribestatus", ast_extension_state2str(firststate)); 10809 10810 /* remove any old subscription from this peer for the same exten/context, 10811 as the peer has obviously forgotten about it and it's wasteful to wait 10812 for it to expire and send NOTIFY messages to the peer only to have them 10813 ignored (or generate errors) 10814 */ 10815 ast_mutex_lock(&iflock); 10816 for (p_old = iflist; p_old; p_old = p_old->next) { 10817 if (p_old == p) 10818 continue; 10819 if (p_old->initreq.method != SIP_SUBSCRIBE) 10820 continue; 10821 if (p_old->subscribed == NONE) 10822 continue; 10823 ast_mutex_lock(&p_old->lock); 10824 if (!strcmp(p_old->username, p->username)) { 10825 if (!strcmp(p_old->exten, p->exten) && 10826 !strcmp(p_old->context, p->context)) { 10827 ast_set_flag(p_old, SIP_NEEDDESTROY); 10828 ast_mutex_unlock(&p_old->lock); 10829 break; 10830 } 10831 } 10832 ast_mutex_unlock(&p_old->lock); 10833 } 10834 ast_mutex_unlock(&iflock); 10835 } 10836 if (!p->expiry) 10837 ast_set_flag(p, SIP_NEEDDESTROY); 10838 } 10839 return 1; 10840 }
|
|
handle_response: Handle SIP response in dialogue ---
Definition at line 9737 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_pvt::authname, sip_pvt::authtries, ast_channel::call_forward, sip_pvt::context, 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, sip_pvt::initreq, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, ast_channel::name, option_verbose, sip_pvt::owner, parse_moved_contact(), sip_pvt::peerpoke, process_sdp(), sip_pvt::recv, sip_pvt::registry, sip_pvt::rtp, sip_pvt::sa, sched, SIP_ACK, SIP_ALREADYGONE, SIP_BYE, sip_cancel_destroy(), sip_methods, SIP_NEEDDESTROY, SIP_OUTGOING, sipmethod, text, sip_pvt::theirtag, transmit_request(), update_call_counter(), sip_pvt::username, VERBOSE_PREFIX_3, and sip_pvt::vrtp. Referenced by handle_request(), mgcpsock_read(), and retrans_pkt(). 09738 { 09739 char *msg, *c; 09740 struct ast_channel *owner; 09741 char iabuf[INET_ADDRSTRLEN]; 09742 int sipmethod; 09743 int res = 1; 09744 09745 c = get_header(req, "Cseq"); 09746 msg = strchr(c, ' '); 09747 if (!msg) 09748 msg = ""; 09749 else 09750 msg++; 09751 sipmethod = find_sip_method(msg); 09752 09753 owner = p->owner; 09754 if (owner) 09755 owner->hangupcause = hangup_sip2cause(resp); 09756 09757 /* Acknowledge whatever it is destined for */ 09758 if ((resp >= 100) && (resp <= 199)) 09759 __sip_semi_ack(p, seqno, 0, sipmethod); 09760 else 09761 __sip_ack(p, seqno, 0, sipmethod); 09762 09763 /* Get their tag if we haven't already */ 09764 if (ast_strlen_zero(p->theirtag) || (resp >= 200)) { 09765 gettag(req, "To", p->theirtag, sizeof(p->theirtag)); 09766 } 09767 if (p->peerpoke) { 09768 /* We don't really care what the response is, just that it replied back. 09769 Well, as long as it's not a 100 response... since we might 09770 need to hang around for something more "definitive" */ 09771 09772 res = handle_response_peerpoke(p, resp, rest, req, ignore, seqno, sipmethod); 09773 } else if (ast_test_flag(p, SIP_OUTGOING)) { 09774 /* Acknowledge sequence number */ 09775 if (p->initid > -1) { 09776 /* Don't auto congest anymore since we've gotten something useful back */ 09777 ast_sched_del(sched, p->initid); 09778 p->initid = -1; 09779 } 09780 switch(resp) { 09781 case 100: /* 100 Trying */ 09782 if (sipmethod == SIP_INVITE) 09783 handle_response_invite(p, resp, rest, req, ignore, seqno); 09784 break; 09785 case 183: /* 183 Session Progress */ 09786 if (sipmethod == SIP_INVITE) 09787 handle_response_invite(p, resp, rest, req, ignore, seqno); 09788 break; 09789 case 180: /* 180 Ringing */ 09790 if (sipmethod == SIP_INVITE) 09791 handle_response_invite(p, resp, rest, req, ignore, seqno); 09792 break; 09793 case 200: /* 200 OK */ 09794 p->authtries = 0; /* Reset authentication counter */ 09795 if (sipmethod == SIP_MESSAGE) { 09796 /* We successfully transmitted a message */ 09797 ast_set_flag(p, SIP_NEEDDESTROY); 09798 } else if (sipmethod == SIP_NOTIFY) { 09799 /* They got the notify, this is the end */ 09800 if (p->owner) { 09801 ast_log(LOG_WARNING, "Notify answer on an owned channel?\n"); 09802 ast_queue_hangup(p->owner); 09803 } else { 09804 if (p->subscribed == NONE) { 09805 ast_set_flag(p, SIP_NEEDDESTROY); 09806 } 09807 } 09808 } else if (sipmethod == SIP_INVITE) { 09809 handle_response_invite(p, resp, rest, req, ignore, seqno); 09810 } else if (sipmethod == SIP_REGISTER) { 09811 res = handle_response_register(p, resp, rest, req, ignore, seqno); 09812 } 09813 break; 09814 case 401: /* Not www-authorized on SIP method */ 09815 if (sipmethod == SIP_INVITE) { 09816 handle_response_invite(p, resp, rest, req, ignore, seqno); 09817 } else if (p->registry && sipmethod == SIP_REGISTER) { 09818 res = handle_response_register(p, resp, rest, req, ignore, seqno); 09819 } else { 09820 ast_log(LOG_WARNING, "Got authentication request (401) on unknown %s to '%s'\n", sip_methods[sipmethod].text, get_header(req, "To")); 09821 ast_set_flag(p, SIP_NEEDDESTROY); 09822 } 09823 break; 09824 case 403: /* Forbidden - we failed authentication */ 09825 if (sipmethod == SIP_INVITE) { 09826 handle_response_invite(p, resp, rest, req, ignore, seqno); 09827 } else if (p->registry && sipmethod == SIP_REGISTER) { 09828 res = handle_response_register(p, resp, rest, req, ignore, seqno); 09829 } else { 09830 ast_log(LOG_WARNING, "Forbidden - wrong password on authentication for %s\n", msg); 09831 } 09832 break; 09833 case 404: /* Not found */ 09834 if (p->registry && sipmethod == SIP_REGISTER) { 09835 res = handle_response_register(p, resp, rest, req, ignore, seqno); 09836 } else if (sipmethod == SIP_INVITE) { 09837 handle_response_invite(p, resp, rest, req, ignore, seqno); 09838 } else if (owner) 09839 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 09840 break; 09841 case 407: /* Proxy auth required */ 09842 if (sipmethod == SIP_INVITE) { 09843 handle_response_invite(p, resp, rest, req, ignore, seqno); 09844 } else if (sipmethod == SIP_BYE || sipmethod == SIP_REFER) { 09845 if (ast_strlen_zero(p->authname)) 09846 ast_log(LOG_WARNING, "Asked to authenticate %s, to %s:%d but we have no matching peer!\n", 09847 msg, ast_inet_ntoa(iabuf, sizeof(iabuf), p->recv.sin_addr), ntohs(p->recv.sin_port)); 09848 ast_set_flag(p, SIP_NEEDDESTROY); 09849 if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, "Proxy-Authenticate", "Proxy-Authorization", sipmethod, 0)) { 09850 ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From")); 09851 ast_set_flag(p, SIP_NEEDDESTROY); 09852 } 09853 } else if (p->registry && sipmethod == SIP_REGISTER) { 09854 res = handle_response_register(p, resp, rest, req, ignore, seqno); 09855 } else /* We can't handle this, giving up in a bad way */ 09856 ast_set_flag(p, SIP_NEEDDESTROY); 09857 09858 break; 09859 case 491: /* Pending */ 09860 if (sipmethod == SIP_INVITE) { 09861 handle_response_invite(p, resp, rest, req, ignore, seqno); 09862 } 09863 case 501: /* Not Implemented */ 09864 if (sipmethod == SIP_INVITE) { 09865 handle_response_invite(p, resp, rest, req, ignore, seqno); 09866 } else 09867 ast_log(LOG_WARNING, "Host '%s' does not implement '%s'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr), msg); 09868 break; 09869 default: 09870 if ((resp >= 300) && (resp < 700)) { 09871 if ((option_verbose > 2) && (resp != 487)) 09872 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)); 09873 ast_set_flag(p, SIP_ALREADYGONE); 09874 if (p->rtp) { 09875 /* Immediately stop RTP */ 09876 ast_rtp_stop(p->rtp); 09877 } 09878 if (p->vrtp) { 09879 /* Immediately stop VRTP */ 09880 ast_rtp_stop(p->vrtp); 09881 } 09882 /* XXX Locking issues?? XXX */ 09883 switch(resp) { 09884 case 300: /* Multiple Choices */ 09885 case 301: /* Moved permenantly */ 09886 case 302: /* Moved temporarily */ 09887 case 305: /* Use Proxy */ 09888 parse_moved_contact(p, req); 09889 /* Fall through */ 09890 case 486: /* Busy here */ 09891 case 600: /* Busy everywhere */ 09892 case 603: /* Decline */ 09893 if (p->owner) 09894 ast_queue_control(p->owner, AST_CONTROL_BUSY); 09895 break; 09896 case 487: 09897 /* channel now destroyed - dec the inUse counter */ 09898 update_call_counter(p, DEC_CALL_LIMIT); 09899 break; 09900 case 482: /* SIP is incapable of performing a hairpin call, which 09901 is yet another failure of not having a layer 2 (again, YAY 09902 IETF for thinking ahead). So we treat this as a call 09903 forward and hope we end up at the right place... */ 09904 ast_log(LOG_DEBUG, "Hairpin detected, setting up call forward for what it's worth\n"); 09905 if (p->owner) 09906 snprintf(p->owner->call_forward, sizeof(p->owner->call_forward), "Local/%s@%s", p->username, p->context); 09907 /* Fall through */ 09908 case 488: /* Not acceptable here - codec error */ 09909 case 480: /* Temporarily Unavailable */ 09910 case 404: /* Not Found */ 09911 case 410: /* Gone */ 09912 case 400: /* Bad Request */ 09913 case 500: /* Server error */ 09914 case 503: /* Service Unavailable */ 09915 if (owner) 09916 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 09917 break; 09918 default: 09919 /* Send hangup */ 09920 if (owner) 09921 ast_queue_hangup(p->owner); 09922 break; 09923 } 09924 /* ACK on invite */ 09925 if (sipmethod == SIP_INVITE) 09926 transmit_request(p, SIP_ACK, seqno, 0, 0); 09927 ast_set_flag(p, SIP_ALREADYGONE); 09928 if (!p->owner) 09929 ast_set_flag(p, SIP_NEEDDESTROY); 09930 } else if ((resp >= 100) && (resp < 200)) { 09931 if (sipmethod == SIP_INVITE) { 09932 sip_cancel_destroy(p); 09933 if (!ast_strlen_zero(get_header(req, "Content-Type"))) 09934 process_sdp(p, req); 09935 if (p->owner) { 09936 /* Queue a progress frame */ 09937 ast_queue_control(p->owner, AST_CONTROL_PROGRESS); 09938 } 09939 } 09940 } else 09941 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)); 09942 } 09943 } else { 09944 /* Responses to OUTGOING SIP requests on INCOMING calls 09945 get handled here. As well as out-of-call message responses */ 09946 if (req->debug) 09947 ast_verbose("SIP Response message for INCOMING dialog %s arrived\n", msg); 09948 if (resp == 200) { 09949 /* Tags in early session is replaced by the tag in 200 OK, which is 09950 the final reply to our INVITE */ 09951 gettag(req, "To", p->theirtag, sizeof(p->theirtag)); 09952 } 09953 09954 switch(resp) { 09955 case 200: 09956 if (sipmethod == SIP_INVITE) { 09957 handle_response_invite(p, resp, rest, req, ignore, seqno); 09958 } else if (sipmethod == SIP_CANCEL) { 09959 ast_log(LOG_DEBUG, "Got 200 OK on CANCEL\n"); 09960 } else if (sipmethod == SIP_MESSAGE) 09961 /* We successfully transmitted a message */ 09962 ast_set_flag(p, SIP_NEEDDESTROY); 09963 break; 09964 case 401: /* www-auth */ 09965 case 407: 09966 if (sipmethod == SIP_BYE || sipmethod == SIP_REFER) { 09967 char *auth, *auth2; 09968 09969 if (resp == 407) { 09970 auth = "Proxy-Authenticate"; 09971 auth2 = "Proxy-Authorization"; 09972 } else { 09973 auth = "WWW-Authenticate"; 09974 auth2 = "Authorization"; 09975 } 09976 if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, auth, auth2, sipmethod, 0)) { 09977 ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From")); 09978 ast_set_flag(p, SIP_NEEDDESTROY); 09979 } 09980 } else if (sipmethod == SIP_INVITE) { 09981 handle_response_invite(p, resp, rest, req, ignore, seqno); 09982 } 09983 break; 09984 case 481: /* Call leg does not exist */ 09985 if (sipmethod == SIP_INVITE) { 09986 /* Re-invite failed */ 09987 handle_response_invite(p, resp, rest, req, ignore, seqno); 09988 } 09989 break; 09990 default: /* Errors without handlers */ 09991 if ((resp >= 100) && (resp < 200)) { 09992 if (sipmethod == SIP_INVITE) { /* re-invite */ 09993 sip_cancel_destroy(p); 09994 } 09995 } 09996 if ((resp >= 300) && (resp < 700)) { 09997 if ((option_verbose > 2) && (resp != 487)) 09998 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)); 09999 switch(resp) { 10000 case 488: /* Not acceptable here - codec error */ 10001 case 603: /* Decline */ 10002 case 500: /* Server error */ 10003 case 503: /* Service Unavailable */ 10004 10005 if (sipmethod == SIP_INVITE) { /* re-invite failed */ 10006 sip_cancel_destroy(p); 10007 } 10008 break; 10009 } 10010 } 10011 break; 10012 } 10013 } 10014 }
|
|
handle_response_invite: Handle SIP response in dialogue ---
Definition at line 9427 of file chan_sip.c. References ast_channel::_state, AST_CONTROL_ANSWER, AST_CONTROL_CONGESTION, AST_CONTROL_PROGRESS, AST_CONTROL_RINGING, ast_log(), ast_queue_control(), ast_queue_frame(), ast_set_flag, ast_setstate(), AST_STATE_RINGING, ast_test_flag, sip_pvt::authtries, build_route(), sip_pvt::callid, check_pendings(), do_proxy_auth(), get_header(), sip_pvt::initreq, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, option_debug, sip_pvt::options, sip_pvt::owner, parse_ok_contact(), process_sdp(), SIP_ACK, SIP_ALREADYGONE, sip_cancel_destroy(), SIP_INVITE, SIP_NEEDDESTROY, SIP_OUTGOING, SIP_PENDINGBYE, sip_pvt::theirtag, transmit_request(), and WWW_AUTH. Referenced by handle_response(). 09428 { 09429 int outgoing = ast_test_flag(p, SIP_OUTGOING); 09430 09431 if (option_debug > 3) { 09432 int reinvite = (p->owner && p->owner->_state == AST_STATE_UP); 09433 if (reinvite) 09434 ast_log(LOG_DEBUG, "SIP response %d to RE-invite on %s call %s\n", resp, outgoing ? "outgoing" : "incoming", p->callid); 09435 else 09436 ast_log(LOG_DEBUG, "SIP response %d to standard invite\n", resp); 09437 } 09438 09439 if (ast_test_flag(p, SIP_ALREADYGONE)) { /* This call is already gone */ 09440 ast_log(LOG_DEBUG, "Got response on call that is already terminated: %s (ignoring)\n", p->callid); 09441 return; 09442 } 09443 09444 switch (resp) { 09445 case 100: /* Trying */ 09446 sip_cancel_destroy(p); 09447 break; 09448 case 180: /* 180 Ringing */ 09449 sip_cancel_destroy(p); 09450 if (!ignore && p->owner) { 09451 ast_queue_control(p->owner, AST_CONTROL_RINGING); 09452 if (p->owner->_state != AST_STATE_UP) 09453 ast_setstate(p->owner, AST_STATE_RINGING); 09454 } 09455 if (!strcasecmp(get_header(req, "Content-Type"), "application/sdp")) { 09456 process_sdp(p, req); 09457 if (!ignore && p->owner) { 09458 /* Queue a progress frame only if we have SDP in 180 */ 09459 ast_queue_control(p->owner, AST_CONTROL_PROGRESS); 09460 } 09461 } 09462 break; 09463 case 183: /* Session progress */ 09464 sip_cancel_destroy(p); 09465 if (!strcasecmp(get_header(req, "Content-Type"), "application/sdp")) { 09466 process_sdp(p, req); 09467 } 09468 if (!ignore && p->owner) { 09469 /* Queue a progress frame */ 09470 ast_queue_control(p->owner, AST_CONTROL_PROGRESS); 09471 } 09472 break; 09473 case 200: /* 200 OK on invite - someone's answering our call */ 09474 sip_cancel_destroy(p); 09475 p->authtries = 0; 09476 if (!strcasecmp(get_header(req, "Content-Type"), "application/sdp")) { 09477 process_sdp(p, req); 09478 } 09479 09480 /* Parse contact header for continued conversation */ 09481 /* When we get 200 OK, we know which device (and IP) to contact for this call */ 09482 /* This is important when we have a SIP proxy between us and the phone */ 09483 if (outgoing) { 09484 parse_ok_contact(p, req); 09485 09486 /* Save Record-Route for any later requests we make on this dialogue */ 09487 build_route(p, req, 1); 09488 } 09489 09490 if (!ignore && p->owner) { 09491 if (p->owner->_state != AST_STATE_UP) { 09492 #ifdef OSP_SUPPORT 09493 time(&p->ospstart); 09494 #endif 09495 ast_queue_control(p->owner, AST_CONTROL_ANSWER); 09496 } else { /* RE-invite */ 09497 struct ast_frame af = { AST_FRAME_NULL, }; 09498 ast_queue_frame(p->owner, &af); 09499 } 09500 } else { 09501 /* It's possible we're getting an ACK after we've tried to disconnect 09502 by sending CANCEL */ 09503 /* THIS NEEDS TO BE CHECKED: OEJ */ 09504 if (!ignore) 09505 ast_set_flag(p, SIP_PENDINGBYE); 09506 } 09507 /* If I understand this right, the branch is different for a non-200 ACK only */ 09508 transmit_request(p, SIP_ACK, seqno, 0, 1); 09509 check_pendings(p); 09510 break; 09511 case 407: /* Proxy authentication */ 09512 case 401: /* Www auth */ 09513 /* First we ACK */ 09514 transmit_request(p, SIP_ACK, seqno, 0, 0); 09515 if (p->options) 09516 p->options->auth_type = (resp == 401 ? WWW_AUTH : PROXY_AUTH); 09517 09518 /* Then we AUTH */ 09519 p->theirtag[0]='\0'; /* forget their old tag, so we don't match tags when getting response */ 09520 if (!ignore) { 09521 char *authenticate = (resp == 401 ? "WWW-Authenticate" : "Proxy-Authenticate"); 09522 char *authorization = (resp == 401 ? "Authorization" : "Proxy-Authorization"); 09523 if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, authenticate, authorization, SIP_INVITE, 1)) { 09524 ast_log(LOG_NOTICE, "Failed to authenticate on INVITE to '%s'\n", get_header(&p->initreq, "From")); 09525 ast_set_flag(p, SIP_NEEDDESTROY); 09526 ast_set_flag(p, SIP_ALREADYGONE); 09527 if (p->owner) 09528 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 09529 } 09530 } 09531 break; 09532 case 403: /* Forbidden */ 09533 /* First we ACK */ 09534 transmit_request(p, SIP_ACK, seqno, 0, 0); 09535 ast_log(LOG_WARNING, "Forbidden - wrong password on authentication for INVITE to '%s'\n", get_header(&p->initreq, "From")); 09536 if (!ignore && p->owner) 09537 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 09538 ast_set_flag(p, SIP_NEEDDESTROY); 09539 ast_set_flag(p, SIP_ALREADYGONE); 09540 break; 09541 case 404: /* Not found */ 09542 transmit_request(p, SIP_ACK, seqno, 0, 0); 09543 if (p->owner && !ignore) 09544 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 09545 ast_set_flag(p, SIP_ALREADYGONE); 09546 break; 09547 case 481: /* Call leg does not exist */ 09548 /* Could be REFER or INVITE */ 09549 ast_log(LOG_WARNING, "Re-invite to non-existing call leg on other UA. SIP dialog '%s'. Giving up.\n", p->callid); 09550 transmit_request(p, SIP_ACK, seqno, 0, 0); 09551 break; 09552 case 491: /* Pending */ 09553 /* we have to wait a while, then retransmit */ 09554 /* Transmission is rescheduled, so everything should be taken care of. 09555 We should support the retry-after at some point */ 09556 break; 09557 case 501: /* Not implemented */ 09558 if (p->owner) 09559 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 09560 break; 09561 } 09562 }
|
|
handle_response_peerpoke: Handle qualification responses (OPTIONS)
Definition at line 9681 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, sched, SIP_ACK, SIP_NEEDDESTROY, sip_poke_peer_s(), sipmethod, transmit_request(), and tv. Referenced by handle_response(). 09682 { 09683 struct sip_peer *peer; 09684 int pingtime; 09685 struct timeval tv; 09686 09687 if (resp != 100) { 09688 int statechanged = 0; 09689 int newstate = 0; 09690 peer = p->peerpoke; 09691 gettimeofday(&tv, NULL); 09692 pingtime = ast_tvdiff_ms(tv, peer->ps); 09693 if (pingtime < 1) 09694 pingtime = 1; 09695 if ((peer->lastms < 0) || (peer->lastms > peer->maxms)) { 09696 if (pingtime <= peer->maxms) { 09697 ast_log(LOG_NOTICE, "Peer '%s' is now REACHABLE! (%dms / %dms)\n", peer->name, pingtime, peer->maxms); 09698 statechanged = 1; 09699 newstate = 1; 09700 } 09701 } else if ((peer->lastms > 0) && (peer->lastms <= peer->maxms)) { 09702 if (pingtime > peer->maxms) { 09703 ast_log(LOG_NOTICE, "Peer '%s' is now TOO LAGGED! (%dms / %dms)\n", peer->name, pingtime, peer->maxms); 09704 statechanged = 1; 09705 newstate = 2; 09706 } 09707 } 09708 if (!peer->lastms) 09709 statechanged = 1; 09710 peer->lastms = pingtime; 09711 peer->call = NULL; 09712 if (statechanged) { 09713 ast_device_state_changed("SIP/%s", peer->name); 09714 if (newstate == 2) { 09715 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Lagged\r\nTime: %d\r\n", peer->name, pingtime); 09716 } else { 09717 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Reachable\r\nTime: %d\r\n", peer->name, pingtime); 09718 } 09719 } 09720 09721 if (peer->pokeexpire > -1) 09722 ast_sched_del(sched, peer->pokeexpire); 09723 if (sipmethod == SIP_INVITE) /* Does this really happen? */ 09724 transmit_request(p, SIP_ACK, seqno, 0, 0); 09725 ast_set_flag(p, SIP_NEEDDESTROY); 09726 09727 /* Try again eventually */ 09728 if ((peer->lastms < 0) || (peer->lastms > peer->maxms)) 09729 peer->pokeexpire = ast_sched_add(sched, DEFAULT_FREQ_NOTOK, sip_poke_peer_s, peer); 09730 else 09731 peer->pokeexpire = ast_sched_add(sched, DEFAULT_FREQ_OK, sip_poke_peer_s, peer); 09732 } 09733 return 1; 09734 }
|
|
handle_response_register: Handle responses on REGISTER to services ---
Definition at line 9565 of file chan_sip.c. References __get_header(), ast_log(), ast_sched_add(), ast_sched_del(), ast_set_flag, ast_strlen_zero(), ASTOBJ_UNREF, sip_pvt::authtries, sip_registry::call, do_register_auth(), EVENT_FLAG_SYSTEM, sip_registry::expire, EXPIRY_GUARD_MIN, EXPIRY_GUARD_PCT, EXPIRY_GUARD_SECS, get_header(), global_regattempts_max, sip_registry::hostname, sip_pvt::initreq, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, manager_event(), MAX, sip_pvt::our_contact, sip_registry::refresh, sip_registry::regattempts, sip_pvt::registry, sip_registry::regstate, regstate2str(), sched, SIP_NEEDDESTROY, sip_registry_destroy(), sip_reregister(), sip_scheddestroy(), strcasestr(), sip_registry::timeout, and sip_registry::username. Referenced by handle_response(). 09566 { 09567 int expires, expires_ms; 09568 struct sip_registry *r; 09569 r=p->registry; 09570 09571 switch (resp) { 09572 case 401: /* Unauthorized */ 09573 if ((p->authtries == MAX_AUTHTRIES) || do_register_auth(p, req, "WWW-Authenticate", "Authorization")) { 09574 ast_log(LOG_NOTICE, "Failed to authenticate on REGISTER to '%s@%s' (Tries %d)\n", p->registry->username, p->registry->hostname, p->authtries); 09575 ast_set_flag(p, SIP_NEEDDESTROY); 09576 } 09577 break; 09578 case 403: /* Forbidden */ 09579 ast_log(LOG_WARNING, "Forbidden - wrong password on authentication for REGISTER for '%s' to '%s'\n", p->registry->username, p->registry->hostname); 09580 if (global_regattempts_max) 09581 p->registry->regattempts = global_regattempts_max+1; 09582 ast_sched_del(sched, r->timeout); 09583 ast_set_flag(p, SIP_NEEDDESTROY); 09584 break; 09585 case 404: /* Not found */ 09586 ast_log(LOG_WARNING, "Got 404 Not found on SIP register to service %s@%s, giving up\n", p->registry->username,p->registry->hostname); 09587 if (global_regattempts_max) 09588 p->registry->regattempts = global_regattempts_max+1; 09589 ast_set_flag(p, SIP_NEEDDESTROY); 09590 r->call = NULL; 09591 ast_sched_del(sched, r->timeout); 09592 break; 09593 case 407: /* Proxy auth */ 09594 if ((p->authtries == MAX_AUTHTRIES) || do_register_auth(p, req, "Proxy-Authenticate", "Proxy-Authorization")) { 09595 ast_log(LOG_NOTICE, "Failed to authenticate on REGISTER to '%s' (tries '%d')\n", get_header(&p->initreq, "From"), p->authtries); 09596 ast_set_flag(p, SIP_NEEDDESTROY); 09597 } 09598 break; 09599 case 479: /* SER: Not able to process the URI - address is wrong in register*/ 09600 ast_log(LOG_WARNING, "Got error 479 on register to %s@%s, giving up (check config)\n", p->registry->username,p->registry->hostname); 09601 if (global_regattempts_max) 09602 p->registry->regattempts = global_regattempts_max+1; 09603 ast_set_flag(p, SIP_NEEDDESTROY); 09604 r->call = NULL; 09605 ast_sched_del(sched, r->timeout); 09606 break; 09607 case 200: /* 200 OK */ 09608 if (!r) { 09609 ast_log(LOG_WARNING, "Got 200 OK on REGISTER that isn't a register\n"); 09610 ast_set_flag(p, SIP_NEEDDESTROY); 09611 return 0; 09612 } 09613 09614 r->regstate=REG_STATE_REGISTERED; 09615 manager_event(EVENT_FLAG_SYSTEM, "Registry", "Channel: SIP\r\nDomain: %s\r\nStatus: %s\r\n", r->hostname, regstate2str(r->regstate)); 09616 r->regattempts = 0; 09617 ast_log(LOG_DEBUG, "Registration successful\n"); 09618 if (r->timeout > -1) { 09619 ast_log(LOG_DEBUG, "Cancelling timeout %d\n", r->timeout); 09620 ast_sched_del(sched, r->timeout); 09621 } 09622 r->timeout=-1; 09623 r->call = NULL; 09624 p->registry = NULL; 09625 /* Let this one hang around until we have all the responses */ 09626 sip_scheddestroy(p, 32000); 09627 /* ast_set_flag(p, SIP_NEEDDESTROY); */ 09628 09629 /* set us up for re-registering */ 09630 /* figure out how long we got registered for */ 09631 if (r->expire > -1) 09632 ast_sched_del(sched, r->expire); 09633 /* according to section 6.13 of RFC, contact headers override 09634 expires headers, so check those first */ 09635 expires = 0; 09636 if (!ast_strlen_zero(get_header(req, "Contact"))) { 09637 char *contact = NULL; 09638 char *tmptmp = NULL; 09639 int start = 0; 09640 for(;;) { 09641 contact = __get_header(req, "Contact", &start); 09642 /* this loop ensures we get a contact header about our register request */ 09643 if(!ast_strlen_zero(contact)) { 09644 if( (tmptmp=strstr(contact, p->our_contact))) { 09645 contact=tmptmp; 09646 break; 09647 } 09648 } else 09649 break; 09650 } 09651 tmptmp = strcasestr(contact, "expires="); 09652 if (tmptmp) { 09653 if (sscanf(tmptmp + 8, "%d;", &expires) != 1) 09654 expires = 0; 09655 } 09656 09657 } 09658 if (!expires) 09659 expires=atoi(get_header(req, "expires")); 09660 if (!expires) 09661 expires=default_expiry; 09662 09663 expires_ms = expires * 1000; 09664 if (expires <= EXPIRY_GUARD_LIMIT) 09665 expires_ms -= MAX((expires_ms * EXPIRY_GUARD_PCT),EXPIRY_GUARD_MIN); 09666 else 09667 expires_ms -= EXPIRY_GUARD_SECS * 1000; 09668 if (sipdebug) 09669 ast_log(LOG_NOTICE, "Outbound Registration: Expiry for %s is %d sec (Scheduling reregistration in %d s)\n", r->hostname, expires, expires_ms/1000); 09670 09671 r->refresh= (int) expires_ms / 1000; 09672 09673 /* Schedule re-registration before we expire */ 09674 r->expire=ast_sched_add(sched, expires_ms, sip_reregister, r); 09675 ASTOBJ_UNREF(r, sip_registry_destroy); 09676 } 09677 return 1; 09678 }
|
|
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. 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 3953 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, sipmethod, and cfsip_methods::text. Referenced by initreqprep(), reqprep(), and transmit_register(). 03954 { 03955 /* Initialize a response */ 03956 if (req->headers || req->len) { 03957 ast_log(LOG_WARNING, "Request already initialized?!?\n"); 03958 return -1; 03959 } 03960 req->header[req->headers] = req->data + req->len; 03961 snprintf(req->header[req->headers], sizeof(req->data) - req->len, "%s %s SIP/2.0\r\n", sip_methods[sipmethod].text, recip); 03962 req->len += strlen(req->header[req->headers]); 03963 req->headers++; 03964 req->method = sipmethod; 03965 return 0; 03966 }
|
|
init_resp: Initialize SIP response, based on SIP request ---
Definition at line 3937 of file chan_sip.c. References ast_log(), sip_request::data, sip_request::header, sip_request::headers, sip_request::len, LOG_WARNING, and sip_request::method. Referenced by respprep(). 03938 { 03939 /* Initialize a response */ 03940 if (req->headers || req->len) { 03941 ast_log(LOG_WARNING, "Request already initialized?!?\n"); 03942 return -1; 03943 } 03944 req->method = SIP_RESPONSE; 03945 req->header[req->headers] = req->data + req->len; 03946 snprintf(req->header[req->headers], sizeof(req->data) - req->len, "SIP/2.0 %s\r\n", resp); 03947 req->len += strlen(req->header[req->headers]); 03948 req->headers++; 03949 return 0; 03950 }
|
|
initreqprep: Initiate new SIP request to peer/user ---
Definition at line 4710 of file chan_sip.c. References add_header(), ast_build_string(), AST_DIGIT_ANYNUM, ast_inet_ntoa(), ast_strlen_zero(), ast_test_flag, ast_uri_encode(), build_contact(), build_rpid(), sip_pvt::callid, sip_pvt::callingpres, ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, DEFAULT_MAX_FORWARDS, default_useragent, sip_pvt::exten, sip_pvt::fromdomain, sip_pvt::fromname, sip_pvt::fromuser, sip_pvt::fullcontact, init_req(), sip_pvt::lastmsg, sip_pvt::ocseq, sip_pvt::options, sip_pvt::our_contact, sip_pvt::ourip, ourport, sip_pvt::owner, sip_pvt::rpid, sip_pvt::rpid_from, sip_pvt::sa, sip_methods, SIP_SENDRPID, SIP_USEREQPHONE, sipmethod, sip_pvt::tag, cfsip_methods::text, sip_pvt::tohost, sip_pvt::uri, sip_invite_param::uri_options, sip_pvt::username, sip_pvt::via, and sip_invite_param::vxml_url. Referenced by sip_notify(), transmit_invite(), and transmit_notify_with_mwi(). 04711 { 04712 char invite_buf[256] = ""; 04713 char *invite = invite_buf; 04714 size_t invite_max = sizeof(invite_buf); 04715 char from[256]; 04716 char to[256]; 04717 char tmp[BUFSIZ/2]; 04718 char tmp2[BUFSIZ/2]; 04719 char iabuf[INET_ADDRSTRLEN]; 04720 char *l = NULL, *n = NULL; 04721 int x; 04722 char urioptions[256]=""; 04723 04724 if (ast_test_flag(p, SIP_USEREQPHONE)) { 04725 char onlydigits = 1; 04726 x=0; 04727 04728 /* Test p->username against allowed characters in AST_DIGIT_ANY 04729 If it matches the allowed characters list, then sipuser = ";user=phone" 04730 If not, then sipuser = "" 04731 */ 04732 /* + is allowed in first position in a tel: uri */ 04733 if (p->username && p->username[0] == '+') 04734 x=1; 04735 04736 for (; x < strlen(p->username); x++) { 04737 if (!strchr(AST_DIGIT_ANYNUM, p->username[x])) { 04738 onlydigits = 0; 04739 break; 04740 } 04741 } 04742 04743 /* If we have only digits, add ;user=phone to the uri */ 04744 if (onlydigits) 04745 strcpy(urioptions, ";user=phone"); 04746 } 04747 04748 04749 snprintf(p->lastmsg, sizeof(p->lastmsg), "Init: %s", sip_methods[sipmethod].text); 04750 04751 if (p->owner) { 04752 l = p->owner->cid.cid_num; 04753 n = p->owner->cid.cid_name; 04754 } 04755 /* if we are not sending RPID and user wants his callerid restricted */ 04756 if (!ast_test_flag(p, SIP_SENDRPID) && ((p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED)) { 04757 l = CALLERID_UNKNOWN; 04758 n = l; 04759 } 04760 if (!l) 04761 l = default_callerid; 04762 if (ast_strlen_zero(n)) 04763 n = l; 04764 /* Allow user to be overridden */ 04765 if (!ast_strlen_zero(p->fromuser)) 04766 l = p->fromuser; 04767 else /* Save for any further attempts */ 04768 ast_copy_string(p->fromuser, l, sizeof(p->fromuser)); 04769 04770 /* Allow user to be overridden */ 04771 if (!ast_strlen_zero(p->fromname)) 04772 n = p->fromname; 04773 else /* Save for any further attempts */ 04774 ast_copy_string(p->fromname, n, sizeof(p->fromname)); 04775 04776 if (pedanticsipchecking) { 04777 ast_uri_encode(n, tmp, sizeof(tmp), 0); 04778 n = tmp; 04779 ast_uri_encode(l, tmp2, sizeof(tmp2), 0); 04780 l = tmp2; 04781 } 04782 04783 if ((ourport != 5060) && ast_strlen_zero(p->fromdomain)) /* Needs to be 5060 */ 04784 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); 04785 else 04786 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); 04787 04788 /* If we're calling a registered SIP peer, use the fullcontact to dial to the peer */ 04789 if (!ast_strlen_zero(p->fullcontact)) { 04790 /* If we have full contact, trust it */ 04791 ast_build_string(&invite, &invite_max, "%s", p->fullcontact); 04792 } else { 04793 /* Otherwise, use the username while waiting for registration */ 04794 ast_build_string(&invite, &invite_max, "sip:"); 04795 if (!ast_strlen_zero(p->username)) { 04796 n = p->username; 04797 if (pedanticsipchecking) { 04798 ast_uri_encode(n, tmp, sizeof(tmp), 0); 04799 n = tmp; 04800 } 04801 ast_build_string(&invite, &invite_max, "%s@", n); 04802 } 04803 ast_build_string(&invite, &invite_max, "%s", p->tohost); 04804 if (ntohs(p->sa.sin_port) != 5060) /* Needs to be 5060 */ 04805 ast_build_string(&invite, &invite_max, ":%d", ntohs(p->sa.sin_port)); 04806 ast_build_string(&invite, &invite_max, "%s", urioptions); 04807 } 04808 04809 /* If custom URI options have been provided, append them */ 04810 if (p->options && p->options->uri_options) 04811 ast_build_string(&invite, &invite_max, ";%s", p->options->uri_options); 04812 04813 ast_copy_string(p->uri, invite_buf, sizeof(p->uri)); 04814 04815 /* If there is a VXML URL append it to the SIP URL */ 04816 if (p->options && p->options->vxml_url) { 04817 snprintf(to, sizeof(to), "<%s>;%s", p->uri, p->options->vxml_url); 04818 } else { 04819 snprintf(to, sizeof(to), "<%s>", p->uri); 04820 } 04821 memset(req, 0, sizeof(struct sip_request)); 04822 init_req(req, sipmethod, p->uri); 04823 snprintf(tmp, sizeof(tmp), "%d %s", ++p->ocseq, sip_methods[sipmethod].text); 04824 04825 add_header(req, "Via", p->via); 04826 /* SLD: FIXME?: do Route: here too? I think not cos this is the first request. 04827 * OTOH, then we won't have anything in p->route anyway */ 04828 /* Build Remote Party-ID and From */ 04829 if (ast_test_flag(p, SIP_SENDRPID) && (sipmethod == SIP_INVITE)) { 04830 build_rpid(p); 04831 add_header(req, "From", p->rpid_from); 04832 } else { 04833 add_header(req, "From", from); 04834 } 04835 add_header(req, "To", to); 04836 ast_copy_string(p->exten, l, sizeof(p->exten)); 04837 build_contact(p); 04838 add_header(req, "Contact", p->our_contact); 04839 add_header(req, "Call-ID", p->callid); 04840 add_header(req, "CSeq", tmp); 04841 add_header(req, "User-Agent", default_useragent); 04842 add_header(req, "Max-Forwards", DEFAULT_MAX_FORWARDS); 04843 if (p->rpid) 04844 add_header(req, "Remote-Party-ID", p->rpid); 04845 }
|
|
insecure2str: Convert Insecure setting to printable string ---
Definition at line 7609 of file chan_sip.c. Referenced by _sip_show_peer(). 07610 { 07611 if (port && invite) 07612 return "port,invite"; 07613 else if (port) 07614 return "port"; 07615 else if (invite) 07616 return "invite"; 07617 else 07618 return "no"; 07619 }
|
|
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 13235 of file chan_sip.c. 13236 {
13237 return ASTERISK_GPL_KEY;
13238 }
|
|
list_route: List all routes - mostly for debugging ---
Definition at line 5949 of file chan_sip.c. References ast_verbose(), sip_route::hop, and sip_route::next. Referenced by build_route(). 05950 { 05951 if (!route) { 05952 ast_verbose("list_route: no route\n"); 05953 return; 05954 } 05955 while (route) { 05956 ast_verbose("list_route: hop: <%s>\n", route->hop); 05957 route = route->next; 05958 } 05959 }
|
|
Initialize the module. Initialize the Agents module. This function is being called by Asterisk when loading the module. Among other thing it registers applications, cli commands and reads the cofiguration file.
Definition at line 13083 of file chan_sip.c. References app_dtmfmode, app_sipaddheader, app_sipgetheader, ast_channel_register(), ast_cli_register_multiple(), ast_custom_function_register(), ast_log(), ast_manager_register2(), ast_register_application(), ast_rtp_proto_register(), ASTOBJ_CONTAINER_INIT, channeltype, checksipdomain_function, descrip_dtmfmode, descrip_sipaddheader, descrip_sipgetheader, EVENT_FLAG_SYSTEM, io, io_context_create(), LOG_ERROR, LOG_WARNING, manager_sip_show_peer(), manager_sip_show_peers(), mandescr_show_peer, mandescr_show_peers, my_clis, peerl, regl, reload_config(), restart_monitor(), sched, sched_context_create(), sip_addheader(), sip_dtmfmode(), sip_getheader(), sip_header_function, sip_poke_all_peers(), sip_rtp, sip_send_all_registers(), sip_tech, sipchaninfo_function, sippeer_function, synopsis_dtmfmode, synopsis_sipaddheader, synopsis_sipgetheader, and userl. 13084 { 13085 ASTOBJ_CONTAINER_INIT(&userl); /* User object list */ 13086 ASTOBJ_CONTAINER_INIT(&peerl); /* Peer object list */ 13087 ASTOBJ_CONTAINER_INIT(®l); /* Registry object list */ 13088 13089 sched = sched_context_create(); 13090 if (!sched) { 13091 ast_log(LOG_WARNING, "Unable to create schedule context\n"); 13092 } 13093 13094 io = io_context_create(); 13095 if (!io) { 13096 ast_log(LOG_WARNING, "Unable to create I/O context\n"); 13097 } 13098 13099 reload_config(); /* Load the configuration from sip.conf */ 13100 13101 /* Make sure we can register our sip channel type */ 13102 if (ast_channel_register(&sip_tech)) { 13103 ast_log(LOG_ERROR, "Unable to register channel type %s\n", channeltype); 13104 return -1; 13105 } 13106 13107 /* Register all CLI functions for SIP */ 13108 ast_cli_register_multiple(my_clis, sizeof(my_clis)/ sizeof(my_clis[0])); 13109 13110 /* Tell the RTP subdriver that we're here */ 13111 ast_rtp_proto_register(&sip_rtp); 13112 13113 /* Register dialplan applications */ 13114 ast_register_application(app_dtmfmode, sip_dtmfmode, synopsis_dtmfmode, descrip_dtmfmode); 13115 13116 /* These will be removed soon */ 13117 ast_register_application(app_sipaddheader, sip_addheader, synopsis_sipaddheader, descrip_sipaddheader); 13118 ast_register_application(app_sipgetheader, sip_getheader, synopsis_sipgetheader, descrip_sipgetheader); 13119 13120 /* Register dialplan functions */ 13121 ast_custom_function_register(&sip_header_function); 13122 ast_custom_function_register(&sippeer_function); 13123 ast_custom_function_register(&sipchaninfo_function); 13124 ast_custom_function_register(&checksipdomain_function); 13125 13126 /* Register manager commands */ 13127 ast_manager_register2("SIPpeers", EVENT_FLAG_SYSTEM, manager_sip_show_peers, 13128 "List SIP peers (text format)", mandescr_show_peers); 13129 ast_manager_register2("SIPshowpeer", EVENT_FLAG_SYSTEM, manager_sip_show_peer, 13130 "Show SIP peer (text format)", mandescr_show_peer); 13131 13132 sip_poke_all_peers(); 13133 sip_send_all_registers(); 13134 13135 /* And start the monitor for the first time */ 13136 restart_monitor(); 13137 13138 return 0; 13139 }
|
|
lws2sws: Parse multiline SIP headers into one header
Definition at line 3264 of file chan_sip.c. Referenced by sipsock_read(). 03265 { 03266 int h = 0, t = 0; 03267 int lws = 0; 03268 03269 for (; h < len;) { 03270 /* Eliminate all CRs */ 03271 if (msgbuf[h] == '\r') { 03272 h++; 03273 continue; 03274 } 03275 /* Check for end-of-line */ 03276 if (msgbuf[h] == '\n') { 03277 /* Check for end-of-message */ 03278 if (h + 1 == len) 03279 break; 03280 /* Check for a continuation line */ 03281 if (msgbuf[h + 1] == ' ' || msgbuf[h + 1] == '\t') { 03282 /* Merge continuation line */ 03283 h++; 03284 continue; 03285 } 03286 /* Propagate LF and start new line */ 03287 msgbuf[t++] = msgbuf[h++]; 03288 lws = 0; 03289 continue; 03290 } 03291 if (msgbuf[h] == ' ' || msgbuf[h] == '\t') { 03292 if (lws) { 03293 h++; 03294 continue; 03295 } 03296 msgbuf[t++] = msgbuf[h++]; 03297 lws = 1; 03298 continue; 03299 } 03300 msgbuf[t++] = msgbuf[h++]; 03301 if (lws) 03302 lws = 0; 03303 } 03304 msgbuf[t] = '\0'; 03305 return t; 03306 }
|
|
Definition at line 3016 of file chan_sip.c. References thread_safe_rand(). Referenced by handle_request_invite(), handle_request_subscribe(), sip_alloc(), and transmit_register(). 03017 { 03018 snprintf(tagbuf, len, "as%08x", thread_safe_rand()); 03019 }
|
|
manager_sip_show_peer: Show SIP peers in the manager API ---
Definition at line 7829 of file chan_sip.c. References _sip_show_peer(), ast_cli(), ast_strlen_zero(), astman_get_header(), astman_send_error(), mansession::fd, and s. Referenced by load_module(). 07830 { 07831 char *id = astman_get_header(m,"ActionID"); 07832 char *a[4]; 07833 char *peer; 07834 int ret; 07835 07836 peer = astman_get_header(m,"Peer"); 07837 if (ast_strlen_zero(peer)) { 07838 astman_send_error(s, m, "Peer: <name> missing.\n"); 07839 return 0; 07840 } 07841 a[0] = "sip"; 07842 a[1] = "show"; 07843 a[2] = "peer"; 07844 a[3] = peer; 07845 07846 if (!ast_strlen_zero(id)) 07847 ast_cli(s->fd, "ActionID: %s\r\n",id); 07848 ret = _sip_show_peer(1, s->fd, s, m, 4, a ); 07849 ast_cli( s->fd, "\r\n\r\n" ); 07850 return ret; 07851 }
|
|
manager_sip_show_peers: Show SIP peers in the manager API ---
Definition at line 7410 of file chan_sip.c. References _sip_show_peers(), ast_cli(), ast_strlen_zero(), astman_get_header(), astman_send_ack(), mansession::fd, and s. Referenced by load_module(). 07411 { 07412 char *id = astman_get_header(m,"ActionID"); 07413 char *a[] = { "sip", "show", "peers" }; 07414 char idtext[256] = ""; 07415 int total = 0; 07416 07417 if (!ast_strlen_zero(id)) 07418 snprintf(idtext,256,"ActionID: %s\r\n",id); 07419 07420 astman_send_ack(s, m, "Peer status list will follow"); 07421 /* List the peers in separate manager events */ 07422 _sip_show_peers(s->fd, &total, s, m, 3, a); 07423 /* Send final confirmation */ 07424 ast_cli(s->fd, 07425 "Event: PeerlistComplete\r\n" 07426 "ListItems: %d\r\n" 07427 "%s" 07428 "\r\n", total, idtext); 07429 return 0; 07430 }
|
|
nat2str: Convert NAT setting to text string
Definition at line 7312 of file chan_sip.c. References SIP_NAT_ALWAYS, SIP_NAT_NEVER, SIP_NAT_RFC3581, and SIP_NAT_ROUTE. Referenced by _sip_show_peer(), sip_show_channel(), sip_show_settings(), and sip_show_users(). 07313 { 07314 switch(nat) { 07315 case SIP_NAT_NEVER: 07316 return "No"; 07317 case SIP_NAT_ROUTE: 07318 return "Route"; 07319 case SIP_NAT_ALWAYS: 07320 return "Always"; 07321 case SIP_NAT_RFC3581: 07322 return "RFC3581"; 07323 default: 07324 return "Unknown"; 07325 } 07326 }
|
|
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 9377 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(). 09378 { 09379 char tmp[256]; 09380 char *s, *e; 09381 ast_copy_string(tmp, get_header(req, "Contact"), sizeof(tmp)); 09382 s = get_in_brackets(tmp); 09383 e = strchr(s, ';'); 09384 if (e) 09385 *e = '\0'; 09386 if (ast_test_flag(p, SIP_PROMISCREDIR)) { 09387 if (!strncasecmp(s, "sip:", 4)) 09388 s += 4; 09389 e = strchr(s, '/'); 09390 if (e) 09391 *e = '\0'; 09392 ast_log(LOG_DEBUG, "Found promiscuous redirection to 'SIP/%s'\n", s); 09393 if (p->owner) 09394 snprintf(p->owner->call_forward, sizeof(p->owner->call_forward), "SIP/%s", s); 09395 } else { 09396 e = strchr(tmp, '@'); 09397 if (e) 09398 *e = '\0'; 09399 e = strchr(tmp, '/'); 09400 if (e) 09401 *e = '\0'; 09402 if (!strncasecmp(s, "sip:", 4)) 09403 s += 4; 09404 ast_log(LOG_DEBUG, "Found 302 Redirect to extension '%s'\n", s); 09405 if (p->owner) 09406 ast_copy_string(p->owner->call_forward, s, sizeof(p->owner->call_forward)); 09407 } 09408 }
|
|
parse_ok_contact: Parse contact header for 200 OK on INVITE ---
Definition at line 5710 of file chan_sip.c. References ahp, ast_gethostbyname(), ast_log(), ast_test_flag, sip_pvt::fullcontact, get_header(), get_in_brackets(), hp, LOG_NOTICE, LOG_WARNING, sip_pvt::okcontacturi, sip_pvt::recv, sip_pvt::sa, and SIP_NAT. Referenced by handle_response_invite(). 05711 { 05712 char contact[250]; 05713 char *c, *n, *pt; 05714 int port; 05715 struct hostent *hp; 05716 struct ast_hostent ahp; 05717 struct sockaddr_in oldsin; 05718 05719 /* Look for brackets */ 05720 ast_copy_string(contact, get_header(req, "Contact"), sizeof(contact)); 05721 c = get_in_brackets(contact); 05722 05723 /* Save full contact to call pvt for later bye or re-invite */ 05724 ast_copy_string(pvt->fullcontact, c, sizeof(pvt->fullcontact)); 05725 05726 /* Save URI for later ACKs, BYE or RE-invites */ 05727 ast_copy_string(pvt->okcontacturi, c, sizeof(pvt->okcontacturi)); 05728 05729 /* Make sure it's a SIP URL */ 05730 if (strncasecmp(c, "sip:", 4)) { 05731 ast_log(LOG_NOTICE, "'%s' is not a valid SIP contact (missing sip:) trying to use anyway\n", c); 05732 } else 05733 c += 4; 05734 05735 /* Ditch arguments */ 05736 n = strchr(c, ';'); 05737 if (n) 05738 *n = '\0'; 05739 05740 /* Grab host */ 05741 n = strchr(c, '@'); 05742 if (!n) { 05743 n = c; 05744 c = NULL; 05745 } else { 05746 *n = '\0'; 05747 n++; 05748 } 05749 pt = strchr(n, ':'); 05750 if (pt) { 05751 *pt = '\0'; 05752 pt++; 05753 port = atoi(pt); 05754 } else 05755 port = DEFAULT_SIP_PORT; 05756 05757 memcpy(&oldsin, &pvt->sa, sizeof(oldsin)); 05758 05759 if (!(ast_test_flag(pvt, SIP_NAT) & SIP_NAT_ROUTE)) { 05760 /* XXX This could block for a long time XXX */ 05761 /* We should only do this if it's a name, not an IP */ 05762 hp = ast_gethostbyname(n, &ahp); 05763 if (!hp) { 05764 ast_log(LOG_WARNING, "Invalid host '%s'\n", n); 05765 return -1; 05766 } 05767 pvt->sa.sin_family = AF_INET; 05768 memcpy(&pvt->sa.sin_addr, hp->h_addr, sizeof(pvt->sa.sin_addr)); 05769 pvt->sa.sin_port = htons(port); 05770 } else { 05771 /* Don't trust the contact field. Just use what they came to us 05772 with. */ 05773 memcpy(&pvt->sa, &pvt->recv, sizeof(pvt->sa)); 05774 } 05775 return 0; 05776 }
|
|
parse_register_contact: Parse contact header and save registration ---
Definition at line 5786 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(), 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(), option_verbose, sip_pvt::our_contact, parse_register_result, sip_pvt::recv, register_peer_exten(), sched, SIP_NAT, 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(). 05787 { 05788 char contact[80]; 05789 char data[256]; 05790 char iabuf[INET_ADDRSTRLEN]; 05791 char *expires = get_header(req, "Expires"); 05792 int expiry = atoi(expires); 05793 char *c, *n, *pt; 05794 int port; 05795 char *useragent; 05796 struct hostent *hp; 05797 struct ast_hostent ahp; 05798 struct sockaddr_in oldsin; 05799 05800 if (ast_strlen_zero(expires)) { /* No expires header */ 05801 expires = strcasestr(get_header(req, "Contact"), ";expires="); 05802 if (expires) { 05803 char *ptr; 05804 if ((ptr = strchr(expires, ';'))) 05805 *ptr = '\0'; 05806 if (sscanf(expires + 9, "%d", &expiry) != 1) 05807 expiry = default_expiry; 05808 } else { 05809 /* Nothing has been specified */ 05810 expiry = default_expiry; 05811 } 05812 } 05813 /* Look for brackets */ 05814 ast_copy_string(contact, get_header(req, "Contact"), sizeof(contact)); 05815 if (strchr(contact, '<') == NULL) { /* No <, check for ; and strip it */ 05816 char *ptr = strchr(contact, ';'); /* This is Header options, not URI options */ 05817 if (ptr) 05818 *ptr = '\0'; 05819 } 05820 c = get_in_brackets(contact); 05821 05822 /* if they did not specify Contact: or Expires:, they are querying 05823 what we currently have stored as their contact address, so return 05824 it 05825 */ 05826 if (ast_strlen_zero(c) && ast_strlen_zero(expires)) { 05827 /* If we have an active registration, tell them when the registration is going to expire */ 05828 if ((p->expire > -1) && !ast_strlen_zero(p->fullcontact)) { 05829 pvt->expiry = ast_sched_when(sched, p->expire); 05830 } 05831 return PARSE_REGISTER_QUERY; 05832 } else if (!strcasecmp(c, "*") || !expiry) { /* Unregister this peer */ 05833 /* This means remove all registrations and return OK */ 05834 memset(&p->addr, 0, sizeof(p->addr)); 05835 if (p->expire > -1) 05836 ast_sched_del(sched, p->expire); 05837 p->expire = -1; 05838 05839 destroy_association(p); 05840 05841 register_peer_exten(p, 0); 05842 p->fullcontact[0] = '\0'; 05843 p->useragent[0] = '\0'; 05844 p->sipoptions = 0; 05845 p->lastms = 0; 05846 05847 if (option_verbose > 2) 05848 ast_verbose(VERBOSE_PREFIX_3 "Unregistered SIP '%s'\n", p->name); 05849 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unregistered\r\n", p->name); 05850 return PARSE_REGISTER_UPDATE; 05851 } 05852 ast_copy_string(p->fullcontact, c, sizeof(p->fullcontact)); 05853 /* For the 200 OK, we should use the received contact */ 05854 snprintf(pvt->our_contact, sizeof(pvt->our_contact) - 1, "<%s>", c); 05855 /* Make sure it's a SIP URL */ 05856 if (strncasecmp(c, "sip:", 4)) { 05857 ast_log(LOG_NOTICE, "'%s' is not a valid SIP contact (missing sip:) trying to use anyway\n", c); 05858 } else 05859 c += 4; 05860 /* Ditch q */ 05861 n = strchr(c, ';'); 05862 if (n) { 05863 *n = '\0'; 05864 } 05865 /* Grab host */ 05866 n = strchr(c, '@'); 05867 if (!n) { 05868 n = c; 05869 c = NULL; 05870 } else { 05871 *n = '\0'; 05872 n++; 05873 } 05874 pt = strchr(n, ':'); 05875 if (pt) { 05876 *pt = '\0'; 05877 pt++; 05878 port = atoi(pt); 05879 } else 05880 port = DEFAULT_SIP_PORT; 05881 memcpy(&oldsin, &p->addr, sizeof(oldsin)); 05882 if (!(ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE)) { 05883 /* XXX This could block for a long time XXX */ 05884 hp = ast_gethostbyname(n, &ahp); 05885 if (!hp) { 05886 ast_log(LOG_WARNING, "Invalid host '%s'\n", n); 05887 return PARSE_REGISTER_FAILED; 05888 } 05889 p->addr.sin_family = AF_INET; 05890 memcpy(&p->addr.sin_addr, hp->h_addr, sizeof(p->addr.sin_addr)); 05891 p->addr.sin_port = htons(port); 05892 } else { 05893 /* Don't trust the contact field. Just use what they came to us 05894 with */ 05895 memcpy(&p->addr, &pvt->recv, sizeof(p->addr)); 05896 } 05897 05898 if (c) /* Overwrite the default username from config at registration */ 05899 ast_copy_string(p->username, c, sizeof(p->username)); 05900 else 05901 p->username[0] = '\0'; 05902 05903 if (p->expire > -1) 05904 ast_sched_del(sched, p->expire); 05905 if ((expiry < 1) || (expiry > max_expiry)) 05906 expiry = max_expiry; 05907 if (!ast_test_flag(p, SIP_REALTIME)) 05908 p->expire = ast_sched_add(sched, (expiry + 10) * 1000, expire_register, p); 05909 else 05910 p->expire = -1; 05911 pvt->expiry = expiry; 05912 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); 05913 if (!ast_test_flag((&p->flags_page2), SIP_PAGE2_RT_FROMCONTACT)) 05914 ast_db_put("SIP/Registry", p->name, data); 05915 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Registered\r\n", p->name); 05916 if (inaddrcmp(&p->addr, &oldsin)) { 05917 sip_poke_peer(p); 05918 if (option_verbose > 2) 05919 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); 05920 register_peer_exten(p, 1); 05921 } 05922 05923 /* Save SIP options profile */ 05924 p->sipoptions = pvt->sipoptions; 05925 05926 /* Save User agent */ 05927 useragent = get_header(req, "User-Agent"); 05928 if (useragent && strcasecmp(useragent, p->useragent)) { 05929 ast_copy_string(p->useragent, useragent, sizeof(p->useragent)); 05930 if (option_verbose > 3) { 05931 ast_verbose(VERBOSE_PREFIX_3 "Saved useragent \"%s\" for peer %s\n",p->useragent,p->name); 05932 } 05933 } 05934 return PARSE_REGISTER_UPDATE; 05935 }
|
|
parse_request: Parse a SIP message ----
Definition at line 3309 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(). 03310 { 03311 /* Divide fields by NULL's */ 03312 char *c; 03313 int f = 0; 03314 03315 c = req->data; 03316 03317 /* First header starts immediately */ 03318 req->header[f] = c; 03319 while(*c) { 03320 if (*c == '\n') { 03321 /* We've got a new header */ 03322 *c = 0; 03323 03324 if (sipdebug && option_debug > 3) 03325 ast_log(LOG_DEBUG, "Header %d: %s (%d)\n", f, req->header[f], (int) strlen(req->header[f])); 03326 if (ast_strlen_zero(req->header[f])) { 03327 /* Line by itself means we're now in content */ 03328 c++; 03329 break; 03330 } 03331 if (f >= SIP_MAX_HEADERS - 1) { 03332 ast_log(LOG_WARNING, "Too many SIP headers. Ignoring.\n"); 03333 } else 03334 f++; 03335 req->header[f] = c + 1; 03336 } else if (*c == '\r') { 03337 /* Ignore but eliminate \r's */ 03338 *c = 0; 03339 } 03340 c++; 03341 } 03342 /* Check for last header */ 03343 if (!ast_strlen_zero(req->header[f])) { 03344 if (sipdebug && option_debug > 3) 03345 ast_log(LOG_DEBUG, "Header %d: %s (%d)\n", f, req->header[f], (int) strlen(req->header[f])); 03346 f++; 03347 } 03348 req->headers = f; 03349 /* Now we process any mime content */ 03350 f = 0; 03351 req->line[f] = c; 03352 while(*c) { 03353 if (*c == '\n') { 03354 /* We've got a new line */ 03355 *c = 0; 03356 if (sipdebug && option_debug > 3) 03357 ast_log(LOG_DEBUG, "Line: %s (%d)\n", req->line[f], (int) strlen(req->line[f])); 03358 if (f >= SIP_MAX_LINES - 1) { 03359 ast_log(LOG_WARNING, "Too many SDP lines. Ignoring.\n"); 03360 } else 03361 f++; 03362 req->line[f] = c + 1; 03363 } else if (*c == '\r') { 03364 /* Ignore and eliminate \r's */ 03365 *c = 0; 03366 } 03367 c++; 03368 } 03369 /* Check for last line */ 03370 if (!ast_strlen_zero(req->line[f])) 03371 f++; 03372 req->lines = f; 03373 if (*c) 03374 ast_log(LOG_WARNING, "Odd content, extra stuff left over ('%s')\n", c); 03375 /* Split up the first line parts */ 03376 determine_firstline_parts(req); 03377 }
|
|
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(), sip_pvt::callid, cfsip_options::id, LOG_DEBUG, option_debug, sip_options, sip_pvt::sipoptions, 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 7330 of file chan_sip.c. References sip_peer::lastms, and sip_peer::maxms. Referenced by __iax2_show_peers(), _sip_show_peer(), _sip_show_peers(), function_iaxpeer(), function_sippeer(), and iax2_show_peer(). 07331 { 07332 int res = 0; 07333 if (peer->maxms) { 07334 if (peer->lastms < 0) { 07335 ast_copy_string(status, "UNREACHABLE", statuslen); 07336 } else if (peer->lastms > peer->maxms) { 07337 snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms); 07338 res = 1; 07339 } else if (peer->lastms) { 07340 snprintf(status, statuslen, "OK (%d ms)", peer->lastms); 07341 res = 1; 07342 } else { 07343 ast_copy_string(status, "UNKNOWN", statuslen); 07344 } 07345 } else { 07346 ast_copy_string(status, "Unmonitored", statuslen); 07347 /* Checking if port is 0 */ 07348 res = -1; 07349 } 07350 return res; 07351 }
|
|
print_codec_to_cli: Print codec list from preference to CLI/manager
Definition at line 7769 of file chan_sip.c. References ast_cli(), ast_codec_pref_index(), and ast_getformatname(). Referenced by _sip_show_peer(), and sip_show_settings(). 07770 { 07771 int x, codec; 07772 07773 for(x = 0; x < 32 ; x++) { 07774 codec = ast_codec_pref_index(pref, x); 07775 if (!codec) 07776 break; 07777 ast_cli(fd, "%s", ast_getformatname(codec)); 07778 if (x < 31 && ast_codec_pref_index(pref, x + 1)) 07779 ast_cli(fd, ","); 07780 } 07781 if (!x) 07782 ast_cli(fd, "none"); 07783 }
|
|
print_group: Print call group and pickup group ---
Definition at line 7586 of file chan_sip.c. References ast_cli(), and ast_print_group(). Referenced by _sip_show_peer(), and sip_show_user(). 07587 { 07588 char buf[256]; 07589 ast_cli(fd, crlf ? "%s\r\n" : "%s\n", ast_print_group(buf, sizeof(buf), group) ); 07590 }
|
|
process_sdp: Process SIP SDP and activate RTP channels---
Definition at line 3380 of file chan_sip.c. References ahp, append_history(), ast_bridged_channel(), ast_clear_flag, ast_codec_choose(), ast_getformatname_multiple(), ast_gethostbyname(), ast_inet_ntoa(), ast_log(), ast_moh_start(), ast_moh_stop(), ast_queue_frame(), 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, EVENT_FLAG_CALL, get_header(), get_sdp(), get_sdp_iterate(), 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, sip_pvt::peercapability, sip_pvt::prefs, ast_channel::readformat, sip_pvt::rtp, sdpLineNum_iterator_init(), SIP_CALL_ONHOLD, sip_debug_test_pvt(), SIP_DTMF, SIP_DTMF_INBAND, SIP_DTMF_RFC2833, SIP_NOVIDEO, ast_channel::uniqueid, sip_pvt::vrtp, and ast_channel::writeformat. Referenced by handle_request(), handle_request_invite(), handle_response(), and handle_response_invite(). 03381 { 03382 char *m; 03383 char *c; 03384 char *a; 03385 char host[258]; 03386 char iabuf[INET_ADDRSTRLEN]; 03387 int len = -1; 03388 int portno = -1; 03389 int vportno = -1; 03390 int peercapability, peernoncodeccapability; 03391 int vpeercapability=0, vpeernoncodeccapability=0; 03392 struct sockaddr_in sin; 03393 char *codecs; 03394 struct hostent *hp; 03395 struct ast_hostent ahp; 03396 int codec; 03397 int destiterator = 0; 03398 int iterator; 03399 int sendonly = 0; 03400 int x,y; 03401 int debug=sip_debug_test_pvt(p); 03402 struct ast_channel *bridgepeer = NULL; 03403 03404 if (!p->rtp) { 03405 ast_log(LOG_ERROR, "Got SDP but have no RTP session allocated.\n"); 03406 return -1; 03407 } 03408 03409 /* Update our last rtprx when we receive an SDP, too */ 03410 time(&p->lastrtprx); 03411 time(&p->lastrtptx); 03412 03413 /* Get codec and RTP info from SDP */ 03414 if (strcasecmp(get_header(req, "Content-Type"), "application/sdp")) { 03415 ast_log(LOG_NOTICE, "Content is '%s', not 'application/sdp'\n", get_header(req, "Content-Type")); 03416 return -1; 03417 } 03418 m = get_sdp(req, "m"); 03419 sdpLineNum_iterator_init(&destiterator); 03420 c = get_sdp_iterate(&destiterator, req, "c"); 03421 if (ast_strlen_zero(m) || ast_strlen_zero(c)) { 03422 ast_log(LOG_WARNING, "Insufficient information for SDP (m = '%s', c = '%s')\n", m, c); 03423 return -1; 03424 } 03425 if (sscanf(c, "IN IP4 %256s", host) != 1) { 03426 ast_log(LOG_WARNING, "Invalid host in c= line, '%s'\n", c); 03427 return -1; 03428 } 03429 /* XXX This could block for a long time, and block the main thread! XXX */ 03430 hp = ast_gethostbyname(host, &ahp); 03431 if (!hp) { 03432 ast_log(LOG_WARNING, "Unable to lookup host in c= line, '%s'\n", c); 03433 return -1; 03434 } 03435 sdpLineNum_iterator_init(&iterator); 03436 ast_set_flag(p, SIP_NOVIDEO); 03437 while ((m = get_sdp_iterate(&iterator, req, "m"))[0] != '\0') { 03438 int found = 0; 03439 if ((sscanf(m, "audio %d/%d RTP/AVP %n", &x, &y, &len) == 2) || 03440 (sscanf(m, "audio %d RTP/AVP %n", &x, &len) == 1)) { 03441 found = 1; 03442 portno = x; 03443 /* Scan through the RTP payload types specified in a "m=" line: */ 03444 ast_rtp_pt_clear(p->rtp); 03445 codecs = m + len; 03446 while(!ast_strlen_zero(codecs)) { 03447 if (sscanf(codecs, "%d%n", &codec, &len) != 1) { 03448 ast_log(LOG_WARNING, "Error in codec string '%s'\n", codecs); 03449 return -1; 03450 } 03451 if (debug) 03452 ast_verbose("Found RTP audio format %d\n", codec); 03453 ast_rtp_set_m_type(p->rtp, codec); 03454 codecs = ast_skip_blanks(codecs + len); 03455 } 03456 } 03457 if (p->vrtp) 03458 ast_rtp_pt_clear(p->vrtp); /* Must be cleared in case no m=video line exists */ 03459 03460 if (p->vrtp && (sscanf(m, "video %d RTP/AVP %n", &x, &len) == 1)) { 03461 found = 1; 03462 ast_clear_flag(p, SIP_NOVIDEO); 03463 vportno = x; 03464 /* Scan through the RTP payload types specified in a "m=" line: */ 03465 codecs = m + len; 03466 while(!ast_strlen_zero(codecs)) { 03467 if (sscanf(codecs, "%d%n", &codec, &len) != 1) { 03468 ast_log(LOG_WARNING, "Error in codec string '%s'\n", codecs); 03469 return -1; 03470 } 03471 if (debug) 03472 ast_verbose("Found RTP video format %d\n", codec); 03473 ast_rtp_set_m_type(p->vrtp, codec); 03474 codecs = ast_skip_blanks(codecs + len); 03475 } 03476 } 03477 if (!found ) 03478 ast_log(LOG_WARNING, "Unknown SDP media type in offer: %s\n", m); 03479 } 03480 if (portno == -1 && vportno == -1) { 03481 /* No acceptable offer found in SDP */ 03482 return -2; 03483 } 03484 /* Check for Media-description-level-address for audio */ 03485 if (pedanticsipchecking) { 03486 c = get_sdp_iterate(&destiterator, req, "c"); 03487 if (!ast_strlen_zero(c)) { 03488 if (sscanf(c, "IN IP4 %256s", host) != 1) { 03489 ast_log(LOG_WARNING, "Invalid secondary host in c= line, '%s'\n", c); 03490 } else { 03491 /* XXX This could block for a long time, and block the main thread! XXX */ 03492 hp = ast_gethostbyname(host, &ahp); 03493 if (!hp) { 03494 ast_log(LOG_WARNING, "Unable to lookup host in secondary c= line, '%s'\n", c); 03495 } 03496 } 03497 } 03498 } 03499 /* RTP addresses and ports for audio and video */ 03500 sin.sin_family = AF_INET; 03501 memcpy(&sin.sin_addr, hp->h_addr, sizeof(sin.sin_addr)); 03502 03503 /* Setup audio port number */ 03504 sin.sin_port = htons(portno); 03505 if (p->rtp && sin.sin_port) { 03506 ast_rtp_set_peer(p->rtp, &sin); 03507 if (debug) { 03508 ast_verbose("Peer audio RTP is at port %s:%d\n", ast_inet_ntoa(iabuf,sizeof(iabuf), sin.sin_addr), ntohs(sin.sin_port)); 03509 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)); 03510 } 03511 } 03512 /* Check for Media-description-level-address for video */ 03513 if (pedanticsipchecking) { 03514 c = get_sdp_iterate(&destiterator, req, "c"); 03515 if (!ast_strlen_zero(c)) { 03516 if (sscanf(c, "IN IP4 %256s", host) != 1) { 03517 ast_log(LOG_WARNING, "Invalid secondary host in c= line, '%s'\n", c); 03518 } else { 03519 /* XXX This could block for a long time, and block the main thread! XXX */ 03520 hp = ast_gethostbyname(host, &ahp); 03521 if (!hp) { 03522 ast_log(LOG_WARNING, "Unable to lookup host in secondary c= line, '%s'\n", c); 03523 } 03524 } 03525 } 03526 } 03527 /* Setup video port number */ 03528 sin.sin_port = htons(vportno); 03529 if (p->vrtp && sin.sin_port) { 03530 ast_rtp_set_peer(p->vrtp, &sin); 03531 if (debug) { 03532 ast_verbose("Peer video RTP is at port %s:%d\n", ast_inet_ntoa(iabuf,sizeof(iabuf), sin.sin_addr), ntohs(sin.sin_port)); 03533 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)); 03534 } 03535 } 03536 03537 /* Next, scan through each "a=rtpmap:" line, noting each 03538 * specified RTP payload type (with corresponding MIME subtype): 03539 */ 03540 sdpLineNum_iterator_init(&iterator); 03541 while ((a = get_sdp_iterate(&iterator, req, "a"))[0] != '\0') { 03542 char* mimeSubtype = ast_strdupa(a); /* ensures we have enough space */ 03543 if (!strcasecmp(a, "sendonly")) { 03544 sendonly=1; 03545 continue; 03546 } 03547 if (!strcasecmp(a, "sendrecv")) { 03548 sendonly=0; 03549 } 03550 if (sscanf(a, "rtpmap: %u %[^/]/", &codec, mimeSubtype) != 2) continue; 03551 if (debug) 03552 ast_verbose("Found description format %s\n", mimeSubtype); 03553 /* Note: should really look at the 'freq' and '#chans' params too */ 03554 ast_rtp_set_rtpmap_type(p->rtp, codec, "audio", mimeSubtype); 03555 if (p->vrtp) 03556 ast_rtp_set_rtpmap_type(p->vrtp, codec, "video", mimeSubtype); 03557 } 03558 03559 /* Now gather all of the codecs that were asked for: */ 03560 ast_rtp_get_current_formats(p->rtp, 03561 &peercapability, &peernoncodeccapability); 03562 if (p->vrtp) 03563 ast_rtp_get_current_formats(p->vrtp, 03564 &vpeercapability, &vpeernoncodeccapability); 03565 p->jointcapability = p->capability & (peercapability | vpeercapability); 03566 p->peercapability = (peercapability | vpeercapability); 03567 p->noncodeccapability = noncodeccapability & peernoncodeccapability; 03568 03569 if (ast_test_flag(p, SIP_DTMF) == SIP_DTMF_AUTO) { 03570 ast_clear_flag(p, SIP_DTMF); 03571 if (p->noncodeccapability & AST_RTP_DTMF) { 03572 /* XXX Would it be reasonable to drop the DSP at this point? XXX */ 03573 ast_set_flag(p, SIP_DTMF_RFC2833); 03574 } else { 03575 ast_set_flag(p, SIP_DTMF_INBAND); 03576 } 03577 } 03578 03579 if (debug) { 03580 /* shame on whoever coded this.... */ 03581 const unsigned slen=512; 03582 char s1[slen], s2[slen], s3[slen], s4[slen]; 03583 03584 ast_verbose("Capabilities: us - %s, peer - audio=%s/video=%s, combined - %s\n", 03585 ast_getformatname_multiple(s1, slen, p->capability), 03586 ast_getformatname_multiple(s2, slen, peercapability), 03587 ast_getformatname_multiple(s3, slen, vpeercapability), 03588 ast_getformatname_multiple(s4, slen, p->jointcapability)); 03589 03590 ast_verbose("Non-codec capabilities: us - %s, peer - %s, combined - %s\n", 03591 ast_rtp_lookup_mime_multiple(s1, slen, noncodeccapability, 0), 03592 ast_rtp_lookup_mime_multiple(s2, slen, peernoncodeccapability, 0), 03593 ast_rtp_lookup_mime_multiple(s3, slen, p->noncodeccapability, 0)); 03594 } 03595 if (!p->jointcapability) { 03596 ast_log(LOG_NOTICE, "No compatible codecs!\n"); 03597 return -1; 03598 } 03599 03600 if (!p->owner) /* There's no open channel owning us */ 03601 return 0; 03602 03603 if (!(p->owner->nativeformats & p->jointcapability)) { 03604 const unsigned slen=512; 03605 char s1[slen], s2[slen]; 03606 ast_log(LOG_DEBUG, "Oooh, we need to change our formats since our peer supports only %s and not %s\n", 03607 ast_getformatname_multiple(s1, slen, p->jointcapability), 03608 ast_getformatname_multiple(s2, slen, p->owner->nativeformats)); 03609 p->owner->nativeformats = ast_codec_choose(&p->prefs, p->jointcapability, 1); 03610 ast_set_read_format(p->owner, p->owner->readformat); 03611 ast_set_write_format(p->owner, p->owner->writeformat); 03612 } 03613 if ((bridgepeer=ast_bridged_channel(p->owner))) { 03614 /* We have a bridge */ 03615 /* Turn on/off music on hold if we are holding/unholding */ 03616 struct ast_frame af = { AST_FRAME_NULL, }; 03617 if (sin.sin_addr.s_addr && !sendonly) { 03618 ast_moh_stop(bridgepeer); 03619 03620 /* Activate a re-invite */ 03621 ast_queue_frame(p->owner, &af); 03622 } else { 03623 /* No address for RTP, we're on hold */ 03624 03625 ast_moh_start(bridgepeer, NULL); 03626 if (sendonly) 03627 ast_rtp_stop(p->rtp); 03628 /* Activate a re-invite */ 03629 ast_queue_frame(p->owner, &af); 03630 } 03631 } 03632 03633 /* Manager Hold and Unhold events must be generated, if necessary */ 03634 if (sin.sin_addr.s_addr && !sendonly) { 03635 append_history(p, "Unhold", req->data); 03636 03637 if (callevents && ast_test_flag(p, SIP_CALL_ONHOLD)) { 03638 manager_event(EVENT_FLAG_CALL, "Unhold", 03639 "Channel: %s\r\n" 03640 "Uniqueid: %s\r\n", 03641 p->owner->name, 03642 p->owner->uniqueid); 03643 03644 } 03645 ast_clear_flag(p, SIP_CALL_ONHOLD); 03646 } else { 03647 /* No address for RTP, we're on hold */ 03648 append_history(p, "Hold", req->data); 03649 03650 if (callevents && !ast_test_flag(p, SIP_CALL_ONHOLD)) { 03651 manager_event(EVENT_FLAG_CALL, "Hold", 03652 "Channel: %s\r\n" 03653 "Uniqueid: %s\r\n", 03654 p->owner->name, 03655 p->owner->uniqueid); 03656 } 03657 ast_set_flag(p, SIP_CALL_ONHOLD); 03658 } 03659 03660 return 0; 03661 }
|
|
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. Referenced by authenticate_reply(), find_peer(), and iax2_getpeername(). 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(), and ast_update_realtime(). Referenced by update_peer(), and update_registry(). 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(), sip_user::flags_page2, global_flags_page2, ast_variable::name, ast_variable::next, ruserobjs, SIP_PAGE2_RTCACHEFRIENDS, SIP_REALTIME, suserobjs, userl, ast_variable::value, and var. Referenced by check_access(), and find_user(). 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 7225 of file chan_sip.c. References ast_log(), ast_queue_frame(), ast_set_flag, ast_verbose(), sip_pvt::callid, ast_frame::data, ast_frame::datalen, ast_frame::frametype, get_header(), get_msg_text(), LOG_WARNING, ast_frame::offset, sip_pvt::owner, sip_debug_test_pvt(), SIP_NEEDDESTROY, ast_frame::subclass, and transmit_response(). Referenced by handle_request_message(). 07226 { 07227 char buf[1024]; 07228 struct ast_frame f; 07229 char *content_type; 07230 07231 content_type = get_header(req, "Content-Type"); 07232 if (strcmp(content_type, "text/plain")) { /* No text/plain attachment */ 07233 transmit_response(p, "415 Unsupported Media Type", req); /* Good enough, or? */ 07234 ast_set_flag(p, SIP_NEEDDESTROY); 07235 return; 07236 } 07237 07238 if (get_msg_text(buf, sizeof(buf), req)) { 07239 ast_log(LOG_WARNING, "Unable to retrieve text from %s\n", p->callid); 07240 transmit_response(p, "202 Accepted", req); 07241 ast_set_flag(p, SIP_NEEDDESTROY); 07242 return; 07243 } 07244 07245 if (p->owner) { 07246 if (sip_debug_test_pvt(p)) 07247 ast_verbose("Message received: '%s'\n", buf); 07248 memset(&f, 0, sizeof(f)); 07249 f.frametype = AST_FRAME_TEXT; 07250 f.subclass = 0; 07251 f.offset = 0; 07252 f.data = buf; 07253 f.datalen = strlen(buf); 07254 ast_queue_frame(p->owner, &f); 07255 transmit_response(p, "202 Accepted", req); /* We respond 202 accepted, since we relay the message */ 07256 } else { /* Message outside of a call, we do not support that */ 07257 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); 07258 transmit_response(p, "405 Method Not Allowed", req); /* Good enough, or? */ 07259 } 07260 ast_set_flag(p, SIP_NEEDDESTROY); 07261 return; 07262 }
|
|
reg_source_db: Get registration details from Asterisk DB ---
Definition at line 5649 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(), sched, SIP_PAGE2_RT_FROMCONTACT, sip_poke_peer(), sip_poke_peer_s(), sipsock, strsep(), thread_safe_rand(), sip_peer::username, and VERBOSE_PREFIX_3. Referenced by build_peer(), realtime_peer(), set_config(), and temp_peer(). 05650 { 05651 char data[256]; 05652 char iabuf[INET_ADDRSTRLEN]; 05653 struct in_addr in; 05654 int expiry; 05655 int port; 05656 char *scan, *addr, *port_str, *expiry_str, *username, *contact; 05657 05658 if (ast_test_flag(&(peer->flags_page2), SIP_PAGE2_RT_FROMCONTACT)) 05659 return; 05660 if (ast_db_get("SIP/Registry", peer->name, data, sizeof(data))) 05661 return; 05662 05663 scan = data; 05664 addr = strsep(&scan, ":"); 05665 port_str = strsep(&scan, ":"); 05666 expiry_str = strsep(&scan, ":"); 05667 username = strsep(&scan, ":"); 05668 contact = scan; /* Contact include sip: and has to be the last part of the database entry as long as we use : as a separator */ 05669 05670 if (!inet_aton(addr, &in)) 05671 return; 05672 05673 if (port_str) 05674 port = atoi(port_str); 05675 else 05676 return; 05677 05678 if (expiry_str) 05679 expiry = atoi(expiry_str); 05680 else 05681 return; 05682 05683 if (username) 05684 ast_copy_string(peer->username, username, sizeof(peer->username)); 05685 if (contact) 05686 ast_copy_string(peer->fullcontact, contact, sizeof(peer->fullcontact)); 05687 05688 if (option_verbose > 2) 05689 ast_verbose(VERBOSE_PREFIX_3 "SIP Seeding peer from astdb: '%s' at %s@%s:%d for %d\n", 05690 peer->name, peer->username, ast_inet_ntoa(iabuf, sizeof(iabuf), in), port, expiry); 05691 05692 memset(&peer->addr, 0, sizeof(peer->addr)); 05693 peer->addr.sin_family = AF_INET; 05694 peer->addr.sin_addr = in; 05695 peer->addr.sin_port = htons(port); 05696 if (sipsock < 0) { 05697 /* SIP isn't up yet, so schedule a poke only, pretty soon */ 05698 if (peer->pokeexpire > -1) 05699 ast_sched_del(sched, peer->pokeexpire); 05700 peer->pokeexpire = ast_sched_add(sched, thread_safe_rand() % 5000 + 1, sip_poke_peer_s, peer); 05701 } else 05702 sip_poke_peer(peer); 05703 if (peer->expire > -1) 05704 ast_sched_del(sched, peer->expire); 05705 peer->expire = ast_sched_add(sched, (expiry + 10) * 1000, expire_register, peer); 05706 register_peer_exten(peer, 1); 05707 }
|
|
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(), channeltype, free, regcontext, sip_peer::regexten, strdup, and strsep(). Referenced by destroy_peer(), expire_register(), expire_registry(), parse_register_contact(), reg_source_db(), sip_destroy_peer(), and update_registry(). 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 6332 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, build_contact(), check_auth(), check_sip_domain(), EVENT_FLAG_SYSTEM, sip_pvt::expiry, 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, peerl, sip_pvt::randdata, sip_peer::secret, sip_cancel_destroy(), sip_destroy_peer(), SIP_DYNAMIC, SIP_NAT, SIP_REGISTER, temp_peer(), transmit_response(), transmit_response_with_date(), and update_peer(). Referenced by handle_request_register(), and socket_read(). 06333 { 06334 int res = -3; 06335 struct sip_peer *peer; 06336 char tmp[256]; 06337 char iabuf[INET_ADDRSTRLEN]; 06338 char *name, *c; 06339 char *t; 06340 char *domain; 06341 06342 /* Terminate URI */ 06343 t = uri; 06344 while(*t && (*t > 32) && (*t != ';')) 06345 t++; 06346 *t = '\0'; 06347 06348 ast_copy_string(tmp, get_header(req, "To"), sizeof(tmp)); 06349 if (pedanticsipchecking) 06350 ast_uri_decode(tmp); 06351 06352 c = get_in_brackets(tmp); 06353 /* Ditch ;user=phone */ 06354 name = strchr(c, ';'); 06355 if (name) 06356 *name = '\0'; 06357 06358 if (!strncmp(c, "sip:", 4)) { 06359 name = c + 4; 06360 } else { 06361 name = c; 06362 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)); 06363 } 06364 06365 /* Strip off the domain name */ 06366 if ((c = strchr(name, '@'))) { 06367 *c++ = '\0'; 06368 domain = c; 06369 if ((c = strchr(domain, ':'))) /* Remove :port */ 06370 *c = '\0'; 06371 if (!AST_LIST_EMPTY(&domain_list)) { 06372 if (!check_sip_domain(domain, NULL, 0)) { 06373 transmit_response(p, "404 Not found (unknown domain)", &p->initreq); 06374 return -3; 06375 } 06376 } 06377 } 06378 06379 ast_copy_string(p->exten, name, sizeof(p->exten)); 06380 build_contact(p); 06381 peer = find_peer(name, NULL, 1); 06382 if (!(peer && ast_apply_ha(peer->ha, sin))) { 06383 if (peer) 06384 ASTOBJ_UNREF(peer,sip_destroy_peer); 06385 } 06386 if (peer) { 06387 if (!ast_test_flag(peer, SIP_DYNAMIC)) { 06388 ast_log(LOG_ERROR, "Peer '%s' is trying to register, but not configured as host=dynamic\n", peer->name); 06389 } else { 06390 ast_copy_flags(p, peer, SIP_NAT); 06391 transmit_response(p, "100 Trying", req); 06392 if (!(res = check_auth(p, req, p->randdata, sizeof(p->randdata), peer->name, peer->secret, peer->md5secret, SIP_REGISTER, uri, 0, ignore))) { 06393 sip_cancel_destroy(p); 06394 switch (parse_register_contact(p, peer, req)) { 06395 case PARSE_REGISTER_FAILED: 06396 ast_log(LOG_WARNING, "Failed to parse contact info\n"); 06397 break; 06398 case PARSE_REGISTER_QUERY: 06399 transmit_response_with_date(p, "200 OK", req); 06400 peer->lastmsgssent = -1; 06401 res = 0; 06402 break; 06403 case PARSE_REGISTER_UPDATE: 06404 update_peer(peer, p->expiry); 06405 /* Say OK and ask subsystem to retransmit msg counter */ 06406 transmit_response_with_date(p, "200 OK", req); 06407 peer->lastmsgssent = -1; 06408 res = 0; 06409 break; 06410 } 06411 } 06412 } 06413 } 06414 if (!peer && autocreatepeer) { 06415 /* Create peer if we have autocreate mode enabled */ 06416 peer = temp_peer(name); 06417 if (peer) { 06418 ASTOBJ_CONTAINER_LINK(&peerl, peer); 06419 peer->lastmsgssent = -1; 06420 sip_cancel_destroy(p); 06421 switch (parse_register_contact(p, peer, req)) { 06422 case PARSE_REGISTER_FAILED: 06423 ast_log(LOG_WARNING, "Failed to parse contact info\n"); 06424 break; 06425 case PARSE_REGISTER_QUERY: 06426 transmit_response_with_date(p, "200 OK", req); 06427 peer->lastmsgssent = -1; 06428 res = 0; 06429 break; 06430 case PARSE_REGISTER_UPDATE: 06431 /* Say OK and ask subsystem to retransmit msg counter */ 06432 transmit_response_with_date(p, "200 OK", req); 06433 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Registered\r\n", peer->name); 06434 peer->lastmsgssent = -1; 06435 res = 0; 06436 break; 06437 } 06438 } 06439 } 06440 if (!res) { 06441 ast_device_state_changed("SIP/%s", peer->name); 06442 } 06443 if (res < 0) { 06444 switch (res) { 06445 case -1: 06446 /* Wrong password in authentication. Go away, don't try again until you fixed it */ 06447 transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq); 06448 break; 06449 case -2: 06450 /* Username and digest username does not match. 06451 Asterisk uses the From: username for authentication. We need the 06452 users to use the same authentication user name until we support 06453 proper authentication by digest auth name */ 06454 transmit_response(p, "403 Authentication user name does not match account name", &p->initreq); 06455 break; 06456 case -3: 06457 /* URI not found */ 06458 transmit_response(p, "404 Not found", &p->initreq); 06459 /* Set res back to -2 because we don't want to return an invalid domain message. That check already happened up above. */ 06460 res = -2; 06461 break; 06462 } 06463 if (option_debug > 1) { 06464 ast_log(LOG_DEBUG, "SIP REGISTER attempt failed for %s : %s\n", 06465 peer->name, 06466 (res == -1) ? "Bad password" : ((res == -2 ) ? "Bad digest user" : "Peer not found")); 06467 } 06468 } 06469 if (peer) 06470 ASTOBJ_UNREF(peer,sip_destroy_peer); 06471 06472 return res; 06473 }
|
|
Definition at line 5198 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. Referenced by handle_response_register(), sip_reg_timeout(), and sip_show_registry(). 05199 { 05200 switch(regstate) { 05201 case REG_STATE_FAILED: 05202 return "Failed"; 05203 case REG_STATE_UNREGISTERED: 05204 return "Unregistered"; 05205 case REG_STATE_REGSENT: 05206 return "Request Sent"; 05207 case REG_STATE_AUTHSENT: 05208 return "Auth. Sent"; 05209 case REG_STATE_REGISTERED: 05210 return "Registered"; 05211 case REG_STATE_REJECTED: 05212 return "Rejected"; 05213 case REG_STATE_TIMEOUT: 05214 return "Timeout"; 05215 case REG_STATE_NOAUTH: 05216 return "No Authentication"; 05217 default: 05218 return "Unknown"; 05219 } 05220 }
|
|
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 13047 of file chan_sip.c. References sip_reload(). 13048 { 13049 return sip_reload(0, 0, NULL); 13050 }
|
|
reload_config: Re-read SIP.conf config file ---
Definition at line 12262 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, DEFAULT_CALLERID, default_callerid, DEFAULT_CONTEXT, default_context, default_expiry, default_fromdomain, default_language, DEFAULT_NOTIFYMIME, default_notifymime, default_qualify, DEFAULT_REALM, 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_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, userl, ast_variable::value, VERBOSE_PREFIX_2, and videosupport. 12263 { 12264 struct ast_config *cfg; 12265 struct ast_variable *v; 12266 struct sip_peer *peer; 12267 struct sip_user *user; 12268 struct ast_hostent ahp; 12269 char *cat; 12270 char *utype; 12271 struct hostent *hp; 12272 int format; 12273 char iabuf[INET_ADDRSTRLEN]; 12274 struct ast_flags dummy; 12275 int auto_sip_domains = 0; 12276 struct sockaddr_in old_bindaddr = bindaddr; 12277 12278 cfg = ast_config_load(config); 12279 12280 /* We *must* have a config file otherwise stop immediately */ 12281 if (!cfg) { 12282 ast_log(LOG_NOTICE, "Unable to load config %s\n", config); 12283 return -1; 12284 } 12285 12286 /* Reset IP addresses */ 12287 memset(&bindaddr, 0, sizeof(bindaddr)); 12288 memset(&localaddr, 0, sizeof(localaddr)); 12289 memset(&externip, 0, sizeof(externip)); 12290 memset(&prefs, 0 , sizeof(prefs)); 12291 sipdebug &= ~SIP_DEBUG_CONFIG; 12292 12293 /* Initialize some reasonable defaults at SIP reload */ 12294 ast_copy_string(default_context, DEFAULT_CONTEXT, sizeof(default_context)); 12295 default_subscribecontext[0] = '\0'; 12296 default_language[0] = '\0'; 12297 default_fromdomain[0] = '\0'; 12298 default_qualify = 0; 12299 allow_external_domains = 1; /* Allow external invites */ 12300 externhost[0] = '\0'; 12301 externexpire = 0; 12302 externrefresh = 10; 12303 ast_copy_string(default_useragent, DEFAULT_USERAGENT, sizeof(default_useragent)); 12304 ast_copy_string(default_notifymime, DEFAULT_NOTIFYMIME, sizeof(default_notifymime)); 12305 global_notifyringing = 1; 12306 ast_copy_string(global_realm, DEFAULT_REALM, sizeof(global_realm)); 12307 ast_copy_string(global_musicclass, "default", sizeof(global_musicclass)); 12308 ast_copy_string(default_callerid, DEFAULT_CALLERID, sizeof(default_callerid)); 12309 memset(&outboundproxyip, 0, sizeof(outboundproxyip)); 12310 outboundproxyip.sin_port = htons(DEFAULT_SIP_PORT); 12311 outboundproxyip.sin_family = AF_INET; /* Type of address: IPv4 */ 12312 videosupport = 0; 12313 compactheaders = 0; 12314 dumphistory = 0; 12315 recordhistory = 0; 12316 relaxdtmf = 0; 12317 callevents = 0; 12318 ourport = DEFAULT_SIP_PORT; 12319 global_rtptimeout = 0; 12320 global_rtpholdtimeout = 0; 12321 global_rtpkeepalive = 0; 12322 pedanticsipchecking = 0; 12323 global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT; 12324 global_regattempts_max = 0; 12325 ast_clear_flag(&global_flags, AST_FLAGS_ALL); 12326 ast_set_flag(&global_flags, SIP_DTMF_RFC2833); 12327 ast_set_flag(&global_flags, SIP_NAT_RFC3581); 12328 ast_set_flag(&global_flags, SIP_CAN_REINVITE); 12329 ast_set_flag(&global_flags_page2, SIP_PAGE2_RTUPDATE); 12330 global_mwitime = DEFAULT_MWITIME; 12331 strcpy(global_vmexten, DEFAULT_VMEXTEN); 12332 srvlookup = 0; 12333 autocreatepeer = 0; 12334 regcontext[0] = '\0'; 12335 tos = 0; 12336 expiry = DEFAULT_EXPIRY; 12337 global_allowguest = 1; 12338 12339 /* Read the [general] config section of sip.conf (or from realtime config) */ 12340 v = ast_variable_browse(cfg, "general"); 12341 while(v) { 12342 if (handle_common_options(&global_flags, &dummy, v)) { 12343 v = v->next; 12344 continue; 12345 } 12346 12347 /* Create the interface list */ 12348 if (!strcasecmp(v->name, "context")) { 12349 ast_copy_string(default_context, v->value, sizeof(default_context)); 12350 } else if (!strcasecmp(v->name, "realm")) { 12351 ast_copy_string(global_realm, v->value, sizeof(global_realm)); 12352 } else if (!strcasecmp(v->name, "useragent")) { 12353 ast_copy_string(default_useragent, v->value, sizeof(default_useragent)); 12354 ast_log(LOG_DEBUG, "Setting User Agent Name to %s\n", 12355 default_useragent); 12356 } else if (!strcasecmp(v->name, "rtcachefriends")) { 12357 ast_set2_flag((&global_flags_page2), ast_true(v->value), SIP_PAGE2_RTCACHEFRIENDS); 12358 } else if (!strcasecmp(v->name, "rtupdate")) { 12359 ast_set2_flag((&global_flags_page2), ast_true(v->value), SIP_PAGE2_RTUPDATE); 12360 } else if (!strcasecmp(v->name, "ignoreregexpire")) { 12361 ast_set2_flag((&global_flags_page2), ast_true(v->value), SIP_PAGE2_IGNOREREGEXPIRE); 12362 } else if (!strcasecmp(v->name, "rtautoclear")) { 12363 int i = atoi(v->value); 12364 if (i > 0) 12365 global_rtautoclear = i; 12366 else 12367 i = 0; 12368 ast_set2_flag((&global_flags_page2), i || ast_true(v->value), SIP_PAGE2_RTAUTOCLEAR); 12369 } else if (!strcasecmp(v->name, "usereqphone")) { 12370 ast_set2_flag((&global_flags), ast_true(v->value), SIP_USEREQPHONE); 12371 } else if (!strcasecmp(v->name, "relaxdtmf")) { 12372 relaxdtmf = ast_true(v->value); 12373 } else if (!strcasecmp(v->name, "checkmwi")) { 12374 if ((sscanf(v->value, "%d", &global_mwitime) != 1) || (global_mwitime < 0)) { 12375 ast_log(LOG_WARNING, "'%s' is not a valid MWI time setting at line %d. Using default (10).\n", v->value, v->lineno); 12376 global_mwitime = DEFAULT_MWITIME; 12377 } 12378 } else if (!strcasecmp(v->name, "vmexten")) { 12379 ast_copy_string(global_vmexten, v->value, sizeof(global_vmexten)); 12380 } else if (!strcasecmp(v->name, "rtptimeout")) { 12381 if ((sscanf(v->value, "%d", &global_rtptimeout) != 1) || (global_rtptimeout < 0)) { 12382 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 12383 global_rtptimeout = 0; 12384 } 12385 } else if (!strcasecmp(v->name, "rtpholdtimeout")) { 12386 if ((sscanf(v->value, "%d", &global_rtpholdtimeout) != 1) || (global_rtpholdtimeout < 0)) { 12387 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 12388 global_rtpholdtimeout = 0; 12389 } 12390 } else if (!strcasecmp(v->name, "rtpkeepalive")) { 12391 if ((sscanf(v->value, "%d", &global_rtpkeepalive) != 1) || (global_rtpkeepalive < 0)) { 12392 ast_log(LOG_WARNING, "'%s' is not a valid RTP keepalive time at line %d. Using default.\n", v->value, v->lineno); 12393 global_rtpkeepalive = 0; 12394 } 12395 } else if (!strcasecmp(v->name, "videosupport")) { 12396 videosupport = ast_true(v->value); 12397 } else if (!strcasecmp(v->name, "compactheaders")) { 12398 compactheaders = ast_true(v->value); 12399 } else if (!strcasecmp(v->name, "notifymimetype")) { 12400 ast_copy_string(default_notifymime, v->value, sizeof(default_notifymime)); 12401 } else if (!strcasecmp(v->name, "notifyringing")) { 12402 global_notifyringing = ast_true(v->value); 12403 } else if (!strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) { 12404 ast_copy_string(global_musicclass, v->value, sizeof(global_musicclass)); 12405 } else if (!strcasecmp(v->name, "language")) { 12406 ast_copy_string(default_language, v->value, sizeof(default_language)); 12407 } else if (!strcasecmp(v->name, "regcontext")) { 12408 ast_copy_string(regcontext, v->value, sizeof(regcontext)); 12409 /* Create context if it doesn't exist already */ 12410 if (!ast_context_find(regcontext)) 12411 ast_context_create(NULL, regcontext, channeltype); 12412 } else if (!strcasecmp(v->name, "callerid")) { 12413 ast_copy_string(default_callerid, v->value, sizeof(default_callerid)); 12414 } else if (!strcasecmp(v->name, "fromdomain")) { 12415 ast_copy_string(default_fromdomain, v->value, sizeof(default_fromdomain)); 12416 } else if (!strcasecmp(v->name, "outboundproxy")) { 12417 if (ast_get_ip_or_srv(&outboundproxyip, v->value, "_sip._udp") < 0) 12418 ast_log(LOG_WARNING, "Unable to locate host '%s'\n", v->value); 12419 } else if (!strcasecmp(v->name, "outboundproxyport")) { 12420 /* Port needs to be after IP */ 12421 sscanf(v->value, "%d", &format); 12422 outboundproxyip.sin_port = htons(format); 12423 } else if (!strcasecmp(v->name, "autocreatepeer")) { 12424 autocreatepeer = ast_true(v->value); 12425 } else if (!strcasecmp(v->name, "srvlookup")) { 12426 srvlookup = ast_true(v->value); 12427 } else if (!strcasecmp(v->name, "pedantic")) { 12428 pedanticsipchecking = ast_true(v->value); 12429 } else if (!strcasecmp(v->name, "maxexpirey") || !strcasecmp(v->name, "maxexpiry")) { 12430 max_expiry = atoi(v->value); 12431 if (max_expiry < 1) 12432 max_expiry = DEFAULT_MAX_EXPIRY; 12433 } else if (!strcasecmp(v->name, "defaultexpiry") || !strcasecmp(v->name, "defaultexpirey")) { 12434 default_expiry = atoi(v->value); 12435 if (default_expiry < 1) 12436 default_expiry = DEFAULT_DEFAULT_EXPIRY; 12437 } else if (!strcasecmp(v->name, "sipdebug")) { 12438 if (ast_true(v->value)) 12439 sipdebug |= SIP_DEBUG_CONFIG; 12440 } else if (!strcasecmp(v->name, "dumphistory")) { 12441 dumphistory = ast_true(v->value); 12442 } else if (!strcasecmp(v->name, "recordhistory")) { 12443 recordhistory = ast_true(v->value); 12444 } else if (!strcasecmp(v->name, "registertimeout")) { 12445 global_reg_timeout = atoi(v->value); 12446 if (global_reg_timeout < 1) 12447 global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT; 12448 } else if (!strcasecmp(v->name, "registerattempts")) { 12449 global_regattempts_max = atoi(v->value); 12450 } else if (!strcasecmp(v->name, "bindaddr")) { 12451 if (!(hp = ast_gethostbyname(v->value, &ahp))) { 12452 ast_log(LOG_WARNING, "Invalid address: %s\n", v->value); 12453 } else { 12454 memcpy(&bindaddr.sin_addr, hp->h_addr, sizeof(bindaddr.sin_addr)); 12455 } 12456 } else if (!strcasecmp(v->name, "localnet")) { 12457 struct ast_ha *na; 12458 if (!(na = ast_append_ha("d", v->value, localaddr))) 12459 ast_log(LOG_WARNING, "Invalid localnet value: %s\n", v->value); 12460 else 12461 localaddr = na; 12462 } else if (!strcasecmp(v->name, "localmask")) { 12463 ast_log(LOG_WARNING, "Use of localmask is no long supported -- use localnet with mask syntax\n"); 12464 } else if (!strcasecmp(v->name, "externip")) { 12465 if (!(hp = ast_gethostbyname(v->value, &ahp))) 12466 ast_log(LOG_WARNING, "Invalid address for externip keyword: %s\n", v->value); 12467 else 12468 memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr)); 12469 externexpire = 0; 12470 } else if (!strcasecmp(v->name, "externhost")) { 12471 ast_copy_string(externhost, v->value, sizeof(externhost)); 12472 if (!(hp = ast_gethostbyname(externhost, &ahp))) 12473 ast_log(LOG_WARNING, "Invalid address for externhost keyword: %s\n", externhost); 12474 else 12475 memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr)); 12476 time(&externexpire); 12477 } else if (!strcasecmp(v->name, "externrefresh")) { 12478 if (sscanf(v->value, "%d", &externrefresh) != 1) { 12479 ast_log(LOG_WARNING, "Invalid externrefresh value '%s', must be an integer >0 at line %d\n", v->value, v->lineno); 12480 externrefresh = 10; 12481 } 12482 } else if (!strcasecmp(v->name, "allow")) { 12483 ast_parse_allow_disallow(&prefs, &global_capability, v->value, 1); 12484 } else if (!strcasecmp(v->name, "disallow")) { 12485 ast_parse_allow_disallow(&prefs, &global_capability, v->value, 0); 12486 } else if (!strcasecmp(v->name, "allowexternaldomains")) { 12487 allow_external_domains = ast_true(v->value); 12488 } else if (!strcasecmp(v->name, "autodomain")) { 12489 auto_sip_domains = ast_true(v->value); 12490 } else if (!strcasecmp(v->name, "domain")) { 12491 char *domain = ast_strdupa(v->value); 12492 char *context = strchr(domain, ','); 12493 12494 if (context) 12495 *context++ = '\0'; 12496 12497 if (ast_strlen_zero(domain)) 12498 ast_log(LOG_WARNING, "Empty domain specified at line %d\n", v->lineno); 12499 else if (ast_strlen_zero(context)) 12500 ast_log(LOG_WARNING, "Empty context specified at line %d for domain '%s'\n", v->lineno, domain); 12501 else 12502 add_sip_domain(ast_strip(domain), SIP_DOMAIN_CONFIG, context ? ast_strip(context) : ""); 12503 } else if (!strcasecmp(v->name, "register")) { 12504 sip_register(v->value, v->lineno); 12505 } else if (!strcasecmp(v->name, "tos")) { 12506 if (ast_str2tos(v->value, &tos)) 12507 ast_log(LOG_WARNING, "Invalid tos value at line %d, should be 'lowdelay', 'throughput', 'reliability', 'mincost', or 'none'\n", v->lineno); 12508 } else if (!strcasecmp(v->name, "bindport")) { 12509 if (sscanf(v->value, "%d", &ourport) == 1) { 12510 bindaddr.sin_port = htons(ourport); 12511 } else { 12512 ast_log(LOG_WARNING, "Invalid port number '%s' at line %d of %s\n", v->value, v->lineno, config); 12513 } 12514 } else if (!strcasecmp(v->name, "qualify")) { 12515 if (!strcasecmp(v->value, "no")) { 12516 default_qualify = 0; 12517 } else if (!strcasecmp(v->value, "yes")) { 12518 default_qualify = DEFAULT_MAXMS; 12519 } else if (sscanf(v->value, "%d", &default_qualify) != 1) { 12520 ast_log(LOG_WARNING, "Qualification default should be 'yes', 'no', or a number of milliseconds at line %d of sip.conf\n", v->lineno); 12521 default_qualify = 0; 12522 } 12523 } else if (!strcasecmp(v->name, "callevents")) { 12524 callevents = ast_true(v->value); 12525 } 12526 /* else if (strcasecmp(v->name,"type")) 12527 * ast_log(LOG_WARNING, "Ignoring %s\n", v->name); 12528 */ 12529 v = v->next; 12530 } 12531 12532 if (!allow_external_domains && AST_LIST_EMPTY(&domain_list)) { 12533 ast_log(LOG_WARNING, "To disallow external domains, you need to configure local SIP domains.\n"); 12534 allow_external_domains = 1; 12535 } 12536 12537 /* Build list of authentication to various SIP realms, i.e. service providers */ 12538 v = ast_variable_browse(cfg, "authentication"); 12539 while(v) { 12540 /* Format for authentication is auth = username:password@realm */ 12541 if (!strcasecmp(v->name, "auth")) { 12542 authl = add_realm_authentication(authl, v->value, v->lineno); 12543 } 12544 v = v->next; 12545 } 12546 12547 /* Load peers, users and friends */ 12548 cat = ast_category_browse(cfg, NULL); 12549 while(cat) { 12550 if (strcasecmp(cat, "general") && strcasecmp(cat, "authentication")) { 12551 utype = ast_variable_retrieve(cfg, cat, "type"); 12552 if (utype) { 12553 if (!strcasecmp(utype, "user") || !strcasecmp(utype, "friend")) { 12554 user = build_user(cat, ast_variable_browse(cfg, cat), 0); 12555 if (user) { 12556 ASTOBJ_CONTAINER_LINK(&userl,user); 12557 ASTOBJ_UNREF(user, sip_destroy_user); 12558 } 12559 } 12560 if (!strcasecmp(utype, "peer") || !strcasecmp(utype, "friend")) { 12561 peer = build_peer(cat, ast_variable_browse(cfg, cat), 0); 12562 if (peer) { 12563 ASTOBJ_CONTAINER_LINK(&peerl,peer); 12564 ASTOBJ_UNREF(peer, sip_destroy_peer); 12565 } 12566 } else if (strcasecmp(utype, "user")) { 12567 ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, "sip.conf"); 12568 } 12569 } else 12570 ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat); 12571 } 12572 cat = ast_category_browse(cfg, cat); 12573 } 12574 if (ast_find_ourip(&__ourip, bindaddr)) { 12575 ast_log(LOG_WARNING, "Unable to get own IP address, SIP disabled\n"); 12576 return 0; 12577 } 12578 if (!ntohs(bindaddr.sin_port)) 12579 bindaddr.sin_port = ntohs(DEFAULT_SIP_PORT); 12580 bindaddr.sin_family = AF_INET; 12581 ast_mutex_lock(&netlock); 12582 if ((sipsock > -1) && (memcmp(&old_bindaddr, &bindaddr, sizeof(struct sockaddr_in)))) { 12583 close(sipsock); 12584 sipsock = -1; 12585 } 12586 if (sipsock < 0) { 12587 sipsock = socket(AF_INET, SOCK_DGRAM, 0); 12588 if (sipsock < 0) { 12589 ast_log(LOG_WARNING, "Unable to create SIP socket: %s\n", strerror(errno)); 12590 } else { 12591 /* Allow SIP clients on the same host to access us: */ 12592 const int reuseFlag = 1; 12593 setsockopt(sipsock, SOL_SOCKET, SO_REUSEADDR, 12594 (const char*)&reuseFlag, 12595 sizeof reuseFlag); 12596 12597 if (bind(sipsock, (struct sockaddr *)&bindaddr, sizeof(bindaddr)) < 0) { 12598 ast_log(LOG_WARNING, "Failed to bind to %s:%d: %s\n", 12599 ast_inet_ntoa(iabuf, sizeof(iabuf), bindaddr.sin_addr), ntohs(bindaddr.sin_port), 12600 strerror(errno)); 12601 close(sipsock); 12602 sipsock = -1; 12603 } else { 12604 if (option_verbose > 1) { 12605 ast_verbose(VERBOSE_PREFIX_2 "SIP Listening on %s:%d\n", 12606 ast_inet_ntoa(iabuf, sizeof(iabuf), bindaddr.sin_addr), ntohs(bindaddr.sin_port)); 12607 ast_verbose(VERBOSE_PREFIX_2 "Using TOS bits %d\n", tos); 12608 } 12609 if (setsockopt(sipsock, IPPROTO_IP, IP_TOS, &tos, sizeof(tos))) 12610 ast_log(LOG_WARNING, "Unable to set TOS to %d\n", tos); 12611 } 12612 } 12613 } 12614 ast_mutex_unlock(&netlock); 12615 12616 /* Add default domains - host name, IP address and IP:port */ 12617 /* Only do this if user added any sip domain with "localdomains" */ 12618 /* In order to *not* break backwards compatibility */ 12619 /* Some phones address us at IP only, some with additional port number */ 12620 if (auto_sip_domains) { 12621 char temp[MAXHOSTNAMELEN]; 12622 12623 /* First our default IP address */ 12624 if (bindaddr.sin_addr.s_addr) { 12625 ast_inet_ntoa(temp, sizeof(temp), bindaddr.sin_addr); 12626 add_sip_domain(temp, SIP_DOMAIN_AUTO, NULL); 12627 } else { 12628 ast_log(LOG_NOTICE, "Can't add wildcard IP address to domain list, please add IP address to domain manually.\n"); 12629 } 12630 12631 /* Our extern IP address, if configured */ 12632 if (externip.sin_addr.s_addr) { 12633 ast_inet_ntoa(temp, sizeof(temp), externip.sin_addr); 12634 add_sip_domain(temp, SIP_DOMAIN_AUTO, NULL); 12635 } 12636 12637 /* Extern host name (NAT traversal support) */ 12638 if (!ast_strlen_zero(externhost)) 12639 add_sip_domain(externhost, SIP_DOMAIN_AUTO, NULL); 12640 12641 /* Our host name */ 12642 if (!gethostname(temp, sizeof(temp))) 12643 add_sip_domain(temp, SIP_DOMAIN_AUTO, NULL); 12644 } 12645 12646 /* Release configuration from memory */ 12647 ast_config_destroy(cfg); 12648 12649 /* Load the list of manual NOTIFY types to support */ 12650 if (notify_types) 12651 ast_config_destroy(notify_types); 12652 notify_types = ast_config_load(notify_config); 12653 12654 return 0; 12655 }
|
|
reply_digest: reply to authentication for outbound registrations ---
Definition at line 8899 of file chan_sip.c. References ast_log(), ast_strlen_zero(), build_reply_digest(), sip_registry::domain, sip_pvt::domain, get_header(), LOG_WARNING, sip_registry::nonce, sip_pvt::nonce, sip_registry::noncecount, sip_pvt::noncecount, sip_registry::opaque, sip_pvt::opaque, sip_registry::qop, sip_pvt::qop, sip_registry::realm, sip_pvt::realm, sip_pvt::registry, sipmethod, and strsep(). Referenced by do_proxy_auth(), and do_register_auth(). 08901 { 08902 char tmp[512]; 08903 char *c; 08904 char oldnonce[256]; 08905 08906 /* table of recognised keywords, and places where they should be copied */ 08907 const struct x { 08908 const char *key; 08909 char *dst; 08910 int dstlen; 08911 } *i, keys[] = { 08912 { "realm=", p->realm, sizeof(p->realm) }, 08913 { "nonce=", p->nonce, sizeof(p->nonce) }, 08914 { "opaque=", p->opaque, sizeof(p->opaque) }, 08915 { "qop=", p->qop, sizeof(p->qop) }, 08916 { "domain=", p->domain, sizeof(p->domain) }, 08917 { NULL, NULL, 0 }, 08918 }; 08919 08920 ast_copy_string(tmp, get_header(req, header), sizeof(tmp)); 08921 if (ast_strlen_zero(tmp)) 08922 return -1; 08923 if (strncasecmp(tmp, "Digest ", strlen("Digest "))) { 08924 ast_log(LOG_WARNING, "missing Digest.\n"); 08925 return -1; 08926 } 08927 c = tmp + strlen("Digest "); 08928 for (i = keys; i->key != NULL; i++) 08929 i->dst[0] = '\0'; /* init all to empty strings */ 08930 ast_copy_string(oldnonce, p->nonce, sizeof(oldnonce)); 08931 while (c && *(c = ast_skip_blanks(c))) { /* lookup for keys */ 08932 for (i = keys; i->key != NULL; i++) { 08933 char *src, *separator; 08934 if (strncasecmp(c, i->key, strlen(i->key)) != 0) 08935 continue; 08936 /* Found. Skip keyword, take text in quotes or up to the separator. */ 08937 c += strlen(i->key); 08938 if (*c == '\"') { 08939 src = ++c; 08940 separator = "\""; 08941 } else { 08942 src = c; 08943 separator = ","; 08944 } 08945 strsep(&c, separator); /* clear separator and move ptr */ 08946 ast_copy_string(i->dst, src, i->dstlen); 08947 break; 08948 } 08949 if (i->key == NULL) /* not found, try ',' */ 08950 strsep(&c, ","); 08951 } 08952 /* Reset nonce count */ 08953 if (strcmp(p->nonce, oldnonce)) 08954 p->noncecount = 0; 08955 08956 /* Save auth data for following registrations */ 08957 if (p->registry) { 08958 struct sip_registry *r = p->registry; 08959 08960 if (strcmp(r->nonce, p->nonce)) { 08961 ast_copy_string(r->realm, p->realm, sizeof(r->realm)); 08962 ast_copy_string(r->nonce, p->nonce, sizeof(r->nonce)); 08963 ast_copy_string(r->domain, p->domain, sizeof(r->domain)); 08964 ast_copy_string(r->opaque, p->opaque, sizeof(r->opaque)); 08965 ast_copy_string(r->qop, p->qop, sizeof(r->qop)); 08966 r->noncecount = 0; 08967 } 08968 } 08969 return build_reply_digest(p, sipmethod, digest, digest_len); 08970 }
|
|
reqprep: Initialize a SIP request response packet ---
Definition at line 4018 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, 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_methods, SIP_OUTGOING, sipmethod, strcasestr(), sip_pvt::tag, text, cfsip_methods::text, sip_pvt::theirtag, thread_safe_rand(), sip_pvt::uri, and sip_pvt::via. Referenced by transmit_audit_endpoint(), transmit_connect_with_sdp(), transmit_connection_del(), transmit_connection_del_w_params(), transmit_info_with_digit(), transmit_info_with_vidupdate(), transmit_invite(), transmit_message_with_text(), transmit_modify_request(), transmit_modify_with_sdp(), transmit_notify_request(), transmit_notify_request_with_callerid(), transmit_notify_with_sipfrag(), transmit_refer(), transmit_reinvite_with_sdp(), transmit_request(), transmit_request_with_auth(), and transmit_state_notify(). 04019 { 04020 struct sip_request *orig = &p->initreq; 04021 char stripped[80]; 04022 char tmp[80]; 04023 char newto[256]; 04024 char *c, *n; 04025 char *ot, *of; 04026 int is_strict = 0; /* Strict routing flag */ 04027 04028 memset(req, 0, sizeof(struct sip_request)); 04029 04030 snprintf(p->lastmsg, sizeof(p->lastmsg), "Tx: %s", sip_methods[sipmethod].text); 04031 04032 if (!seqno) { 04033 p->ocseq++; 04034 seqno = p->ocseq; 04035 } 04036 04037 if (newbranch) { 04038 p->branch ^= thread_safe_rand(); 04039 build_via(p, p->via, sizeof(p->via)); 04040 } 04041 04042 /* Check for strict or loose router */ 04043 if (p->route && !ast_strlen_zero(p->route->hop) && strstr(p->route->hop,";lr") == NULL) 04044 is_strict = 1; 04045 04046 if (sipmethod == SIP_CANCEL) { 04047 c = p->initreq.rlPart2; /* Use original URI */ 04048 } else if (sipmethod == SIP_ACK) { 04049 /* Use URI from Contact: in 200 OK (if INVITE) 04050 (we only have the contacturi on INVITEs) */ 04051 if (!ast_strlen_zero(p->okcontacturi)) 04052 c = is_strict ? p->route->hop : p->okcontacturi; 04053 else 04054 c = p->initreq.rlPart2; 04055 } else if (!ast_strlen_zero(p->okcontacturi)) { 04056 c = is_strict ? p->route->hop : p->okcontacturi; /* Use for BYE or REINVITE */ 04057 } else if (!ast_strlen_zero(p->uri)) { 04058 c = p->uri; 04059 } else { 04060 /* We have no URI, use To: or From: header as URI (depending on direction) */ 04061 c = get_header(orig, (ast_test_flag(p, SIP_OUTGOING)) ? "To" : "From"); 04062 ast_copy_string(stripped, c, sizeof(stripped)); 04063 c = get_in_brackets(stripped); 04064 n = strchr(c, ';'); 04065 if (n) 04066 *n = '\0'; 04067 } 04068 init_req(req, sipmethod, c); 04069 04070 snprintf(tmp, sizeof(tmp), "%d %s", seqno, sip_methods[sipmethod].text); 04071 04072 add_header(req, "Via", p->via); 04073 if (p->route) { 04074 set_destination(p, p->route->hop); 04075 if (is_strict) 04076 add_route(req, p->route->next); 04077 else 04078 add_route(req, p->route); 04079 } 04080 04081 ot = get_header(orig, "To"); 04082 of = get_header(orig, "From"); 04083 04084 /* Add tag *unless* this is a CANCEL, in which case we need to send it exactly 04085 as our original request, including tag (or presumably lack thereof) */ 04086 if (!strcasestr(ot, "tag=") && sipmethod != SIP_CANCEL) { 04087 /* Add the proper tag if we don't have it already. If they have specified 04088 their tag, use it. Otherwise, use our own tag */ 04089 if (ast_test_flag(p, SIP_OUTGOING) && !ast_strlen_zero(p->theirtag)) 04090 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->theirtag); 04091 else if (!ast_test_flag(p, SIP_OUTGOING)) 04092 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->tag); 04093 else 04094 snprintf(newto, sizeof(newto), "%s", ot); 04095 ot = newto; 04096 } 04097 04098 if (ast_test_flag(p, SIP_OUTGOING)) { 04099 add_header(req, "From", of); 04100 add_header(req, "To", ot); 04101 } else { 04102 add_header(req, "From", ot); 04103 add_header(req, "To", of); 04104 } 04105 add_header(req, "Contact", p->our_contact); 04106 copy_header(req, orig, "Call-ID"); 04107 add_header(req, "CSeq", tmp); 04108 04109 add_header(req, "User-Agent", default_useragent); 04110 add_header(req, "Max-Forwards", DEFAULT_MAX_FORWARDS); 04111 04112 if (p->rpid) 04113 add_header(req, "Remote-Party-ID", p->rpid); 04114 04115 return 0; 04116 }
|
|
respprep: Prepare SIP response packet ---
Definition at line 3970 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_SUBSCRIBE, strcasestr(), sip_pvt::tag, and sip_pvt::theirtag. Referenced by __transmit_response(), transmit_response(), transmit_response_with_allow(), transmit_response_with_auth(), transmit_response_with_date(), transmit_response_with_sdp(), and transmit_response_with_unsupported(). 03971 { 03972 char newto[256], *ot; 03973 03974 memset(resp, 0, sizeof(*resp)); 03975 init_resp(resp, msg, req); 03976 copy_via_headers(p, resp, req, "Via"); 03977 if (msg[0] == '2') 03978 copy_all_header(resp, req, "Record-Route"); 03979 copy_header(resp, req, "From"); 03980 ot = get_header(req, "To"); 03981 if (!strcasestr(ot, "tag=") && strncmp(msg, "100", 3)) { 03982 /* Add the proper tag if we don't have it already. If they have specified 03983 their tag, use it. Otherwise, use our own tag */ 03984 if (!ast_strlen_zero(p->theirtag) && ast_test_flag(p, SIP_OUTGOING)) 03985 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->theirtag); 03986 else if (p->tag && !ast_test_flag(p, SIP_OUTGOING)) 03987 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->tag); 03988 else { 03989 ast_copy_string(newto, ot, sizeof(newto)); 03990 newto[sizeof(newto) - 1] = '\0'; 03991 } 03992 ot = newto; 03993 } 03994 add_header(resp, "To", ot); 03995 copy_header(resp, req, "Call-ID"); 03996 copy_header(resp, req, "CSeq"); 03997 add_header(resp, "User-Agent", default_useragent); 03998 add_header(resp, "Allow", ALLOWED_METHODS); 03999 if (msg[0] == '2' && (p->method == SIP_SUBSCRIBE || p->method == SIP_REGISTER)) { 04000 /* For registration responses, we also need expiry and 04001 contact info */ 04002 char tmp[256]; 04003 04004 snprintf(tmp, sizeof(tmp), "%d", p->expiry); 04005 add_header(resp, "Expires", tmp); 04006 if (p->expiry) { /* Only add contact if we have an expiry time */ 04007 char contact[256]; 04008 snprintf(contact, sizeof(contact), "%s;expires=%d", p->our_contact, p->expiry); 04009 add_header(resp, "Contact", contact); /* Not when we unregister */ 04010 } 04011 } else if (p->our_contact[0]) { 04012 add_header(resp, "Contact", p->our_contact); 04013 } 04014 return 0; 04015 }
|
|
restart_monitor: Start the channel monitor thread ---
Definition at line 11328 of file chan_sip.c. References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_pthread_create, do_monitor(), LOG_ERROR, LOG_WARNING, and monitor_thread. 11329 { 11330 /* If we're supposed to be stopped -- stay stopped */ 11331 if (monitor_thread == AST_PTHREADT_STOP) 11332 return 0; 11333 if (ast_mutex_lock(&monlock)) { 11334 ast_log(LOG_WARNING, "Unable to lock monitor\n"); 11335 return -1; 11336 } 11337 if (monitor_thread == pthread_self()) { 11338 ast_mutex_unlock(&monlock); 11339 ast_log(LOG_WARNING, "Cannot kill myself\n"); 11340 return -1; 11341 } 11342 if (monitor_thread != AST_PTHREADT_NULL) { 11343 /* Wake up the thread */ 11344 pthread_kill(monitor_thread, SIGURG); 11345 } else { 11346 /* Start a new monitor */ 11347 if (ast_pthread_create(&monitor_thread, NULL, do_monitor, NULL) < 0) { 11348 ast_mutex_unlock(&monlock); 11349 ast_log(LOG_ERROR, "Unable to start monitor thread.\n"); 11350 return -1; 11351 } 11352 } 11353 ast_mutex_unlock(&monlock); 11354 return 0; 11355 }
|
|
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, FLAG_FATAL, FLAG_RESPONSE, free, ast_channel::lock, sip_pvt::lock, LOG_DEBUG, LOG_WARNING, 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_pkt::seqno, SIP_ALREADYGONE, sip_debug_test_pvt(), SIP_INVITE, sip_methods, SIP_NAT, SIP_NEEDDESTROY, SIP_OPTIONS, sipdebug, sip_pkt::timer_a, and sip_pkt::timer_t1. Referenced by __sip_reliable_xmit(). 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 2864 of file chan_sip.c. Referenced by process_sdp(). 02865 { 02866 *iterator = 0; 02867 }
|
|
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_pvt::recv, sip_pvt::sa, sip_debug_test_pvt(), and SIP_NAT. Referenced by transmit_audit_endpoint(), transmit_connect_with_sdp(), transmit_connection_del(), transmit_connection_del_w_params(), transmit_info_with_digit(), transmit_info_with_vidupdate(), transmit_invite(), transmit_message_with_text(), transmit_modify_request(), transmit_modify_with_sdp(), transmit_notify_request(), transmit_notify_request_with_callerid(), transmit_notify_with_mwi(), transmit_notify_with_sipfrag(), transmit_refer(), transmit_register(), transmit_reinvite_with_sdp(), transmit_request(), transmit_request_with_auth(), transmit_sip_request(), and transmit_state_notify(). 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_pvt::recv, sip_pvt::sa, sip_debug_test_pvt(), and SIP_NAT. Referenced by __transmit_response(), transmit_response(), transmit_response_with_allow(), transmit_response_with_auth(), transmit_response_with_date(), transmit_response_with_sdp(), and transmit_response_with_unsupported(). 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 3874 of file chan_sip.c. References ahp, ast_gethostbyname(), ast_inet_ntoa(), ast_log(), ast_verbose(), hp, LOG_WARNING, sip_pvt::sa, and sip_debug_test_pvt(). Referenced by reqprep(). 03875 { 03876 char *h, *maddr, hostname[256]; 03877 char iabuf[INET_ADDRSTRLEN]; 03878 int port, hn; 03879 struct hostent *hp; 03880 struct ast_hostent ahp; 03881 int debug=sip_debug_test_pvt(p); 03882 03883 /* Parse uri to h (host) and port - uri is already just the part inside the <> */ 03884 /* general form we are expecting is sip[s]:username[:password]@host[:port][;...] */ 03885 03886 if (debug) 03887 ast_verbose("set_destination: Parsing <%s> for address/port to send to\n", uri); 03888 03889 /* Find and parse hostname */ 03890 h = strchr(uri, '@'); 03891 if (h) 03892 ++h; 03893 else { 03894 h = uri; 03895 if (strncmp(h, "sip:", 4) == 0) 03896 h += 4; 03897 else if (strncmp(h, "sips:", 5) == 0) 03898 h += 5; 03899 } 03900 hn = strcspn(h, ":;>") + 1; 03901 if (hn > sizeof(hostname)) 03902 hn = sizeof(hostname); 03903 ast_copy_string(hostname, h, hn); 03904 h += hn - 1; 03905 03906 /* Is "port" present? if not default to DEFAULT_SIP_PORT */ 03907 if (*h == ':') { 03908 /* Parse port */ 03909 ++h; 03910 port = strtol(h, &h, 10); 03911 } 03912 else 03913 port = DEFAULT_SIP_PORT; 03914 03915 /* Got the hostname:port - but maybe there's a "maddr=" to override address? */ 03916 maddr = strstr(h, "maddr="); 03917 if (maddr) { 03918 maddr += 6; 03919 hn = strspn(maddr, "0123456789.") + 1; 03920 if (hn > sizeof(hostname)) hn = sizeof(hostname); 03921 ast_copy_string(hostname, maddr, hn); 03922 } 03923 03924 hp = ast_gethostbyname(hostname, &ahp); 03925 if (hp == NULL) { 03926 ast_log(LOG_WARNING, "Can't find address for host '%s'\n", hostname); 03927 return; 03928 } 03929 p->sa.sin_family = AF_INET; 03930 memcpy(&p->sa.sin_addr, hp->h_addr, sizeof(p->sa.sin_addr)); 03931 p->sa.sin_port = htons(port); 03932 if (debug) 03933 ast_verbose("set_destination: set destination to %s, port %d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr), port); 03934 }
|
|
sip_addheader: Add a SIP header ---
Definition at line 12804 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(), and pbx_builtin_setvar_helper(). Referenced by load_module(). 12805 { 12806 int no = 0; 12807 int ok = 0; 12808 char varbuf[128]; 12809 12810 if (ast_strlen_zero((char *)data)) { 12811 ast_log(LOG_WARNING, "This application requires the argument: Header\n"); 12812 return 0; 12813 } 12814 ast_mutex_lock(&chan->lock); 12815 12816 /* Check for headers */ 12817 while (!ok && no <= 50) { 12818 no++; 12819 snprintf(varbuf, sizeof(varbuf), "_SIPADDHEADER%02d", no); 12820 if (ast_strlen_zero(pbx_builtin_getvar_helper(chan, varbuf + 1))) 12821 ok = 1; 12822 } 12823 if (ok) { 12824 pbx_builtin_setvar_helper (chan, varbuf, (char *)data); 12825 if (sipdebug) 12826 ast_log(LOG_DEBUG,"SIP Header added \"%s\" as %s\n", (char *) data, varbuf); 12827 } else { 12828 ast_log(LOG_WARNING, "Too many SIP headers added, max 50\n"); 12829 } 12830 ast_mutex_unlock(&chan->lock); 12831 return 0; 12832 }
|
|
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 3022 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_new_with_bindaddr(), ast_rtp_setnat(), ast_rtp_settos(), ast_sip_ouraddrfor(), ast_test_flag, ast_variables_destroy(), sip_pvt::autokillid, bindaddr, build_callid(), build_via(), calloc, default_context, default_fromdomain, free, global_flags, global_musicclass, iflist, sip_pvt::initid, io, LOG_DEBUG, LOG_WARNING, make_our_tag(), sip_pvt::method, cfsip_methods::need_rtp, sip_pvt::prefs, sched, SIP_DTMF, SIP_FLAGS_TO_COPY, sip_methods, SIP_NAT, SIP_NAT_ROUTE, sip_pvt::stateid, 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(). 03023 { 03024 struct sip_pvt *p; 03025 03026 if (!(p = calloc(1, sizeof(*p)))) 03027 return NULL; 03028 03029 ast_mutex_init(&p->lock); 03030 03031 p->method = intended_method; 03032 p->initid = -1; 03033 p->autokillid = -1; 03034 p->subscribed = NONE; 03035 p->stateid = -1; 03036 p->prefs = prefs; 03037 if (intended_method != SIP_OPTIONS) /* Peerpoke has it's own system */ 03038 p->timer_t1 = 500; /* Default SIP retransmission timer T1 (RFC 3261) */ 03039 #ifdef OSP_SUPPORT 03040 p->osphandle = -1; 03041 p->osptimelimit = 0; 03042 #endif 03043 if (sin) { 03044 memcpy(&p->sa, sin, sizeof(p->sa)); 03045 if (ast_sip_ouraddrfor(&p->sa.sin_addr,&p->ourip)) 03046 memcpy(&p->ourip, &__ourip, sizeof(p->ourip)); 03047 } else { 03048 memcpy(&p->ourip, &__ourip, sizeof(p->ourip)); 03049 } 03050 03051 p->branch = thread_safe_rand(); 03052 make_our_tag(p->tag, sizeof(p->tag)); 03053 /* Start with 101 instead of 1 */ 03054 p->ocseq = 101; 03055 03056 if (sip_methods[intended_method].need_rtp) { 03057 p->rtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr.sin_addr); 03058 if (videosupport) 03059 p->vrtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr.sin_addr); 03060 if (!p->rtp || (videosupport && !p->vrtp)) { 03061 ast_log(LOG_WARNING, "Unable to create RTP audio %s session: %s\n", videosupport ? "and video" : "", strerror(errno)); 03062 ast_mutex_destroy(&p->lock); 03063 if (p->chanvars) { 03064 ast_variables_destroy(p->chanvars); 03065 p->chanvars = NULL; 03066 } 03067 free(p); 03068 return NULL; 03069 } 03070 ast_rtp_settos(p->rtp, tos); 03071 if (p->vrtp) 03072 ast_rtp_settos(p->vrtp, tos); 03073 p->rtptimeout = global_rtptimeout; 03074 p->rtpholdtimeout = global_rtpholdtimeout; 03075 p->rtpkeepalive = global_rtpkeepalive; 03076 } 03077 03078 if (useglobal_nat && sin) { 03079 /* Setup NAT structure according to global settings if we have an address */ 03080 ast_copy_flags(p, &global_flags, SIP_NAT); 03081 memcpy(&p->recv, sin, sizeof(p->recv)); 03082 if (p->rtp) 03083 ast_rtp_setnat(p->rtp, (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE)); 03084 if (p->vrtp) 03085 ast_rtp_setnat(p->vrtp, (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE)); 03086 } 03087 03088 if (p->method != SIP_REGISTER) 03089 ast_copy_string(p->fromdomain, default_fromdomain, sizeof(p->fromdomain)); 03090 build_via(p, p->via, sizeof(p->via)); 03091 if (!callid) 03092 build_callid(p->callid, sizeof(p->callid), p->ourip, p->fromdomain); 03093 else 03094 ast_copy_string(p->callid, callid, sizeof(p->callid)); 03095 ast_copy_flags(p, &global_flags, SIP_FLAGS_TO_COPY); 03096 /* Assign default music on hold class */ 03097 strcpy(p->musicclass, global_musicclass); 03098 p->capability = global_capability; 03099 if ((ast_test_flag(p, SIP_DTMF) == SIP_DTMF_RFC2833) || (ast_test_flag(p, SIP_DTMF) == SIP_DTMF_AUTO)) 03100 p->noncodeccapability |= AST_RTP_DTMF; 03101 strcpy(p->context, default_context); 03102 03103 /* Add to active dialog list */ 03104 ast_mutex_lock(&iflock); 03105 p->next = iflist; 03106 iflist = p; 03107 ast_mutex_unlock(&iflock); 03108 if (option_debug) 03109 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"); 03110 return p; 03111 }
|
|
sip_answer: Answer SIP call , send 200 OK on Invite Part of PBX interface
Definition at line 2488 of file chan_sip.c. References ast_channel::_state, ast_getformatbyname(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_setstate(), AST_STATE_UP, sip_pvt::capability, fmt, sip_pvt::initreq, sip_pvt::jointcapability, sip_pvt::lock, LOG_DEBUG, LOG_NOTICE, ast_channel::name, sip_pvt::owner, pbx_builtin_getvar_helper(), ast_channel::tech_pvt, and transmit_response_with_sdp(). 02489 { 02490 int res = 0,fmt; 02491 char *codec; 02492 struct sip_pvt *p = ast->tech_pvt; 02493 02494 ast_mutex_lock(&p->lock); 02495 if (ast->_state != AST_STATE_UP) { 02496 #ifdef OSP_SUPPORT 02497 time(&p->ospstart); 02498 #endif 02499 02500 codec=pbx_builtin_getvar_helper(p->owner,"SIP_CODEC"); 02501 if (codec) { 02502 fmt=ast_getformatbyname(codec); 02503 if (fmt) { 02504 ast_log(LOG_NOTICE, "Changing codec to '%s' for this call because of ${SIP_CODEC) variable\n",codec); 02505 if (p->jointcapability & fmt) { 02506 p->jointcapability &= fmt; 02507 p->capability &= fmt; 02508 } else 02509 ast_log(LOG_NOTICE, "Ignoring ${SIP_CODEC} variable because it is not shared by both ends.\n"); 02510 } else ast_log(LOG_NOTICE, "Ignoring ${SIP_CODEC} variable because of unrecognized/not configured codec (check allow/disallow in sip.conf): %s\n",codec); 02511 } 02512 02513 ast_setstate(ast, AST_STATE_UP); 02514 if (option_debug) 02515 ast_log(LOG_DEBUG, "sip_answer(%s)\n", ast->name); 02516 res = transmit_response_with_sdp(p, "200 OK", &p->initreq, 1); 02517 } 02518 ast_mutex_unlock(&p->lock); 02519 return res; 02520 }
|
|
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_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. References debugaddr, and sipdebug. 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, SIP_NAT_ROUTE, and sipdebug. Referenced by __sip_destroy(), add_sdp(), build_route(), check_via(), do_register_auth(), get_also_info(), get_destination(), get_rdnis(), get_refer_info(), handle_request(), process_sdp(), receive_message(), retrans_pkt(), send_request(), send_response(), set_destination(), sip_scheddestroy(), sip_sendtext(), 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(), sip_user::chanvars, free, sip_user::ha, ruserobjs, SIP_REALTIME, and suserobjs. Referenced by check_user_full(), reload_config(), sip_prune_realtime(), 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 11453 of file chan_sip.c. References sip_peer::addr, ahp, ast_gethostbyname(), ast_log(), ast_strdupa, ASTOBJ_UNREF, sip_peer::call_limit, sip_peer::defaddr, find_peer(), hp, sip_peer::inUse, sip_peer::lastms, LOG_DEBUG, sip_peer::maxms, option_debug, and sip_destroy_peer(). 11454 { 11455 char *host; 11456 char *tmp; 11457 11458 struct hostent *hp; 11459 struct ast_hostent ahp; 11460 struct sip_peer *p; 11461 11462 int res = AST_DEVICE_INVALID; 11463 11464 host = ast_strdupa(data); 11465 if ((tmp = strchr(host, '@'))) 11466 host = tmp + 1; 11467 11468 if (option_debug > 2) 11469 ast_log(LOG_DEBUG, "Checking device state for peer %s\n", host); 11470 11471 if ((p = find_peer(host, NULL, 1))) { 11472 if (p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) { 11473 /* we have an address for the peer */ 11474 /* if qualify is turned on, check the status */ 11475 if (p->maxms && (p->lastms > p->maxms)) { 11476 res = AST_DEVICE_UNAVAILABLE; 11477 } else { 11478 /* qualify is not on, or the peer is responding properly */ 11479 /* check call limit */ 11480 if (p->call_limit && (p->inUse == p->call_limit)) 11481 res = AST_DEVICE_BUSY; 11482 else if (p->call_limit && p->inUse) 11483 res = AST_DEVICE_INUSE; 11484 else if (p->call_limit) 11485 res = AST_DEVICE_NOT_INUSE; 11486 else 11487 res = AST_DEVICE_UNKNOWN; 11488 } 11489 } else { 11490 /* there is no address, it's unavailable */ 11491 res = AST_DEVICE_UNAVAILABLE; 11492 } 11493 ASTOBJ_UNREF(p,sip_destroy_peer); 11494 } else { 11495 hp = ast_gethostbyname(host, &ahp); 11496 if (hp) 11497 res = AST_DEVICE_UNKNOWN; 11498 } 11499 11500 return res; 11501 }
|
|
sip_do_debug: Turn on SIP debugging (CLI command)
Definition at line 8731 of file chan_sip.c. References ast_cli(), debugaddr, sip_do_debug_ip(), sip_do_debug_peer(), and sipdebug. 08732 { 08733 int oldsipdebug = sipdebug & SIP_DEBUG_CONSOLE; 08734 if (argc != 2) { 08735 if (argc != 4) 08736 return RESULT_SHOWUSAGE; 08737 else if (strncmp(argv[2], "ip\0", 3) == 0) 08738 return sip_do_debug_ip(fd, argc, argv); 08739 else if (strncmp(argv[2], "peer\0", 5) == 0) 08740 return sip_do_debug_peer(fd, argc, argv); 08741 else return RESULT_SHOWUSAGE; 08742 } 08743 sipdebug |= SIP_DEBUG_CONSOLE; 08744 memset(&debugaddr, 0, sizeof(debugaddr)); 08745 if (oldsipdebug) 08746 ast_cli(fd, "SIP Debugging re-enabled\n"); 08747 else 08748 ast_cli(fd, "SIP Debugging enabled\n"); 08749 return RESULT_SUCCESS; 08750 }
|
|
sip_do_debug: Enable SIP Debugging in CLI ---
Definition at line 8675 of file chan_sip.c. References ahp, ast_cli(), ast_gethostbyname(), ast_inet_ntoa(), debugaddr, hp, and sipdebug. Referenced by sip_do_debug(). 08676 { 08677 struct hostent *hp; 08678 struct ast_hostent ahp; 08679 char iabuf[INET_ADDRSTRLEN]; 08680 int port = 0; 08681 char *p, *arg; 08682 08683 if (argc != 4) 08684 return RESULT_SHOWUSAGE; 08685 arg = argv[3]; 08686 p = strstr(arg, ":"); 08687 if (p) { 08688 *p = '\0'; 08689 p++; 08690 port = atoi(p); 08691 } 08692 hp = ast_gethostbyname(arg, &ahp); 08693 if (hp == NULL) { 08694 return RESULT_SHOWUSAGE; 08695 } 08696 debugaddr.sin_family = AF_INET; 08697 memcpy(&debugaddr.sin_addr, hp->h_addr, sizeof(debugaddr.sin_addr)); 08698 debugaddr.sin_port = htons(port); 08699 if (port == 0) 08700 ast_cli(fd, "SIP Debugging Enabled for IP: %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), debugaddr.sin_addr)); 08701 else 08702 ast_cli(fd, "SIP Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), debugaddr.sin_addr), port); 08703 sipdebug |= SIP_DEBUG_CONSOLE; 08704 return RESULT_SUCCESS; 08705 }
|
|
sip_do_debug_peer: Turn on SIP debugging with peer mask
Definition at line 8708 of file chan_sip.c. References sip_peer::addr, ast_cli(), ast_inet_ntoa(), ASTOBJ_UNREF, debugaddr, find_peer(), sip_destroy_peer(), and sipdebug. Referenced by sip_do_debug(). 08709 { 08710 struct sip_peer *peer; 08711 char iabuf[INET_ADDRSTRLEN]; 08712 if (argc != 4) 08713 return RESULT_SHOWUSAGE; 08714 peer = find_peer(argv[3], NULL, 1); 08715 if (peer) { 08716 if (peer->addr.sin_addr.s_addr) { 08717 debugaddr.sin_family = AF_INET; 08718 memcpy(&debugaddr.sin_addr, &peer->addr.sin_addr, sizeof(debugaddr.sin_addr)); 08719 debugaddr.sin_port = peer->addr.sin_port; 08720 ast_cli(fd, "SIP Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), debugaddr.sin_addr), ntohs(debugaddr.sin_port)); 08721 sipdebug |= SIP_DEBUG_CONSOLE; 08722 } else 08723 ast_cli(fd, "Unable to get IP address of peer '%s'\n", argv[3]); 08724 ASTOBJ_UNREF(peer,sip_destroy_peer); 08725 } else 08726 ast_cli(fd, "No such peer '%s'\n", argv[3]); 08727 return RESULT_SUCCESS; 08728 }
|
|
sip_do_history: Enable SIP History logging (CLI) ---
Definition at line 8810 of file chan_sip.c. References ast_cli(), and recordhistory. 08811 { 08812 if (argc != 2) { 08813 return RESULT_SHOWUSAGE; 08814 } 08815 recordhistory = 1; 08816 ast_cli(fd, "SIP History Recording Enabled (use 'sip show history')\n"); 08817 return RESULT_SUCCESS; 08818 }
|
|
sip_do_reload: Reload module
Definition at line 12999 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(). 13000 { 13001 clear_realm_authentication(authl); 13002 clear_sip_domains(); 13003 authl = NULL; 13004 13005 /* First, destroy all outstanding registry calls */ 13006 /* This is needed, since otherwise active registry entries will not be destroyed */ 13007 ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { 13008 ASTOBJ_RDLOCK(iterator); 13009 if (iterator->call) { 13010 if (option_debug > 2) 13011 ast_log(LOG_DEBUG, "Destroying active SIP dialog for registry %s@%s\n", iterator->username, iterator->hostname); 13012 /* This will also remove references to the registry */ 13013 sip_destroy(iterator->call); 13014 } 13015 ASTOBJ_UNLOCK(iterator); 13016 } while(0)); 13017 13018 ASTOBJ_CONTAINER_DESTROYALL(&userl, sip_destroy_user); 13019 ASTOBJ_CONTAINER_DESTROYALL(®l, sip_registry_destroy); 13020 ASTOBJ_CONTAINER_MARKALL(&peerl); 13021 reload_config(); 13022 /* Prune peers who still are supposed to be deleted */ 13023 ASTOBJ_CONTAINER_PRUNE_MARKED(&peerl, sip_destroy_peer); 13024 13025 sip_poke_all_peers(); 13026 sip_send_all_registers(); 13027 13028 return 0; 13029 }
|
|
sip_dtmfmode: change the DTMFmode for a SIP call (application) ---
Definition at line 12754 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, 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(). 12755 { 12756 struct sip_pvt *p; 12757 char *mode; 12758 if (data) 12759 mode = (char *)data; 12760 else { 12761 ast_log(LOG_WARNING, "This application requires the argument: info, inband, rfc2833\n"); 12762 return 0; 12763 } 12764 ast_mutex_lock(&chan->lock); 12765 if (chan->type != channeltype) { 12766 ast_log(LOG_WARNING, "Call this application only on SIP incoming calls\n"); 12767 ast_mutex_unlock(&chan->lock); 12768 return 0; 12769 } 12770 p = chan->tech_pvt; 12771 if (!p) { 12772 ast_mutex_unlock(&chan->lock); 12773 return 0; 12774 } 12775 ast_mutex_lock(&p->lock); 12776 if (!strcasecmp(mode,"info")) { 12777 ast_clear_flag(p, SIP_DTMF); 12778 ast_set_flag(p, SIP_DTMF_INFO); 12779 } else if (!strcasecmp(mode,"rfc2833")) { 12780 ast_clear_flag(p, SIP_DTMF); 12781 ast_set_flag(p, SIP_DTMF_RFC2833); 12782 } else if (!strcasecmp(mode,"inband")) { 12783 ast_clear_flag(p, SIP_DTMF); 12784 ast_set_flag(p, SIP_DTMF_INBAND); 12785 } else 12786 ast_log(LOG_WARNING, "I don't know about this dtmf mode: %s\n",mode); 12787 if (ast_test_flag(p, SIP_DTMF) == SIP_DTMF_INBAND) { 12788 if (!p->vad) { 12789 p->vad = ast_dsp_new(); 12790 ast_dsp_set_features(p->vad, DSP_FEATURE_DTMF_DETECT); 12791 } 12792 } else { 12793 if (p->vad) { 12794 ast_dsp_free(p->vad); 12795 p->vad = NULL; 12796 } 12797 } 12798 ast_mutex_unlock(&p->lock); 12799 ast_mutex_unlock(&chan->lock); 12800 return 0; 12801 }
|
|
dump_history: Dump SIP history to debug log file at end of lifespan for SIP dialog
Definition at line 8556 of file chan_sip.c. References ast_log(), sip_pvt::callid, sip_history::event, sip_pvt::history, LOG_DEBUG, and sip_history::next. Referenced by __sip_destroy(). 08557 { 08558 int x; 08559 struct sip_history *hist; 08560 08561 if (!dialog) 08562 return; 08563 08564 ast_log(LOG_DEBUG, "\n---------- SIP HISTORY for '%s' \n", dialog->callid); 08565 if (dialog->subscribed) 08566 ast_log(LOG_DEBUG, " * Subscription\n"); 08567 else 08568 ast_log(LOG_DEBUG, " * SIP Call\n"); 08569 x = 0; 08570 hist = dialog->history; 08571 while(hist) { 08572 x++; 08573 ast_log(LOG_DEBUG, " %d. %s\n", x, hist->event); 08574 hist = hist->next; 08575 } 08576 if (!x) 08577 ast_log(LOG_DEBUG, "Call '%s' has no history\n", dialog->callid); 08578 ast_log(LOG_DEBUG, "\n---------- END SIP HISTORY for '%s' \n", dialog->callid); 08579 08580 }
|
|
sip_fixup: Fix up a channel: If a channel is consumed, this is called. Basically update any ->owner links ----
Definition at line 2576 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. 02577 { 02578 struct sip_pvt *p = newchan->tech_pvt; 02579 ast_mutex_lock(&p->lock); 02580 if (p->owner != oldchan) { 02581 ast_log(LOG_WARNING, "old channel wasn't %p but was %p\n", oldchan, p->owner); 02582 ast_mutex_unlock(&p->lock); 02583 return -1; 02584 } 02585 p->owner = newchan; 02586 ast_mutex_unlock(&p->lock); 02587 return 0; 02588 }
|
|
sip_get_codec: Return SIP UA's codec (part of the RTP interface) ---
Definition at line 12950 of file chan_sip.c. References sip_pvt::peercapability, and ast_channel::tech_pvt. 12951 { 12952 struct sip_pvt *p = chan->tech_pvt; 12953 return p->peercapability; 12954 }
|
|
sip_get_rtp_peer: Returns null if we can't reinvite (part of RTP interface)
Definition at line 12658 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. 12659 { 12660 struct sip_pvt *p; 12661 struct ast_rtp *rtp = NULL; 12662 p = chan->tech_pvt; 12663 if (!p) 12664 return NULL; 12665 ast_mutex_lock(&p->lock); 12666 if (p->rtp && ast_test_flag(p, SIP_CAN_REINVITE)) 12667 rtp = p->rtp; 12668 ast_mutex_unlock(&p->lock); 12669 return rtp; 12670 }
|
|
sip_get_vrtp_peer: Returns null if we can't reinvite video (part of RTP interface)
Definition at line 12673 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. 12674 { 12675 struct sip_pvt *p; 12676 struct ast_rtp *rtp = NULL; 12677 p = chan->tech_pvt; 12678 if (!p) 12679 return NULL; 12680 12681 ast_mutex_lock(&p->lock); 12682 if (p->vrtp && ast_test_flag(p, SIP_CAN_REINVITE)) 12683 rtp = p->vrtp; 12684 ast_mutex_unlock(&p->lock); 12685 return rtp; 12686 }
|
|
sip_getheader: Get a SIP header (dialplan app) ---
Definition at line 12835 of file chan_sip.c. References ast_goto_if_exists(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_strdupa, ast_strlen_zero(), 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(). 12836 { 12837 static int dep_warning = 0; 12838 struct sip_pvt *p; 12839 char *argv, *varname = NULL, *header = NULL, *content; 12840 12841 if (!dep_warning) { 12842 ast_log(LOG_WARNING, "SIPGetHeader is deprecated, use the SIP_HEADER function instead.\n"); 12843 dep_warning = 1; 12844 } 12845 12846 argv = ast_strdupa(data); 12847 if (!argv) { 12848 ast_log(LOG_DEBUG, "Memory allocation failed\n"); 12849 return 0; 12850 } 12851 12852 if (strchr (argv, '=') ) { /* Pick out argumenet */ 12853 varname = strsep (&argv, "="); 12854 header = strsep (&argv, "\0"); 12855 } 12856 12857 if (!varname || !header) { 12858 ast_log(LOG_DEBUG, "SipGetHeader: Ignoring command, Syntax error in argument\n"); 12859 return 0; 12860 } 12861 12862 ast_mutex_lock(&chan->lock); 12863 if (chan->type != channeltype) { 12864 ast_log(LOG_WARNING, "Call this application only on incoming SIP calls\n"); 12865 ast_mutex_unlock(&chan->lock); 12866 return 0; 12867 } 12868 12869 p = chan->tech_pvt; 12870 content = get_header(&p->initreq, header); /* Get the header */ 12871 if (!ast_strlen_zero(content)) { 12872 pbx_builtin_setvar_helper(chan, varname, content); 12873 } else { 12874 ast_log(LOG_WARNING,"SIP Header %s not found for channel variable %s\n", header, varname); 12875 ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101); 12876 } 12877 12878 ast_mutex_unlock(&chan->lock); 12879 return 0; 12880 }
|
|
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_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::initid, sip_pvt::initreq, sip_pvt::lock, LOG_DEBUG, LOG_WARNING, ast_channel::name, sip_pvt::ocseq, 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, 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 transmit_request_with_auth(p, SIP_CANCEL, p->ocseq, 1, 0); 02451 /* Actually don't destroy us yet, wait for the 487 on our original 02452 INVITE, but do set an autodestruct just in case we never get it. */ 02453 ast_clear_flag(&locflags, SIP_NEEDDESTROY); 02454 sip_scheddestroy(p, 15000); 02455 /* stop retransmitting an INVITE that has not received a response */ 02456 __sip_pretend_ack(p); 02457 if ( p->initid != -1 ) { 02458 /* channel still up - reverse dec of inUse counter 02459 only if the channel is not auto-congested */ 02460 update_call_counter(p, INC_CALL_LIMIT); 02461 } 02462 } else { /* Incoming call, not up */ 02463 char *res; 02464 if (ast->hangupcause && ((res = hangup_cause2sip(ast->hangupcause)))) { 02465 transmit_response_reliable(p, res, &p->initreq, 1); 02466 } else 02467 transmit_response_reliable(p, "603 Declined", &p->initreq, 1); 02468 } 02469 } else { /* Call is in UP state, send BYE */ 02470 if (!p->pendinginvite) { 02471 /* Send a hangup */ 02472 transmit_request_with_auth(p, SIP_BYE, 0, 1, 1); 02473 } else { 02474 /* Note we will need a BYE when this all settles out 02475 but we can't send one while we have "INVITE" outstanding. */ 02476 ast_set_flag(p, SIP_PENDINGBYE); 02477 ast_clear_flag(p, SIP_NEEDREINVITE); 02478 } 02479 } 02480 } 02481 ast_copy_flags(p, (&locflags), SIP_NEEDDESTROY); 02482 ast_mutex_unlock(&p->lock); 02483 return 0; 02484 }
|
|
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 2633 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_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_PROGRESS_SENT, SIP_RINGING, ast_channel::tech_pvt, transmit_info_with_vidupdate(), transmit_response(), transmit_response_with_sdp(), and sip_pvt::vrtp. 02634 { 02635 struct sip_pvt *p = ast->tech_pvt; 02636 int res = 0; 02637 02638 ast_mutex_lock(&p->lock); 02639 switch(condition) { 02640 case AST_CONTROL_RINGING: 02641 if (ast->_state == AST_STATE_RING) { 02642 if (!ast_test_flag(p, SIP_PROGRESS_SENT) || 02643 (ast_test_flag(p, SIP_PROG_INBAND) == SIP_PROG_INBAND_NEVER)) { 02644 /* Send 180 ringing if out-of-band seems reasonable */ 02645 transmit_response(p, "180 Ringing", &p->initreq); 02646 ast_set_flag(p, SIP_RINGING); 02647 if (ast_test_flag(p, SIP_PROG_INBAND) != SIP_PROG_INBAND_YES) 02648 break; 02649 } else { 02650 /* Well, if it's not reasonable, just send in-band */ 02651 } 02652 } 02653 res = -1; 02654 break; 02655 case AST_CONTROL_BUSY: 02656 if (ast->_state != AST_STATE_UP) { 02657 transmit_response(p, "486 Busy Here", &p->initreq); 02658 ast_set_flag(p, SIP_ALREADYGONE); 02659 ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV); 02660 break; 02661 } 02662 res = -1; 02663 break; 02664 case AST_CONTROL_CONGESTION: 02665 if (ast->_state != AST_STATE_UP) { 02666 transmit_response(p, "503 Service Unavailable", &p->initreq); 02667 ast_set_flag(p, SIP_ALREADYGONE); 02668 ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV); 02669 break; 02670 } 02671 res = -1; 02672 break; 02673 case AST_CONTROL_PROCEEDING: 02674 if ((ast->_state != AST_STATE_UP) && !ast_test_flag(p, SIP_PROGRESS_SENT) && !ast_test_flag(p, SIP_OUTGOING)) { 02675 transmit_response(p, "100 Trying", &p->initreq); 02676 break; 02677 } 02678 res = -1; 02679 break; 02680 case AST_CONTROL_PROGRESS: 02681 if ((ast->_state != AST_STATE_UP) && !ast_test_flag(p, SIP_PROGRESS_SENT) && !ast_test_flag(p, SIP_OUTGOING)) { 02682 transmit_response_with_sdp(p, "183 Session Progress", &p->initreq, 0); 02683 ast_set_flag(p, SIP_PROGRESS_SENT); 02684 break; 02685 } 02686 res = -1; 02687 break; 02688 case AST_CONTROL_HOLD: /* The other part of the bridge are put on hold */ 02689 if (sipdebug) 02690 ast_log(LOG_DEBUG, "Bridged channel now on hold%s\n", p->callid); 02691 res = -1; 02692 break; 02693 case AST_CONTROL_UNHOLD: /* The other part of the bridge are back from hold */ 02694 if (sipdebug) 02695 ast_log(LOG_DEBUG, "Bridged channel is back from hold, let's talk! : %s\n", p->callid); 02696 res = -1; 02697 break; 02698 case AST_CONTROL_VIDUPDATE: /* Request a video frame update */ 02699 if (p->vrtp && !ast_test_flag(p, SIP_NOVIDEO)) { 02700 transmit_info_with_vidupdate(p); 02701 res = 0; 02702 } else 02703 res = -1; 02704 break; 02705 case -1: 02706 res = -1; 02707 break; 02708 default: 02709 ast_log(LOG_WARNING, "Don't know how to indicate condition %d\n", condition); 02710 res = -1; 02711 break; 02712 } 02713 ast_mutex_unlock(&p->lock); 02714 return res; 02715 }
|
|
sip_new: Initiate a call in the SIP channel
Definition at line 2721 of file chan_sip.c. References ast_channel::accountcode, ast_channel::adsicpe, ast_channel::amaflags, 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_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, global_capability, 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, strdup, ast_channel::tech, ast_channel::tech_pvt, thread_safe_rand(), ast_channel::type, usecnt, ast_variable::value, and ast_channel::writeformat. Referenced by handle_request_invite(), and sip_request_call(). 02722 { 02723 struct ast_channel *tmp; 02724 struct ast_variable *v = NULL; 02725 int fmt; 02726 #ifdef OSP_SUPPORT 02727 char iabuf[INET_ADDRSTRLEN]; 02728 char peer[MAXHOSTNAMELEN]; 02729 #endif 02730 02731 ast_mutex_unlock(&i->lock); 02732 /* Don't hold a sip pvt lock while we allocate a channel */ 02733 tmp = ast_channel_alloc(1); 02734 ast_mutex_lock(&i->lock); 02735 if (!tmp) { 02736 ast_log(LOG_WARNING, "Unable to allocate SIP channel structure\n"); 02737 return NULL; 02738 } 02739 tmp->tech = &sip_tech; 02740 /* Select our native format based on codec preference until we receive 02741 something from another device to the contrary. */ 02742 if (i->jointcapability) 02743 tmp->nativeformats = ast_codec_choose(&i->prefs, i->jointcapability, 1); 02744 else if (i->capability) 02745 tmp->nativeformats = ast_codec_choose(&i->prefs, i->capability, 1); 02746 else 02747 tmp->nativeformats = ast_codec_choose(&i->prefs, global_capability, 1); 02748 fmt = ast_best_codec(tmp->nativeformats); 02749 02750 if (title) 02751 snprintf(tmp->name, sizeof(tmp->name), "SIP/%s-%04x", title, thread_safe_rand() & 0xffff); 02752 else if (strchr(i->fromdomain,':')) 02753 snprintf(tmp->name, sizeof(tmp->name), "SIP/%s-%08x", strchr(i->fromdomain,':')+1, (int)(long)(i)); 02754 else 02755 snprintf(tmp->name, sizeof(tmp->name), "SIP/%s-%08x", i->fromdomain, (int)(long)(i)); 02756 02757 tmp->type = channeltype; 02758 if (ast_test_flag(i, SIP_DTMF) == SIP_DTMF_INBAND) { 02759 i->vad = ast_dsp_new(); 02760 ast_dsp_set_features(i->vad, DSP_FEATURE_DTMF_DETECT); 02761 if (relaxdtmf) 02762 ast_dsp_digitmode(i->vad, DSP_DIGITMODE_DTMF | DSP_DIGITMODE_RELAXDTMF); 02763 } 02764 if (i->rtp) { 02765 tmp->fds[0] = ast_rtp_fd(i->rtp); 02766 tmp->fds[1] = ast_rtcp_fd(i->rtp); 02767 } 02768 if (i->vrtp) { 02769 tmp->fds[2] = ast_rtp_fd(i->vrtp); 02770 tmp->fds[3] = ast_rtcp_fd(i->vrtp); 02771 } 02772 if (state == AST_STATE_RING) 02773 tmp->rings = 1; 02774 tmp->adsicpe = AST_ADSI_UNAVAILABLE; 02775 tmp->writeformat = fmt; 02776 tmp->rawwriteformat = fmt; 02777 tmp->readformat = fmt; 02778 tmp->rawreadformat = fmt; 02779 tmp->tech_pvt = i; 02780 02781 tmp->callgroup = i->callgroup; 02782 tmp->pickupgroup = i->pickupgroup; 02783 tmp->cid.cid_pres = i->callingpres; 02784 if (!ast_strlen_zero(i->accountcode)) 02785 ast_copy_string(tmp->accountcode, i->accountcode, sizeof(tmp->accountcode)); 02786 if (i->amaflags) 02787 tmp->amaflags = i->amaflags; 02788 if (!ast_strlen_zero(i->language)) 02789 ast_copy_string(tmp->language, i->language, sizeof(tmp->language)); 02790 if (!ast_strlen_zero(i->musicclass)) 02791 ast_copy_string(tmp->musicclass, i->musicclass, sizeof(tmp->musicclass)); 02792 i->owner = tmp; 02793 ast_mutex_lock(&usecnt_lock); 02794 usecnt++; 02795 ast_mutex_unlock(&usecnt_lock); 02796 ast_copy_string(tmp->context, i->context, sizeof(tmp->context)); 02797 ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten)); 02798 if (!ast_strlen_zero(i->cid_num)) 02799 tmp->cid.cid_num = strdup(i->cid_num); 02800 if (!ast_strlen_zero(i->cid_name)) 02801 tmp->cid.cid_name = strdup(i->cid_name); 02802 if (!ast_strlen_zero(i->rdnis)) 02803 tmp->cid.cid_rdnis = strdup(i->rdnis); 02804 if (!ast_strlen_zero(i->exten) && strcmp(i->exten, "s")) 02805 tmp->cid.cid_dnid = strdup(i->exten); 02806 tmp->priority = 1; 02807 if (!ast_strlen_zero(i->uri)) { 02808 pbx_builtin_setvar_helper(tmp, "SIPURI", i->uri); 02809 } 02810 if (!ast_strlen_zero(i->domain)) { 02811 pbx_builtin_setvar_helper(tmp, "SIPDOMAIN", i->domain); 02812 } 02813 if (!ast_strlen_zero(i->useragent)) { 02814 pbx_builtin_setvar_helper(tmp, "SIPUSERAGENT", i->useragent); 02815 } 02816 if (!ast_strlen_zero(i->callid)) { 02817 pbx_builtin_setvar_helper(tmp, "SIPCALLID", i->callid); 02818 } 02819 #ifdef OSP_SUPPORT 02820 snprintf(peer, sizeof(peer), "[%s]:%d", ast_inet_ntoa(iabuf, sizeof(iabuf), i->sa.sin_addr), ntohs(i->sa.sin_port)); 02821 pbx_builtin_setvar_helper(tmp, "OSPPEER", peer); 02822 #endif 02823 ast_setstate(tmp, state); 02824 if (state != AST_STATE_DOWN) { 02825 if (ast_pbx_start(tmp)) { 02826 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name); 02827 ast_hangup(tmp); 02828 tmp = NULL; 02829 } 02830 } 02831 /* Set channel variables for this call from configuration */ 02832 for (v = i->chanvars ; v ; v = v->next) 02833 pbx_builtin_setvar_helper(tmp,v->name,v->value); 02834 02835 return tmp; 02836 }
|
|
sip_no_debug: Disable SIP Debugging in CLI ---
Definition at line 8832 of file chan_sip.c. References ast_cli(), and sipdebug. 08834 { 08835 if (argc != 3) 08836 return RESULT_SHOWUSAGE; 08837 sipdebug &= ~SIP_DEBUG_CONSOLE; 08838 ast_cli(fd, "SIP Debugging Disabled\n"); 08839 return RESULT_SUCCESS; 08840 }
|
|
sip_no_history: Disable SIP History logging (CLI) ---
Definition at line 8821 of file chan_sip.c. References ast_cli(), and recordhistory. 08822 { 08823 if (argc != 3) { 08824 return RESULT_SHOWUSAGE; 08825 } 08826 recordhistory = 0; 08827 ast_cli(fd, "SIP History Recording Disabled\n"); 08828 return RESULT_SUCCESS; 08829 }
|
|
sip_notify: Send SIP notify to peer
Definition at line 8753 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(), sip_pvt::callid, create_addr(), sip_pvt::fromdomain, initreqprep(), LOG_WARNING, ast_variable::name, ast_variable::next, notify_config, notify_types, sip_pvt::ourip, sip_pvt::sa, sip_alloc(), sip_destroy(), SIP_NOTIFY, sip_scheddestroy(), transmit_sip_request(), ast_variable::value, var, and sip_pvt::via. 08754 { 08755 struct ast_variable *varlist; 08756 int i; 08757 08758 if (argc < 4) 08759 return RESULT_SHOWUSAGE; 08760 08761 if (!notify_types) { 08762 ast_cli(fd, "No %s file found, or no types listed there\n", notify_config); 08763 return RESULT_FAILURE; 08764 } 08765 08766 varlist = ast_variable_browse(notify_types, argv[2]); 08767 08768 if (!varlist) { 08769 ast_cli(fd, "Unable to find notify type '%s'\n", argv[2]); 08770 return RESULT_FAILURE; 08771 } 08772 08773 for (i = 3; i < argc; i++) { 08774 struct sip_pvt *p; 08775 struct sip_request req; 08776 struct ast_variable *var; 08777 08778 p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY); 08779 if (!p) { 08780 ast_log(LOG_WARNING, "Unable to build sip pvt data for notify\n"); 08781 return RESULT_FAILURE; 08782 } 08783 08784 if (create_addr(p, argv[i])) { 08785 /* Maybe they're not registered, etc. */ 08786 sip_destroy(p); 08787 ast_cli(fd, "Could not create address for '%s'\n", argv[i]); 08788 continue; 08789 } 08790 08791 initreqprep(&req, p, SIP_NOTIFY); 08792 08793 for (var = varlist; var; var = var->next) 08794 add_header(&req, var->name, var->value); 08795 08796 add_blank_header(&req); 08797 /* Recalculate our side, and recalculate Call ID */ 08798 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 08799 memcpy(&p->ourip, &__ourip, sizeof(p->ourip)); 08800 build_via(p, p->via, sizeof(p->via)); 08801 build_callid(p->callid, sizeof(p->callid), p->ourip, p->fromdomain); 08802 ast_cli(fd, "Sending NOTIFY of type '%s' to '%s'\n", argv[2], argv[i]); 08803 transmit_sip_request(p, &req); 08804 sip_scheddestroy(p, 15000); 08805 } 08806 08807 return RESULT_SUCCESS; 08808 }
|
|
sip_park: Park a call ---
Definition at line 10046 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, sip_dual::chan1, 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(). 10047 { 10048 struct sip_dual *d; 10049 struct ast_channel *chan1m, *chan2m; 10050 pthread_t th; 10051 chan1m = ast_channel_alloc(0); 10052 chan2m = ast_channel_alloc(0); 10053 if ((!chan2m) || (!chan1m)) { 10054 if (chan1m) 10055 ast_hangup(chan1m); 10056 if (chan2m) 10057 ast_hangup(chan2m); 10058 return -1; 10059 } 10060 snprintf(chan1m->name, sizeof(chan1m->name), "Parking/%s", chan1->name); 10061 /* Make formats okay */ 10062 chan1m->readformat = chan1->readformat; 10063 chan1m->writeformat = chan1->writeformat; 10064 ast_channel_masquerade(chan1m, chan1); 10065 /* Setup the extensions and such */ 10066 ast_copy_string(chan1m->context, chan1->context, sizeof(chan1m->context)); 10067 ast_copy_string(chan1m->exten, chan1->exten, sizeof(chan1m->exten)); 10068 chan1m->priority = chan1->priority; 10069 10070 /* We make a clone of the peer channel too, so we can play 10071 back the announcement */ 10072 snprintf(chan2m->name, sizeof (chan2m->name), "SIPPeer/%s",chan2->name); 10073 /* Make formats okay */ 10074 chan2m->readformat = chan2->readformat; 10075 chan2m->writeformat = chan2->writeformat; 10076 ast_channel_masquerade(chan2m, chan2); 10077 /* Setup the extensions and such */ 10078 ast_copy_string(chan2m->context, chan2->context, sizeof(chan2m->context)); 10079 ast_copy_string(chan2m->exten, chan2->exten, sizeof(chan2m->exten)); 10080 chan2m->priority = chan2->priority; 10081 ast_mutex_lock(&chan2m->lock); 10082 if (ast_do_masquerade(chan2m)) { 10083 ast_log(LOG_WARNING, "Masquerade failed :(\n"); 10084 ast_mutex_unlock(&chan2m->lock); 10085 ast_hangup(chan2m); 10086 return -1; 10087 } 10088 ast_mutex_unlock(&chan2m->lock); 10089 d = malloc(sizeof(struct sip_dual)); 10090 if (d) { 10091 memset(d, 0, sizeof(*d)); 10092 /* Save original request for followup */ 10093 copy_request(&d->req, req); 10094 d->chan1 = chan1m; 10095 d->chan2 = chan2m; 10096 if (!ast_pthread_create(&th, NULL, sip_park_thread, d)) 10097 return 0; 10098 free(d); 10099 } 10100 return -1; 10101 }
|
|
sip_park_thread: Park SIP call support function
Definition at line 10023 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(). 10024 { 10025 struct ast_channel *chan1, *chan2; 10026 struct sip_dual *d; 10027 struct sip_request req; 10028 int ext; 10029 int res; 10030 d = stuff; 10031 chan1 = d->chan1; 10032 chan2 = d->chan2; 10033 copy_request(&req, &d->req); 10034 free(d); 10035 ast_mutex_lock(&chan1->lock); 10036 ast_do_masquerade(chan1); 10037 ast_mutex_unlock(&chan1->lock); 10038 res = ast_park_call(chan1, chan2, 0, &ext); 10039 /* Then hangup */ 10040 ast_hangup(chan2); 10041 ast_log(LOG_DEBUG, "Parked on extension '%d'\n", ext); 10042 return NULL; 10043 }
|
|
sip_poke_all_peers: Send a poke to all known peers
Definition at line 12966 of file chan_sip.c. References ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_UNLOCK, ASTOBJ_WRLOCK, peerl, and sip_poke_peer(). Referenced by load_module(). 12967 { 12968 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 12969 ASTOBJ_WRLOCK(iterator); 12970 sip_poke_peer(iterator); 12971 ASTOBJ_UNLOCK(iterator); 12972 } while (0) 12973 ); 12974 }
|
|
sip_poke_noanswer: No answer to Qualify poke ---
Definition at line 11358 of file chan_sip.c. References ast_device_state_changed(), ast_log(), ast_sched_add(), sip_peer::call, DEFAULT_FREQ_NOTOK, EVENT_FLAG_SYSTEM, sip_peer::lastms, LOG_NOTICE, manager_event(), sip_peer::pokeexpire, sched, sip_destroy(), and sip_poke_peer_s(). Referenced by sip_poke_peer(). 11359 { 11360 struct sip_peer *peer = data; 11361 11362 peer->pokeexpire = -1; 11363 if (peer->lastms > -1) { 11364 ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Last qualify: %d\n", peer->name, peer->lastms); 11365 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, -1); 11366 } 11367 if (peer->call) 11368 sip_destroy(peer->call); 11369 peer->call = NULL; 11370 peer->lastms = -1; 11371 ast_device_state_changed("SIP/%s", peer->name); 11372 /* Try again quickly */ 11373 peer->pokeexpire = ast_sched_add(sched, DEFAULT_FREQ_NOTOK, sip_poke_peer_s, peer); 11374 return 0; 11375 }
|
|
sip_poke_peer: Check availability of peer, also keep NAT open ---
Definition at line 11380 of file chan_sip.c. References __ourip, sip_peer::addr, 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, sched, sip_alloc(), sip_destroy(), SIP_INVITE, SIP_OPTIONS, SIP_OUTGOING, sip_poke_noanswer(), 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(). 11381 { 11382 struct sip_pvt *p; 11383 if (!peer->maxms || !peer->addr.sin_addr.s_addr) { 11384 /* IF we have no IP, or this isn't to be monitored, return 11385 imeediately after clearing things out */ 11386 if (peer->pokeexpire > -1) 11387 ast_sched_del(sched, peer->pokeexpire); 11388 peer->lastms = 0; 11389 peer->pokeexpire = -1; 11390 peer->call = NULL; 11391 return 0; 11392 } 11393 if (peer->call > 0) { 11394 if (sipdebug) 11395 ast_log(LOG_NOTICE, "Still have a QUALIFY dialog active, deleting\n"); 11396 sip_destroy(peer->call); 11397 } 11398 p = peer->call = sip_alloc(NULL, NULL, 0, SIP_OPTIONS); 11399 if (!peer->call) { 11400 ast_log(LOG_WARNING, "Unable to allocate dialog for poking peer '%s'\n", peer->name); 11401 return -1; 11402 } 11403 memcpy(&p->sa, &peer->addr, sizeof(p->sa)); 11404 memcpy(&p->recv, &peer->addr, sizeof(p->sa)); 11405 11406 /* Send options to peer's fullcontact */ 11407 if (!ast_strlen_zero(peer->fullcontact)) { 11408 ast_copy_string (p->fullcontact, peer->fullcontact, sizeof(p->fullcontact)); 11409 } 11410 11411 if (!ast_strlen_zero(peer->tohost)) 11412 ast_copy_string(p->tohost, peer->tohost, sizeof(p->tohost)); 11413 else 11414 ast_inet_ntoa(p->tohost, sizeof(p->tohost), peer->addr.sin_addr); 11415 11416 /* Recalculate our side, and recalculate Call ID */ 11417 if (ast_sip_ouraddrfor(&p->sa.sin_addr,&p->ourip)) 11418 memcpy(&p->ourip, &__ourip, sizeof(p->ourip)); 11419 build_via(p, p->via, sizeof(p->via)); 11420 build_callid(p->callid, sizeof(p->callid), p->ourip, p->fromdomain); 11421 11422 if (peer->pokeexpire > -1) 11423 ast_sched_del(sched, peer->pokeexpire); 11424 p->peerpoke = peer; 11425 ast_set_flag(p, SIP_OUTGOING); 11426 #ifdef VOCAL_DATA_HACK 11427 ast_copy_string(p->username, "__VOCAL_DATA_SHOULD_READ_THE_SIP_SPEC__", sizeof(p->username)); 11428 transmit_invite(p, SIP_INVITE, 0, 2); 11429 #else 11430 transmit_invite(p, SIP_OPTIONS, 0, 2); 11431 #endif 11432 gettimeofday(&peer->ps, NULL); 11433 peer->pokeexpire = ast_sched_add(sched, DEFAULT_MAXMS * 2, sip_poke_noanswer, peer); 11434 11435 return 0; 11436 }
|
|
Definition at line 5640 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(). 05641 { 05642 struct sip_peer *peer = data; 05643 peer->pokeexpire = -1; 05644 sip_poke_peer(peer); 05645 return 0; 05646 }
|
|
sip_prune_realtime: Remove temporary realtime objects from memory (CLI) ---
Definition at line 7622 of file chan_sip.c. References ast_cli(), ast_test_flag, ASTOBJ_CONTAINER_FIND_UNLINK, ASTOBJ_CONTAINER_LINK, ASTOBJ_CONTAINER_PRUNE_MARKED, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_CONTAINER_UNLOCK, ASTOBJ_CONTAINER_WRLOCK, ASTOBJ_MARK, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, ASTOBJ_UNREF, sip_user::flags_page2, sip_peer::flags_page2, name, peerl, sip_destroy_peer(), sip_destroy_user(), SIP_PAGE2_RTCACHEFRIENDS, and userl. 07623 { 07624 struct sip_peer *peer; 07625 struct sip_user *user; 07626 int pruneuser = 0; 07627 int prunepeer = 0; 07628 int multi = 0; 07629 char *name = NULL; 07630 regex_t regexbuf; 07631 07632 switch (argc) { 07633 case 4: 07634 if (!strcasecmp(argv[3], "user")) 07635 return RESULT_SHOWUSAGE; 07636 if (!strcasecmp(argv[3], "peer")) 07637 return RESULT_SHOWUSAGE; 07638 if (!strcasecmp(argv[3], "like")) 07639 return RESULT_SHOWUSAGE; 07640 if (!strcasecmp(argv[3], "all")) { 07641 multi = 1; 07642 pruneuser = prunepeer = 1; 07643 } else { 07644 pruneuser = prunepeer = 1; 07645 name = argv[3]; 07646 } 07647 break; 07648 case 5: 07649 if (!strcasecmp(argv[4], "like")) 07650 return RESULT_SHOWUSAGE; 07651 if (!strcasecmp(argv[3], "all")) 07652 return RESULT_SHOWUSAGE; 07653 if (!strcasecmp(argv[3], "like")) { 07654 multi = 1; 07655 name = argv[4]; 07656 pruneuser = prunepeer = 1; 07657 } else if (!strcasecmp(argv[3], "user")) { 07658 pruneuser = 1; 07659 if (!strcasecmp(argv[4], "all")) 07660 multi = 1; 07661 else 07662 name = argv[4]; 07663 } else if (!strcasecmp(argv[3], "peer")) { 07664 prunepeer = 1; 07665 if (!strcasecmp(argv[4], "all")) 07666 multi = 1; 07667 else 07668 name = argv[4]; 07669 } else 07670 return RESULT_SHOWUSAGE; 07671 break; 07672 case 6: 07673 if (strcasecmp(argv[4], "like")) 07674 return RESULT_SHOWUSAGE; 07675 if (!strcasecmp(argv[3], "user")) { 07676 pruneuser = 1; 07677 name = argv[5]; 07678 } else if (!strcasecmp(argv[3], "peer")) { 07679 prunepeer = 1; 07680 name = argv[5]; 07681 } else 07682 return RESULT_SHOWUSAGE; 07683 break; 07684 default: 07685 return RESULT_SHOWUSAGE; 07686 } 07687 07688 if (multi && name) { 07689 if (regcomp(®exbuf, name, REG_EXTENDED | REG_NOSUB)) 07690 return RESULT_SHOWUSAGE; 07691 } 07692 07693 if (multi) { 07694 if (prunepeer) { 07695 int pruned = 0; 07696 07697 ASTOBJ_CONTAINER_WRLOCK(&peerl); 07698 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 07699 ASTOBJ_RDLOCK(iterator); 07700 if (name && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 07701 ASTOBJ_UNLOCK(iterator); 07702 continue; 07703 }; 07704 if (ast_test_flag((&iterator->flags_page2), SIP_PAGE2_RTCACHEFRIENDS)) { 07705 ASTOBJ_MARK(iterator); 07706 pruned++; 07707 } 07708 ASTOBJ_UNLOCK(iterator); 07709 } while (0) ); 07710 if (pruned) { 07711 ASTOBJ_CONTAINER_PRUNE_MARKED(&peerl, sip_destroy_peer); 07712 ast_cli(fd, "%d peers pruned.\n", pruned); 07713 } else 07714 ast_cli(fd, "No peers found to prune.\n"); 07715 ASTOBJ_CONTAINER_UNLOCK(&peerl); 07716 } 07717 if (pruneuser) { 07718 int pruned = 0; 07719 07720 ASTOBJ_CONTAINER_WRLOCK(&userl); 07721 ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do { 07722 ASTOBJ_RDLOCK(iterator); 07723 if (name && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 07724 ASTOBJ_UNLOCK(iterator); 07725 continue; 07726 }; 07727 if (ast_test_flag((&iterator->flags_page2), SIP_PAGE2_RTCACHEFRIENDS)) { 07728 ASTOBJ_MARK(iterator); 07729 pruned++; 07730 } 07731 ASTOBJ_UNLOCK(iterator); 07732 } while (0) ); 07733 if (pruned) { 07734 ASTOBJ_CONTAINER_PRUNE_MARKED(&userl, sip_destroy_user); 07735 ast_cli(fd, "%d users pruned.\n", pruned); 07736 } else 07737 ast_cli(fd, "No users found to prune.\n"); 07738 ASTOBJ_CONTAINER_UNLOCK(&userl); 07739 } 07740 } else { 07741 if (prunepeer) { 07742 if ((peer = ASTOBJ_CONTAINER_FIND_UNLINK(&peerl, name))) { 07743 if (!ast_test_flag((&peer->flags_page2), SIP_PAGE2_RTCACHEFRIENDS)) { 07744 ast_cli(fd, "Peer '%s' is not a Realtime peer, cannot be pruned.\n", name); 07745 ASTOBJ_CONTAINER_LINK(&peerl, peer); 07746 } else 07747 ast_cli(fd, "Peer '%s' pruned.\n", name); 07748 ASTOBJ_UNREF(peer, sip_destroy_peer); 07749 } else 07750 ast_cli(fd, "Peer '%s' not found.\n", name); 07751 } 07752 if (pruneuser) { 07753 if ((user = ASTOBJ_CONTAINER_FIND_UNLINK(&userl, name))) { 07754 if (!ast_test_flag((&user->flags_page2), SIP_PAGE2_RTCACHEFRIENDS)) { 07755 ast_cli(fd, "User '%s' is not a Realtime user, cannot be pruned.\n", name); 07756 ASTOBJ_CONTAINER_LINK(&userl, user); 07757 } else 07758 ast_cli(fd, "User '%s' pruned.\n", name); 07759 ASTOBJ_UNREF(user, sip_destroy_user); 07760 } else 07761 ast_cli(fd, "User '%s' not found.\n", name); 07762 } 07763 } 07764 07765 return RESULT_SUCCESS; 07766 }
|
|
sip_read: Read SIP RTP from channel
Definition at line 2985 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. 02986 { 02987 struct ast_frame *fr; 02988 struct sip_pvt *p = ast->tech_pvt; 02989 ast_mutex_lock(&p->lock); 02990 fr = sip_rtp_read(ast, p); 02991 time(&p->lastrtprx); 02992 ast_mutex_unlock(&p->lock); 02993 return fr; 02994 }
|
|
sip_reg_timeout: Registration timeout, register again
Definition at line 5260 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(), 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(). 05261 { 05262 05263 /* if we are here, our registration timed out, so we'll just do it over */ 05264 struct sip_registry *r = ASTOBJ_REF((struct sip_registry *) data); 05265 struct sip_pvt *p; 05266 int res; 05267 05268 /* if we couldn't get a reference to the registry object, punt */ 05269 if (!r) 05270 return 0; 05271 05272 ast_log(LOG_NOTICE, " -- Registration for '%s@%s' timed out, trying again (Attempt #%d)\n", r->username, r->hostname, r->regattempts); 05273 if (r->call) { 05274 /* Unlink us, destroy old call. Locking is not relevant here because all this happens 05275 in the single SIP manager thread. */ 05276 p = r->call; 05277 if (p->registry) 05278 ASTOBJ_UNREF(p->registry, sip_registry_destroy); 05279 r->call = NULL; 05280 ast_set_flag(p, SIP_NEEDDESTROY); 05281 /* Pretend to ACK anything just in case */ 05282 __sip_pretend_ack(p); 05283 } 05284 /* If we have a limit, stop registration and give up */ 05285 if (global_regattempts_max && (r->regattempts > global_regattempts_max)) { 05286 /* Ok, enough is enough. Don't try any more */ 05287 /* We could add an external notification here... 05288 steal it from app_voicemail :-) */ 05289 ast_log(LOG_NOTICE, " -- Giving up forever trying to register '%s@%s'\n", r->username, r->hostname); 05290 r->regstate=REG_STATE_FAILED; 05291 } else { 05292 r->regstate=REG_STATE_UNREGISTERED; 05293 r->timeout = -1; 05294 res=transmit_register(r, SIP_REGISTER, NULL, NULL); 05295 } 05296 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)); 05297 ASTOBJ_UNREF(r,sip_registry_destroy); 05298 return 0; 05299 }
|
|
sip_register: Parse register=> line in sip.conf and add to registry
Definition at line 3190 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, sip_registry::expire, sip_registry::hostname, LOG_ERROR, LOG_WARNING, malloc, sip_registry::ocseq, sip_registry::portno, sip_registry::refresh, regl, regobjs, sip_registry::secret, sip_registry_destroy(), strsep(), sip_registry::timeout, and sip_registry::username. Referenced by reload_config(). 03191 { 03192 struct sip_registry *reg; 03193 char copy[256]; 03194 char *username=NULL, *hostname=NULL, *secret=NULL, *authuser=NULL; 03195 char *porta=NULL; 03196 char *contact=NULL; 03197 char *stringp=NULL; 03198 03199 if (!value) 03200 return -1; 03201 ast_copy_string(copy, value, sizeof(copy)); 03202 stringp=copy; 03203 username = stringp; 03204 hostname = strrchr(stringp, '@'); 03205 if (hostname) { 03206 *hostname = '\0'; 03207 hostname++; 03208 } 03209 if (ast_strlen_zero(username) || ast_strlen_zero(hostname)) { 03210 ast_log(LOG_WARNING, "Format for registration is user[:secret[:authuser]]@host[:port][/contact] at line %d\n", lineno); 03211 return -1; 03212 } 03213 stringp=username; 03214 username = strsep(&stringp, ":"); 03215 if (username) { 03216 secret = strsep(&stringp, ":"); 03217 if (secret) 03218 authuser = strsep(&stringp, ":"); 03219 } 03220 stringp = hostname; 03221 hostname = strsep(&stringp, "/"); 03222 if (hostname) 03223 contact = strsep(&stringp, "/"); 03224 if (ast_strlen_zero(contact)) 03225 contact = "s"; 03226 stringp=hostname; 03227 hostname = strsep(&stringp, ":"); 03228 porta = strsep(&stringp, ":"); 03229 03230 if (porta && !atoi(porta)) { 03231 ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno); 03232 return -1; 03233 } 03234 reg = malloc(sizeof(struct sip_registry)); 03235 if (!reg) { 03236 ast_log(LOG_ERROR, "Out of memory. Can't allocate SIP registry entry\n"); 03237 return -1; 03238 } 03239 memset(reg, 0, sizeof(struct sip_registry)); 03240 regobjs++; 03241 ASTOBJ_INIT(reg); 03242 ast_copy_string(reg->contact, contact, sizeof(reg->contact)); 03243 if (username) 03244 ast_copy_string(reg->username, username, sizeof(reg->username)); 03245 if (hostname) 03246 ast_copy_string(reg->hostname, hostname, sizeof(reg->hostname)); 03247 if (authuser) 03248 ast_copy_string(reg->authuser, authuser, sizeof(reg->authuser)); 03249 if (secret) 03250 ast_copy_string(reg->secret, secret, sizeof(reg->secret)); 03251 reg->expire = -1; 03252 reg->timeout = -1; 03253 reg->refresh = default_expiry; 03254 reg->portno = porta ? atoi(porta) : 0; 03255 reg->callid_valid = 0; 03256 reg->ocseq = 101; 03257 ASTOBJ_CONTAINER_LINK(®l, reg); 03258 ASTOBJ_UNREF(reg,sip_registry_destroy); 03259 return 0; 03260 }
|
|
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, regobjs, sched, sip_destroy(), and sip_registry::timeout. Referenced by __sip_destroy(), handle_response_register(), 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 13032 of file chan_sip.c. References ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), restart_monitor(), and sip_reloading. Referenced by reload(). 13033 { 13034 13035 ast_mutex_lock(&sip_reload_lock); 13036 if (sip_reloading) { 13037 ast_verbose("Previous SIP reload not yet done\n"); 13038 } else 13039 sip_reloading = 1; 13040 ast_mutex_unlock(&sip_reload_lock); 13041 restart_monitor(); 13042 13043 return 0; 13044 }
|
|
sip_request: PBX interface function -build SIP pvt structure ---
Definition at line 11505 of file chan_sip.c. References __ourip, AST_FORMAT_MAX_AUDIO, 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, sip_pvt::lock, LOG_ERROR, LOG_NOTICE, LOG_WARNING, 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. 11506 { 11507 int oldformat; 11508 struct sip_pvt *p; 11509 struct ast_channel *tmpc = NULL; 11510 char *ext, *host; 11511 char tmp[256]; 11512 char *dest = data; 11513 11514 oldformat = format; 11515 format &= ((AST_FORMAT_MAX_AUDIO << 1) - 1); 11516 if (!format) { 11517 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)); 11518 return NULL; 11519 } 11520 p = sip_alloc(NULL, NULL, 0, SIP_INVITE); 11521 if (!p) { 11522 ast_log(LOG_WARNING, "Unable to build sip pvt data for '%s'\n", (char *)data); 11523 return NULL; 11524 } 11525 11526 p->options = calloc(1, sizeof(*p->options)); 11527 if (!p->options) { 11528 ast_log(LOG_ERROR, "Out of memory\n"); 11529 return NULL; 11530 } 11531 11532 ast_copy_string(tmp, dest, sizeof(tmp)); 11533 host = strchr(tmp, '@'); 11534 if (host) { 11535 *host = '\0'; 11536 host++; 11537 ext = tmp; 11538 } else { 11539 ext = strchr(tmp, '/'); 11540 if (ext) { 11541 *ext++ = '\0'; 11542 host = tmp; 11543 } 11544 else { 11545 host = tmp; 11546 ext = NULL; 11547 } 11548 } 11549 11550 if (create_addr(p, host)) { 11551 *cause = AST_CAUSE_UNREGISTERED; 11552 sip_destroy(p); 11553 return NULL; 11554 } 11555 if (ast_strlen_zero(p->peername) && ext) 11556 ast_copy_string(p->peername, ext, sizeof(p->peername)); 11557 /* Recalculate our side, and recalculate Call ID */ 11558 if (ast_sip_ouraddrfor(&p->sa.sin_addr,&p->ourip)) 11559 memcpy(&p->ourip, &__ourip, sizeof(p->ourip)); 11560 build_via(p, p->via, sizeof(p->via)); 11561 build_callid(p->callid, sizeof(p->callid), p->ourip, p->fromdomain); 11562 11563 /* We have an extension to call, don't use the full contact here */ 11564 /* This to enable dialling registered peers with extension dialling, 11565 like SIP/peername/extension 11566 SIP/peername will still use the full contact */ 11567 if (ext) { 11568 ast_copy_string(p->username, ext, sizeof(p->username)); 11569 p->fullcontact[0] = 0; 11570 } 11571 #if 0 11572 printf("Setting up to call extension '%s' at '%s'\n", ext ? ext : "<none>", host); 11573 #endif 11574 p->prefcodec = format; 11575 ast_mutex_lock(&p->lock); 11576 tmpc = sip_new(p, AST_STATE_DOWN, host); /* Place the call */ 11577 ast_mutex_unlock(&p->lock); 11578 if (!tmpc) 11579 sip_destroy(p); 11580 ast_update_use_count(); 11581 restart_monitor(); 11582 return tmpc; 11583 }
|
|
sip_reregister: Update registration with SIP Proxy---
Definition at line 5225 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, sip_registry_destroy(), and sip_registry::username. Referenced by handle_response_register(), and sip_send_all_registers(). 05226 { 05227 /* if we are here, we know that we need to reregister. */ 05228 struct sip_registry *r= ASTOBJ_REF((struct sip_registry *) data); 05229 05230 /* if we couldn't get a reference to the registry object, punt */ 05231 if (!r) 05232 return 0; 05233 05234 if (r->call && recordhistory) { 05235 char tmp[80]; 05236 snprintf(tmp, sizeof(tmp), "Account: %s@%s", r->username, r->hostname); 05237 append_history(r->call, "RegistryRenew", tmp); 05238 } 05239 /* Since registry's are only added/removed by the the monitor thread, this 05240 may be overkill to reference/dereference at all here */ 05241 if (sipdebug) 05242 ast_log(LOG_NOTICE, " -- Re-registration for %s@%s\n", r->username, r->hostname); 05243 05244 r->expire = -1; 05245 __sip_do_register(r); 05246 ASTOBJ_UNREF(r, sip_registry_destroy); 05247 return 0; 05248 }
|
|
sip_rtp_read: Read RTP from network ---
Definition at line 2935 of file chan_sip.c. References ast_dsp_process(), 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, ast_frame::subclass, sip_pvt::vad, sip_pvt::vrtp, and ast_channel::writeformat. Referenced by sip_read(). 02936 { 02937 /* Retrieve audio/etc from channel. Assumes p->lock is already held. */ 02938 struct ast_frame *f; 02939 static struct ast_frame null_frame = { AST_FRAME_NULL, }; 02940 02941 if (!p->rtp) { 02942 /* We have no RTP allocated for this channel */ 02943 return &null_frame; 02944 } 02945 02946 switch(ast->fdno) { 02947 case 0: 02948 f = ast_rtp_read(p->rtp); /* RTP Audio */ 02949 break; 02950 case 1: 02951 f = ast_rtcp_read(p->rtp); /* RTCP Control Channel */ 02952 break; 02953 case 2: 02954 f = ast_rtp_read(p->vrtp); /* RTP Video */ 02955 break; 02956 case 3: 02957 f = ast_rtcp_read(p->vrtp); /* RTCP Control Channel for video */ 02958 break; 02959 default: 02960 f = &null_frame; 02961 } 02962 /* Don't forward RFC2833 if we're not supposed to */ 02963 if (f && (f->frametype == AST_FRAME_DTMF) && (ast_test_flag(p, SIP_DTMF) != SIP_DTMF_RFC2833)) 02964 return &null_frame; 02965 if (p->owner) { 02966 /* We already hold the channel lock */ 02967 if (f->frametype == AST_FRAME_VOICE) { 02968 if (f->subclass != p->owner->nativeformats) { 02969 ast_log(LOG_DEBUG, "Oooh, format changed to %d\n", f->subclass); 02970 p->owner->nativeformats = f->subclass; 02971 ast_set_read_format(p->owner, p->owner->readformat); 02972 ast_set_write_format(p->owner, p->owner->writeformat); 02973 } 02974 if ((ast_test_flag(p, SIP_DTMF) == SIP_DTMF_INBAND) && p->vad) { 02975 f = ast_dsp_process(p->owner, p->vad, f); 02976 if (f && (f->frametype == AST_FRAME_DTMF)) 02977 ast_log(LOG_DEBUG, "* Detected inband DTMF '%c'\n", f->subclass); 02978 } 02979 } 02980 } 02981 return f; 02982 }
|
|
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 12977 of file chan_sip.c. References ast_sched_add(), ast_sched_del(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_UNLOCK, ASTOBJ_WRLOCK, default_expiry, regl, sched, and sip_reregister(). Referenced by load_module(). 12978 { 12979 int ms; 12980 int regspacing; 12981 if (!regobjs) 12982 return; 12983 regspacing = default_expiry * 1000/regobjs; 12984 if (regspacing > 100) 12985 regspacing = 100; 12986 ms = regspacing; 12987 ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { 12988 ASTOBJ_WRLOCK(iterator); 12989 if (iterator->expire > -1) 12990 ast_sched_del(sched, iterator->expire); 12991 ms += regspacing; 12992 iterator->expire = ast_sched_add(sched, ms, sip_reregister, iterator); 12993 ASTOBJ_UNLOCK(iterator); 12994 } while (0) 12995 ); 12996 }
|
|
sip_send_mwi_to_peer: Send message waiting indication ---
Definition at line 11155 of file chan_sip.c. References __ourip, ast_app_messagecount(), ast_log(), ast_set_flag, ast_sip_ouraddrfor(), build_callid(), build_via(), sip_pvt::callid, create_addr_from_peer(), sip_pvt::fromdomain, sip_peer::lastmsgcheck, sip_peer::lastmsgssent, LOG_WARNING, sip_peer::mailbox, sip_pvt::ourip, sip_pvt::sa, sip_alloc(), sip_destroy(), SIP_NOTIFY, SIP_OUTGOING, sip_scheddestroy(), transmit_notify_with_mwi(), sip_pvt::via, and sip_peer::vmexten. Referenced by do_monitor(). 11156 { 11157 /* Called with peerl lock, but releases it */ 11158 struct sip_pvt *p; 11159 int newmsgs, oldmsgs; 11160 11161 /* Check for messages */ 11162 ast_app_messagecount(peer->mailbox, &newmsgs, &oldmsgs); 11163 11164 time(&peer->lastmsgcheck); 11165 11166 /* Return now if it's the same thing we told them last time */ 11167 if (((newmsgs << 8) | (oldmsgs)) == peer->lastmsgssent) { 11168 return 0; 11169 } 11170 11171 p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY); 11172 if (!p) { 11173 ast_log(LOG_WARNING, "Unable to build sip pvt data for MWI\n"); 11174 return -1; 11175 } 11176 peer->lastmsgssent = ((newmsgs << 8) | (oldmsgs)); 11177 if (create_addr_from_peer(p, peer)) { 11178 /* Maybe they're not registered, etc. */ 11179 sip_destroy(p); 11180 return 0; 11181 } 11182 /* Recalculate our side, and recalculate Call ID */ 11183 if (ast_sip_ouraddrfor(&p->sa.sin_addr,&p->ourip)) 11184 memcpy(&p->ourip, &__ourip, sizeof(p->ourip)); 11185 build_via(p, p->via, sizeof(p->via)); 11186 build_callid(p->callid, sizeof(p->callid), p->ourip, p->fromdomain); 11187 /* Send MWI */ 11188 ast_set_flag(p, SIP_OUTGOING); 11189 transmit_notify_with_mwi(p, newmsgs, oldmsgs, peer->vmexten); 11190 sip_scheddestroy(p, 15000); 11191 return 0; 11192 }
|
|
sip_senddigit: Send DTMF character on SIP channel
Definition at line 2592 of file chan_sip.c. References ast_mutex_lock(), ast_mutex_unlock(), ast_rtp_senddigit(), ast_test_flag, sip_pvt::lock, sip_pvt::rtp, SIP_DTMF, SIP_DTMF_INBAND, SIP_DTMF_INFO, SIP_DTMF_RFC2833, ast_channel::tech_pvt, and transmit_info_with_digit(). 02593 { 02594 struct sip_pvt *p = ast->tech_pvt; 02595 int res = 0; 02596 ast_mutex_lock(&p->lock); 02597 switch (ast_test_flag(p, SIP_DTMF)) { 02598 case SIP_DTMF_INFO: 02599 transmit_info_with_digit(p, digit); 02600 break; 02601 case SIP_DTMF_RFC2833: 02602 if (p->rtp) 02603 ast_rtp_senddigit(p->rtp, digit); 02604 break; 02605 case SIP_DTMF_INBAND: 02606 res = -1; 02607 break; 02608 } 02609 ast_mutex_unlock(&p->lock); 02610 return res; 02611 }
|
|
sip_sendtext: Send SIP MESSAGE text within a call ---
Definition at line 1574 of file chan_sip.c. References ast_strlen_zero(), ast_verbose(), ast_channel::name, sip_debug_test_pvt(), ast_channel::tech_pvt, text, 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 12689 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_GOTREFER, SIP_NEEDREINVITE, SIP_PENDINGBYE, ast_channel::tech_pvt, transmit_reinvite_with_sdp(), and sip_pvt::vredirip. 12690 { 12691 struct sip_pvt *p; 12692 12693 p = chan->tech_pvt; 12694 if (!p) 12695 return -1; 12696 ast_mutex_lock(&p->lock); 12697 if (rtp) 12698 ast_rtp_get_peer(rtp, &p->redirip); 12699 else 12700 memset(&p->redirip, 0, sizeof(p->redirip)); 12701 if (vrtp) 12702 ast_rtp_get_peer(vrtp, &p->vredirip); 12703 else 12704 memset(&p->vredirip, 0, sizeof(p->vredirip)); 12705 p->redircodecs = codecs; 12706 if (!ast_test_flag(p, SIP_GOTREFER)) { 12707 if (!p->pendinginvite) { 12708 if (option_debug > 2) { 12709 char iabuf[INET_ADDRSTRLEN]; 12710 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)); 12711 } 12712 transmit_reinvite_with_sdp(p); 12713 } else if (!ast_test_flag(p, SIP_PENDINGBYE)) { 12714 if (option_debug > 2) { 12715 char iabuf[INET_ADDRSTRLEN]; 12716 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)); 12717 } 12718 ast_set_flag(p, SIP_NEEDREINVITE); 12719 } 12720 } 12721 /* Reset lastrtprx timer */ 12722 time(&p->lastrtprx); 12723 time(&p->lastrtptx); 12724 ast_mutex_unlock(&p->lock); 12725 return 0; 12726 }
|
|
sip_show_channel: Show details of one call ---
Definition at line 8446 of file chan_sip.c. References ast_cli(), ast_getformatname(), ast_inet_ntoa(), ast_mutex_lock(), ast_mutex_unlock(), ast_strlen_zero(), ast_test_flag, sip_pvt::callid, sip_pvt::capability, sip_pvt::cid_num, dtmfmode2str(), sip_route::hop, cfsip_options::id, sip_pvt::jointcapability, sip_pvt::lastmsg, nat2str(), ast_channel::nativeformats, sip_pvt::next, sip_pvt::noncodeccapability, sip_pvt::ourip, sip_pvt::owner, sip_pvt::peercapability, sip_pvt::peername, sip_pvt::recv, sip_pvt::redirip, sip_pvt::route, sip_pvt::sa, SIP_DTMF, SIP_NAT, SIP_NEEDDESTROY, sip_options, SIP_OUTGOING, SIP_PROMISCREDIR, sip_pvt::sipoptions, subscription_type2str(), sip_pvt::tag, text, sip_pvt::theirtag, sip_pvt::uri, sip_pvt::useragent, and sip_pvt::username. 08447 { 08448 struct sip_pvt *cur; 08449 char iabuf[INET_ADDRSTRLEN]; 08450 size_t len; 08451 int found = 0; 08452 08453 if (argc != 4) 08454 return RESULT_SHOWUSAGE; 08455 len = strlen(argv[3]); 08456 ast_mutex_lock(&iflock); 08457 cur = iflist; 08458 while(cur) { 08459 if (!strncasecmp(cur->callid, argv[3],len)) { 08460 ast_cli(fd,"\n"); 08461 if (cur->subscribed != NONE) 08462 ast_cli(fd, " * Subscription (type: %s)\n", subscription_type2str(cur->subscribed)); 08463 else 08464 ast_cli(fd, " * SIP Call\n"); 08465 ast_cli(fd, " Direction: %s\n", ast_test_flag(cur, SIP_OUTGOING)?"Outgoing":"Incoming"); 08466 ast_cli(fd, " Call-ID: %s\n", cur->callid); 08467 ast_cli(fd, " Our Codec Capability: %d\n", cur->capability); 08468 ast_cli(fd, " Non-Codec Capability: %d\n", cur->noncodeccapability); 08469 ast_cli(fd, " Their Codec Capability: %d\n", cur->peercapability); 08470 ast_cli(fd, " Joint Codec Capability: %d\n", cur->jointcapability); 08471 ast_cli(fd, " Format %s\n", ast_getformatname(cur->owner ? cur->owner->nativeformats : 0) ); 08472 ast_cli(fd, " Theoretical Address: %s:%d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), cur->sa.sin_addr), ntohs(cur->sa.sin_port)); 08473 ast_cli(fd, " Received Address: %s:%d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), cur->recv.sin_addr), ntohs(cur->recv.sin_port)); 08474 ast_cli(fd, " NAT Support: %s\n", nat2str(ast_test_flag(cur, SIP_NAT))); 08475 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)" ); 08476 ast_cli(fd, " Our Tag: %s\n", cur->tag); 08477 ast_cli(fd, " Their Tag: %s\n", cur->theirtag); 08478 ast_cli(fd, " SIP User agent: %s\n", cur->useragent); 08479 if (!ast_strlen_zero(cur->username)) 08480 ast_cli(fd, " Username: %s\n", cur->username); 08481 if (!ast_strlen_zero(cur->peername)) 08482 ast_cli(fd, " Peername: %s\n", cur->peername); 08483 if (!ast_strlen_zero(cur->uri)) 08484 ast_cli(fd, " Original uri: %s\n", cur->uri); 08485 if (!ast_strlen_zero(cur->cid_num)) 08486 ast_cli(fd, " Caller-ID: %s\n", cur->cid_num); 08487 ast_cli(fd, " Need Destroy: %d\n", ast_test_flag(cur, SIP_NEEDDESTROY)); 08488 ast_cli(fd, " Last Message: %s\n", cur->lastmsg); 08489 ast_cli(fd, " Promiscuous Redir: %s\n", ast_test_flag(cur, SIP_PROMISCREDIR) ? "Yes" : "No"); 08490 ast_cli(fd, " Route: %s\n", cur->route ? cur->route->hop : "N/A"); 08491 ast_cli(fd, " DTMF Mode: %s\n", dtmfmode2str(ast_test_flag(cur, SIP_DTMF))); 08492 ast_cli(fd, " SIP Options: "); 08493 if (cur->sipoptions) { 08494 int x; 08495 for (x=0 ; (x < (sizeof(sip_options) / sizeof(sip_options[0]))); x++) { 08496 if (cur->sipoptions & sip_options[x].id) 08497 ast_cli(fd, "%s ", sip_options[x].text); 08498 } 08499 } else 08500 ast_cli(fd, "(none)\n"); 08501 ast_cli(fd, "\n\n"); 08502 found++; 08503 } 08504 cur = cur->next; 08505 } 08506 ast_mutex_unlock(&iflock); 08507 if (!found) 08508 ast_cli(fd, "No such SIP Call ID starting with '%s'\n", argv[3]); 08509 return RESULT_SUCCESS; 08510 }
|
|
sip_show_channels: Show active SIP channels ---
Definition at line 8247 of file chan_sip.c. References __sip_show_channels(). 08248 { 08249 return __sip_show_channels(fd, argc, argv, 0); 08250 }
|
|
Definition at line 7799 of file chan_sip.c. References ast_cli(), AST_LIST_EMPTY, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, domain::context, domain::domain, domain_mode_to_text(), and FORMAT. 07800 { 07801 struct domain *d; 07802 07803 if (AST_LIST_EMPTY(&domain_list)) { 07804 ast_cli(fd, "SIP Domain support not enabled.\n\n"); 07805 return RESULT_SUCCESS; 07806 } else { 07807 ast_cli(fd, FORMAT, "Our local SIP domains:", "Context", "Set by"); 07808 AST_LIST_LOCK(&domain_list); 07809 AST_LIST_TRAVERSE(&domain_list, d, list) 07810 ast_cli(fd, FORMAT, d->domain, ast_strlen_zero(d->context) ? "(default)": d->context, 07811 domain_mode_to_text(d->mode)); 07812 AST_LIST_UNLOCK(&domain_list); 07813 ast_cli(fd, "\n"); 07814 return RESULT_SUCCESS; 07815 } 07816 }
|
|
sip_show_history: Show history details of one call ---
Definition at line 8513 of file chan_sip.c. References ast_cli(), ast_mutex_lock(), ast_mutex_unlock(), sip_pvt::callid, sip_history::event, sip_pvt::history, sip_pvt::next, and sip_history::next. 08514 { 08515 struct sip_pvt *cur; 08516 struct sip_history *hist; 08517 size_t len; 08518 int x; 08519 int found = 0; 08520 08521 if (argc != 4) 08522 return RESULT_SHOWUSAGE; 08523 if (!recordhistory) 08524 ast_cli(fd, "\n***Note: History recording is currently DISABLED. Use 'sip history' to ENABLE.\n"); 08525 len = strlen(argv[3]); 08526 ast_mutex_lock(&iflock); 08527 cur = iflist; 08528 while(cur) { 08529 if (!strncasecmp(cur->callid, argv[3], len)) { 08530 ast_cli(fd,"\n"); 08531 if (cur->subscribed != NONE) 08532 ast_cli(fd, " * Subscription\n"); 08533 else 08534 ast_cli(fd, " * SIP Call\n"); 08535 x = 0; 08536 hist = cur->history; 08537 while(hist) { 08538 x++; 08539 ast_cli(fd, "%d. %s\n", x, hist->event); 08540 hist = hist->next; 08541 } 08542 if (!x) 08543 ast_cli(fd, "Call '%s' has no history\n", cur->callid); 08544 found++; 08545 } 08546 cur = cur->next; 08547 } 08548 ast_mutex_unlock(&iflock); 08549 if (!found) 08550 ast_cli(fd, "No such SIP Call ID starting with '%s'\n", argv[3]); 08551 return RESULT_SUCCESS; 08552 }
|
|
sip_show_inuse: CLI Command to show calls within limits set by call_limit ---
Definition at line 7266 of file chan_sip.c. References ast_cli(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, FORMAT, FORMAT2, peerl, and userl. 07266 { 07267 #define FORMAT "%-25.25s %-15.15s %-15.15s \n" 07268 #define FORMAT2 "%-25.25s %-15.15s %-15.15s \n" 07269 char ilimits[40]; 07270 char iused[40]; 07271 int showall = 0; 07272 07273 if (argc < 3) 07274 return RESULT_SHOWUSAGE; 07275 07276 if (argc == 4 && !strcmp(argv[3],"all")) 07277 showall = 1; 07278 07279 ast_cli(fd, FORMAT, "* User name", "In use", "Limit"); 07280 ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do { 07281 ASTOBJ_RDLOCK(iterator); 07282 if (iterator->call_limit) 07283 snprintf(ilimits, sizeof(ilimits), "%d", iterator->call_limit); 07284 else 07285 ast_copy_string(ilimits, "N/A", sizeof(ilimits)); 07286 snprintf(iused, sizeof(iused), "%d", iterator->inUse); 07287 if (showall || iterator->call_limit) 07288 ast_cli(fd, FORMAT2, iterator->name, iused, ilimits); 07289 ASTOBJ_UNLOCK(iterator); 07290 } while (0) ); 07291 07292 ast_cli(fd, FORMAT, "* Peer name", "In use", "Limit"); 07293 07294 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 07295 ASTOBJ_RDLOCK(iterator); 07296 if (iterator->call_limit) 07297 snprintf(ilimits, sizeof(ilimits), "%d", iterator->call_limit); 07298 else 07299 ast_copy_string(ilimits, "N/A", sizeof(ilimits)); 07300 snprintf(iused, sizeof(iused), "%d", iterator->inUse); 07301 if (showall || iterator->call_limit) 07302 ast_cli(fd, FORMAT2, iterator->name, iused, ilimits); 07303 ASTOBJ_UNLOCK(iterator); 07304 } while (0) ); 07305 07306 return RESULT_SUCCESS; 07307 #undef FORMAT 07308 #undef FORMAT2 07309 }
|
|
sip_show_objects: List all allocated SIP Objects ---
Definition at line 7572 of file chan_sip.c. References apeerobjs, ast_cli(), ASTOBJ_CONTAINER_DUMP, peerl, regl, regobjs, rpeerobjs, ruserobjs, speerobjs, suserobjs, and userl. 07573 { 07574 char tmp[256]; 07575 if (argc != 3) 07576 return RESULT_SHOWUSAGE; 07577 ast_cli(fd, "-= User objects: %d static, %d realtime =-\n\n", suserobjs, ruserobjs); 07578 ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), &userl); 07579 ast_cli(fd, "-= Peer objects: %d static, %d realtime, %d autocreate =-\n\n", speerobjs, rpeerobjs, apeerobjs); 07580 ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), &peerl); 07581 ast_cli(fd, "-= Registry objects: %d =-\n\n", regobjs); 07582 ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), ®l); 07583 return RESULT_SUCCESS; 07584 }
|
|
sip_show_peer: Show one peer in detail ---
Definition at line 7856 of file chan_sip.c. References _sip_show_peer(). 07857 { 07858 return _sip_show_peer(0, fd, NULL, NULL, argc, argv); 07859 }
|
|
sip_show_peers: CLI Show Peers command
Definition at line 7433 of file chan_sip.c. References _sip_show_peers(). 07434 { 07435 return _sip_show_peers(fd, NULL, NULL, NULL, argc, argv); 07436 }
|
|
sip_show_registry: Show SIP Registry (registrations with other SIP proxies ---
Definition at line 8112 of file chan_sip.c. References ast_cli(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, DEFAULT_SIP_PORT, FORMAT, FORMAT2, regl, and regstate2str(). 08113 { 08114 #define FORMAT2 "%-30.30s %-12.12s %8.8s %-20.20s\n" 08115 #define FORMAT "%-30.30s %-12.12s %8d %-20.20s\n" 08116 char host[80]; 08117 08118 if (argc != 3) 08119 return RESULT_SHOWUSAGE; 08120 ast_cli(fd, FORMAT2, "Host", "Username", "Refresh", "State"); 08121 ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { 08122 ASTOBJ_RDLOCK(iterator); 08123 snprintf(host, sizeof(host), "%s:%d", iterator->hostname, iterator->portno ? iterator->portno : DEFAULT_SIP_PORT); 08124 ast_cli(fd, FORMAT, host, iterator->username, iterator->refresh, regstate2str(iterator->regstate)); 08125 ASTOBJ_UNLOCK(iterator); 08126 } while(0)); 08127 return RESULT_SUCCESS; 08128 #undef FORMAT 08129 #undef FORMAT2 08130 }
|
|
sip_show_settings: List global settings for the SIP channel ---
Definition at line 8133 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, 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. 08134 { 08135 char tmp[BUFSIZ]; 08136 int realtimepeers = 0; 08137 int realtimeusers = 0; 08138 08139 realtimepeers = ast_check_realtime("sippeers"); 08140 realtimeusers = ast_check_realtime("sipusers"); 08141 08142 if (argc != 3) 08143 return RESULT_SHOWUSAGE; 08144 ast_cli(fd, "\n\nGlobal Settings:\n"); 08145 ast_cli(fd, "----------------\n"); 08146 ast_cli(fd, " SIP Port: %d\n", ntohs(bindaddr.sin_port)); 08147 ast_cli(fd, " Bindaddress: %s\n", ast_inet_ntoa(tmp, sizeof(tmp), bindaddr.sin_addr)); 08148 ast_cli(fd, " Videosupport: %s\n", videosupport ? "Yes" : "No"); 08149 ast_cli(fd, " AutoCreatePeer: %s\n", autocreatepeer ? "Yes" : "No"); 08150 ast_cli(fd, " Allow unknown access: %s\n", global_allowguest ? "Yes" : "No"); 08151 ast_cli(fd, " Promsic. redir: %s\n", ast_test_flag(&global_flags, SIP_PROMISCREDIR) ? "Yes" : "No"); 08152 ast_cli(fd, " SIP domain support: %s\n", AST_LIST_EMPTY(&domain_list) ? "No" : "Yes"); 08153 ast_cli(fd, " Call to non-local dom.: %s\n", allow_external_domains ? "Yes" : "No"); 08154 ast_cli(fd, " URI user is phone no: %s\n", ast_test_flag(&global_flags, SIP_USEREQPHONE) ? "Yes" : "No"); 08155 ast_cli(fd, " Our auth realm %s\n", global_realm); 08156 ast_cli(fd, " Realm. auth: %s\n", authl ? "Yes": "No"); 08157 ast_cli(fd, " User Agent: %s\n", default_useragent); 08158 ast_cli(fd, " MWI checking interval: %d secs\n", global_mwitime); 08159 ast_cli(fd, " Reg. context: %s\n", ast_strlen_zero(regcontext) ? "(not set)" : regcontext); 08160 ast_cli(fd, " Caller ID: %s\n", default_callerid); 08161 ast_cli(fd, " From: Domain: %s\n", default_fromdomain); 08162 ast_cli(fd, " Record SIP history: %s\n", recordhistory ? "On" : "Off"); 08163 ast_cli(fd, " Call Events: %s\n", callevents ? "On" : "Off"); 08164 ast_cli(fd, " IP ToS: 0x%x\n", tos); 08165 #ifdef OSP_SUPPORT 08166 ast_cli(fd, " OSP Support: Yes\n"); 08167 #else 08168 ast_cli(fd, " OSP Support: No\n"); 08169 #endif 08170 if (!realtimepeers && !realtimeusers) 08171 ast_cli(fd, " SIP realtime: Disabled\n" ); 08172 else 08173 ast_cli(fd, " SIP realtime: Enabled\n" ); 08174 08175 ast_cli(fd, "\nGlobal Signalling Settings:\n"); 08176 ast_cli(fd, "---------------------------\n"); 08177 ast_cli(fd, " Codecs: "); 08178 print_codec_to_cli(fd, &prefs); 08179 ast_cli(fd, "\n"); 08180 ast_cli(fd, " Relax DTMF: %s\n", relaxdtmf ? "Yes" : "No"); 08181 ast_cli(fd, " Compact SIP headers: %s\n", compactheaders ? "Yes" : "No"); 08182 ast_cli(fd, " RTP Timeout: %d %s\n", global_rtptimeout, global_rtptimeout ? "" : "(Disabled)" ); 08183 ast_cli(fd, " RTP Hold Timeout: %d %s\n", global_rtpholdtimeout, global_rtpholdtimeout ? "" : "(Disabled)"); 08184 ast_cli(fd, " MWI NOTIFY mime type: %s\n", default_notifymime); 08185 ast_cli(fd, " DNS SRV lookup: %s\n", srvlookup ? "Yes" : "No"); 08186 ast_cli(fd, " Pedantic SIP support: %s\n", pedanticsipchecking ? "Yes" : "No"); 08187 ast_cli(fd, " Reg. max duration: %d secs\n", max_expiry); 08188 ast_cli(fd, " Reg. default duration: %d secs\n", default_expiry); 08189 ast_cli(fd, " Outbound reg. timeout: %d secs\n", global_reg_timeout); 08190 ast_cli(fd, " Outbound reg. attempts: %d\n", global_regattempts_max); 08191 ast_cli(fd, " Notify ringing state: %s\n", global_notifyringing ? "Yes" : "No"); 08192 ast_cli(fd, "\nDefault Settings:\n"); 08193 ast_cli(fd, "-----------------\n"); 08194 ast_cli(fd, " Context: %s\n", default_context); 08195 ast_cli(fd, " Nat: %s\n", nat2str(ast_test_flag(&global_flags, SIP_NAT))); 08196 ast_cli(fd, " DTMF: %s\n", dtmfmode2str(ast_test_flag(&global_flags, SIP_DTMF))); 08197 ast_cli(fd, " Qualify: %d\n", default_qualify); 08198 ast_cli(fd, " Use ClientCode: %s\n", ast_test_flag(&global_flags, SIP_USECLIENTCODE) ? "Yes" : "No"); 08199 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" ); 08200 ast_cli(fd, " Language: %s\n", ast_strlen_zero(default_language) ? "(Defaults to English)" : default_language); 08201 ast_cli(fd, " Musicclass: %s\n", global_musicclass); 08202 ast_cli(fd, " Voice Mail Extension: %s\n", global_vmexten); 08203 08204 08205 if (realtimepeers || realtimeusers) { 08206 ast_cli(fd, "\nRealtime SIP Settings:\n"); 08207 ast_cli(fd, "----------------------\n"); 08208 ast_cli(fd, " Realtime Peers: %s\n", realtimepeers ? "Yes" : "No"); 08209 ast_cli(fd, " Realtime Users: %s\n", realtimeusers ? "Yes" : "No"); 08210 ast_cli(fd, " Cache Friends: %s\n", ast_test_flag(&global_flags_page2, SIP_PAGE2_RTCACHEFRIENDS) ? "Yes" : "No"); 08211 ast_cli(fd, " Update: %s\n", ast_test_flag(&global_flags_page2, SIP_PAGE2_RTUPDATE) ? "Yes" : "No"); 08212 ast_cli(fd, " Ignore Reg. Expire: %s\n", ast_test_flag(&global_flags_page2, SIP_PAGE2_IGNOREREGEXPIRE) ? "Yes" : "No"); 08213 ast_cli(fd, " Auto Clear: %d\n", global_rtautoclear); 08214 } 08215 ast_cli(fd, "\n----\n"); 08216 return RESULT_SUCCESS; 08217 }
|
|
sip_show_subscriptions: Show active SIP subscriptions ---
Definition at line 8253 of file chan_sip.c. References __sip_show_channels(). 08254 { 08255 return __sip_show_channels(fd, argc, argv, 1); 08256 }
|
|
sip_show_user: Show one user in detail ---
Definition at line 8048 of file chan_sip.c. References sip_user::accountcode, sip_user::amaflags, ast_callerid_merge(), ast_cdr_flags2str(), ast_cli(), ast_codec_pref_index(), ast_describe_caller_presentation(), ast_getformatname(), ast_strlen_zero(), ASTOBJ_UNREF, sip_user::call_limit, sip_user::callgroup, sip_user::callingpres, sip_user::chanvars, sip_user::cid_name, sip_user::cid_num, sip_user::context, find_user(), sip_user::ha, sip_user::language, sip_user::md5secret, ast_variable::name, ast_variable::next, sip_user::pickupgroup, sip_user::prefs, print_group(), sip_user::secret, sip_destroy_user(), and ast_variable::value. 08049 { 08050 char cbuf[256]; 08051 struct sip_user *user; 08052 struct ast_codec_pref *pref; 08053 struct ast_variable *v; 08054 int x = 0, codec = 0, load_realtime = 0; 08055 08056 if (argc < 4) 08057 return RESULT_SHOWUSAGE; 08058 08059 /* Load from realtime storage? */ 08060 load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? 1 : 0; 08061 08062 user = find_user(argv[3], load_realtime); 08063 if (user) { 08064 ast_cli(fd,"\n\n"); 08065 ast_cli(fd, " * Name : %s\n", user->name); 08066 ast_cli(fd, " Secret : %s\n", ast_strlen_zero(user->secret)?"<Not set>":"<Set>"); 08067 ast_cli(fd, " MD5Secret : %s\n", ast_strlen_zero(user->md5secret)?"<Not set>":"<Set>"); 08068 ast_cli(fd, " Context : %s\n", user->context); 08069 ast_cli(fd, " Language : %s\n", user->language); 08070 if (!ast_strlen_zero(user->accountcode)) 08071 ast_cli(fd, " Accountcode : %s\n", user->accountcode); 08072 ast_cli(fd, " AMA flags : %s\n", ast_cdr_flags2str(user->amaflags)); 08073 ast_cli(fd, " CallingPres : %s\n", ast_describe_caller_presentation(user->callingpres)); 08074 ast_cli(fd, " Call limit : %d\n", user->call_limit); 08075 ast_cli(fd, " Callgroup : "); 08076 print_group(fd, user->callgroup, 0); 08077 ast_cli(fd, " Pickupgroup : "); 08078 print_group(fd, user->pickupgroup, 0); 08079 ast_cli(fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), user->cid_name, user->cid_num, "<unspecified>")); 08080 ast_cli(fd, " ACL : %s\n", (user->ha?"Yes":"No")); 08081 ast_cli(fd, " Codec Order : ("); 08082 pref = &user->prefs; 08083 for(x = 0; x < 32 ; x++) { 08084 codec = ast_codec_pref_index(pref,x); 08085 if (!codec) 08086 break; 08087 ast_cli(fd, "%s", ast_getformatname(codec)); 08088 if (x < 31 && ast_codec_pref_index(pref,x+1)) 08089 ast_cli(fd, "|"); 08090 } 08091 08092 if (!x) 08093 ast_cli(fd, "none"); 08094 ast_cli(fd, ")\n"); 08095 08096 if (user->chanvars) { 08097 ast_cli(fd, " Variables :\n"); 08098 for (v = user->chanvars ; v ; v = v->next) 08099 ast_cli(fd, " %s = %s\n", v->name, v->value); 08100 } 08101 ast_cli(fd,"\n"); 08102 ASTOBJ_UNREF(user,sip_destroy_user); 08103 } else { 08104 ast_cli(fd,"User %s not found.\n", argv[3]); 08105 ast_cli(fd,"\n"); 08106 } 08107 08108 return RESULT_SUCCESS; 08109 }
|
|
sip_show_users: CLI Command 'SIP Show Users' ---
Definition at line 7354 of file chan_sip.c. References ast_cli(), ast_test_flag, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, FORMAT, nat2str(), SIP_NAT, and userl. 07355 { 07356 regex_t regexbuf; 07357 int havepattern = 0; 07358 07359 #define FORMAT "%-25.25s %-15.15s %-15.15s %-15.15s %-5.5s%-10.10s\n" 07360 07361 switch (argc) { 07362 case 5: 07363 if (!strcasecmp(argv[3], "like")) { 07364 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 07365 return RESULT_SHOWUSAGE; 07366 havepattern = 1; 07367 } else 07368 return RESULT_SHOWUSAGE; 07369 case 3: 07370 break; 07371 default: 07372 return RESULT_SHOWUSAGE; 07373 } 07374 07375 ast_cli(fd, FORMAT, "Username", "Secret", "Accountcode", "Def.Context", "ACL", "NAT"); 07376 ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do { 07377 ASTOBJ_RDLOCK(iterator); 07378 07379 if (havepattern && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 07380 ASTOBJ_UNLOCK(iterator); 07381 continue; 07382 } 07383 07384 ast_cli(fd, FORMAT, iterator->name, 07385 iterator->secret, 07386 iterator->accountcode, 07387 iterator->context, 07388 iterator->ha ? "Yes" : "No", 07389 nat2str(ast_test_flag(iterator, SIP_NAT))); 07390 ASTOBJ_UNLOCK(iterator); 07391 } while (0) 07392 ); 07393 07394 if (havepattern) 07395 regfree(®exbuf); 07396 07397 return RESULT_SUCCESS; 07398 #undef FORMAT 07399 }
|
|
sip_sipredirect: Transfer call before connect with a 302 redirect ---
Definition at line 12886 of file chan_sip.c. References ast_log(), ast_set_flag, ast_strdupa, ast_strlen_zero(), get_header(), sip_pvt::initreq, LOG_ERROR, sip_pvt::our_contact, SIP_ALREADYGONE, strsep(), and transmit_response_reliable(). Referenced by sip_transfer(). 12887 { 12888 char *cdest; 12889 char *extension, *host, *port; 12890 char tmp[80]; 12891 12892 cdest = ast_strdupa(dest); 12893 if (!cdest) { 12894 ast_log(LOG_ERROR, "Problem allocating the memory\n"); 12895 return 0; 12896 } 12897 extension = strsep(&cdest, "@"); 12898 host = strsep(&cdest, ":"); 12899 port = strsep(&cdest, ":"); 12900 if (!extension) { 12901 ast_log(LOG_ERROR, "Missing mandatory argument: extension\n"); 12902 return 0; 12903 } 12904 12905 /* we'll issue the redirect message here */ 12906 if (!host) { 12907 char *localtmp; 12908 ast_copy_string(tmp, get_header(&p->initreq, "To"), sizeof(tmp)); 12909 if (!strlen(tmp)) { 12910 ast_log(LOG_ERROR, "Cannot retrieve the 'To' header from the original SIP request!\n"); 12911 return 0; 12912 } 12913 if ((localtmp = strstr(tmp, "sip:")) && (localtmp = strchr(localtmp, '@'))) { 12914 char lhost[80], lport[80]; 12915 memset(lhost, 0, sizeof(lhost)); 12916 memset(lport, 0, sizeof(lport)); 12917 localtmp++; 12918 /* This is okey because lhost and lport are as big as tmp */ 12919 sscanf(localtmp, "%[^<>:; ]:%[^<>:; ]", lhost, lport); 12920 if (!strlen(lhost)) { 12921 ast_log(LOG_ERROR, "Can't find the host address\n"); 12922 return 0; 12923 } 12924 host = ast_strdupa(lhost); 12925 if (!host) { 12926 ast_log(LOG_ERROR, "Problem allocating the memory\n"); 12927 return 0; 12928 } 12929 if (!ast_strlen_zero(lport)) { 12930 port = ast_strdupa(lport); 12931 if (!port) { 12932 ast_log(LOG_ERROR, "Problem allocating the memory\n"); 12933 return 0; 12934 } 12935 } 12936 } 12937 } 12938 12939 snprintf(p->our_contact, sizeof(p->our_contact), "Transfer <sip:%s@%s%s%s>", extension, host, port ? ":" : "", port ? port : ""); 12940 transmit_response_reliable(p, "302 Moved Temporarily", &p->initreq, 1); 12941 12942 /* this is all that we want to send to that SIP device */ 12943 ast_set_flag(p, SIP_ALREADYGONE); 12944 12945 /* hangup here */ 12946 return -1; 12947 }
|
|
sip_transfer: Transfer SIP call
Definition at line 2616 of file chan_sip.c. References ast_channel::_state, ast_mutex_lock(), ast_mutex_unlock(), sip_pvt::lock, sip_sipredirect(), ast_channel::tech_pvt, and transmit_refer(). 02617 { 02618 struct sip_pvt *p = ast->tech_pvt; 02619 int res; 02620 02621 ast_mutex_lock(&p->lock); 02622 if (ast->_state == AST_STATE_RING) 02623 res = sip_sipredirect(p, dest); 02624 else 02625 res = transmit_refer(p, dest); 02626 ast_mutex_unlock(&p->lock); 02627 return res; 02628 }
|
|
sip_write: Send frame to media channel (rtp) ---
Definition at line 2523 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_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. 02524 { 02525 struct sip_pvt *p = ast->tech_pvt; 02526 int res = 0; 02527 switch (frame->frametype) { 02528 case AST_FRAME_VOICE: 02529 if (!(frame->subclass & ast->nativeformats)) { 02530 ast_log(LOG_WARNING, "Asked to transmit frame type %d, while native formats is %d (read/write = %d/%d)\n", 02531 frame->subclass, ast->nativeformats, ast->readformat, ast->writeformat); 02532 return 0; 02533 } 02534 if (p) { 02535 ast_mutex_lock(&p->lock); 02536 if (p->rtp) { 02537 /* If channel is not up, activate early media session */ 02538 if ((ast->_state != AST_STATE_UP) && !ast_test_flag(p, SIP_PROGRESS_SENT) && !ast_test_flag(p, SIP_OUTGOING)) { 02539 transmit_response_with_sdp(p, "183 Session Progress", &p->initreq, 0); 02540 ast_set_flag(p, SIP_PROGRESS_SENT); 02541 } 02542 time(&p->lastrtptx); 02543 res = ast_rtp_write(p->rtp, frame); 02544 } 02545 ast_mutex_unlock(&p->lock); 02546 } 02547 break; 02548 case AST_FRAME_VIDEO: 02549 if (p) { 02550 ast_mutex_lock(&p->lock); 02551 if (p->vrtp) { 02552 /* Activate video early media */ 02553 if ((ast->_state != AST_STATE_UP) && !ast_test_flag(p, SIP_PROGRESS_SENT) && !ast_test_flag(p, SIP_OUTGOING)) { 02554 transmit_response_with_sdp(p, "183 Session Progress", &p->initreq, 0); 02555 ast_set_flag(p, SIP_PROGRESS_SENT); 02556 } 02557 time(&p->lastrtptx); 02558 res = ast_rtp_write(p->vrtp, frame); 02559 } 02560 ast_mutex_unlock(&p->lock); 02561 } 02562 break; 02563 case AST_FRAME_IMAGE: 02564 return 0; 02565 break; 02566 default: 02567 ast_log(LOG_WARNING, "Can't send %d type frames with SIP write\n", frame->frametype); 02568 return 0; 02569 } 02570 02571 return res; 02572 }
|
|
sipsock_read: Read data from SIP socket ---
Definition at line 11065 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, sip_request::data, find_call(), find_sip_method(), get_header(), handle_request(), sip_request::len, sip_pvt::lock, ast_channel::lock, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, lws2sws(), sip_request::method, sip_pvt::owner, parse_request(), sip_pvt::recv, sip_debug_test_addr(), SIP_PKT_DEBUG, and sipsock. Referenced by do_monitor(). 11066 { 11067 struct sip_request req; 11068 struct sockaddr_in sin = { 0, }; 11069 struct sip_pvt *p; 11070 int res; 11071 socklen_t len; 11072 int nounlock; 11073 int recount = 0; 11074 char iabuf[INET_ADDRSTRLEN]; 11075 11076 len = sizeof(sin); 11077 memset(&req, 0, sizeof(req)); 11078 res = recvfrom(sipsock, req.data, sizeof(req.data) - 1, 0, (struct sockaddr *)&sin, &len); 11079 if (res < 0) { 11080 #if !defined(__FreeBSD__) 11081 if (errno == EAGAIN) 11082 ast_log(LOG_NOTICE, "SIP: Received packet with bad UDP checksum\n"); 11083 else 11084 #endif 11085 if (errno != ECONNREFUSED) 11086 ast_log(LOG_WARNING, "Recv error: %s\n", strerror(errno)); 11087 return 1; 11088 } 11089 if (res == sizeof(req.data)) { 11090 ast_log(LOG_DEBUG, "Received packet exceeds buffer. Data is possibly lost\n"); 11091 } 11092 req.data[res] = '\0'; 11093 req.len = res; 11094 if(sip_debug_test_addr(&sin)) 11095 ast_set_flag(&req, SIP_PKT_DEBUG); 11096 if (pedanticsipchecking) 11097 req.len = lws2sws(req.data, req.len); /* Fix multiline headers */ 11098 if (ast_test_flag(&req, SIP_PKT_DEBUG)) { 11099 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); 11100 } 11101 parse_request(&req); 11102 req.method = find_sip_method(req.rlPart1); 11103 if (ast_test_flag(&req, SIP_PKT_DEBUG)) { 11104 ast_verbose("--- (%d headers %d lines)", req.headers, req.lines); 11105 if (req.headers + req.lines == 0) 11106 ast_verbose(" Nat keepalive "); 11107 ast_verbose("---\n"); 11108 } 11109 11110 if (req.headers < 2) { 11111 /* Must have at least two headers */ 11112 return 1; 11113 } 11114 11115 11116 /* Process request, with netlock held */ 11117 retrylock: 11118 ast_mutex_lock(&netlock); 11119 p = find_call(&req, &sin, req.method); 11120 if (p) { 11121 /* Go ahead and lock the owner if it has one -- we may need it */ 11122 if (p->owner && ast_mutex_trylock(&p->owner->lock)) { 11123 ast_log(LOG_DEBUG, "Failed to grab lock, trying again...\n"); 11124 ast_mutex_unlock(&p->lock); 11125 ast_mutex_unlock(&netlock); 11126 /* Sleep infintismly short amount of time */ 11127 usleep(1); 11128 goto retrylock; 11129 } 11130 memcpy(&p->recv, &sin, sizeof(p->recv)); 11131 if (recordhistory) { 11132 char tmp[80]; 11133 /* This is a response, note what it was for */ 11134 snprintf(tmp, sizeof(tmp), "%s / %s", req.data, get_header(&req, "CSeq")); 11135 append_history(p, "Rx", tmp); 11136 } 11137 nounlock = 0; 11138 if (handle_request(p, &req, &sin, &recount, &nounlock) == -1) { 11139 /* Request failed */ 11140 ast_log(LOG_DEBUG, "SIP message could not be handled, bad request: %-70.70s\n", p->callid[0] ? p->callid : "<no callid>"); 11141 } 11142 11143 if (p->owner && !nounlock) 11144 ast_mutex_unlock(&p->owner->lock); 11145 ast_mutex_unlock(&p->lock); 11146 } 11147 ast_mutex_unlock(&netlock); 11148 if (recount) 11149 ast_update_use_count(); 11150 11151 return 1; 11152 }
|
|
subscription_type2str: Show subscription type in string format
Definition at line 8220 of file chan_sip.c. References subscription_types, and cfsubscription_types::text. Referenced by __sip_show_channels(), and sip_show_channel(). 08220 { 08221 int i; 08222 08223 for (i = 1; (i < (sizeof(subscription_types) / sizeof(subscription_types[0]))); i++) { 08224 if (subscription_types[i].type == subtype) { 08225 return subscription_types[i].text; 08226 } 08227 } 08228 return subscription_types[0].text; 08229 }
|
|
temp_peer: Create temporary peer (used in autocreatepeer mode) ---
Definition at line 11957 of file chan_sip.c. References sip_peer::addr, apeerobjs, ast_copy_flags, ast_set_flag, ASTOBJ_INIT, sip_peer::capability, default_context, default_language, DEFAULT_SIP_PORT, default_subscribecontext, sip_peer::expire, global_flags, global_musicclass, malloc, name, sip_peer::pokeexpire, sip_peer::prefs, reg_source_db(), sip_peer::rtpholdtimeout, sip_peer::rtpkeepalive, sip_peer::rtptimeout, SIP_DYNAMIC, SIP_FLAGS_TO_COPY, and SIP_SELFDESTRUCT. Referenced by register_verify(). 11958 { 11959 struct sip_peer *peer; 11960 11961 peer = malloc(sizeof(*peer)); 11962 if (!peer) 11963 return NULL; 11964 11965 memset(peer, 0, sizeof(*peer)); 11966 apeerobjs++; 11967 ASTOBJ_INIT(peer); 11968 11969 peer->expire = -1; 11970 peer->pokeexpire = -1; 11971 ast_copy_string(peer->name, name, sizeof(peer->name)); 11972 ast_copy_flags(peer, &global_flags, SIP_FLAGS_TO_COPY); 11973 strcpy(peer->context, default_context); 11974 strcpy(peer->subscribecontext, default_subscribecontext); 11975 strcpy(peer->language, default_language); 11976 strcpy(peer->musicclass, global_musicclass); 11977 peer->addr.sin_port = htons(DEFAULT_SIP_PORT); 11978 peer->addr.sin_family = AF_INET; 11979 peer->capability = global_capability; 11980 peer->rtptimeout = global_rtptimeout; 11981 peer->rtpholdtimeout = global_rtpholdtimeout; 11982 peer->rtpkeepalive = global_rtpkeepalive; 11983 ast_set_flag(peer, SIP_SELFDESTRUCT); 11984 ast_set_flag(peer, SIP_DYNAMIC); 11985 peer->prefs = prefs; 11986 reg_source_db(peer); 11987 11988 return peer; 11989 }
|
|
Thread-safe random number generator.
Definition at line 956 of file chan_sip.c. References ast_mutex_lock(), ast_mutex_unlock(), force_inline, and val. 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 5546 of file chan_sip.c. References add_digit(), sip_pvt::ocseq, reqprep(), send_request(), and SIP_INFO. Referenced by sip_senddigit(). 05547 { 05548 struct sip_request req; 05549 reqprep(&req, p, SIP_INFO, 0, 1); 05550 add_digit(&req, digit); 05551 return send_request(p, &req, 1, p->ocseq); 05552 }
|
|
transmit_info_with_vidupdate: Send SIP INFO with video update request ---
Definition at line 5555 of file chan_sip.c. References add_vidupdate(), sip_pvt::ocseq, reqprep(), send_request(), and SIP_INFO. Referenced by sip_indicate(). 05556 { 05557 struct sip_request req; 05558 reqprep(&req, p, SIP_INFO, 0, 1); 05559 add_vidupdate(&req); 05560 return send_request(p, &req, 1, p->ocseq); 05561 }
|
|
transmit_invite: Build REFER/INVITE/OPTIONS message and transmit it ---
Definition at line 4848 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(), sipmethod, thread_safe_rand(), ast_channel::varshead, and sip_pvt::via. Referenced by do_proxy_auth(), sip_call(), and sip_poke_peer(). 04849 { 04850 struct sip_request req; 04851 04852 req.method = sipmethod; 04853 if (init) { 04854 /* Bump branch even on initial requests */ 04855 p->branch ^= thread_safe_rand(); 04856 build_via(p, p->via, sizeof(p->via)); 04857 if (init > 1) 04858 initreqprep(&req, p, sipmethod); 04859 else 04860 reqprep(&req, p, sipmethod, 0, 1); 04861 } else 04862 reqprep(&req, p, sipmethod, 0, 1); 04863 04864 if (p->options && p->options->auth) 04865 add_header(&req, p->options->authheader, p->options->auth); 04866 append_date(&req); 04867 if (sipmethod == SIP_REFER) { /* Call transfer */ 04868 if (!ast_strlen_zero(p->refer_to)) 04869 add_header(&req, "Refer-To", p->refer_to); 04870 if (!ast_strlen_zero(p->referred_by)) 04871 add_header(&req, "Referred-By", p->referred_by); 04872 } 04873 #ifdef OSP_SUPPORT 04874 if ((req.method != SIP_OPTIONS) && p->options && !ast_strlen_zero(p->options->osptoken)) { 04875 ast_log(LOG_DEBUG,"Adding OSP Token: %s\n", p->options->osptoken); 04876 add_header(&req, "P-OSP-Auth-Token", p->options->osptoken); 04877 } 04878 #endif 04879 if (p->options && !ast_strlen_zero(p->options->distinctive_ring)) 04880 { 04881 add_header(&req, "Alert-Info", p->options->distinctive_ring); 04882 } 04883 add_header(&req, "Allow", ALLOWED_METHODS); 04884 if (p->options && p->options->addsipheaders ) { 04885 struct ast_channel *ast; 04886 char *header = (char *) NULL; 04887 char *content = (char *) NULL; 04888 char *end = (char *) NULL; 04889 struct varshead *headp = (struct varshead *) NULL; 04890 struct ast_var_t *current; 04891 04892 ast = p->owner; /* The owner channel */ 04893 if (ast) { 04894 char *headdup; 04895 headp = &ast->varshead; 04896 if (!headp) 04897 ast_log(LOG_WARNING,"No Headp for the channel...ooops!\n"); 04898 else { 04899 AST_LIST_TRAVERSE(headp, current, entries) { 04900 /* SIPADDHEADER: Add SIP header to outgoing call */ 04901 if (!strncasecmp(ast_var_name(current), "SIPADDHEADER", strlen("SIPADDHEADER"))) { 04902 header = ast_var_value(current); 04903 headdup = ast_strdupa(header); 04904 /* Strip of the starting " (if it's there) */ 04905 if (*headdup == '"') 04906 headdup++; 04907 if ((content = strchr(headdup, ':'))) { 04908 *content = '\0'; 04909 content++; /* Move pointer ahead */ 04910 /* Skip white space */ 04911 while (*content == ' ') 04912 content++; 04913 /* Strip the ending " (if it's there) */ 04914 end = content + strlen(content) -1; 04915 if (*end == '"') 04916 *end = '\0'; 04917 04918 add_header(&req, headdup, content); 04919 if (sipdebug) 04920 ast_log(LOG_DEBUG, "Adding SIP Header \"%s\" with content :%s: \n", headdup, content); 04921 } 04922 } 04923 } 04924 } 04925 } 04926 } 04927 if (sdp && p->rtp) { 04928 ast_rtp_offered_from_local(p->rtp, 1); 04929 add_sdp(&req, p); 04930 } else { 04931 add_header_contentLength(&req, 0); 04932 add_blank_header(&req); 04933 } 04934 04935 if (!p->initreq.headers) { 04936 /* Use this as the basis */ 04937 copy_request(&p->initreq, &req); 04938 parse_request(&p->initreq); 04939 if (sip_debug_test_pvt(p)) 04940 ast_verbose("%d headers, %d lines\n", p->initreq.headers, p->initreq.lines); 04941 } 04942 p->lastinvite = p->ocseq; 04943 return send_request(p, &req, init ? 2 : 1, p->ocseq); 04944 }
|
|
transmit_message_with_text: Transmit text with SIP MESSAGE method ---
Definition at line 5492 of file chan_sip.c. References add_text(), sip_pvt::ocseq, reqprep(), send_request(), SIP_MESSAGE, and text. Referenced by sip_sendtext(). 05493 { 05494 struct sip_request req; 05495 reqprep(&req, p, SIP_MESSAGE, 0, 1); 05496 add_text(&req, text); 05497 return send_request(p, &req, 1, p->ocseq); 05498 }
|
|
transmit_notify_with_mwi: Notify user of messages waiting in voicemail ---
Definition at line 5119 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(), and SIP_NOTIFY. Referenced by sip_send_mwi_to_peer(). 05120 { 05121 struct sip_request req; 05122 char tmp[500]; 05123 char *t = tmp; 05124 size_t maxbytes = sizeof(tmp); 05125 char iabuf[INET_ADDRSTRLEN]; 05126 05127 initreqprep(&req, p, SIP_NOTIFY); 05128 add_header(&req, "Event", "message-summary"); 05129 add_header(&req, "Content-Type", default_notifymime); 05130 05131 ast_build_string(&t, &maxbytes, "Messages-Waiting: %s\r\n", newmsgs ? "yes" : "no"); 05132 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); 05133 ast_build_string(&t, &maxbytes, "Voice-Message: %d/%d (0/0)\r\n", newmsgs, oldmsgs); 05134 05135 if (t > tmp + sizeof(tmp)) 05136 ast_log(LOG_WARNING, "Buffer overflow detected!! (Please file a bug report)\n"); 05137 05138 add_header_contentLength(&req, strlen(tmp)); 05139 add_line(&req, tmp); 05140 05141 if (!p->initreq.headers) { /* Use this as the basis */ 05142 copy_request(&p->initreq, &req); 05143 parse_request(&p->initreq); 05144 if (sip_debug_test_pvt(p)) 05145 ast_verbose("%d headers, %d lines\n", p->initreq.headers, p->initreq.lines); 05146 determine_firstline_parts(&p->initreq); 05147 } 05148 05149 return send_request(p, &req, 1, p->ocseq); 05150 }
|
|
transmit_notify_with_sipfrag: Notify a transferring party of the status of trasnfer ---
Definition at line 5172 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(). 05173 { 05174 struct sip_request req; 05175 char tmp[20]; 05176 reqprep(&req, p, SIP_NOTIFY, 0, 1); 05177 snprintf(tmp, sizeof(tmp), "refer;id=%d", cseq); 05178 add_header(&req, "Event", tmp); 05179 add_header(&req, "Subscription-state", "terminated;reason=noresource"); 05180 add_header(&req, "Content-Type", "message/sipfrag;version=2.0"); 05181 05182 strcpy(tmp, "SIP/2.0 200 OK"); 05183 add_header_contentLength(&req, strlen(tmp)); 05184 add_line(&req, tmp); 05185 05186 if (!p->initreq.headers) { 05187 /* Use this as the basis */ 05188 copy_request(&p->initreq, &req); 05189 parse_request(&p->initreq); 05190 if (sip_debug_test_pvt(p)) 05191 ast_verbose("%d headers, %d lines\n", p->initreq.headers, p->initreq.lines); 05192 determine_firstline_parts(&p->initreq); 05193 } 05194 05195 return send_request(p, &req, 1, p->ocseq); 05196 }
|
|
transmit_refer: Transmit SIP REFER message ---
Definition at line 5501 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(). 05502 { 05503 struct sip_request req; 05504 char from[256]; 05505 char *of, *c; 05506 char referto[256]; 05507 05508 if (ast_test_flag(p, SIP_OUTGOING)) 05509 of = get_header(&p->initreq, "To"); 05510 else 05511 of = get_header(&p->initreq, "From"); 05512 ast_copy_string(from, of, sizeof(from)); 05513 of = get_in_brackets(from); 05514 ast_copy_string(p->from,of,sizeof(p->from)); 05515 if (strncmp(of, "sip:", 4)) { 05516 ast_log(LOG_NOTICE, "From address missing 'sip:', using it anyway\n"); 05517 } else 05518 of += 4; 05519 /* Get just the username part */ 05520 if ((c = strchr(dest, '@'))) { 05521 c = NULL; 05522 } else if ((c = strchr(of, '@'))) { 05523 *c = '\0'; 05524 c++; 05525 } 05526 if (c) { 05527 snprintf(referto, sizeof(referto), "<sip:%s@%s>", dest, c); 05528 } else { 05529 snprintf(referto, sizeof(referto), "<sip:%s>", dest); 05530 } 05531 05532 /* save in case we get 407 challenge */ 05533 ast_copy_string(p->refer_to, referto, sizeof(p->refer_to)); 05534 ast_copy_string(p->referred_by, p->our_contact, sizeof(p->referred_by)); 05535 05536 reqprep(&req, p, SIP_REFER, 0, 1); 05537 add_header(&req, "Refer-To", referto); 05538 if (!ast_strlen_zero(p->our_contact)) 05539 add_header(&req, "Referred-By", p->our_contact); 05540 add_blank_header(&req); 05541 return send_request(p, &req, 1, p->ocseq); 05542 }
|
|
transmit_register: Transmit register to SIP proxy or UA ---
Definition at line 5302 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, REG_STATE_AUTHSENT, REG_STATE_REGSENT, sip_registry::regattempts, sip_pvt::registry, sip_registry::regstate, sip_pvt::sa, sched, sip_registry::secret, send_request(), sip_alloc(), sip_debug_test_pvt(), sip_destroy(), sip_methods, SIP_OUTGOING, sip_reg_timeout(), SIP_REGISTER, sipmethod, 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(). 05303 { 05304 struct sip_request req; 05305 char from[256]; 05306 char to[256]; 05307 char tmp[80]; 05308 char via[80]; 05309 char addr[80]; 05310 struct sip_pvt *p; 05311 05312 /* exit if we are already in process with this registrar ?*/ 05313 if ( r == NULL || ((auth==NULL) && (r->regstate==REG_STATE_REGSENT || r->regstate==REG_STATE_AUTHSENT))) { 05314 ast_log(LOG_NOTICE, "Strange, trying to register %s@%s when registration already pending\n", r->username, r->hostname); 05315 return 0; 05316 } 05317 05318 if (r->call) { /* We have a registration */ 05319 if (!auth) { 05320 ast_log(LOG_WARNING, "Already have a REGISTER going on to %s@%s?? \n", r->username, r->hostname); 05321 return 0; 05322 } else { 05323 p = r->call; 05324 make_our_tag(p->tag, sizeof(p->tag)); /* create a new local tag for every register attempt */ 05325 p->theirtag[0]='\0'; /* forget their old tag, so we don't match tags when getting response */ 05326 } 05327 } else { 05328 /* Build callid for registration if we haven't registered before */ 05329 if (!r->callid_valid) { 05330 build_callid(r->callid, sizeof(r->callid), __ourip, default_fromdomain); 05331 r->callid_valid = 1; 05332 } 05333 /* Allocate SIP packet for registration */ 05334 p=sip_alloc( r->callid, NULL, 0, SIP_REGISTER); 05335 if (!p) { 05336 ast_log(LOG_WARNING, "Unable to allocate registration call\n"); 05337 return 0; 05338 } 05339 if (recordhistory) { 05340 char tmp[80]; 05341 snprintf(tmp, sizeof(tmp), "Account: %s@%s", r->username, r->hostname); 05342 append_history(p, "RegistryInit", tmp); 05343 } 05344 /* Find address to hostname */ 05345 if (create_addr(p, r->hostname)) { 05346 /* we have what we hope is a temporary network error, 05347 * probably DNS. We need to reschedule a registration try */ 05348 sip_destroy(p); 05349 if (r->timeout > -1) { 05350 ast_sched_del(sched, r->timeout); 05351 r->timeout = ast_sched_add(sched, global_reg_timeout*1000, sip_reg_timeout, r); 05352 ast_log(LOG_WARNING, "Still have a registration timeout for %s@%s (create_addr() error), %d\n", r->username, r->hostname, r->timeout); 05353 } else { 05354 r->timeout = ast_sched_add(sched, global_reg_timeout*1000, sip_reg_timeout, r); 05355 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); 05356 } 05357 r->regattempts++; 05358 return 0; 05359 } 05360 /* Copy back Call-ID in case create_addr changed it */ 05361 ast_copy_string(r->callid, p->callid, sizeof(r->callid)); 05362 if (r->portno) 05363 p->sa.sin_port = htons(r->portno); 05364 ast_set_flag(p, SIP_OUTGOING); /* Registration is outgoing call */ 05365 r->call=p; /* Save pointer to SIP packet */ 05366 p->registry=ASTOBJ_REF(r); /* Add pointer to registry in packet */ 05367 if (!ast_strlen_zero(r->secret)) /* Secret (password) */ 05368 ast_copy_string(p->peersecret, r->secret, sizeof(p->peersecret)); 05369 if (!ast_strlen_zero(r->md5secret)) 05370 ast_copy_string(p->peermd5secret, r->md5secret, sizeof(p->peermd5secret)); 05371 /* User name in this realm 05372 - if authuser is set, use that, otherwise use username */ 05373 if (!ast_strlen_zero(r->authuser)) { 05374 ast_copy_string(p->peername, r->authuser, sizeof(p->peername)); 05375 ast_copy_string(p->authname, r->authuser, sizeof(p->authname)); 05376 } else { 05377 if (!ast_strlen_zero(r->username)) { 05378 ast_copy_string(p->peername, r->username, sizeof(p->peername)); 05379 ast_copy_string(p->authname, r->username, sizeof(p->authname)); 05380 ast_copy_string(p->fromuser, r->username, sizeof(p->fromuser)); 05381 } 05382 } 05383 if (!ast_strlen_zero(r->username)) 05384 ast_copy_string(p->username, r->username, sizeof(p->username)); 05385 /* Save extension in packet */ 05386 ast_copy_string(p->exten, r->contact, sizeof(p->exten)); 05387 05388 /* 05389 check which address we should use in our contact header 05390 based on whether the remote host is on the external or 05391 internal network so we can register through nat 05392 */ 05393 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 05394 memcpy(&p->ourip, &bindaddr.sin_addr, sizeof(p->ourip)); 05395 build_contact(p); 05396 } 05397 05398 /* set up a timeout */ 05399 if (auth == NULL) { 05400 if (r->timeout > -1) { 05401 ast_log(LOG_WARNING, "Still have a registration timeout, #%d - deleting it\n", r->timeout); 05402 ast_sched_del(sched, r->timeout); 05403 } 05404 r->timeout = ast_sched_add(sched, global_reg_timeout * 1000, sip_reg_timeout, r); 05405 ast_log(LOG_DEBUG, "Scheduled a registration timeout for %s id #%d \n", r->hostname, r->timeout); 05406 } 05407 05408 if (strchr(r->username, '@')) { 05409 snprintf(from, sizeof(from), "<sip:%s>;tag=%s", r->username, p->tag); 05410 if (!ast_strlen_zero(p->theirtag)) 05411 snprintf(to, sizeof(to), "<sip:%s>;tag=%s", r->username, p->theirtag); 05412 else 05413 snprintf(to, sizeof(to), "<sip:%s>", r->username); 05414 } else { 05415 snprintf(from, sizeof(from), "<sip:%s@%s>;tag=%s", r->username, p->tohost, p->tag); 05416 if (!ast_strlen_zero(p->theirtag)) 05417 snprintf(to, sizeof(to), "<sip:%s@%s>;tag=%s", r->username, p->tohost, p->theirtag); 05418 else 05419 snprintf(to, sizeof(to), "<sip:%s@%s>", r->username, p->tohost); 05420 } 05421 05422 /* Fromdomain is what we are registering to, regardless of actual 05423 host name from SRV */ 05424 if (!ast_strlen_zero(p->fromdomain)) 05425 snprintf(addr, sizeof(addr), "sip:%s", p->fromdomain); 05426 else 05427 snprintf(addr, sizeof(addr), "sip:%s", r->hostname); 05428 ast_copy_string(p->uri, addr, sizeof(p->uri)); 05429 05430 p->branch ^= thread_safe_rand(); 05431 05432 memset(&req, 0, sizeof(req)); 05433 init_req(&req, sipmethod, addr); 05434 05435 /* Add to CSEQ */ 05436 snprintf(tmp, sizeof(tmp), "%u %s", ++r->ocseq, sip_methods[sipmethod].text); 05437 p->ocseq = r->ocseq; 05438 05439 build_via(p, via, sizeof(via)); 05440 add_header(&req, "Via", via); 05441 add_header(&req, "From", from); 05442 add_header(&req, "To", to); 05443 add_header(&req, "Call-ID", p->callid); 05444 add_header(&req, "CSeq", tmp); 05445 add_header(&req, "User-Agent", default_useragent); 05446 add_header(&req, "Max-Forwards", DEFAULT_MAX_FORWARDS); 05447 05448 05449 if (auth) /* Add auth header */ 05450 add_header(&req, authheader, auth); 05451 else if (!ast_strlen_zero(r->nonce)) { 05452 char digest[1024]; 05453 05454 /* We have auth data to reuse, build a digest header! */ 05455 if (sipdebug) 05456 ast_log(LOG_DEBUG, " >>> Re-using Auth data for %s@%s\n", r->username, r->hostname); 05457 ast_copy_string(p->realm, r->realm, sizeof(p->realm)); 05458 ast_copy_string(p->nonce, r->nonce, sizeof(p->nonce)); 05459 ast_copy_string(p->domain, r->domain, sizeof(p->domain)); 05460 ast_copy_string(p->opaque, r->opaque, sizeof(p->opaque)); 05461 ast_copy_string(p->qop, r->qop, sizeof(p->qop)); 05462 p->noncecount = r->noncecount++; 05463 05464 memset(digest,0,sizeof(digest)); 05465 if(!build_reply_digest(p, sipmethod, digest, sizeof(digest))) 05466 add_header(&req, "Authorization", digest); 05467 else 05468 ast_log(LOG_NOTICE, "No authorization available for authentication of registration to %s@%s\n", r->username, r->hostname); 05469 05470 } 05471 05472 snprintf(tmp, sizeof(tmp), "%d", default_expiry); 05473 add_header(&req, "Expires", tmp); 05474 add_header(&req, "Contact", p->our_contact); 05475 add_header(&req, "Event", "registration"); 05476 add_header_contentLength(&req, 0); 05477 add_blank_header(&req); 05478 copy_request(&p->initreq, &req); 05479 parse_request(&p->initreq); 05480 if (sip_debug_test_pvt(p)) { 05481 ast_verbose("REGISTER %d headers, %d lines\n", p->initreq.headers, p->initreq.lines); 05482 } 05483 determine_firstline_parts(&p->initreq); 05484 r->regstate=auth?REG_STATE_AUTHSENT:REG_STATE_REGSENT; 05485 r->regattempts++; /* Another attempt */ 05486 if (option_debug > 3) 05487 ast_verbose("REGISTER attempt %d to %s@%s\n", r->regattempts, r->username, r->hostname); 05488 return send_request(p, &req, 2, p->ocseq); 05489 }
|
|
transmit_reinvite_with_sdp: Transmit reinvite with SDP :-) ---
Definition at line 4579 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, and SIP_UPDATE. Referenced by check_pendings(), and sip_set_rtp_peer(). 04580 { 04581 struct sip_request req; 04582 if (ast_test_flag(p, SIP_REINVITE_UPDATE)) 04583 reqprep(&req, p, SIP_UPDATE, 0, 1); 04584 else 04585 reqprep(&req, p, SIP_INVITE, 0, 1); 04586 04587 add_header(&req, "Allow", ALLOWED_METHODS); 04588 if (sipdebug) 04589 add_header(&req, "X-asterisk-info", "SIP re-invite (RTP bridge)"); 04590 ast_rtp_offered_from_local(p->rtp, 1); 04591 add_sdp(&req, p); 04592 /* Use this as the basis */ 04593 copy_request(&p->initreq, &req); 04594 parse_request(&p->initreq); 04595 if (sip_debug_test_pvt(p)) 04596 ast_verbose("%d headers, %d lines\n", p->initreq.headers, p->initreq.lines); 04597 p->lastinvite = p->ocseq; 04598 ast_set_flag(p, SIP_OUTGOING); 04599 return send_request(p, &req, 1, p->ocseq); 04600 }
|
|
transmit_request: transmit generic SIP request ---
Definition at line 5564 of file chan_sip.c. References add_blank_header(), add_header_contentLength(), sip_pvt::ocseq, reqprep(), send_request(), and sipmethod. Referenced by handle_response(), handle_response_invite(), and handle_response_peerpoke(). 05565 { 05566 struct sip_request resp; 05567 reqprep(&resp, p, sipmethod, seqno, newbranch); 05568 add_header_contentLength(&resp, 0); 05569 add_blank_header(&resp); 05570 return send_request(p, &resp, reliable, seqno ? seqno : p->ocseq); 05571 }
|
|
transmit_request_with_auth: Transmit SIP request, auth added ---
Definition at line 5574 of file chan_sip.c. References add_blank_header(), add_header(), add_header_contentLength(), ast_cause2str(), ast_log(), build_reply_digest(), sip_pvt::callid, ast_channel::hangupcause, LOG_WARNING, sip_pvt::ocseq, sip_pvt::options, sip_pvt::owner, sip_pvt::realm, reqprep(), send_request(), and sipmethod. Referenced by check_pendings(), handle_request_refer(), and sip_hangup(). 05575 { 05576 struct sip_request resp; 05577 05578 reqprep(&resp, p, sipmethod, seqno, newbranch); 05579 if (*p->realm) { 05580 char digest[1024]; 05581 05582 memset(digest, 0, sizeof(digest)); 05583 if(!build_reply_digest(p, sipmethod, digest, sizeof(digest))) { 05584 if (p->options && p->options->auth_type == PROXY_AUTH) 05585 add_header(&resp, "Proxy-Authorization", digest); 05586 else if (p->options && p->options->auth_type == WWW_AUTH) 05587 add_header(&resp, "Authorization", digest); 05588 else /* Default, to be backwards compatible (maybe being too careful, but leaving it for now) */ 05589 add_header(&resp, "Proxy-Authorization", digest); 05590 } else 05591 ast_log(LOG_WARNING, "No authentication available for call %s\n", p->callid); 05592 } 05593 /* If we are hanging up and know a cause for that, send it in clear text to make 05594 debugging easier. */ 05595 if (sipmethod == SIP_BYE) { 05596 if (p->owner && p->owner->hangupcause) { 05597 add_header(&resp, "X-Asterisk-HangupCause", ast_cause2str(p->owner->hangupcause)); 05598 } 05599 } 05600 05601 add_header_contentLength(&resp, 0); 05602 add_blank_header(&resp); 05603 return send_request(p, &resp, reliable, seqno ? seqno : p->ocseq); 05604 }
|
|
transmit_response: Transmit response, no retransmits
Definition at line 4140 of file chan_sip.c. References __transmit_response(). 04141 { 04142 return __transmit_response(p, msg, req, 0); 04143 }
|
|
transmit_response_reliable: Transmit response, Make sure you get a reply
Definition at line 4156 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(). 04157 { 04158 return __transmit_response(p, msg, req, fatal ? 2 : 1); 04159 }
|
|
transmit_response_with_allow: Append Accept header, content length before transmitting response ---
Definition at line 4186 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(). 04187 { 04188 struct sip_request resp; 04189 respprep(&resp, p, msg, req); 04190 add_header(&resp, "Accept", "application/sdp"); 04191 add_header_contentLength(&resp, 0); 04192 add_blank_header(&resp); 04193 return send_response(p, &resp, reliable, 0); 04194 }
|
|
Definition at line 4197 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(). 04198 { 04199 struct sip_request resp; 04200 char tmp[256]; 04201 int seqno = 0; 04202 04203 if (reliable && (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1)) { 04204 ast_log(LOG_WARNING, "Unable to determine sequence number from '%s'\n", get_header(req, "CSeq")); 04205 return -1; 04206 } 04207 /* Stale means that they sent us correct authentication, but 04208 based it on an old challenge (nonce) */ 04209 snprintf(tmp, sizeof(tmp), "Digest realm=\"%s\", nonce=\"%s\"%s", global_realm, randdata, stale ? ", stale=true" : ""); 04210 respprep(&resp, p, msg, req); 04211 add_header(&resp, header, tmp); 04212 add_header_contentLength(&resp, 0); 04213 add_blank_header(&resp); 04214 return send_response(p, &resp, reliable, seqno); 04215 }
|
|
transmit_response_with_date: Append date and content length before transmitting response ---
Definition at line 4175 of file chan_sip.c. References add_blank_header(), add_header_contentLength(), append_date(), respprep(), and send_response(). Referenced by register_verify(). 04176 { 04177 struct sip_request resp; 04178 respprep(&resp, p, msg, req); 04179 append_date(&resp); 04180 add_header_contentLength(&resp, 0); 04181 add_blank_header(&resp); 04182 return send_response(p, &resp, 0, 0); 04183 }
|
|
transmit_response_with_sdp: Used for 200 OK and 183 early media ---
Definition at line 4506 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, and send_response(). Referenced by handle_request_invite(), sip_answer(), sip_indicate(), and sip_write(). 04507 { 04508 struct sip_request resp; 04509 int seqno; 04510 if (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1) { 04511 ast_log(LOG_WARNING, "Unable to get seqno from '%s'\n", get_header(req, "CSeq")); 04512 return -1; 04513 } 04514 respprep(&resp, p, msg, req); 04515 if (p->rtp) { 04516 ast_rtp_offered_from_local(p->rtp, 0); 04517 add_sdp(&resp, p); 04518 } else { 04519 ast_log(LOG_ERROR, "Can't add SDP to response, since we have no RTP session allocated. Call-ID %s\n", p->callid); 04520 } 04521 return send_response(p, &resp, retrans, seqno); 04522 }
|
|
transmit_response_with_unsupported: Transmit response, no retransmits
Definition at line 4146 of file chan_sip.c. References add_header(), append_date(), respprep(), and send_response(). Referenced by handle_request_invite(). 04147 { 04148 struct sip_request resp; 04149 respprep(&resp, p, msg, req); 04150 append_date(&resp); 04151 add_header(&resp, "Unsupported", unsupported); 04152 return send_response(p, &resp, 0, 0); 04153 }
|
|
transmit_sip_request: Transmit SIP request
Definition at line 5153 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(). 05154 { 05155 if (!p->initreq.headers) { 05156 /* Use this as the basis */ 05157 copy_request(&p->initreq, req); 05158 parse_request(&p->initreq); 05159 if (sip_debug_test_pvt(p)) 05160 ast_verbose("%d headers, %d lines\n", p->initreq.headers, p->initreq.lines); 05161 determine_firstline_parts(&p->initreq); 05162 } 05163 05164 return send_request(p, req, 0, p->ocseq); 05165 }
|
|
transmit_state_notify: Used in the SUBSCRIBE notification subsystem ----
Definition at line 4947 of file chan_sip.c. References add_header(), add_header_contentLength(), add_line(), ast_build_string(), ast_device_state(), 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(), sip_pvt::context, CPIM_PIDF_XML, DIALOG_INFO_XML, sip_pvt::dialogver, cfsubscription_types::event, sip_pvt::expiry, sip_pvt::exten, find_subscription_type(), get_header(), get_in_brackets(), sip_pvt::initreq, LOG_WARNING, cfsubscription_types::mediatype, NONE, sip_pvt::ocseq, PIDF_XML, reqprep(), send_request(), SIP_NOTIFY, subscriptiontype, and XPIDF_XML. Referenced by __sip_autodestruct(), cb_extensionstate(), and handle_request_subscribe(). 04948 { 04949 char tmp[4000], from[256], to[256]; 04950 char *t = tmp, *c, *a, *mfrom, *mto; 04951 size_t maxbytes = sizeof(tmp); 04952 struct sip_request req; 04953 char hint[AST_MAX_EXTENSION]; 04954 char *statestring = "terminated"; 04955 const struct cfsubscription_types *subscriptiontype; 04956 enum state { NOTIFY_OPEN, NOTIFY_INUSE, NOTIFY_CLOSED } local_state = NOTIFY_OPEN; 04957 char *pidfstate = "--"; 04958 char *pidfnote= "Ready"; 04959 04960 memset(from, 0, sizeof(from)); 04961 memset(to, 0, sizeof(to)); 04962 memset(tmp, 0, sizeof(tmp)); 04963 04964 switch (state) { 04965 case (AST_EXTENSION_RINGING | AST_EXTENSION_INUSE): 04966 if (global_notifyringing) 04967 statestring = "early"; 04968 else 04969 statestring = "confirmed"; 04970 local_state = NOTIFY_INUSE; 04971 pidfstate = "busy"; 04972 pidfnote = "Ringing"; 04973 break; 04974 case AST_EXTENSION_RINGING: 04975 statestring = "early"; 04976 local_state = NOTIFY_INUSE; 04977 pidfstate = "busy"; 04978 pidfnote = "Ringing"; 04979 break; 04980 case AST_EXTENSION_INUSE: 04981 statestring = "confirmed"; 04982 local_state = NOTIFY_INUSE; 04983 pidfstate = "busy"; 04984 pidfnote = "On the phone"; 04985 break; 04986 case AST_EXTENSION_BUSY: 04987 statestring = "confirmed"; 04988 local_state = NOTIFY_CLOSED; 04989 pidfstate = "busy"; 04990 pidfnote = "On the phone"; 04991 break; 04992 case AST_EXTENSION_UNAVAILABLE: 04993 statestring = "confirmed"; 04994 local_state = NOTIFY_CLOSED; 04995 pidfstate = "away"; 04996 pidfnote = "Unavailable"; 04997 break; 04998 case AST_EXTENSION_NOT_INUSE: 04999 default: 05000 /* Default setting */ 05001 break; 05002 } 05003 05004 subscriptiontype = find_subscription_type(p->subscribed); 05005 05006 /* Check which device/devices we are watching and if they are registered */ 05007 if (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, p->context, p->exten)) { 05008 /* If they are not registered, we will override notification and show no availability */ 05009 if (ast_device_state(hint) == AST_DEVICE_UNAVAILABLE) { 05010 local_state = NOTIFY_CLOSED; 05011 pidfstate = "away"; 05012 pidfnote = "Not online"; 05013 } 05014 } 05015 05016 ast_copy_string(from, get_header(&p->initreq, "From"), sizeof(from)); 05017 c = get_in_brackets(from); 05018 if (strncmp(c, "sip:", 4)) { 05019 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", c); 05020 return -1; 05021 } 05022 if ((a = strchr(c, ';'))) 05023 *a = '\0'; 05024 mfrom = c; 05025 05026 ast_copy_string(to, get_header(&p->initreq, "To"), sizeof(to)); 05027 c = get_in_brackets(to); 05028 if (strncmp(c, "sip:", 4)) { 05029 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", c); 05030 return -1; 05031 } 05032 if ((a = strchr(c, ';'))) 05033 *a = '\0'; 05034 mto = c; 05035 05036 reqprep(&req, p, SIP_NOTIFY, 0, 1); 05037 05038 05039 add_header(&req, "Event", subscriptiontype->event); 05040 add_header(&req, "Content-Type", subscriptiontype->mediatype); 05041 switch(state) { 05042 case AST_EXTENSION_DEACTIVATED: 05043 if (p->subscribed == TIMEOUT) 05044 add_header(&req, "Subscription-State", "terminated;reason=timeout"); 05045 else { 05046 add_header(&req, "Subscription-State", "terminated;reason=probation"); 05047 add_header(&req, "Retry-After", "60"); 05048 } 05049 break; 05050 case AST_EXTENSION_REMOVED: 05051 add_header(&req, "Subscription-State", "terminated;reason=noresource"); 05052 break; 05053 break; 05054 default: 05055 if (p->expiry) 05056 add_header(&req, "Subscription-State", "active"); 05057 else /* Expired */ 05058 add_header(&req, "Subscription-State", "terminated;reason=timeout"); 05059 } 05060 switch (p->subscribed) { 05061 case XPIDF_XML: 05062 case CPIM_PIDF_XML: 05063 ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\"?>\n"); 05064 ast_build_string(&t, &maxbytes, "<!DOCTYPE presence PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n"); 05065 ast_build_string(&t, &maxbytes, "<presence>\n"); 05066 ast_build_string(&t, &maxbytes, "<presentity uri=\"%s;method=SUBSCRIBE\" />\n", mfrom); 05067 ast_build_string(&t, &maxbytes, "<atom id=\"%s\">\n", p->exten); 05068 ast_build_string(&t, &maxbytes, "<address uri=\"%s;user=ip\" priority=\"0.800000\">\n", mto); 05069 ast_build_string(&t, &maxbytes, "<status status=\"%s\" />\n", (local_state == NOTIFY_OPEN) ? "open" : (local_state == NOTIFY_INUSE) ? "inuse" : "closed"); 05070 ast_build_string(&t, &maxbytes, "<msnsubstatus substatus=\"%s\" />\n", (local_state == NOTIFY_OPEN) ? "online" : (local_state == NOTIFY_INUSE) ? "onthephone" : "offline"); 05071 ast_build_string(&t, &maxbytes, "</address>\n</atom>\n</presence>\n"); 05072 break; 05073 case PIDF_XML: /* Eyebeam supports this format */ 05074 ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n"); 05075 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); 05076 ast_build_string(&t, &maxbytes, "<pp:person><status>\n"); 05077 if (pidfstate[0] != '-') 05078 ast_build_string(&t, &maxbytes, "<ep:activities><ep:%s/></ep:activities>\n", pidfstate); 05079 ast_build_string(&t, &maxbytes, "</status></pp:person>\n"); 05080 ast_build_string(&t, &maxbytes, "<note>%s</note>\n", pidfnote); /* Note */ 05081 ast_build_string(&t, &maxbytes, "<tuple id=\"%s\">\n", p->exten); /* Tuple start */ 05082 ast_build_string(&t, &maxbytes, "<contact priority=\"1\">%s</contact>\n", mto); 05083 if (pidfstate[0] == 'b') /* Busy? Still open ... */ 05084 ast_build_string(&t, &maxbytes, "<status><basic>open</basic></status>\n"); 05085 else 05086 ast_build_string(&t, &maxbytes, "<status><basic>%s</basic></status>\n", (local_state != NOTIFY_CLOSED) ? "open" : "closed"); 05087 ast_build_string(&t, &maxbytes, "</tuple>\n</presence>\n"); 05088 break; 05089 case DIALOG_INFO_XML: /* SNOM subscribes in this format */ 05090 ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\"?>\n"); 05091 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); 05092 if ((state & AST_EXTENSION_RINGING) && global_notifyringing) 05093 ast_build_string(&t, &maxbytes, "<dialog id=\"%s\" direction=\"recipient\">\n", p->exten); 05094 else 05095 ast_build_string(&t, &maxbytes, "<dialog id=\"%s\">\n", p->exten); 05096 ast_build_string(&t, &maxbytes, "<state>%s</state>\n", statestring); 05097 ast_build_string(&t, &maxbytes, "</dialog>\n</dialog-info>\n"); 05098 break; 05099 case NONE: 05100 default: 05101 break; 05102 } 05103 05104 if (t > tmp + sizeof(tmp)) 05105 ast_log(LOG_WARNING, "Buffer overflow detected!! (Please file a bug report)\n"); 05106 05107 add_header_contentLength(&req, strlen(tmp)); 05108 add_line(&req, tmp); 05109 05110 return send_request(p, &req, 1, p->ocseq); 05111 }
|
|
Cleanup all module structures, sockets, etc. This is called at exit. Any registrations and memory allocations need to be unregistered and free'd here. Nothing else will do these for you (until exit).
Definition at line 13141 of file chan_sip.c. References app_dtmfmode, app_sipaddheader, app_sipgetheader, ast_channel_unregister(), ast_cli_unregister_multiple(), ast_custom_function_unregister(), ast_free_ha(), ast_log(), ast_manager_unregister(), ast_mutex_destroy(), ast_mutex_lock(), ast_mutex_unlock(), ast_rtp_proto_unregister(), ast_softhangup(), AST_SOFTHANGUP_APPUNLOAD, ast_unregister_application(), ast_variables_destroy(), ASTOBJ_CONTAINER_DESTROY, ASTOBJ_CONTAINER_DESTROYALL, authl, sip_pvt::chanvars, checksipdomain_function, clear_realm_authentication(), clear_sip_domains(), free, iflist, localaddr, sip_pvt::lock, LOG_WARNING, monitor_thread, my_clis, sip_pvt::next, sip_pvt::owner, peerl, regl, sched, sched_context_destroy(), sip_destroy_peer(), sip_destroy_user(), sip_header_function, sip_registry_destroy(), sip_rtp, sip_tech, sipchaninfo_function, sippeer_function, sipsock, and userl. 13142 { 13143 struct sip_pvt *p, *pl; 13144 13145 /* First, take us out of the channel type list */ 13146 ast_channel_unregister(&sip_tech); 13147 13148 ast_custom_function_unregister(&sipchaninfo_function); 13149 ast_custom_function_unregister(&sippeer_function); 13150 ast_custom_function_unregister(&sip_header_function); 13151 ast_custom_function_unregister(&checksipdomain_function); 13152 13153 ast_unregister_application(app_dtmfmode); 13154 ast_unregister_application(app_sipaddheader); 13155 ast_unregister_application(app_sipgetheader); 13156 13157 ast_cli_unregister_multiple(my_clis, sizeof(my_clis) / sizeof(my_clis[0])); 13158 13159 ast_rtp_proto_unregister(&sip_rtp); 13160 13161 ast_manager_unregister("SIPpeers"); 13162 ast_manager_unregister("SIPshowpeer"); 13163 13164 if (!ast_mutex_lock(&iflock)) { 13165 /* Hangup all interfaces if they have an owner */ 13166 p = iflist; 13167 while (p) { 13168 if (p->owner) 13169 ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD); 13170 p = p->next; 13171 } 13172 ast_mutex_unlock(&iflock); 13173 } else { 13174 ast_log(LOG_WARNING, "Unable to lock the interface list\n"); 13175 return -1; 13176 } 13177 13178 if (!ast_mutex_lock(&monlock)) { 13179 if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP)) { 13180 pthread_cancel(monitor_thread); 13181 pthread_kill(monitor_thread, SIGURG); 13182 pthread_join(monitor_thread, NULL); 13183 } 13184 monitor_thread = AST_PTHREADT_STOP; 13185 ast_mutex_unlock(&monlock); 13186 } else { 13187 ast_log(LOG_WARNING, "Unable to lock the monitor\n"); 13188 return -1; 13189 } 13190 13191 if (!ast_mutex_lock(&iflock)) { 13192 /* Destroy all the interfaces and free their memory */ 13193 p = iflist; 13194 while (p) { 13195 pl = p; 13196 p = p->next; 13197 /* Free associated memory */ 13198 ast_mutex_destroy(&pl->lock); 13199 if (pl->chanvars) { 13200 ast_variables_destroy(pl->chanvars); 13201 pl->chanvars = NULL; 13202 } 13203 free(pl); 13204 } 13205 iflist = NULL; 13206 ast_mutex_unlock(&iflock); 13207 } else { 13208 ast_log(LOG_WARNING, "Unable to lock the interface list\n"); 13209 return -1; 13210 } 13211 13212 /* Free memory for local network address mask */ 13213 ast_free_ha(localaddr); 13214 13215 ASTOBJ_CONTAINER_DESTROYALL(&userl, sip_destroy_user); 13216 ASTOBJ_CONTAINER_DESTROY(&userl); 13217 ASTOBJ_CONTAINER_DESTROYALL(&peerl, sip_destroy_peer); 13218 ASTOBJ_CONTAINER_DESTROY(&peerl); 13219 ASTOBJ_CONTAINER_DESTROYALL(®l, sip_registry_destroy); 13220 ASTOBJ_CONTAINER_DESTROY(®l); 13221 13222 clear_realm_authentication(authl); 13223 clear_sip_domains(); 13224 close(sipsock); 13225 sched_context_destroy(sched); 13226 13227 return 0; 13228 }
|
|
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, 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, expiry, 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 13230 of file chan_sip.c. 13231 {
13232 return usecnt;
13233 }
|
|
Definition at line 409 of file chan_sip.c. Referenced by reload_config(), sip_alloc(), sip_notify(), sip_poke_peer(), sip_request_call(), sip_send_mwi_to_peer(), and transmit_register(). |
|
Structure for conversion between compressed SIP and "normal" SIP.
Referenced by add_header(), and find_alias(). |
|
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_destroy_peer(), sip_show_objects(), and temp_peer(). |
|
Definition at line 12730 of file chan_sip.c. Referenced by load_module(), and unload_module(). |
|
Definition at line 12732 of file chan_sip.c. Referenced by load_module(), and unload_module(). |
|
Definition at line 12744 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 reload_config(), and sip_show_settings(). |
|
Definition at line 867 of file chan_sip.c. Referenced by ast_sip_ouraddrfor(), reload_config(), sip_alloc(), sip_show_settings(), and transmit_register(). |
|
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. Referenced by load_module(), register_peer_exten(), and reload_config(). |
|
Definition at line 9199 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 reload_config(), and sip_show_settings(). |
|
Definition at line 144 of file chan_sip.c. Referenced by reload_config(). |
|
Definition at line 9098 of file chan_sip.c. |
|
Definition at line 416 of file chan_sip.c. Referenced by sip_debug_test_addr(), sip_do_debug(), sip_do_debug_ip(), and sip_do_debug_peer(). |
|
Definition at line 341 of file chan_sip.c. Referenced by reload_config(), and sip_show_settings(). |
|
Definition at line 332 of file chan_sip.c. Referenced by build_peer(), build_user(), handle_request_bye(), handle_request_invite(), handle_request_options(), handle_request_refer(), handle_request_subscribe(), reload_config(), sip_alloc(), sip_show_settings(), and temp_peer(). |
|
Definition at line 119 of file chan_sip.c. Referenced by reload_config(), 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 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 initreqprep(), reload_config(), reqprep(), respprep(), sip_show_settings(), and transmit_register(). |
|
Definition at line 142 of file chan_sip.c. |
|
Definition at line 12729 of file chan_sip.c. Referenced by load_module(). |
|
Definition at line 12736 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 12747 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 parse_register_contact(), reg_source_db(), reload_config(), and update_peer(). |
|
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 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 reload_config(), sip_new(), and sip_request_call(). |
|
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(), and sip_show_settings(). |
|
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. Referenced by realtime_peer(), reload_config(), and sip_show_settings(). |
|
Definition at line 365 of file chan_sip.c. Referenced by reload_config(), and sip_show_settings(). |
|
Definition at line 367 of file chan_sip.c. Referenced by reload_config(). |
|
Definition at line 363 of file chan_sip.c. Referenced by reload_config(), and sip_show_settings(). |
|
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 9115 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. Referenced by do_monitor(), load_module(), and sip_alloc(). |
|
Definition at line 872 of file chan_sip.c. Referenced by ast_sip_ouraddrfor(), reload_config(), and unload_module(). |
|
Definition at line 7819 of file chan_sip.c. Referenced by load_module(). |
|
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 7401 of file chan_sip.c. Referenced by load_module(). |
|
Definition at line 118 of file chan_sip.c. Referenced by 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. Referenced by restart_monitor(), and unload_module(). |
|
Definition at line 13052 of file chan_sip.c. Referenced by load_module(), and unload_module(). |
|
Initial value: "Usage: sip no debug\n" " Disables dumping of SIP packets for debugging purposes\n" Definition at line 9107 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 9111 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 9047 of file chan_sip.c. |
|
Definition at line 411 of file chan_sip.c. Referenced by build_contact(), build_via(), initreqprep(), and reload_config(). |
|
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 find_call(), reload_config(), and sip_show_settings(). |
|
The peer list: Peers and Friends ---.
Referenced by _sip_show_peers(), build_peer(), complete_sip_peer(), do_monitor(), expire_register(), find_peer(), load_module(), realtime_peer(), register_verify(), reload_config(), sip_poke_all_peers(), sip_prune_realtime(), sip_show_inuse(), sip_show_objects(), and unload_module(). |
|
Definition at line 444 of file chan_sip.c. Referenced by reload_config(), and sip_show_settings(). |
|
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 9089 of file chan_sip.c. |
|
Record SIP history. Off by default Definition at line 424 of file chan_sip.c. Referenced by append_history(), reload_config(), sip_do_history(), sip_no_history(), and sip_show_settings(). |
|
Context for auto-extensions Definition at line 430 of file chan_sip.c. Referenced by register_peer_exten(), reload_config(), and sip_show_settings(). |
|
The register list: Other SIP proxys we register with and call ---.
Referenced by 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_registry_destroy(), 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(), sip_destroy_peer(), and sip_show_objects(). |
|
Definition at line 374 of file chan_sip.c. Referenced by realtime_user(), sip_destroy_user(), and sip_show_objects(). |
|
|
Initial value: "Usage: sip show channel <channel>\n" " Provides detailed status on a given SIP channel.\n" Definition at line 9071 of file chan_sip.c. |
|
Initial value: "Usage: sip show channels\n" " Lists all currently active SIP channels.\n" Definition at line 9067 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 9042 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 9075 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 9062 of file chan_sip.c. |
|
Initial value: "Usage: sip show objects\n" " Shows status of known SIP objects\n" Definition at line 9128 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 9084 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 9079 of file chan_sip.c. |
|
Initial value: "Usage: sip show registry\n" " Lists all registration requests and status.\n" Definition at line 9094 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 9132 of file chan_sip.c. |
|
Initial value: "Usage: sip show subscriptions\n" " Shows active SIP subscriptions for extension states\n" Definition at line 9124 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 9057 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 9052 of file chan_sip.c. |
|
Definition at line 9178 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(), initreqprep(), 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 9120 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 12957 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(), and unload_module(). |
|
Definition at line 9360 of file chan_sip.c. Referenced by load_module(), and unload_module(). |
|
Definition at line 415 of file chan_sip.c. Referenced by __sip_ack(), handle_request_subscribe(), parse_request(), reload_config(), retrans_pkt(), sip_debug_test_addr(), sip_debug_test_pvt(), sip_do_debug(), sip_do_debug_ip(), sip_do_debug_peer(), and sip_no_debug(). |
|
Definition at line 9284 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(), sip_destroy_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(), realtime_user(), sip_destroy_user(), and sip_show_objects(). |
|
Definition at line 12728 of file chan_sip.c. Referenced by load_module(). |
|
Definition at line 12733 of file chan_sip.c. Referenced by load_module(). |
|
Definition at line 12745 of file chan_sip.c. Referenced by load_module(). |
|
Definition at line 418 of file chan_sip.c. Referenced by reload_config(), sip_alloc(), and sip_show_settings(). |
|
Definition at line 385 of file chan_sip.c. Referenced by sip_hangup(), and sip_new(). |
|
The user list: Users and friends ---.
Referenced by complete_sip_user(), find_user(), load_module(), realtime_user(), reload_config(), sip_prune_realtime(), sip_show_inuse(), sip_show_objects(), sip_show_users(), and unload_module(). |
|
Definition at line 420 of file chan_sip.c. Referenced by add_sdp(), reload_config(), sip_alloc(), and sip_show_settings(). |