Mon Mar 20 08:25:53 2006

Asterisk developer's documentation


Main Page | Modules | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals | Related Pages

chan_sip.c File Reference

Implementation of Session Initiation Protocol. More...

#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_authadd_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_peerbuild_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_userbuild_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_pvtfind_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_peerfind_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_authfind_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_typesfind_subscription_type (enum subscriptiontype subtype)
 find_subscription_type: Find subscription type in array
sip_userfind_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_pvtget_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_peerrealtime_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_userrealtime_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_pvtsip_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_rtpsip_get_rtp_peer (struct ast_channel *chan)
 sip_get_rtp_peer: Returns null if we can't reinvite (part of RTP interface)
ast_rtpsip_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_channelsip_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_framesip_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_channelsip_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_framesip_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_peertemp_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_authauthl
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_pvtiflist
 sip_pvt: PVT structures are used for each SIP conversation, ie. a call
io_contextio
ast_halocaladdr
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_confignotify_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_contextsched
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


Detailed Description

Implementation of Session Initiation Protocol.

Implementation of RFC 3261 - without S/MIME, TCP and TLS support Configuration file sip.conf

Todo:
SIP over TCP

SIP over TLS

Better support of forking

Definition in file chan_sip.c.


Define Documentation

#define ALLOWED_METHODS   "INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY"
 

SIP Methods we support.

Definition at line 321 of file chan_sip.c.

Referenced by respprep(), transmit_invite(), and transmit_reinvite_with_sdp().

#define CALLERID_UNKNOWN   "Unknown"
 

Definition at line 125 of file chan_sip.c.

#define DEBUG_READ   0
 

Definition at line 139 of file chan_sip.c.

#define DEBUG_SEND   1
 

Definition at line 140 of file chan_sip.c.

#define DEC_CALL_LIMIT   0
 

Definition at line 441 of file chan_sip.c.

Referenced by handle_request_invite(), handle_response(), sip_hangup(), and update_call_counter().

#define DEFAULT_CALLERID   "asterisk"
 

Definition at line 340 of file chan_sip.c.

Referenced by reload_config().

#define DEFAULT_CONTEXT   "default"
 

Definition at line 331 of file chan_sip.c.

Referenced by reload_config().

#define DEFAULT_DEFAULT_EXPIRY   120
 

Definition at line 101 of file chan_sip.c.

#define DEFAULT_EXPIRY   900
 

Expire slowly

Definition at line 432 of file chan_sip.c.

#define DEFAULT_FREQ_NOTOK   10 * 1000
 

Definition at line 131 of file chan_sip.c.

#define DEFAULT_FREQ_OK   60 * 1000
 

Definition at line 130 of file chan_sip.c.

#define DEFAULT_MAX_EXPIRY   3600
 

Definition at line 102 of file chan_sip.c.

#define DEFAULT_MAX_FORWARDS   "70"
 

Definition at line 104 of file chan_sip.c.

Referenced by initreqprep(), reqprep(), and transmit_register().

#define DEFAULT_MAXMS   2000
 

Definition at line 129 of file chan_sip.c.

#define DEFAULT_MWITIME   10
 

Definition at line 382 of file chan_sip.c.

#define DEFAULT_NOTIFYMIME   "application/simple-message-summary"
 

Definition at line 345 of file chan_sip.c.

Referenced by reload_config().

#define DEFAULT_REALM   "asterisk"
 

Definition at line 428 of file chan_sip.c.

Referenced by reload_config().

#define DEFAULT_REGISTRATION_TIMEOUT   20
 

Definition at line 103 of file chan_sip.c.

#define DEFAULT_RETRANS   1000
 

Definition at line 133 of file chan_sip.c.

#define DEFAULT_SIP_PORT   5060
 

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().

#define DEFAULT_USERAGENT   "Asterisk PBX"
 

Definition at line 90 of file chan_sip.c.

Referenced by reload_config().

#define DEFAULT_VMEXTEN   "asterisk"
 

Definition at line 335 of file chan_sip.c.

Referenced by reload_config().

#define EXPIRY_GUARD_LIMIT   30
 

Definition at line 109 of file chan_sip.c.

#define EXPIRY_GUARD_MIN   500
 

Definition at line 111 of file chan_sip.c.

Referenced by handle_response_register().

#define EXPIRY_GUARD_PCT   0.20
 

Definition at line 115 of file chan_sip.c.

Referenced by handle_response_register().

#define EXPIRY_GUARD_SECS   15
 

Definition at line 108 of file chan_sip.c.

Referenced by handle_response_register().

#define FLAG_FATAL   (1 << 1)
 

Definition at line 696 of file chan_sip.c.

Referenced by __sip_reliable_xmit(), and retrans_pkt().

#define FLAG_RESPONSE   (1 << 0)
 

Definition at line 695 of file chan_sip.c.

Referenced by __sip_ack(), __sip_pretend_ack(), __sip_semi_ack(), handle_request(), and retrans_pkt().

#define FORMAT   "%-15.15s %-10.10s %-11.11s %5.5d/%5.5d %-4.4s %-3.3s %-3.3s %-15.15s\n"
 

sip_show_domains: CLI command to list local domains

Definition at line 7798 of file chan_sip.c.

#define FORMAT   "%-30.30s %-12.12s %8d %-20.20s\n"
 

sip_show_domains: CLI command to list local domains

Definition at line 7798 of file chan_sip.c.

#define FORMAT   "%-40.40s %-20.20s %-16.16s\n"
 

sip_show_domains: CLI command to list local domains

Definition at line 7798 of file chan_sip.c.

#define FORMAT   "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8d %-10s\n"
 

sip_show_domains: CLI command to list local domains

Definition at line 7798 of file chan_sip.c.

#define FORMAT   "%-25.25s %-15.15s %-15.15s %-15.15s %-5.5s%-10.10s\n"
 

sip_show_domains: CLI command to list local domains

Definition at line 7798 of file chan_sip.c.

#define FORMAT   "%-25.25s %-15.15s %-15.15s \n"
 

sip_show_domains: CLI command to list local domains

Definition at line 7798 of file chan_sip.c.

#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"
 

Referenced by __sip_show_channels().

#define INC_CALL_LIMIT   1
 

Definition at line 442 of file chan_sip.c.

Referenced by handle_request_invite(), sip_call(), sip_hangup(), and update_call_counter().

#define IPTOS_MINCOST   0x02
 

Definition at line 95 of file chan_sip.c.

#define MAX a,
 )     ((a) > (b) ? (a) : (b))
 

Definition at line 122 of file chan_sip.c.

#define MAX_AUTHTRIES   3
 

Definition at line 136 of file chan_sip.c.

#define MAX_RETRANS   6
 

Definition at line 135 of file chan_sip.c.

#define NO_RTP   0
 

Definition at line 148 of file chan_sip.c.

#define NOT_SUPPORTED   0
 

Definition at line 265 of file chan_sip.c.

#define REG_STATE_AUTHSENT   2
 

Definition at line 804 of file chan_sip.c.

Referenced by regstate2str(), and transmit_register().

#define REG_STATE_FAILED   7
 

Definition at line 809 of file chan_sip.c.

Referenced by regstate2str().

#define REG_STATE_NOAUTH   6
 

Definition at line 808 of file chan_sip.c.

Referenced by regstate2str().

#define REG_STATE_REGISTERED   3
 

Definition at line 805 of file chan_sip.c.

Referenced by regstate2str().

#define REG_STATE_REGSENT   1
 

Definition at line 803 of file chan_sip.c.

Referenced by regstate2str(), and transmit_register().

#define REG_STATE_REJECTED   4
 

Definition at line 806 of file chan_sip.c.

Referenced by regstate2str().

#define REG_STATE_TIMEOUT   5
 

Definition at line 807 of file chan_sip.c.

Referenced by regstate2str().

#define REG_STATE_UNREGISTERED   0
 

Definition at line 802 of file chan_sip.c.

Referenced by regstate2str().

#define RTP   1
 

Definition at line 147 of file chan_sip.c.

#define SIP_ALREADYGONE   (1 << 0)
 

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().

#define SIP_CALL_LIMIT   (1 << 29)
 

Definition at line 560 of file chan_sip.c.

Referenced by check_user_full(), create_addr_from_peer(), and update_call_counter().

#define SIP_CALL_ONHOLD   (1 << 28)
 

Definition at line 559 of file chan_sip.c.

Referenced by __sip_show_channels(), and process_sdp().

#define SIP_CAN_REINVITE   (1 << 20)
 

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().

#define SIP_DEBUG_CONFIG   1 << 0
 

Definition at line 413 of file chan_sip.c.

#define SIP_DEBUG_CONSOLE   1 << 1
 

Definition at line 414 of file chan_sip.c.

#define SIP_DTMF   (3 << 16)
 

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().

#define SIP_DTMF_AUTO   (3 << 16)
 

AUTO switch between rfc2833 and in-band DTMF

Definition at line 533 of file chan_sip.c.

Referenced by dtmfmode2str(), and handle_common_options().

#define SIP_DTMF_INBAND   (1 << 16)
 

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().

#define SIP_DTMF_INFO   (2 << 16)
 

SIP Info messages

Definition at line 532 of file chan_sip.c.

Referenced by dtmfmode2str(), handle_common_options(), sip_dtmfmode(), and sip_senddigit().

#define SIP_DTMF_RFC2833   (0 << 16)
 

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().

#define SIP_DYNAMIC   (1 << 15)
 

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().

#define SIP_FLAGS_TO_COPY
 

Value:

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().

#define SIP_GOTREFER   (1 << 7)
 

Got a refer?

Definition at line 519 of file chan_sip.c.

Referenced by handle_request_refer(), and sip_set_rtp_peer().

#define SIP_INC_COUNT   (1 << 31)
 

Definition at line 564 of file chan_sip.c.

Referenced by update_call_counter().

#define SIP_INSECURE_INVITE   (1 << 23)
 

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().

#define SIP_INSECURE_PORT   (1 << 22)
 

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().

#define SIP_MAX_HEADERS   64
 

Max amount of SIP headers to read

Definition at line 438 of file chan_sip.c.

Referenced by parse_request().

#define SIP_MAX_LINES   64
 

Max amount of lines in SIP attachment (like SDP)

Definition at line 439 of file chan_sip.c.

Referenced by parse_request().

#define SIP_MAX_PACKET   4096
 

Also from RFC 3261 (2543), should sub headers tho

Definition at line 327 of file chan_sip.c.

#define SIP_NAT   (3 << 18)
 

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().

#define SIP_NAT_ALWAYS   (3 << 18)
 

Definition at line 539 of file chan_sip.c.

Referenced by handle_common_options(), and nat2str().

#define SIP_NAT_NEVER   (0 << 18)
 

No nat support

Definition at line 536 of file chan_sip.c.

Referenced by handle_common_options(), and nat2str().

#define SIP_NAT_RFC3581   (1 << 18)
 

Definition at line 537 of file chan_sip.c.

Referenced by handle_common_options(), nat2str(), and reload_config().

#define SIP_NAT_ROUTE   (2 << 18)
 

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().

#define SIP_NEEDDESTROY   (1 << 1)
 

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().

#define SIP_NEEDREINVITE   (1 << 5)
 

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().

#define SIP_NOVIDEO   (1 << 2)
 

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().

#define SIP_OPT_100REL   (1 << 1)
 

Definition at line 268 of file chan_sip.c.

#define SIP_OPT_EARLY_SESSION   (1 << 3)
 

Definition at line 270 of file chan_sip.c.

#define SIP_OPT_EVENTLIST   (1 << 11)
 

Definition at line 278 of file chan_sip.c.

#define SIP_OPT_GRUU   (1 << 12)
 

Definition at line 279 of file chan_sip.c.

#define SIP_OPT_JOIN   (1 << 4)
 

Definition at line 271 of file chan_sip.c.

#define SIP_OPT_PATH   (1 << 5)
 

Definition at line 272 of file chan_sip.c.

#define SIP_OPT_PRECONDITION   (1 << 7)
 

Definition at line 274 of file chan_sip.c.

#define SIP_OPT_PREF   (1 << 6)
 

Definition at line 273 of file chan_sip.c.

#define SIP_OPT_PRIVACY   (1 << 8)
 

Definition at line 275 of file chan_sip.c.

#define SIP_OPT_REPLACES   (1 << 0)
 

Definition at line 267 of file chan_sip.c.

#define SIP_OPT_SDP_ANAT   (1 << 9)
 

Definition at line 276 of file chan_sip.c.

#define SIP_OPT_SEC_AGREE   (1 << 10)
 

Definition at line 277 of file chan_sip.c.

#define SIP_OPT_TARGET_DIALOG   (1 << 13)
 

Definition at line 280 of file chan_sip.c.

#define SIP_OPT_TIMER   (1 << 2)
 

Definition at line 269 of file chan_sip.c.

#define SIP_OSPAUTH   (3 << 26)
 

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().

#define SIP_OSPAUTH_EXCLUSIVE   (3 << 26)
 

Definition at line 557 of file chan_sip.c.

Referenced by check_auth(), and handle_common_options().

#define SIP_OSPAUTH_GATEWAY   (1 << 26)
 

Definition at line 555 of file chan_sip.c.

Referenced by check_auth(), and handle_common_options().

#define SIP_OSPAUTH_NO   (0 << 26)
 

Definition at line 554 of file chan_sip.c.

Referenced by check_auth().

#define SIP_OSPAUTH_PROXY   (2 << 26)
 

Definition at line 556 of file chan_sip.c.

Referenced by check_auth(), and handle_common_options().

#define SIP_OUTGOING   (1 << 13)
 

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().

#define SIP_PAGE2_IGNOREREGEXPIRE   (1 << 3)
 

Definition at line 575 of file chan_sip.c.

Referenced by build_peer(), destroy_association(), reload_config(), and sip_show_settings().

#define SIP_PAGE2_RT_FROMCONTACT   (1 << 4)
 

Definition at line 576 of file chan_sip.c.

Referenced by build_peer(), destroy_association(), parse_register_contact(), and reg_source_db().

#define SIP_PAGE2_RTAUTOCLEAR   (1 << 2)
 

Definition at line 574 of file chan_sip.c.

Referenced by expire_register(), realtime_peer(), and reload_config().

#define SIP_PAGE2_RTCACHEFRIENDS   (1 << 0)
 

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().

#define SIP_PAGE2_RTUPDATE   (1 << 1)
 

Definition at line 573 of file chan_sip.c.

Referenced by reload_config(), sip_show_settings(), and update_peer().

#define SIP_PENDINGBYE   (1 << 6)
 

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().

#define SIP_PKT_DEBUG   (1 << 0)
 

Debug this packet

Definition at line 579 of file chan_sip.c.

Referenced by sipsock_read().

#define SIP_PKT_WITH_TOTAG   (1 << 1)
 

This packet has a to-tag

Definition at line 580 of file chan_sip.c.

Referenced by find_call(), and handle_request().

#define SIP_PROG_INBAND   (3 << 24)
 

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().

#define SIP_PROG_INBAND_NEVER   (0 << 24)
 

Definition at line 549 of file chan_sip.c.

Referenced by sip_show_settings().

#define SIP_PROG_INBAND_NO   (1 << 24)
 

Definition at line 550 of file chan_sip.c.

Referenced by handle_common_options(), and sip_show_settings().

#define SIP_PROG_INBAND_YES   (2 << 24)
 

Definition at line 551 of file chan_sip.c.

Referenced by handle_common_options().

#define SIP_PROGRESS_SENT   (1 << 4)
 

Have sent 183 message progress

Definition at line 516 of file chan_sip.c.

Referenced by sip_indicate(), and sip_write().

#define SIP_PROMISCREDIR   (1 << 8)
 

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().

#define SIP_REALTIME   (1 << 11)
 

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().

#define SIP_REINVITE   (3 << 20)
 

two bits used

Definition at line 541 of file chan_sip.c.

Referenced by handle_common_options().

#define SIP_REINVITE_UPDATE   (2 << 20)
 

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().

#define SIP_RINGING   (1 << 3)
 

Have sent 180 ringing

Definition at line 515 of file chan_sip.c.

Referenced by sip_indicate().

#define SIP_SELFDESTRUCT   (1 << 14)
 

Definition at line 526 of file chan_sip.c.

Referenced by expire_register(), sip_destroy_peer(), and temp_peer().

#define SIP_SENDRPID   (1 << 30)
 

Definition at line 562 of file chan_sip.c.

Referenced by _sip_show_peer(), handle_common_options(), and initreqprep().

#define SIP_TRUSTRPID   (1 << 9)
 

Trust RPID headers?

Definition at line 521 of file chan_sip.c.

Referenced by _sip_show_peer(), check_user_full(), and handle_common_options().

#define SIP_USECLIENTCODE   (1 << 12)
 

Trust X-ClientCode info message

Definition at line 524 of file chan_sip.c.

Referenced by handle_common_options(), handle_request_info(), and sip_show_settings().

#define SIP_USEREQPHONE   (1 << 10)
 

Add user=phone to numeric URI. Default off

Definition at line 522 of file chan_sip.c.

Referenced by _sip_show_peer(), build_peer(), initreqprep(), reload_config(), and sip_show_settings().

#define SIPDUMPER
 

Definition at line 100 of file chan_sip.c.

#define SUPPORTED   1
 

Define SIP option tags, used in Require: and Supported: headers We need to be aware of these properties in the phones to use the replace: header. We should not do that without knowing that the other end supports it... This is nothing we can configure, we learn by the dialog Supported: header on the REGISTER (peer) or the INVITE (other devices) We are not using many of these today, but will in the future. This is documented in RFC 3261

Definition at line 264 of file chan_sip.c.

#define SUPPORTED_EXTENSIONS   "replaces"
 

SIP Extensions we support.

Definition at line 324 of file chan_sip.c.

#define VIDEO_CODEC_MASK   0x1fc0000
 

Definition at line 93 of file chan_sip.c.


Enumeration Type Documentation

enum domain_mode
 

Enumeration values:
SIP_DOMAIN_AUTO  This domain is auto-configured
SIP_DOMAIN_CONFIG  This domain is from configuration

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 };

enum parse_register_result
 

Enumeration values:
PARSE_REGISTER_FAILED 
PARSE_REGISTER_UPDATE 
PARSE_REGISTER_QUERY 

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 };

enum sip_auth_type
 

Enumeration values:
PROXY_AUTH 
WWW_AUTH 

Definition at line 200 of file chan_sip.c.

00200                    {
00201    PROXY_AUTH,
00202    WWW_AUTH,
00203 };

enum sipmethod
 

Enumeration values:
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 

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;

enum subscriptiontype
 

Enumeration values:
NONE 
TIMEOUT 
XPIDF_XML 
DIALOG_INFO_XML 
CPIM_PIDF_XML 
PIDF_XML 

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 };


Function Documentation

char* __get_header struct sip_request req,
char *  name,
int *  start
[static]
 

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 }

int __sip_ack struct sip_pvt p,
int  seqno,
int  resp,
int  sipmethod
[static]
 

__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 }

int __sip_autodestruct void *  data  )  [static]
 

__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 }

void __sip_destroy struct sip_pvt p,
int  lockowner
[static]
 

__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 }

int __sip_do_register struct sip_registry r  )  [static]
 

__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 }

int __sip_pretend_ack struct sip_pvt p  )  [static]
 

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 }

int __sip_reliable_xmit struct sip_pvt p,
int  seqno,
int  resp,
char *  data,
int  len,
int  fatal,
int  sipmethod
[static]
 

__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 }

int __sip_semi_ack struct sip_pvt p,
int  seqno,
int  resp,
int  sipmethod
[static]
 

__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 }

int __sip_show_channels int  fd,
int  argc,
char *  argv[],
int  subscriptions
[static]
 

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 }

int __sip_xmit struct sip_pvt p,
char *  data,
int  len
[static]
 

__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 }

int __transmit_response struct sip_pvt p,
char *  msg,
struct sip_request req,
int  reliable
[static]
 

__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 }

int _sip_show_peer int  type,
int  fd,
struct mansession s,
struct message m,
int  argc,
char *  argv[]
[static]
 

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 }

int _sip_show_peers int  fd,
int *  total,
struct mansession s,
struct message m,
int  argc,
char *  argv[]
[static]
 

_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(&regexbuf, 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(&regexbuf, 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(&regexbuf);
07561 
07562    if (total)
07563       *total = total_peers;
07564    
07565 
07566    return RESULT_SUCCESS;
07567 #undef FORMAT
07568 #undef FORMAT2
07569 }

int add_blank_header struct sip_request req  )  [static]
 

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 }

void add_codec_to_sdp const struct sip_pvt p,
int  codec,
int  sample_rate,
char **  m_buf,
size_t *  m_size,
char **  a_buf,
size_t *  a_size,
int  debug
[static]
 

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 }

int add_digit struct sip_request req,
char  digit
[static]
 

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 }

int add_header struct sip_request req,
const char *  var,
const char *  value
[static]
 

add_header: Add header to SIP message

Definition at line 3664 of file chan_sip.c.

References aliases, ast_log(), sip_request::data, sip_request::header, sip_request::headers, sip_request::len, sip_request::lines, LOG_WARNING, cfalias::shortname, and var.

Referenced by __transmit_response(), add_digit(), add_header_contentLength(), add_route(), add_sdp(), add_text(), add_vidupdate(), append_date(), copy_all_header(), copy_header(), copy_via_headers(), initreqprep(), reqprep(), respprep(), sip_notify(), transmit_audit_endpoint(), transmit_connect_with_sdp(), transmit_connection_del(), transmit_connection_del_w_params(), transmit_invite(), 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_with_auth(), transmit_response_with_allow(), transmit_response_with_auth(), transmit_response_with_unsupported(), and transmit_state_notify().

03665 {
03666    int x = 0;
03667 
03668    if (req->headers == SIP_MAX_HEADERS) {
03669       ast_log(LOG_WARNING, "Out of SIP header space\n");
03670       return -1;
03671    }
03672 
03673    if (req->lines) {
03674       ast_log(LOG_WARNING, "Can't add more headers when lines have been added\n");
03675       return -1;
03676    }
03677 
03678    if (req->len >= sizeof(req->data) - 4) {
03679       ast_log(LOG_WARNING, "Out of space, can't add anymore (%s:%s)\n", var, value);
03680       return -1;
03681    }
03682 
03683    req->header[req->headers] = req->data + req->len;
03684 
03685    if (compactheaders) {
03686       for (x = 0; x < (sizeof(aliases) / sizeof(aliases[0])); x++)
03687          if (!strcasecmp(aliases[x].fullname, var))
03688             var = aliases[x].shortname;
03689    }
03690 
03691    snprintf(req->header[req->headers], sizeof(req->data) - req->len - 4, "%s: %s\r\n", var, value);
03692    req->len += strlen(req->header[req->headers]);
03693    req->headers++;
03694 
03695    return 0;   
03696 }

int add_header_contentLength struct sip_request req,
int  len
[static]
 

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 }

int add_line struct sip_request req,
const char *  line
[static]
 

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 }

void add_noncodec_to_sdp const struct sip_pvt p,
int  format,
int  sample_rate,
char **  m_buf,
size_t *  m_size,
char **  a_buf,
size_t *  a_size,
int  debug
[static]
 

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 }

struct sip_auth * add_realm_authentication struct sip_auth authlist,
char *  configuration,
int  lineno
[static]
 

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 }

void add_route struct sip_request req,
struct sip_route route
[static]
 

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 }

int add_sdp struct sip_request resp,
struct sip_pvt p
[static]
 

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 }

int add_sip_domain const char *  domain,
const enum domain_mode  mode,
const char *  context
[static]
 

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 }

int add_text struct sip_request req,
const char *  text
[static]
 

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 }

int add_vidupdate struct sip_request req  )  [static]
 

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 }

void append_date struct sip_request req  )  [static]
 

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 }

int append_history struct sip_pvt p,
const char *  event,
const char *  data
[static]
 

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 }

AST_LIST_HEAD_STATIC domain_list  ,
domain 
[static]
 

The SIP domain list

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  )  [static]
 

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 }

int ast_sip_ouraddrfor struct in_addr *  them,
struct in_addr *  us
[static]
 

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 }

int attempt_transfer struct sip_pvt p1,
struct sip_pvt p2
[static]
 

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 }

int auto_congest void *  nothing  )  [static]
 

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 }

void build_callid char *  callid,
int  len,
struct in_addr  ourip,
char *  fromdomain
[static]
 

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 }

void build_contact struct sip_pvt p  )  [static]
 

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 }

struct sip_peer * build_peer const char *  name,
struct ast_variable v,
int  realtime
[static]
 

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 *)&regseconds) != 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 }

int build_reply_digest struct sip_pvt p,
int  method,
char *  digest,
int  digest_len
[static]
 

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 }

void build_route struct sip_pvt p,
struct sip_request req,
int  backwards
[static]
 

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 }

void build_rpid struct sip_pvt p  )  [static]
 

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 }

struct sip_user * build_user const char *  name,
struct ast_variable v,
int  realtime
[static]
 

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 }

void build_via struct sip_pvt p,
char *  buf,
int  len
[static]
 

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 }

int cb_extensionstate char *  context,
char *  exten,
int  state,
void *  data
[static]
 

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 }

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
[static]
 

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 }

void check_pendings struct sip_pvt p  )  [static]
 

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 }

int check_sip_domain const char *  domain,
char *  context,
size_t  len
[static]
 

check_sip_domain: Check if domain part of uri is local to our server

Definition at line 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 }

int check_user struct sip_pvt p,
struct sip_request req,
int  sipmethod,
char *  uri,
int  reliable,
struct sockaddr_in *  sin,
int  ignore
[static]
 

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 }

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
[static]
 

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 }

int check_via struct sip_pvt p,
struct sip_request req
[static]
 

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 }

int clear_realm_authentication struct sip_auth authlist  )  [static]
 

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 }

void clear_sip_domains void   )  [static]
 

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 }

char* complete_sip_debug_peer char *  line,
char *  word,
int  pos,
int  state
[static]
 

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 }

char* complete_sip_peer char *  word,
int  state,
int  flags2
[static]
 

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 }

char* complete_sip_prune_realtime_peer char *  line,
char *  word,
int  pos,
int  state
[static]
 

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 }

char* complete_sip_prune_realtime_user char *  line,
char *  word,
int  pos,
int  state
[static]
 

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 }

char* complete_sip_show_peer char *  line,
char *  word,
int  pos,
int  state
[static]
 

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 }

char* complete_sip_show_user char *  line,
char *  word,
int  pos,
int  state
[static]
 

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 }

char* complete_sip_user char *  word,
int  state,
int  flags2
[static]
 

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 }

char* complete_sipch char *  line,
char *  word,
int  pos,
int  state
[static]
 

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 }

char* complete_sipnotify char *  line,
char *  word,
int  pos,
int  state
[static]
 

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 }

int copy_all_header struct sip_request req,
struct sip_request orig,
char *  field
[static]
 

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 }

int copy_header struct sip_request req,
struct sip_request orig,
char *  field
[static]
 

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 }

void copy_request struct sip_request dst,
struct sip_request src
[static]
 

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 }

int copy_via_headers struct sip_pvt p,
struct sip_request req,
struct sip_request orig,
char *  field
[static]
 

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 }

int create_addr struct sip_pvt dialog,
char *  opeer
[static]
 

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 }

int create_addr_from_peer struct sip_pvt r,
struct sip_peer peer
[static]
 

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 }

char* description void   ) 
 

Provides a description of the module.

Returns:
a short description of your module

Definition at line 13240 of file chan_sip.c.

13241 {
13242    return (char *) desc;
13243 }

void destroy_association struct sip_peer peer  )  [static]
 

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 }

int determine_firstline_parts struct sip_request req  )  [static]
 

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 }

void* do_monitor void *  data  )  [static]
 

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 }

int do_proxy_auth struct sip_pvt p,
struct sip_request req,
char *  header,
char *  respheader,
int  sipmethod,
int  init
[static]
 

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 }

int do_register_auth struct sip_pvt p,
struct sip_request req,
char *  header,
char *  respheader
[static]
 

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 }

const char* domain_mode_to_text const enum domain_mode  mode  )  [static]
 

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 }

const char* dtmfmode2str int  mode  )  [static]
 

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 }

int expire_register void *  data  )  [static]
 

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 }

void extract_uri struct sip_pvt p,
struct sip_request req
[static]
 

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 }

char* find_alias const char *  name,
char *  _default
[static]
 

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 }

struct sip_pvt* find_call struct sip_request req,
struct sockaddr_in *  sin,
const int  intended_method
[static]
 

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 }

struct sip_peer* find_peer const char *  peer,
struct sockaddr_in *  sin,
int  realtime
[static]
 

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 }

struct sip_auth * find_realm_authentication struct sip_auth authlist,
char *  realm
[static]
 

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 }

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

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 }

const struct cfsubscription_types * find_subscription_type enum subscriptiontype  subtype  )  [static]
 

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 }

struct sip_user* find_user const char *  name,
int  realtime
[static]
 

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 }

void free_old_route struct sip_route route  )  [static]
 

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 }

char* func_check_sipdomain struct ast_channel chan,
char *  cmd,
char *  data,
char *  buf,
size_t  len
[static]
 

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 }

char* func_header_read struct ast_channel chan,
char *  cmd,
char *  data,
char *  buf,
size_t  len
[static]
 

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 }

char* function_sipchaninfo_read struct ast_channel chan,
char *  cmd,
char *  data,
char *  buf,
size_t  len
[static]
 

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 }

char* function_sippeer struct ast_channel chan,
char *  cmd,
char *  data,
char *  buf,
size_t  len
[static]
 

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 }

int get_also_info struct sip_pvt p,
struct sip_request oreq
[static]
 

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 }

char* get_calleridname char *  input,
char *  output,
size_t  outputsize
[static]
 

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 }

int get_destination struct sip_pvt p,
struct sip_request oreq
[static]
 

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 }

char * get_header struct sip_request req,
char *  name
[static]
 

get_header: Get header from SIP request ---

Definition at line 2928 of file chan_sip.c.

References __get_header(), and name.

Referenced by __transmit_response(), build_route(), check_auth(), check_user_full(), check_via(), copy_header(), extract_uri(), find_call(), func_header_read(), get_also_info(), get_destination(), get_rdnis(), get_refer_info(), gettag(), handle_request(), handle_request_bye(), handle_request_info(), handle_request_invite(), handle_request_register(), handle_request_subscribe(), handle_response(), handle_response_invite(), handle_response_register(), parse_moved_contact(), parse_ok_contact(), parse_register_contact(), process_sdp(), receive_message(), register_verify(), reply_digest(), reqprep(), respprep(), send_request(), send_response(), sip_getheader(), sip_sipredirect(), sipsock_read(), transmit_refer(), transmit_response_with_auth(), transmit_response_with_sdp(), and transmit_state_notify().

02929 {
02930    int start = 0;
02931    return __get_header(req, name, &start);
02932 }

char* get_in_brackets char *  tmp  )  [static]
 

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 }

int get_msg_text char *  buf,
int  len,
struct sip_request req
[static]
 

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 }

int get_rdnis struct sip_pvt p,
struct sip_request oreq
[static]
 

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 }

int get_refer_info struct sip_pvt sip_pvt,
struct sip_request outgoing_req
[static]
 

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 }

int get_rpid_num char *  input,
char *  output,
int  maxlen
[static]
 

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 }

char* get_sdp struct sip_request req,
char *  name
[static]
 

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 }

char* get_sdp_by_line char *  line,
char *  name,
int  nameLen
[static]
 

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 }

char* get_sdp_iterate int *  iterator,
struct sip_request req,
char *  name
[static]
 

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 }

struct sip_pvt* get_sip_pvt_byid_locked char *  callid  )  [static]
 

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 }

char * gettag struct sip_request req,
char *  header,
char *  tagbuf,
int  tagbufsize
[static]
 

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 }

int handle_common_options struct ast_flags flags,
struct ast_flags mask,
struct ast_variable v
[static]
 

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 }

int handle_request struct sip_pvt p,
struct sip_request req,
struct sockaddr_in *  sin,
int *  recount,
int *  nounlock
[static]
 

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 }

int handle_request_bye struct sip_pvt p,
struct sip_request req,
int  debug,
int  ignore
[static]
 

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 }

int handle_request_cancel struct sip_pvt p,
struct sip_request req,
int  debug,
int  ignore
[static]
 

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 }

void handle_request_info struct sip_pvt p,
struct sip_request req
[static]
 

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 }

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
[static]
 

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 }

int handle_request_message struct sip_pvt p,
struct sip_request req,
int  debug,
int  ignore
[static]
 

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 }

int handle_request_options struct sip_pvt p,
struct sip_request req,
int  debug
[static]
 

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 }

int handle_request_refer struct sip_pvt p,
struct sip_request req,
int  debug,
int  ignore,
int  seqno,
int *  nounlock
[static]
 

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 }

int handle_request_register struct sip_pvt p,
struct sip_request req,
int  debug,
int  ignore,
struct sockaddr_in *  sin,
char *  e
[static]
 

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 }

int handle_request_subscribe struct sip_pvt p,
struct sip_request req,
int  debug,
int  ignore,
struct sockaddr_in *  sin,
int  seqno,
char *  e
[static]
 

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 }

void handle_response struct sip_pvt p,
int  resp,
char *  rest,
struct sip_request req,
int  ignore,
int  seqno
[static]
 

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 }

void handle_response_invite struct sip_pvt p,
int  resp,
char *  rest,
struct sip_request req,
int  ignore,
int  seqno
[static]
 

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 }

int handle_response_peerpoke struct sip_pvt p,
int  resp,
char *  rest,
struct sip_request req,
int  ignore,
int  seqno,
int  sipmethod
[static]
 

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 }

int handle_response_register struct sip_pvt p,
int  resp,
char *  rest,
struct sip_request req,
int  ignore,
int  seqno
[static]
 

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 }

char* hangup_cause2sip int  cause  )  [static]
 

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 }

int hangup_sip2cause int  cause  )  [static]
 

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 }

int init_req struct sip_request req,
int  sipmethod,
char *  recip
[static]
 

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 }

int init_resp struct sip_request req,
char *  resp,
struct sip_request orig
[static]
 

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 }

void initreqprep struct sip_request req,
struct sip_pvt p,
int  sipmethod
[static]
 

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 }

const char* insecure2str int  port,
int  invite
[static]
 

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 }

char* key void   ) 
 

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;
 }

Returns:
ASTERISK_GPL_KEY

Definition at line 13235 of file chan_sip.c.

13236 {
13237    return ASTERISK_GPL_KEY;
13238 }

void list_route struct sip_route route  )  [static]
 

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 }

int load_module void   ) 
 

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.

Returns:
int Always 0.

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(&regl); /* 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 }

int lws2sws char *  msgbuf,
int  len
[static]
 

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 }

void make_our_tag char *  tagbuf,
size_t  len
[static]
 

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 }

int manager_sip_show_peer struct mansession s,
struct message m
[static]
 

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 }

int manager_sip_show_peers struct mansession s,
struct message m
[static]
 

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 }

char* nat2str int  nat  )  [static]
 

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 }

void parse_copy struct sip_request dst,
struct sip_request src
[static]
 

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 }

void parse_moved_contact struct sip_pvt p,
struct sip_request req
[static]
 

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 }

int parse_ok_contact struct sip_pvt pvt,
struct sip_request req
[static]
 

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 }

enum parse_register_result parse_register_contact struct sip_pvt pvt,
struct sip_peer p,
struct sip_request req
[static]
 

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 }

void parse_request struct sip_request req  )  [static]
 

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 }

unsigned int parse_sip_options struct sip_pvt pvt,
char *  supported
 

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 }

int peer_status struct sip_peer peer,
char *  status,
int  statuslen
[static]
 

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 }

void print_codec_to_cli int  fd,
struct ast_codec_pref pref
[static]
 

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 }

void print_group int  fd,
unsigned int  group,
int  crlf
[static]
 

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 }

int process_sdp struct sip_pvt p,
struct sip_request req
[static]
 

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 }

struct sip_peer* realtime_peer const char *  peername,
struct sockaddr_in *  sin
[static]
 

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 }

void realtime_update_peer const char *  peername,
struct sockaddr_in *  sin,
const char *  username,
const char *  fullcontact,
int  expirey
[static]
 

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 }

struct sip_user* realtime_user const char *  username  )  [static]
 

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 }

void receive_message struct sip_pvt p,
struct sip_request req
[static]
 

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 }

void reg_source_db struct sip_peer peer  )  [static]
 

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 }

void register_peer_exten struct sip_peer peer,
int  onoff
[static]
 

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 }

int register_verify struct sip_pvt p,
struct sockaddr_in *  sin,
struct sip_request req,
char *  uri,
int  ignore
[static]
 

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 }

char* regstate2str int  regstate  )  [static]
 

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 }

int reload void   ) 
 

Reload stuff.

This function is where any reload routines take place. Re-read config files, change signalling, whatever is appropriate on a reload.

Returns:
The return value is not used.

Definition at line 13047 of file chan_sip.c.

References sip_reload().

13048 {
13049    return sip_reload(0, 0, NULL);
13050 }

int reload_config void   )  [static]
 

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 }

int reply_digest struct sip_pvt p,
struct sip_request req,
char *  header,
int  sipmethod,
char *  digest,
int  digest_len
[static]
 

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 }

int reqprep struct sip_request req,
struct sip_pvt p,
int  sipmethod,
int  seqno,
int  newbranch
[static]
 

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 }

int respprep struct sip_request resp,
struct sip_pvt p,
char *  msg,
struct sip_request req
[static]
 

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 }

int restart_monitor void   )  [static]
 

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 }

int retrans_pkt void *  data  )  [static]
 

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 }

void sdpLineNum_iterator_init int *  iterator  )  [static]
 

Definition at line 2864 of file chan_sip.c.

Referenced by process_sdp().

02865 {
02866    *iterator = 0;
02867 }

int send_request struct sip_pvt p,
struct sip_request req,
int  reliable,
int  seqno
[static]
 

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 }

int send_response struct sip_pvt p,
struct sip_request req,
int  reliable,
int  seqno
[static]
 

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 }

void set_destination struct sip_pvt p,
char *  uri
[static]
 

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 }

int sip_addheader struct ast_channel chan,
void *  data
[static]
 

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 }

int sip_addrcmp char *  name,
struct sockaddr_in *  sin
[static]
 

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 }

struct sip_pvt* sip_alloc char *  callid,
struct sockaddr_in *  sin,
int  useglobal_nat,
const int  intended_method
[static]
 

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 }

int sip_answer struct ast_channel ast  )  [static]
 

sip_answer: Answer SIP call , send 200 OK on Invite Part of PBX interface

Definition at line 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 }

int sip_call struct ast_channel ast,
char *  dest,
int  timeout
[static]
 

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 }

int sip_cancel_destroy struct sip_pvt p  )  [static]
 

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 }

int sip_debug_test_addr struct sockaddr_in *  addr  )  [inline, static]
 

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 }

int sip_debug_test_pvt struct sip_pvt p  )  [inline, static]
 

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 }

void sip_destroy struct sip_pvt p  )  [static]
 

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 }

void sip_destroy_peer struct sip_peer peer  )  [static]
 

sip_destroy_peer: Destroy peer object from memory

Definition at line 1629 of file chan_sip.c.

References apeerobjs, ast_dnsmgr_release(), ast_free_ha(), ast_sched_del(), ast_test_flag, ast_variables_destroy(), sip_peer::auth, sip_peer::call, sip_peer::chanvars, clear_realm_authentication(), sip_peer::dnsmgr, sip_peer::expire, free, sip_peer::ha, sip_peer::pokeexpire, register_peer_exten(), rpeerobjs, sched, sip_destroy(), SIP_REALTIME, SIP_SELFDESTRUCT, and speerobjs.

Referenced by _sip_show_peer(), build_peer(), check_user_full(), create_addr(), do_monitor(), expire_register(), function_sippeer(), register_verify(), reload_config(), sip_devicestate(), sip_do_debug_peer(), sip_prune_realtime(), unload_module(), and update_call_counter().

01630 {
01631    /* Delete it, it needs to disappear */
01632    if (peer->call)
01633       sip_destroy(peer->call);
01634    if (peer->chanvars) {
01635       ast_variables_destroy(peer->chanvars);
01636       peer->chanvars = NULL;
01637    }
01638    if (peer->expire > -1)
01639       ast_sched_del(sched, peer->expire);
01640    if (peer->pokeexpire > -1)
01641       ast_sched_del(sched, peer->pokeexpire);
01642    register_peer_exten(peer, 0);
01643    ast_free_ha(peer->ha);
01644    if (ast_test_flag(peer, SIP_SELFDESTRUCT))
01645       apeerobjs--;
01646    else if (ast_test_flag(peer, SIP_REALTIME))
01647       rpeerobjs--;
01648    else
01649       speerobjs--;
01650    clear_realm_authentication(peer->auth);
01651    peer->auth = (struct sip_auth *) NULL;
01652    if (peer->dnsmgr)
01653       ast_dnsmgr_release(peer->dnsmgr);
01654    free(peer);
01655 }

void sip_destroy_user struct sip_user user  )  [static]
 

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 }

int sip_devicestate void *  data  )  [static]
 

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 }

int sip_do_debug int  fd,
int  argc,
char *  argv[]
[static]
 

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 }

int sip_do_debug_ip int  fd,
int  argc,
char *  argv[]
[static]
 

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 }

int sip_do_debug_peer int  fd,
int  argc,
char *  argv[]
[static]
 

sip_do_debug_peer: Turn on SIP debugging with peer mask

Definition at line 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 }

int sip_do_history int  fd,
int  argc,
char *  argv[]
[static]
 

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 }

int sip_do_reload void   )  [static]
 

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(&regl, 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(&regl, 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 }

int sip_dtmfmode struct ast_channel chan,
void *  data
[static]
 

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 }

void sip_dump_history struct sip_pvt dialog  )  [static]
 

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 }

int sip_fixup struct ast_channel oldchan,
struct ast_channel newchan
[static]
 

sip_fixup: Fix up a channel: If a channel is consumed, this is called. Basically update any ->owner links ----

Definition at line 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 }

int sip_get_codec struct ast_channel chan  )  [static]
 

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 }

struct ast_rtp* sip_get_rtp_peer struct ast_channel chan  )  [static]
 

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 }

struct ast_rtp* sip_get_vrtp_peer struct ast_channel chan  )  [static]
 

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 }

int sip_getheader struct ast_channel chan,
void *  data
[static]
 

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 }

int sip_hangup struct ast_channel ast  )  [static]
 

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 }

int sip_indicate struct ast_channel ast,
int  condition
[static]
 

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 }

struct ast_channel* sip_new struct sip_pvt i,
int  state,
char *  title
[static]
 

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 }

int sip_no_debug int  fd,
int  argc,
char *  argv[]
[static]
 

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 }

int sip_no_history int  fd,
int  argc,
char *  argv[]
[static]
 

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 }

int sip_notify int  fd,
int  argc,
char *  argv[]
[static]
 

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 }

int sip_park struct ast_channel chan1,
struct ast_channel chan2,
struct sip_request req
[static]
 

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 }

void* sip_park_thread void *  stuff  )  [static]
 

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 }

void sip_poke_all_peers void   )  [static]
 

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 }

int sip_poke_noanswer void *  data  )  [static]
 

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 }

int sip_poke_peer struct sip_peer peer  )  [static]
 

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 }

int sip_poke_peer_s void *  data  )  [static]
 

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 }

int sip_prune_realtime int  fd,
int  argc,
char *  argv[]
[static]
 

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(&regexbuf, 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(&regexbuf, 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(&regexbuf, 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 }

struct ast_frame * sip_read struct ast_channel ast  )  [static]
 

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 }

int sip_reg_timeout void *  data  )  [static]
 

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 }

int sip_register char *  value,
int  lineno
[static]
 

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(&regl, reg);
03258    ASTOBJ_UNREF(reg,sip_registry_destroy);
03259    return 0;
03260 }

void sip_registry_destroy struct sip_registry reg  )  [static]
 

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 }

int sip_reload int  fd,
int  argc,
char *  argv[]
[static]
 

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 }

struct ast_channel * sip_request_call const char *  type,
int  format,
void *  data,
int *  cause
[static]
 

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 }

int sip_reregister void *  data  )  [static]
 

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 }

struct ast_frame* sip_rtp_read struct ast_channel ast,
struct sip_pvt p
[static]
 

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 }

int sip_scheddestroy struct sip_pvt p,
int  ms
[static]
 

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 }

void sip_send_all_registers void   )  [static]
 

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(&regl, 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 }

int sip_send_mwi_to_peer struct sip_peer peer  )  [static]
 

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 }

int sip_senddigit struct ast_channel ast,
char  digit
[static]
 

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 }

int sip_sendtext struct ast_channel ast,
const char *  text
[static]
 

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 }

int sip_set_rtp_peer struct ast_channel chan,
struct ast_rtp rtp,
struct ast_rtp vrtp,
int  codecs,
int  nat_active
[static]
 

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 }

int sip_show_channel int  fd,
int  argc,
char *  argv[]
[static]
 

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 }

int sip_show_channels int  fd,
int  argc,
char *  argv[]
[static]
 

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 }

int sip_show_domains int  fd,
int  argc,
char *  argv[]
[static]
 

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 }

int sip_show_history int  fd,
int  argc,
char *  argv[]
[static]
 

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 }

int sip_show_inuse int  fd,
int  argc,
char *  argv[]
[static]
 

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 }

int sip_show_objects int  fd,
int  argc,
char *  argv[]
[static]
 

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), &regl);
07583    return RESULT_SUCCESS;
07584 }

int sip_show_peer int  fd,
int  argc,
char *  argv[]
[static]
 

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 }

int sip_show_peers int  fd,
int  argc,
char *  argv[]
[static]
 

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 }

int sip_show_registry int  fd,
int  argc,
char *  argv[]
[static]
 

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(&regl, 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 }

int sip_show_settings int  fd,
int  argc,
char *  argv[]
[static]
 

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 }

int sip_show_subscriptions int  fd,
int  argc,
char *  argv[]
[static]
 

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 }

int sip_show_user int  fd,
int  argc,
char *  argv[]
[static]
 

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 }

int sip_show_users int  fd,
int  argc,
char *  argv[]
[static]
 

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(&regexbuf, 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(&regexbuf, 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(&regexbuf);
07396 
07397    return RESULT_SUCCESS;
07398 #undef FORMAT
07399 }

int sip_sipredirect struct sip_pvt p,
const char *  dest
[static]
 

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 }

int sip_transfer struct ast_channel ast,
const char *  dest
[static]
 

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 }

int sip_write struct ast_channel ast,
struct ast_frame frame
[static]
 

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 }

int sipsock_read int *  id,
int  fd,
short  events,
void *  ignore
[static]
 

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 }

const char* subscription_type2str enum subscriptiontype  subtype  )  [static]
 

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 }

struct sip_peer * temp_peer const char *  name  )  [static]
 

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 }

force_inline int thread_safe_rand void   )  [static]
 

Thread-safe random number generator.

Returns:
a random number
This function uses a mutex lock to guarantee that no two threads will receive the same random number.

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 }

int transmit_info_with_digit struct sip_pvt p,
char  digit
[static]
 

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 }

int transmit_info_with_vidupdate struct sip_pvt p  )  [static]
 

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 }

int transmit_invite struct sip_pvt p,
int  sipmethod,
int  sdp,
int  init
[static]
 

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 }

int transmit_message_with_text struct sip_pvt p,
const char *  text
[static]
 

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 }

int transmit_notify_with_mwi struct sip_pvt p,
int  newmsgs,
int  oldmsgs,
char *  vmexten
[static]
 

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 }

int transmit_notify_with_sipfrag struct sip_pvt p,
int  cseq
[static]
 

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 }

int transmit_refer struct sip_pvt p,
const char *  dest
[static]
 

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 }

int transmit_register struct sip_registry r,
int  sipmethod,
char *  auth,
char *  authheader
[static]
 

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 }

int transmit_reinvite_with_sdp struct sip_pvt p  )  [static]
 

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 }

int transmit_request struct sip_pvt p,
int  sipmethod,
int  seqno,
int  reliable,
int  newbranch
[static]
 

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 }

int transmit_request_with_auth struct sip_pvt p,
int  sipmethod,
int  seqno,
int  reliable,
int  newbranch
[static]
 

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 }

int transmit_response struct sip_pvt p,
char *  msg,
struct sip_request req
[static]
 

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 }

int transmit_response_reliable struct sip_pvt p,
char *  msg,
struct sip_request req,
int  fatal
[static]
 

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 }

int transmit_response_with_allow struct sip_pvt p,
char *  msg,
struct sip_request req,
int  reliable
[static]
 

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 }

int transmit_response_with_auth struct sip_pvt p,
char *  msg,
struct sip_request req,
char *  rand,
int  reliable,
char *  header,
int  stale
[static]
 

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 }

int transmit_response_with_date struct sip_pvt p,
char *  msg,
struct sip_request req
[static]
 

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 }

int transmit_response_with_sdp struct sip_pvt p,
char *  msg,
struct sip_request req,
int  retrans
[static]
 

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 }

int transmit_response_with_unsupported struct sip_pvt p,
char *  msg,
struct sip_request req,
char *  unsupported
[static]
 

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 }

int transmit_sip_request struct sip_pvt p,
struct sip_request req
[static]
 

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 }

int transmit_state_notify struct sip_pvt p,
int  state,
int  full,
int  substate
[static]
 

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 }

int unload_module void   ) 
 

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).

Returns:
Zero on success, or non-zero on error.

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(&regl, sip_registry_destroy);
13220    ASTOBJ_CONTAINER_DESTROY(&regl);
13221 
13222    clear_realm_authentication(authl);
13223    clear_sip_domains();
13224    close(sipsock);
13225    sched_context_destroy(sched);
13226       
13227    return 0;
13228 }

int update_call_counter struct sip_pvt fup,
int  event
[static]
 

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 }

void update_peer struct sip_peer p,
int  expiry
[static]
 

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 }

int usecount void   ) 
 

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.

Returns:
The module's usecount.

Definition at line 13230 of file chan_sip.c.

13231 {
13232    return usecnt;
13233 }


Variable Documentation

struct in_addr __ourip [static]
 

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().

const struct cfalias aliases[] [static]
 

Structure for conversion between compressed SIP and "normal" SIP.

Referenced by add_header(), and find_alias().

int allow_external_domains
 

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().

int apeerobjs = 0 [static]
 

Definition at line 377 of file chan_sip.c.

Referenced by sip_destroy_peer(), sip_show_objects(), and temp_peer().

char* app_dtmfmode = "SIPDtmfMode" [static]
 

Definition at line 12730 of file chan_sip.c.

Referenced by load_module(), and unload_module().

char* app_sipaddheader = "SIPAddHeader" [static]
 

Definition at line 12732 of file chan_sip.c.

Referenced by load_module(), and unload_module().

char* app_sipgetheader = "SIPGetHeader" [static]
 

Definition at line 12744 of file chan_sip.c.

Referenced by load_module(), and unload_module().

struct sip_auth* authl [static]
 

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().

int autocreatepeer = 0 [static]
 

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().

struct sockaddr_in bindaddr = { 0, } [static]
 

Definition at line 867 of file chan_sip.c.

Referenced by ast_sip_ouraddrfor(), reload_config(), sip_alloc(), sip_show_settings(), and transmit_register().

int callevents = 0 [static]
 

Definition at line 902 of file chan_sip.c.

Referenced by process_sdp(), reload_config(), and sip_show_settings().

const char channeltype[] = "SIP" [static]
 

Definition at line 143 of file chan_sip.c.

Referenced by load_module(), register_peer_exten(), and reload_config().

struct ast_custom_function checksipdomain_function [static]
 

Definition at line 9199 of file chan_sip.c.

Referenced by load_module(), and unload_module().

int compactheaders = 0 [static]
 

send compact sip headers

Definition at line 422 of file chan_sip.c.

Referenced by reload_config(), and sip_show_settings().

const char config[] = "sip.conf" [static]
 

Definition at line 144 of file chan_sip.c.

Referenced by reload_config().

char debug_usage[] [static]
 

Definition at line 9098 of file chan_sip.c.

struct sockaddr_in debugaddr [static]
 

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().

char default_callerid[AST_MAX_EXTENSION] = DEFAULT_CALLERID [static]
 

Definition at line 341 of file chan_sip.c.

Referenced by reload_config(), and sip_show_settings().

char default_context[AST_MAX_CONTEXT] = DEFAULT_CONTEXT [static]
 

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().

int default_expiry = DEFAULT_DEFAULT_EXPIRY [static]
 

Definition at line 119 of file chan_sip.c.

Referenced by reload_config(), sip_send_all_registers(), sip_show_settings(), and transmit_register().

char default_fromdomain[AST_MAX_EXTENSION] = "" [static]
 

Definition at line 343 of file chan_sip.c.

Referenced by reload_config(), sip_alloc(), sip_show_settings(), and transmit_register().

char default_language[MAX_LANGUAGE] = "" [static]
 

Definition at line 338 of file chan_sip.c.

Referenced by build_peer(), build_user(), reload_config(), sip_show_settings(), and temp_peer().

char default_notifymime[AST_MAX_EXTENSION] = DEFAULT_NOTIFYMIME [static]
 

Definition at line 346 of file chan_sip.c.

Referenced by reload_config(), sip_show_settings(), and transmit_notify_with_mwi().

int default_qualify = 0 [static]
 

Default Qualify= setting

Definition at line 350 of file chan_sip.c.

Referenced by reload_config(), and sip_show_settings().

char default_subscribecontext[AST_MAX_CONTEXT] [static]
 

Definition at line 333 of file chan_sip.c.

Referenced by build_peer(), reload_config(), and temp_peer().

char default_useragent[AST_MAX_EXTENSION] = DEFAULT_USERAGENT [static]
 

Definition at line 329 of file chan_sip.c.

Referenced by initreqprep(), reload_config(), reqprep(), respprep(), sip_show_settings(), and transmit_register().

const char desc[] = "Session Initiation Protocol (SIP)" [static]
 

Definition at line 142 of file chan_sip.c.

char* descrip_dtmfmode = "SIPDtmfMode(inband|info|rfc2833): Changes the dtmfmode for a SIP call\n" [static]
 

Definition at line 12729 of file chan_sip.c.

Referenced by load_module().

char* descrip_sipaddheader [static]
 

Definition at line 12736 of file chan_sip.c.

Referenced by load_module().

char* descrip_sipgetheader [static]
 

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().

int dumphistory = 0 [static]
 

Dump history to verbose before destroying SIP dialog

Definition at line 425 of file chan_sip.c.

Referenced by reload_config().

int expiry = DEFAULT_EXPIRY [static]
 

Definition at line 433 of file chan_sip.c.

Referenced by parse_register_contact(), reg_source_db(), reload_config(), and update_peer().

time_t externexpire = 0 [static]
 

Definition at line 870 of file chan_sip.c.

Referenced by ast_sip_ouraddrfor(), and reload_config().

char externhost[MAXHOSTNAMELEN] = "" [static]
 

Definition at line 869 of file chan_sip.c.

Referenced by ast_sip_ouraddrfor(), and reload_config().

struct sockaddr_in externip [static]
 

Definition at line 868 of file chan_sip.c.

Referenced by ast_sip_ouraddrfor(), and reload_config().

int externrefresh = 10 [static]
 

Definition at line 871 of file chan_sip.c.

Referenced by reload_config().

int global_allowguest = 1 [static]
 

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().

int global_capability = AST_FORMAT_ULAW | AST_FORMAT_ALAW | AST_FORMAT_GSM | AST_FORMAT_H263 [static]
 

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().

struct ast_flags global_flags = {0} [static]
 

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().

struct ast_flags global_flags_page2 = {0} [static]
 

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().

char global_musicclass[MAX_MUSICCLASS] = "" [static]
 

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().

int global_mwitime = DEFAULT_MWITIME [static]
 

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().

int global_notifyringing = 1 [static]
 

Send notifications on ringing

Definition at line 348 of file chan_sip.c.

Referenced by reload_config(), and sip_show_settings().

char global_realm[MAXHOSTNAMELEN] = DEFAULT_REALM [static]
 

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().

int global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT [static]
 

Definition at line 369 of file chan_sip.c.

Referenced by reload_config(), sip_show_settings(), and transmit_register().

int global_regattempts_max = 0 [static]
 

Definition at line 370 of file chan_sip.c.

Referenced by handle_response_register(), reload_config(), sip_reg_timeout(), and sip_show_settings().

int global_rtautoclear = 120 [static]
 

Definition at line 582 of file chan_sip.c.

Referenced by realtime_peer(), reload_config(), and sip_show_settings().

int global_rtpholdtimeout = 0 [static]
 

Definition at line 365 of file chan_sip.c.

Referenced by reload_config(), and sip_show_settings().

int global_rtpkeepalive = 0 [static]
 

Definition at line 367 of file chan_sip.c.

Referenced by reload_config().

int global_rtptimeout = 0 [static]
 

Definition at line 363 of file chan_sip.c.

Referenced by reload_config(), and sip_show_settings().

char global_vmexten[AST_MAX_EXTENSION] = DEFAULT_VMEXTEN [static]
 

Definition at line 336 of file chan_sip.c.

Referenced by build_peer(), reload_config(), sip_show_settings(), and transmit_notify_with_mwi().

char history_usage[] [static]
 

Initial value:

 
"Usage: sip history\n"
"       Enables recording of SIP dialog history for debugging purposes.\n"
"Use 'sip show history' to view the history of a call number.\n"

Definition at line 9115 of file chan_sip.c.

struct sip_pvt * iflist [static]
 

sip_pvt: PVT structures are used for each SIP conversation, ie. a call

struct io_context* io [static]
 

Definition at line 436 of file chan_sip.c.

Referenced by do_monitor(), load_module(), and sip_alloc().

struct ast_ha* localaddr [static]
 

Definition at line 872 of file chan_sip.c.

Referenced by ast_sip_ouraddrfor(), reload_config(), and unload_module().

char mandescr_show_peer[] [static]
 

Definition at line 7819 of file chan_sip.c.

Referenced by load_module().

char mandescr_show_peers[] [static]
 

Initial value:

 
"Description: Lists SIP peers in text format with details on current status.\n"
"Variables: \n"
"  ActionID: <id> Action ID for this transaction. Will be returned.\n"

Definition at line 7401 of file chan_sip.c.

Referenced by load_module().

int max_expiry = DEFAULT_MAX_EXPIRY [static]
 

Definition at line 118 of file chan_sip.c.

Referenced by reload_config(), and sip_show_settings().

pthread_t monitor_thread = AST_PTHREADT_NULL [static]
 

This is the thread for the monitor which checks for input on the channels which are not currently in use.

Definition at line 401 of file chan_sip.c.

Referenced by restart_monitor(), and unload_module().

struct ast_cli_entry my_clis[] [static]
 

Definition at line 13052 of file chan_sip.c.

Referenced by load_module(), and unload_module().

char no_debug_usage[] [static]
 

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.

char no_history_usage[] [static]
 

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.

int noncodeccapability = AST_RTP_DTMF [static]
 

Definition at line 407 of file chan_sip.c.

Referenced by process_sdp().

const char notify_config[] = "sip_notify.conf" [static]
 

Definition at line 145 of file chan_sip.c.

Referenced by reload_config(), and sip_notify().

struct ast_config* notify_types
 

Definition at line 875 of file chan_sip.c.

Referenced by complete_sipnotify(), reload_config(), and sip_notify().

char notify_usage[] [static]
 

Initial value:

"Usage: sip notify <type> <peer> [<peer>...]\n"
"       Send a NOTIFY message to a SIP peer or peers\n"
"       Message types are defined in sip_notify.conf\n"

Definition at line 9047 of file chan_sip.c.

int ourport [static]
 

Definition at line 411 of file chan_sip.c.

Referenced by build_contact(), build_via(), initreqprep(), and reload_config().

struct sockaddr_in outboundproxyip [static]
 

Definition at line 410 of file chan_sip.c.

Referenced by reload_config().

int pedanticsipchecking = 0 [static]
 

Extra checking ? Default off

Definition at line 357 of file chan_sip.c.

Referenced by find_call(), reload_config(), and sip_show_settings().

struct ast_peer_list peerl [static]
 

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().

struct ast_codec_pref prefs [static]
 

Definition at line 444 of file chan_sip.c.

Referenced by reload_config(), and sip_show_settings().

char prune_realtime_usage[] [static]
 

Initial value:

"Usage: sip prune realtime [peer|user] [<name>|all|like <pattern>]\n"
"       Prunes object(s) from the cache.\n"
"       Optional regular expression pattern is used to filter the objects.\n"

Definition at line 9089 of file chan_sip.c.

int recordhistory = 0 [static]
 

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().

char regcontext[AST_MAX_CONTEXT] = "" [static]
 

Context for auto-extensions

Definition at line 430 of file chan_sip.c.

Referenced by register_peer_exten(), reload_config(), and sip_show_settings().

struct ast_register_list regl [static]
 

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().

int regobjs = 0 [static]
 

Definition at line 378 of file chan_sip.c.

Referenced by sip_register(), sip_registry_destroy(), and sip_show_objects().

int relaxdtmf = 0 [static]
 

Definition at line 361 of file chan_sip.c.

Referenced by reload_config(), and sip_show_settings().

int rpeerobjs = 0 [static]
 

Definition at line 376 of file chan_sip.c.

Referenced by build_peer(), sip_destroy_peer(), and sip_show_objects().

int ruserobjs = 0 [static]
 

Definition at line 374 of file chan_sip.c.

Referenced by realtime_user(), sip_destroy_user(), and sip_show_objects().

struct sched_context* sched [static]
 

Definition at line 435 of file chan_sip.c.

Referenced by __sip_ack(), __sip_destroy(), __sip_reliable_xmit(), __sip_semi_ack(), _sip_show_peer(), build_peer(), do_monitor(), handle_response(), handle_response_peerpoke(), handle_response_register(), load_module(), parse_register_contact(), realtime_peer(), reg_source_db(), sip_alloc(), sip_call(), sip_cancel_destroy(), sip_destroy_peer(), sip_poke_noanswer(), sip_poke_peer(), sip_registry_destroy(), sip_scheddestroy(), sip_send_all_registers(), transmit_register(), and unload_module().

char show_channel_usage[] [static]
 

Initial value:

 
"Usage: sip show channel <channel>\n"
"       Provides detailed status on a given SIP channel.\n"

Definition at line 9071 of file chan_sip.c.

char show_channels_usage[] [static]
 

Initial value:

 
"Usage: sip show channels\n"
"       Lists all currently active SIP channels.\n"

Definition at line 9067 of file chan_sip.c.

char show_domains_usage[] [static]
 

Initial value:

 
"Usage: sip show domains\n"
"       Lists all configured SIP local domains.\n"
"       Asterisk only responds to SIP messages to local domains.\n"

Definition at line 9042 of file chan_sip.c.

char show_history_usage[] [static]
 

Initial value:

 
"Usage: sip show history <channel>\n"
"       Provides detailed dialog history on a given SIP channel.\n"

Definition at line 9075 of file chan_sip.c.

char show_inuse_usage[] [static]
 

Initial value:

 
"Usage: sip show inuse [all]\n"
"       List all SIP users and peers usage counters and limits.\n"
"       Add option \"all\" to show all devices, not only those with a limit.\n"

Definition at line 9062 of file chan_sip.c.

char show_objects_usage[] [static]
 

Initial value:

"Usage: sip show objects\n" 
"       Shows status of known SIP objects\n"

Definition at line 9128 of file chan_sip.c.

char show_peer_usage[] [static]
 

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.

char show_peers_usage[] [static]
 

Initial value:

 
"Usage: sip show peers [like <pattern>]\n"
"       Lists all known SIP peers.\n"
"       Optional regular expression pattern is used to filter the peer list.\n"

Definition at line 9079 of file chan_sip.c.

char show_reg_usage[] [static]
 

Initial value:

"Usage: sip show registry\n"
"       Lists all registration requests and status.\n"

Definition at line 9094 of file chan_sip.c.

char show_settings_usage[] [static]
 

Initial value:

 
"Usage: sip show settings\n"
"       Provides detailed list of the configuration of the SIP channel.\n"

Definition at line 9132 of file chan_sip.c.

char show_subscriptions_usage[] [static]
 

Initial value:

"Usage: sip show subscriptions\n" 
"       Shows active SIP subscriptions for extension states\n"

Definition at line 9124 of file chan_sip.c.

char show_user_usage[] [static]
 

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.

char show_users_usage[] [static]
 

Initial value:

 
"Usage: sip show users [like <pattern>]\n"
"       Lists all known SIP users.\n"
"       Optional regular expression pattern is used to filter the user list.\n"

Definition at line 9052 of file chan_sip.c.

struct ast_custom_function sip_header_function [static]
 

Definition at line 9178 of file chan_sip.c.

Referenced by load_module(), and unload_module().

enum sipmethod sip_method_list
 

const struct cfsip_methods sip_methods[] [static]
 

XXX Note that sip_methods[i].id == i must hold or the code breaks

Referenced by __sip_ack(), __sip_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().

const struct cfsip_options sip_options[] [static]
 

List of well-known SIP options. If we get this in a require, we should check the list and answer accordingly.

Referenced by _sip_show_peer(), parse_sip_options(), and sip_show_channel().

char sip_reload_usage[] [static]
 

Initial value:

"Usage: sip reload\n"
"       Reloads SIP configuration from sip.conf\n"

Definition at line 9120 of file chan_sip.c.

int sip_reloading = 0 [static]
 

Definition at line 799 of file chan_sip.c.

Referenced by do_monitor(), and sip_reload().

struct ast_rtp_protocol sip_rtp [static]
 

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().

const struct ast_channel_tech sip_tech [static]
 

Definition of this channel for PBX channel registration.

Definition at line 928 of file chan_sip.c.

Referenced by load_module(), and unload_module().

struct ast_custom_function sipchaninfo_function [static]
 

Definition at line 9360 of file chan_sip.c.

Referenced by load_module(), and unload_module().

int sipdebug = 0 [static]
 

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().

struct ast_custom_function sippeer_function
 

Definition at line 9284 of file chan_sip.c.

Referenced by load_module(), and unload_module().

int sipsock = -1 [static]
 

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().

int speerobjs = 0 [static]
 

Definition at line 375 of file chan_sip.c.

Referenced by build_peer(), sip_destroy_peer(), and sip_show_objects().

int srvlookup = 0 [static]
 

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().

const struct cfsubscription_types subscription_types[] [static]
 

Referenced by find_subscription_type(), and subscription_type2str().

int suserobjs = 0 [static]
 

Definition at line 373 of file chan_sip.c.

Referenced by build_user(), realtime_user(), sip_destroy_user(), and sip_show_objects().

char* synopsis_dtmfmode = "Change the dtmfmode for a SIP call" [static]
 

Definition at line 12728 of file chan_sip.c.

Referenced by load_module().

char* synopsis_sipaddheader = "Add a SIP header to the outbound call" [static]
 

Definition at line 12733 of file chan_sip.c.

Referenced by load_module().

char* synopsis_sipgetheader = "Get a SIP header from an incoming call" [static]
 

Definition at line 12745 of file chan_sip.c.

Referenced by load_module().

int tos = 0 [static]
 

Definition at line 418 of file chan_sip.c.

Referenced by reload_config(), sip_alloc(), and sip_show_settings().

int usecnt = 0 [static]
 

Definition at line 385 of file chan_sip.c.

Referenced by sip_hangup(), and sip_new().

struct ast_user_list userl [static]
 

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().

int videosupport = 0 [static]
 

Definition at line 420 of file chan_sip.c.

Referenced by add_sdp(), reload_config(), sip_alloc(), and sip_show_settings().


Generated on Mon Mar 20 08:25:55 2006 for Asterisk - the Open Source PBX by  doxygen 1.3.9.1