Fri May 26 01:47:00 2006

Asterisk developer's documentation


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"

Include dependency graph for chan_sip.c:

Go to the source code of this file.

Data Structures

struct  ast_peer_list
 The peer list: Peers and Friends ---. More...
struct  ast_register_list
 The register list: Other SIP proxys we register with and call ---. More...
struct  ast_user_list
 The user list: Users and friends ---. More...
struct  cfalias
 Structure for conversion between compressed SIP and "normal" SIP. More...
struct  cfsip_methods
struct  cfsip_options
 List of well-known SIP options. If we get this in a require, we should check the list and answer accordingly. More...
struct  cfsubscription_types
struct  domain
struct  sip_auth
 sip_auth: Creadentials for authentication to other SIP services More...
struct  sip_dual
struct  sip_history
 sip_history: Structure for saving transactions within a SIP dialog More...
struct  sip_invite_param
 Parameters to the transmit_invite function. More...
struct  sip_peer
struct  sip_pkt
 sip packet - read in sipsock_read, transmitted in send_request More...
struct  sip_pvt
 sip_pvt: PVT structures are used for each SIP conversation, ie. a call More...
struct  sip_registry
 sip_registry: Registrations with other SIP proxies More...
struct  sip_request
 sip_request: The data grabbed from the UDP socket More...
struct  sip_route
struct  sip_user
 Structure for SIP user data. User's place calls to us. More...

Defines

#define ALLOWED_METHODS   "INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY"
 SIP Methods we support.
#define CALLERID_UNKNOWN   "Unknown"
#define DEBUG_READ   0
#define DEBUG_SEND   1
#define DEC_CALL_LIMIT   0
#define DEFAULT_CALLERID   "asterisk"
#define DEFAULT_CONTEXT   "default"
#define DEFAULT_DEFAULT_EXPIRY   120
#define DEFAULT_EXPIRY   900
#define DEFAULT_FREQ_NOTOK   10 * 1000
#define DEFAULT_FREQ_OK   60 * 1000
#define DEFAULT_MAX_EXPIRY   3600
#define DEFAULT_MAX_FORWARDS   "70"
#define DEFAULT_MAXMS   2000
#define DEFAULT_MWITIME   10
#define DEFAULT_NOTIFYMIME   "application/simple-message-summary"
#define DEFAULT_REALM   "asterisk"
#define DEFAULT_REGISTRATION_TIMEOUT   20
#define DEFAULT_RETRANS   1000
#define DEFAULT_SIP_PORT   5060
#define DEFAULT_USERAGENT   "Asterisk PBX"
#define DEFAULT_VMEXTEN   "asterisk"
#define EXPIRY_GUARD_LIMIT   30
#define EXPIRY_GUARD_MIN   500
#define EXPIRY_GUARD_PCT   0.20
#define EXPIRY_GUARD_SECS   15
#define FLAG_FATAL   (1 << 1)
#define FLAG_RESPONSE   (1 << 0)
#define FORMAT   "%-15.15s %-10.10s %-11.11s %5.5d/%5.5d %-4.4s %-3.3s %-3.3s %-15.15s\n"
 sip_show_domains: CLI command to list local domains
#define FORMAT   "%-30.30s %-12.12s %8d %-20.20s\n"
 sip_show_domains: CLI command to list local domains
#define FORMAT   "%-40.40s %-20.20s %-16.16s\n"
 sip_show_domains: CLI command to list local domains
#define FORMAT   "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8d %-10s\n"
 sip_show_domains: CLI command to list local domains
#define FORMAT   "%-25.25s %-15.15s %-15.15s %-15.15s %-5.5s%-10.10s\n"
 sip_show_domains: CLI command to list local domains
#define FORMAT   "%-25.25s %-15.15s %-15.15s \n"
 sip_show_domains: CLI command to list local domains
#define FORMAT2   "%-15.15s %-10.10s %-11.11s %-11.11s %-4.4s %-7.7s %-15.15s\n"
#define FORMAT2   "%-30.30s %-12.12s %8.8s %-20.20s\n"
#define FORMAT2   "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8s %-10s\n"
#define FORMAT2   "%-25.25s %-15.15s %-15.15s \n"
#define FORMAT3   "%-15.15s %-10.10s %-11.11s %-15.15s %-13.13s %-15.15s\n"
#define INC_CALL_LIMIT   1
#define IPTOS_MINCOST   0x02
#define MAX(a, b)   ((a) > (b) ? (a) : (b))
#define MAX_AUTHTRIES   3
#define MAX_RETRANS   6
#define NO_RTP   0
#define NOT_SUPPORTED   0
#define REG_STATE_AUTHSENT   2
#define REG_STATE_FAILED   7
#define REG_STATE_NOAUTH   6
#define REG_STATE_REGISTERED   3
#define REG_STATE_REGSENT   1
#define REG_STATE_REJECTED   4
#define REG_STATE_TIMEOUT   5
#define REG_STATE_UNREGISTERED   0
#define RTP   1
#define SIP_ALREADYGONE   (1 << 0)
#define SIP_CALL_LIMIT   (1 << 29)
#define SIP_CALL_ONHOLD   (1 << 28)
#define SIP_CAN_REINVITE   (1 << 20)
#define SIP_DEBUG_CONFIG   1 << 0
#define SIP_DEBUG_CONSOLE   1 << 1
#define SIP_DTMF   (3 << 16)
#define SIP_DTMF_AUTO   (3 << 16)
#define SIP_DTMF_INBAND   (1 << 16)
#define SIP_DTMF_INFO   (2 << 16)
#define SIP_DTMF_RFC2833   (0 << 16)
#define SIP_DYNAMIC   (1 << 15)
#define SIP_FLAGS_TO_COPY
#define SIP_GOTREFER   (1 << 7)
#define SIP_INC_COUNT   (1 << 31)
#define SIP_INSECURE_INVITE   (1 << 23)
#define SIP_INSECURE_PORT   (1 << 22)
#define SIP_MAX_HEADERS   64
#define SIP_MAX_LINES   64
#define SIP_MAX_PACKET   4096
#define SIP_NAT   (3 << 18)
#define SIP_NAT_ALWAYS   (3 << 18)
#define SIP_NAT_NEVER   (0 << 18)
#define SIP_NAT_RFC3581   (1 << 18)
#define SIP_NAT_ROUTE   (2 << 18)
#define SIP_NEEDDESTROY   (1 << 1)
#define SIP_NEEDREINVITE   (1 << 5)
#define SIP_NOVIDEO   (1 << 2)
#define SIP_OPT_100REL   (1 << 1)
#define SIP_OPT_EARLY_SESSION   (1 << 3)
#define SIP_OPT_EVENTLIST   (1 << 11)
#define SIP_OPT_GRUU   (1 << 12)
#define SIP_OPT_JOIN   (1 << 4)
#define SIP_OPT_PATH   (1 << 5)
#define SIP_OPT_PRECONDITION   (1 << 7)
#define SIP_OPT_PREF   (1 << 6)
#define SIP_OPT_PRIVACY   (1 << 8)
#define SIP_OPT_REPLACES   (1 << 0)
#define SIP_OPT_SDP_ANAT   (1 << 9)
#define SIP_OPT_SEC_AGREE   (1 << 10)
#define SIP_OPT_TARGET_DIALOG   (1 << 13)
#define SIP_OPT_TIMER   (1 << 2)
#define SIP_OSPAUTH   (3 << 26)
#define SIP_OSPAUTH_EXCLUSIVE   (3 << 26)
#define SIP_OSPAUTH_GATEWAY   (1 << 26)
#define SIP_OSPAUTH_NO   (0 << 26)
#define SIP_OSPAUTH_PROXY   (2 << 26)
#define SIP_OUTGOING   (1 << 13)
#define SIP_PAGE2_IGNOREREGEXPIRE   (1 << 3)
#define SIP_PAGE2_RT_FROMCONTACT   (1 << 4)
#define SIP_PAGE2_RTAUTOCLEAR   (1 << 2)
#define SIP_PAGE2_RTCACHEFRIENDS   (1 << 0)
#define SIP_PAGE2_RTUPDATE   (1 << 1)
#define SIP_PENDINGBYE   (1 << 6)
#define SIP_PKT_DEBUG   (1 << 0)
#define SIP_PKT_WITH_TOTAG   (1 << 1)
#define SIP_PROG_INBAND   (3 << 24)
#define SIP_PROG_INBAND_NEVER   (0 << 24)
#define SIP_PROG_INBAND_NO   (1 << 24)
#define SIP_PROG_INBAND_YES   (2 << 24)
#define SIP_PROGRESS_SENT   (1 << 4)
#define SIP_PROMISCREDIR   (1 << 8)
#define SIP_REALTIME   (1 << 11)
#define SIP_REINVITE   (3 << 20)
#define SIP_REINVITE_UPDATE   (2 << 20)
#define SIP_RINGING   (1 << 3)
#define SIP_SELFDESTRUCT   (1 << 14)
#define SIP_SENDRPID   (1 << 30)
#define SIP_TRUSTRPID   (1 << 9)
#define SIP_USECLIENTCODE   (1 << 12)
#define SIP_USEREQPHONE   (1 << 10)
#define SIPDUMPER
#define SUPPORTED   1
#define SUPPORTED_EXTENSIONS   "replaces"
 SIP Extensions we support.
#define VIDEO_CODEC_MASK   0x1fc0000

Enumerations

enum  domain_mode { SIP_DOMAIN_AUTO, SIP_DOMAIN_CONFIG }
enum  parse_register_result { PARSE_REGISTER_FAILED, PARSE_REGISTER_UPDATE, PARSE_REGISTER_QUERY }
enum  sip_auth_type { PROXY_AUTH, WWW_AUTH }
enum  sipmethod {
  SIP_UNKNOWN, SIP_RESPONSE, SIP_REGISTER, SIP_OPTIONS,
  SIP_NOTIFY, SIP_INVITE, SIP_ACK, SIP_PRACK,
  SIP_BYE, SIP_REFER, SIP_SUBSCRIBE, SIP_MESSAGE,
  SIP_UPDATE, SIP_INFO, SIP_CANCEL, SIP_PUBLISH
}
enum  subscriptiontype {
  NONE = 0, TIMEOUT, XPIDF_XML, DIALOG_INFO_XML,
  CPIM_PIDF_XML, PIDF_XML
}

Functions

static char * __get_header (struct sip_request *req, char *name, int *start)
static int __sip_ack (struct sip_pvt *p, int seqno, int resp, int sipmethod)
 __sip_ack: Acknowledges receipt of a packet and stops retransmission ---
static int __sip_autodestruct (void *data)
 __sip_autodestruct: Kill a call (called by scheduler) ---
static void __sip_destroy (struct sip_pvt *p, int lockowner)
 __sip_destroy: Execute destrucion of call structure, release memory---
static int __sip_do_register (struct sip_registry *r)
 __sip_do_register: Register with SIP proxy ---
static int __sip_pretend_ack (struct sip_pvt *p)
static int __sip_reliable_xmit (struct sip_pvt *p, int seqno, int resp, char *data, int len, int fatal, int sipmethod)
 __sip_reliable_xmit: transmit packet with retransmits ---
static int __sip_semi_ack (struct sip_pvt *p, int seqno, int resp, int sipmethod)
 __sip_semi_ack: Acks receipt of packet, keep it around (used for provisional responses) ---
static int __sip_show_channels (int fd, int argc, char *argv[], int subscriptions)
static int __sip_xmit (struct sip_pvt *p, char *data, int len)
 __sip_xmit: Transmit SIP message ---
static int __transmit_response (struct sip_pvt *p, char *msg, struct sip_request *req, int reliable)
 __transmit_response: Base transmit response function
static int _sip_show_peer (int type, int fd, struct mansession *s, struct message *m, int argc, char *argv[])
static int _sip_show_peers (int fd, int *total, struct mansession *s, struct message *m, int argc, char *argv[])
 _sip_show_peers: Execute sip show peers command
static int add_blank_header (struct sip_request *req)
 add_blank_header: Add blank header to SIP message
static void add_codec_to_sdp (const struct sip_pvt *p, int codec, int sample_rate, char **m_buf, size_t *m_size, char **a_buf, size_t *a_size, int debug)
static int add_digit (struct sip_request *req, char digit)
 add_digit: add DTMF INFO tone to sip message ---
static int add_header (struct sip_request *req, const char *var, const char *value)
 add_header: Add header to SIP message
static int add_header_contentLength (struct sip_request *req, int len)
 add_header_contentLen: Add 'Content-Length' header to SIP message
static int add_line (struct sip_request *req, const char *line)
 add_line: Add content (not header) to SIP message
static void add_noncodec_to_sdp (const struct sip_pvt *p, int format, int sample_rate, char **m_buf, size_t *m_size, char **a_buf, size_t *a_size, int debug)
static struct sip_authadd_realm_authentication (struct sip_auth *authlist, char *configuration, int lineno)
 add_realm_authentication: Add realm authentication in list ---
static void add_route (struct sip_request *req, struct sip_route *route)
 add_route: Add route header into request per learned route ---
static int add_sdp (struct sip_request *resp, struct sip_pvt *p)
 add_sdp: Add Session Description Protocol message ---
static int add_sip_domain (const char *domain, const enum domain_mode mode, const char *context)
 add_sip_domain: Add SIP domain to list of domains we are responsible for
static int add_text (struct sip_request *req, const char *text)
 add_text: Add text body to SIP message ---
static int add_vidupdate (struct sip_request *req)
 add_vidupdate: add XML encoded media control with update ---
static void append_date (struct sip_request *req)
 append_date: Append date to SIP message ---
static int append_history (struct sip_pvt *p, const char *event, const char *data)
 append_history: Append to SIP dialog history
static AST_LIST_HEAD_STATIC (domain_list, domain)
 AST_MUTEX_DEFINE_STATIC (sip_reload_lock)
 AST_MUTEX_DEFINE_STATIC (monlock)
 AST_MUTEX_DEFINE_STATIC (netlock)
 Protect the monitoring thread, so only one process can kill or start it, and not when it's doing something critical.
 AST_MUTEX_DEFINE_STATIC (iflock)
 Protect the interface list (of sip_pvt's).
 AST_MUTEX_DEFINE_STATIC (rand_lock)
 AST_MUTEX_DEFINE_STATIC (usecnt_lock)
static void ast_quiet_chan (struct ast_channel *chan)
 ast_quiet_chan: Turn off generator data
static int ast_sip_ouraddrfor (struct in_addr *them, struct in_addr *us)
 ast_sip_ouraddrfor: NAT fix - decide which IP address to use for ASterisk server? ---
static int attempt_transfer (struct sip_pvt *p1, struct sip_pvt *p2)
 attempt_transfer: Attempt transfer of SIP call ---
static int auto_congest (void *nothing)
 auto_congest: Scheduled congestion on a call ---
static void build_callid (char *callid, int len, struct in_addr ourip, char *fromdomain)
 build_callid: Build SIP CALLID header ---
static void build_contact (struct sip_pvt *p)
 build_contact: Build contact header - the contact header we send out ---
static struct sip_peerbuild_peer (const char *name, struct ast_variable *v, int realtime)
 build_peer: Build peer from config file ---
static int build_reply_digest (struct sip_pvt *p, int method, char *digest, int digest_len)
 build_reply_digest: Build reply digest ---
static void build_route (struct sip_pvt *p, struct sip_request *req, int backwards)
 build_route: Build route list from Record-Route header ---
static void build_rpid (struct sip_pvt *p)
 build_rpid: Build the Remote Party-ID & From using callingpres options ---
static struct sip_userbuild_user (const char *name, struct ast_variable *v, int realtime)
 build_user: Initiate a SIP user structure from sip.conf ---
static void build_via (struct sip_pvt *p, char *buf, int len)
 build_via: Build a Via header for a request ---
static int cb_extensionstate (char *context, char *exten, int state, void *data)
 cb_extensionstate: Callback for the devicestate notification (SUBSCRIBE) support subsystem ---
static int check_auth (struct sip_pvt *p, struct sip_request *req, char *randdata, int randlen, char *username, char *secret, char *md5secret, int sipmethod, char *uri, int reliable, int ignore)
 check_auth: Check user authorization from peer definition ---
static void check_pendings (struct sip_pvt *p)
 check_pendings: Check pending actions on SIP call ---
static int check_sip_domain (const char *domain, char *context, size_t len)
 check_sip_domain: Check if domain part of uri is local to our server
static int check_user (struct sip_pvt *p, struct sip_request *req, int sipmethod, char *uri, int reliable, struct sockaddr_in *sin, int ignore)
 check_user: Find user ---
static int check_user_full (struct sip_pvt *p, struct sip_request *req, int sipmethod, char *uri, int reliable, struct sockaddr_in *sin, int ignore, char *mailbox, int mailboxlen)
 check_user_full: Check if matching user or peer is defined ---
static int check_via (struct sip_pvt *p, struct sip_request *req)
 check Via: header for hostname, port and rport request/answer
static int clear_realm_authentication (struct sip_auth *authlist)
 clear_realm_authentication: Clear realm authentication list (at reload) ---
static void clear_sip_domains (void)
 clear_sip_domains: Clear our domain list (at reload)
static char * complete_sip_debug_peer (char *line, char *word, int pos, int state)
 complete_sip_debug_peer: Support routine for 'sip debug peer' CLI ---
static char * complete_sip_peer (char *word, int state, int flags2)
 complete_sip_peer: Do completion on peer name ---
static char * complete_sip_prune_realtime_peer (char *line, char *word, int pos, int state)
 complete_sip_prune_realtime_peer: Support routine for 'sip prune realtime peer' CLI ---
static char * complete_sip_prune_realtime_user (char *line, char *word, int pos, int state)
 complete_sip_prune_realtime_user: Support routine for 'sip prune realtime user' CLI ---
static char * complete_sip_show_peer (char *line, char *word, int pos, int state)
 complete_sip_show_peer: Support routine for 'sip show peer' CLI ---
static char * complete_sip_show_user (char *line, char *word, int pos, int state)
 complete_sip_show_user: Support routine for 'sip show user' CLI ---
static char * complete_sip_user (char *word, int state, int flags2)
 complete_sip_user: Do completion on user name ---
static char * complete_sipch (char *line, char *word, int pos, int state)
 complete_sipch: Support routine for 'sip show channel' CLI ---
static char * complete_sipnotify (char *line, char *word, int pos, int state)
 complete_sipnotify: Support routine for 'sip notify' CLI ---
static int copy_all_header (struct sip_request *req, struct sip_request *orig, char *field)
 copy_all_header: Copy all headers from one request to another ---
static int copy_header (struct sip_request *req, struct sip_request *orig, char *field)
 copy_header: Copy one header field from one request to another
static void copy_request (struct sip_request *dst, struct sip_request *src)
 copy_request: copy SIP request (mostly used to save request for responses) ---
static int copy_via_headers (struct sip_pvt *p, struct sip_request *req, struct sip_request *orig, char *field)
 copy_via_headers: Copy SIP VIA Headers from the request to the response ---
static int create_addr (struct sip_pvt *dialog, char *opeer)
 create_addr: create address structure from peer name Or, if peer not found, find it in the global DNS returns TRUE (-1) on failure, FALSE on success
static int create_addr_from_peer (struct sip_pvt *r, struct sip_peer *peer)
 create_addr_from_peer: create address structure from peer reference ---
char * description ()
 Provides a description of the module.
static void destroy_association (struct sip_peer *peer)
static int determine_firstline_parts (struct sip_request *req)
 determine_firstline_parts: parse first line of incoming SIP request
static void * do_monitor (void *data)
 do_monitor: The SIP monitoring thread ---
static int do_proxy_auth (struct sip_pvt *p, struct sip_request *req, char *header, char *respheader, int sipmethod, int init)
 do_proxy_auth: Add authentication on outbound SIP packet ---
static int do_register_auth (struct sip_pvt *p, struct sip_request *req, char *header, char *respheader)
 do_register_auth: Authenticate for outbound registration ---
static const char * domain_mode_to_text (const enum domain_mode mode)
static const char * dtmfmode2str (int mode)
 dtmfmode2str: Convert DTMF mode to printable string ---
static int expire_register (void *data)
 expire_register: Expire registration of SIP peer ---
static void extract_uri (struct sip_pvt *p, struct sip_request *req)
 extract_uri: Check Contact: URI of SIP message ---
static char * find_alias (const char *name, char *_default)
static struct sip_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
static struct 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
static struct 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
static const struct cfsubscription_typesfind_subscription_type (enum subscriptiontype subtype)
 find_subscription_type: Find subscription type in array
static struct 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)
static void free_old_route (struct sip_route *route)
 free_old_route: Remove route from route list ---
static char * func_check_sipdomain (struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
 function_check_sipdomain: Dial plan function to check if domain is local
static char * func_header_read (struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
 func_header_read: Read SIP header (dialplan function)
static char * function_sipchaninfo_read (struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
 function_sipchaninfo_read: ${SIPCHANINFO()} Dialplan function - reads sip channel data
static char * function_sippeer (struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
 function_sippeer: ${SIPPEER()} Dialplan function - reads peer data
static int get_also_info (struct sip_pvt *p, struct sip_request *oreq)
 get_also_info: Call transfer support (old way, depreciated)--
static char * get_calleridname (char *input, char *output, size_t outputsize)
 get_calleridname: Get caller id name from SIP headers ---
static int get_destination (struct sip_pvt *p, struct sip_request *oreq)
 get_destination: Find out who the call is for --
static char * get_header (struct sip_request *req, char *name)
 get_header: Get header from SIP request ---
static char * get_in_brackets (char *tmp)
 get_in_brackets: Pick out text in brackets from character string ---
static int get_msg_text (char *buf, int len, struct sip_request *req)
 get_msg_text: Get text out of a SIP MESSAGE packet ---
static int get_rdnis (struct sip_pvt *p, struct sip_request *oreq)
 get_rdnis: get referring dnis ---
static int get_refer_info (struct sip_pvt *sip_pvt, struct sip_request *outgoing_req)
 get_refer_info: Call transfer support (the REFER method) ---
static int get_rpid_num (char *input, char *output, int maxlen)
 get_rpid_num: Get caller id number from Remote-Party-ID header field Returns true if number should be restricted (privacy setting found) output is set to NULL if no number found
static char * get_sdp (struct sip_request *req, char *name)
 get_sdp: Gets all kind of SIP message bodies, including SDP, but the name wrongly applies _only_ sdp
static char * get_sdp_by_line (char *line, char *name, int nameLen)
 get_sdp_by_line: Reads one line of SIP message body
static char * get_sdp_iterate (int *iterator, struct sip_request *req, char *name)
static struct sip_pvtget_sip_pvt_byid_locked (char *callid)
 get_sip_pvt_byid_locked: Lock interface lock and find matching pvt lock ---
static char * gettag (struct sip_request *req, char *header, char *tagbuf, int tagbufsize)
 gettag: Get tag from packet
static int handle_common_options (struct ast_flags *flags, struct ast_flags *mask, struct ast_variable *v)
 handle_common_options: Handle flag-type options common to users and peers ---
static int handle_request (struct sip_pvt *p, struct sip_request *req, struct sockaddr_in *sin, int *recount, int *nounlock)
 handle_request: Handle SIP requests (methods) ---
static int handle_request_bye (struct sip_pvt *p, struct sip_request *req, int debug, int ignore)
 handle_request_bye: Handle incoming BYE request ---
static int handle_request_cancel (struct sip_pvt *p, struct sip_request *req, int debug, int ignore)
 handle_request_cancel: Handle incoming CANCEL request ---
static void handle_request_info (struct sip_pvt *p, struct sip_request *req)
 handle_request_info: Receive SIP INFO Message ---
static int handle_request_invite (struct sip_pvt *p, struct sip_request *req, int debug, int ignore, int seqno, struct sockaddr_in *sin, int *recount, char *e)
 handle_request_invite: Handle incoming INVITE request
static int handle_request_message (struct sip_pvt *p, struct sip_request *req, int debug, int ignore)
 handle_request_message: Handle incoming MESSAGE request ---
static int handle_request_options (struct sip_pvt *p, struct sip_request *req, int debug)
 handle_request_options: Handle incoming OPTIONS request
static int handle_request_refer (struct sip_pvt *p, struct sip_request *req, int debug, int ignore, int seqno, int *nounlock)
 handle_request_refer: Handle incoming REFER request ---
static int handle_request_register (struct sip_pvt *p, struct sip_request *req, int debug, int ignore, struct sockaddr_in *sin, char *e)
 handle_request_register: Handle incoming REGISTER request ---
static int handle_request_subscribe (struct sip_pvt *p, struct sip_request *req, int debug, int ignore, struct sockaddr_in *sin, int seqno, char *e)
 handle_request_subscribe: Handle incoming SUBSCRIBE request ---
static void handle_response (struct sip_pvt *p, int resp, char *rest, struct sip_request *req, int ignore, int seqno)
 handle_response: Handle SIP response in dialogue ---
static void handle_response_invite (struct sip_pvt *p, int resp, char *rest, struct sip_request *req, int ignore, int seqno)
 handle_response_invite: Handle SIP response in dialogue ---
static int handle_response_peerpoke (struct sip_pvt *p, int resp, char *rest, struct sip_request *req, int ignore, int seqno, int sipmethod)
 handle_response_peerpoke: Handle qualification responses (OPTIONS)
static int handle_response_register (struct sip_pvt *p, int resp, char *rest, struct sip_request *req, int ignore, int seqno)
 handle_response_register: Handle responses on REGISTER to services ---
static char * hangup_cause2sip (int cause)
 hangup_cause2sip: Convert Asterisk hangup causes to SIP codes
static int hangup_sip2cause (int cause)
 hangup_sip2cause: Convert SIP hangup causes to Asterisk hangup causes ---
static int init_req (struct sip_request *req, int sipmethod, char *recip)
 init_req: Initialize SIP request ---
static int init_resp (struct sip_request *req, char *resp, struct sip_request *orig)
 init_resp: Initialize SIP response, based on SIP request ---
static void initreqprep (struct sip_request *req, struct sip_pvt *p, int sipmethod)
 initreqprep: Initiate new SIP request to peer/user ---
static const char * insecure2str (int port, int invite)
 insecure2str: Convert Insecure setting to printable string ---
char * key ()
 Returns the ASTERISK_GPL_KEY.
static void list_route (struct sip_route *route)
 list_route: List all routes - mostly for debugging ---
int load_module ()
 Initialize the module.
static int lws2sws (char *msgbuf, int len)
 lws2sws: Parse multiline SIP headers into one header
static void make_our_tag (char *tagbuf, size_t len)
static int manager_sip_show_peer (struct mansession *s, struct message *m)
 manager_sip_show_peer: Show SIP peers in the manager API ---
static int manager_sip_show_peers (struct mansession *s, struct message *m)
 manager_sip_show_peers: Show SIP peers in the manager API ---
static char * nat2str (int nat)
 nat2str: Convert NAT setting to text string
static void parse_copy (struct sip_request *dst, struct sip_request *src)
 parse_copy: Copy SIP request, parse it
static void parse_moved_contact (struct sip_pvt *p, struct sip_request *req)
 parse_moved_contact: Parse 302 Moved temporalily response
static int parse_ok_contact (struct sip_pvt *pvt, struct sip_request *req)
 parse_ok_contact: Parse contact header for 200 OK on INVITE ---
static enum parse_register_result parse_register_contact (struct sip_pvt *pvt, struct sip_peer *p, struct sip_request *req)
 parse_register_contact: Parse contact header and save registration ---
static void parse_request (struct sip_request *req)
 parse_request: Parse a SIP message ----
unsigned int parse_sip_options (struct sip_pvt *pvt, char *supported)
 parse_sip_options: Parse supported header in incoming packet
static int peer_status (struct sip_peer *peer, char *status, int statuslen)
 peer_status: Report Peer status in character string
static void print_codec_to_cli (int fd, struct ast_codec_pref *pref)
 print_codec_to_cli: Print codec list from preference to CLI/manager
static void print_group (int fd, unsigned int group, int crlf)
 print_group: Print call group and pickup group ---
static int process_sdp (struct sip_pvt *p, struct sip_request *req)
 process_sdp: Process SIP SDP and activate RTP channels---
static struct sip_peerrealtime_peer (const char *peername, struct sockaddr_in *sin)
 realtime_peer: Get peer from realtime storage Checks the "sippeers" realtime family from extconfig.conf
static void realtime_update_peer (const char *peername, struct sockaddr_in *sin, const char *username, const char *fullcontact, int expirey)
 realtime_update_peer: Update peer object in realtime storage ---
static struct sip_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)
static void receive_message (struct sip_pvt *p, struct sip_request *req)
 receive_message: Receive SIP MESSAGE method messages ---
static void reg_source_db (struct sip_peer *peer)
 reg_source_db: Get registration details from Asterisk DB ---
static void register_peer_exten (struct sip_peer *peer, int onoff)
 register_peer_exten: Automatically add peer extension to dial plan ---
static int register_verify (struct sip_pvt *p, struct sockaddr_in *sin, struct sip_request *req, char *uri, int ignore)
 register_verify: Verify registration of user
static char * regstate2str (int regstate)
int reload (void)
 Reload stuff.
static int reload_config (void)
 reload_config: Re-read SIP.conf config file ---
static int reply_digest (struct sip_pvt *p, struct sip_request *req, char *header, int sipmethod, char *digest, int digest_len)
 reply_digest: reply to authentication for outbound registrations ---
static int reqprep (struct sip_request *req, struct sip_pvt *p, int sipmethod, int seqno, int newbranch)
 reqprep: Initialize a SIP request response packet ---
static int respprep (struct sip_request *resp, struct sip_pvt *p, char *msg, struct sip_request *req)
 respprep: Prepare SIP response packet ---
static int restart_monitor (void)
 restart_monitor: Start the channel monitor thread ---
static int retrans_pkt (void *data)
 retrans_pkt: Retransmit SIP message if no answer ---
static void sdpLineNum_iterator_init (int *iterator)
static int send_request (struct sip_pvt *p, struct sip_request *req, int reliable, int seqno)
 send_request: Send SIP Request to the other part of the dialogue ---
static int send_response (struct sip_pvt *p, struct sip_request *req, int reliable, int seqno)
 send_response: Transmit response on SIP request---
static void set_destination (struct sip_pvt *p, char *uri)
 set_destination: Set destination from SIP URI ---
static int sip_addheader (struct ast_channel *chan, void *data)
 sip_addheader: Add a SIP header ---
static int sip_addrcmp (char *name, struct sockaddr_in *sin)
 sip_addrcmp: Support routine for find_peer ---
static struct sip_pvtsip_alloc (char *callid, struct sockaddr_in *sin, int useglobal_nat, const int intended_method)
 sip_alloc: Allocate SIP_PVT structure and set defaults ---
static int sip_answer (struct ast_channel *ast)
 sip_answer: Answer SIP call , send 200 OK on Invite Part of PBX interface
static int sip_call (struct ast_channel *ast, char *dest, int timeout)
 sip_call: Initiate SIP call from PBX used from the dial() application
static int sip_cancel_destroy (struct sip_pvt *p)
 sip_cancel_destroy: Cancel destruction of SIP call ---
static int sip_debug_test_addr (struct sockaddr_in *addr)
 sip_debug_test_addr: See if we pass debug IP filter
static int sip_debug_test_pvt (struct sip_pvt *p)
 sip_debug_test_pvt: Test PVT for debugging output
static void sip_destroy (struct sip_pvt *p)
 sip_destroy: Destroy SIP call structure ---
static void sip_destroy_peer (struct sip_peer *peer)
 sip_destroy_peer: Destroy peer object from memory
static void sip_destroy_user (struct sip_user *user)
 sip_destroy_user: Remove user object from in-memory storage ---
static int sip_devicestate (void *data)
 sip_devicestate: Part of PBX channel interface ---
static int sip_do_debug (int fd, int argc, char *argv[])
 sip_do_debug: Turn on SIP debugging (CLI command)
static int sip_do_debug_ip (int fd, int argc, char *argv[])
 sip_do_debug: Enable SIP Debugging in CLI ---
static int sip_do_debug_peer (int fd, int argc, char *argv[])
 sip_do_debug_peer: Turn on SIP debugging with peer mask
static int sip_do_history (int fd, int argc, char *argv[])
 sip_do_history: Enable SIP History logging (CLI) ---
static int sip_do_reload (void)
 sip_do_reload: Reload module
static int sip_dtmfmode (struct ast_channel *chan, void *data)
 sip_dtmfmode: change the DTMFmode for a SIP call (application) ---
static void sip_dump_history (struct sip_pvt *dialog)
 dump_history: Dump SIP history to debug log file at end of lifespan for SIP dialog
static int sip_fixup (struct ast_channel *oldchan, struct ast_channel *newchan)
 sip_fixup: Fix up a channel: If a channel is consumed, this is called. Basically update any ->owner links ----
static int sip_get_codec (struct ast_channel *chan)
 sip_get_codec: Return SIP UA's codec (part of the RTP interface) ---
static struct ast_rtpsip_get_rtp_peer (struct ast_channel *chan)
 sip_get_rtp_peer: Returns null if we can't reinvite (part of RTP interface)
static struct ast_rtpsip_get_vrtp_peer (struct ast_channel *chan)
 sip_get_vrtp_peer: Returns null if we can't reinvite video (part of RTP interface)
static int sip_getheader (struct ast_channel *chan, void *data)
 sip_getheader: Get a SIP header (dialplan app) ---
static int sip_hangup (struct ast_channel *ast)
 sip_hangup: Hangup SIP call Part of PBX interface, called from ast_hangup
static int sip_indicate (struct ast_channel *ast, int condition)
 sip_indicate: Play indication to user With SIP a lot of indications is sent as messages, letting the device play the indication - busy signal, congestion etc
static struct ast_channelsip_new (struct sip_pvt *i, int state, char *title)
 sip_new: Initiate a call in the SIP channel
static int sip_no_debug (int fd, int argc, char *argv[])
 sip_no_debug: Disable SIP Debugging in CLI ---
static int sip_no_history (int fd, int argc, char *argv[])
 sip_no_history: Disable SIP History logging (CLI) ---
static int sip_notify (int fd, int argc, char *argv[])
 sip_notify: Send SIP notify to peer
static int sip_park (struct ast_channel *chan1, struct ast_channel *chan2, struct sip_request *req)
 sip_park: Park a call ---
static void * sip_park_thread (void *stuff)
 sip_park_thread: Park SIP call support function
static void sip_poke_all_peers (void)
 sip_poke_all_peers: Send a poke to all known peers
static int sip_poke_noanswer (void *data)
 sip_poke_noanswer: No answer to Qualify poke ---
static int sip_poke_peer (struct sip_peer *peer)
 sip_poke_peer: Check availability of peer, also keep NAT open ---
static int sip_poke_peer_s (void *data)
static int sip_prune_realtime (int fd, int argc, char *argv[])
 sip_prune_realtime: Remove temporary realtime objects from memory (CLI) ---
static struct ast_framesip_read (struct ast_channel *ast)
 sip_read: Read SIP RTP from channel
static int sip_reg_timeout (void *data)
 sip_reg_timeout: Registration timeout, register again
static int sip_register (char *value, int lineno)
 sip_register: Parse register=> line in sip.conf and add to registry
static void sip_registry_destroy (struct sip_registry *reg)
 sip_registry_destroy: Destroy registry object ---
static int sip_reload (int fd, int argc, char *argv[])
 sip_reload: Force reload of module from cli ---
static struct ast_channelsip_request_call (const char *type, int format, void *data, int *cause)
 sip_request: PBX interface function -build SIP pvt structure ---
static int sip_reregister (void *data)
 sip_reregister: Update registration with SIP Proxy---
static struct ast_framesip_rtp_read (struct ast_channel *ast, struct sip_pvt *p)
 sip_rtp_read: Read RTP from network ---
static int sip_scheddestroy (struct sip_pvt *p, int ms)
 sip_scheddestroy: Schedule destruction of SIP call ---
static void sip_send_all_registers (void)
 sip_send_all_registers: Send all known registrations
static int sip_send_mwi_to_peer (struct sip_peer *peer)
 sip_send_mwi_to_peer: Send message waiting indication ---
static int sip_senddigit (struct ast_channel *ast, char digit)
 sip_senddigit: Send DTMF character on SIP channel
static int sip_sendtext (struct ast_channel *ast, const char *text)
 sip_sendtext: Send SIP MESSAGE text within a call ---
static int sip_set_rtp_peer (struct ast_channel *chan, struct ast_rtp *rtp, struct ast_rtp *vrtp, int codecs, int nat_active)
 sip_set_rtp_peer: Set the RTP peer for this call ---
static int sip_show_channel (int fd, int argc, char *argv[])
 sip_show_channel: Show details of one call ---
static int sip_show_channels (int fd, int argc, char *argv[])
 sip_show_channels: Show active SIP channels ---
static int sip_show_domains (int fd, int argc, char *argv[])
static int sip_show_history (int fd, int argc, char *argv[])
 sip_show_history: Show history details of one call ---
static int sip_show_inuse (int fd, int argc, char *argv[])
 sip_show_inuse: CLI Command to show calls within limits set by call_limit ---
static int sip_show_objects (int fd, int argc, char *argv[])
 sip_show_objects: List all allocated SIP Objects ---
static int sip_show_peer (int fd, int argc, char *argv[])
 sip_show_peer: Show one peer in detail ---
static int sip_show_peers (int fd, int argc, char *argv[])
 sip_show_peers: CLI Show Peers command
static int sip_show_registry (int fd, int argc, char *argv[])
 sip_show_registry: Show SIP Registry (registrations with other SIP proxies ---
static int sip_show_settings (int fd, int argc, char *argv[])
 sip_show_settings: List global settings for the SIP channel ---
static int sip_show_subscriptions (int fd, int argc, char *argv[])
 sip_show_subscriptions: Show active SIP subscriptions ---
static int sip_show_user (int fd, int argc, char *argv[])
 sip_show_user: Show one user in detail ---
static int sip_show_users (int fd, int argc, char *argv[])
 sip_show_users: CLI Command 'SIP Show Users' ---
static int sip_sipredirect (struct sip_pvt *p, const char *dest)
 sip_sipredirect: Transfer call before connect with a 302 redirect ---
static int sip_transfer (struct ast_channel *ast, const char *dest)
 sip_transfer: Transfer SIP call
static int sip_write (struct ast_channel *ast, struct ast_frame *frame)
 sip_write: Send frame to media channel (rtp) ---
static int sipsock_read (int *id, int fd, short events, void *ignore)
 sipsock_read: Read data from SIP socket ---
static const char * subscription_type2str (enum subscriptiontype subtype)
 subscription_type2str: Show subscription type in string format
static struct sip_peertemp_peer (const char *name)
 temp_peer: Create temporary peer (used in autocreatepeer mode) ---
static force_inline int thread_safe_rand (void)
 Thread-safe random number generator.
static int transmit_info_with_digit (struct sip_pvt *p, char digit)
 transmit_info_with_digit: Send SIP INFO dtmf message, see Cisco documentation on cisco.co m ---
static int transmit_info_with_vidupdate (struct sip_pvt *p)
 transmit_info_with_vidupdate: Send SIP INFO with video update request ---
static int transmit_invite (struct sip_pvt *p, int sipmethod, int sdp, int init)
 transmit_invite: Build REFER/INVITE/OPTIONS message and transmit it ---
static int transmit_message_with_text (struct sip_pvt *p, const char *text)
 transmit_message_with_text: Transmit text with SIP MESSAGE method ---
static int transmit_notify_with_mwi (struct sip_pvt *p, int newmsgs, int oldmsgs, char *vmexten)
 transmit_notify_with_mwi: Notify user of messages waiting in voicemail ---
static int transmit_notify_with_sipfrag (struct sip_pvt *p, int cseq)
 transmit_notify_with_sipfrag: Notify a transferring party of the status of trasnfer ---
static int transmit_refer (struct sip_pvt *p, const char *dest)
 transmit_refer: Transmit SIP REFER message ---
static int transmit_register (struct sip_registry *r, int sipmethod, char *auth, char *authheader)
 transmit_register: Transmit register to SIP proxy or UA ---
static int transmit_reinvite_with_sdp (struct sip_pvt *p)
 transmit_reinvite_with_sdp: Transmit reinvite with SDP :-) ---
static int transmit_request (struct sip_pvt *p, int sipmethod, int seqno, int reliable, int newbranch)
 transmit_request: transmit generic SIP request ---
static int transmit_request_with_auth (struct sip_pvt *p, int sipmethod, int seqno, int reliable, int newbranch)
 transmit_request_with_auth: Transmit SIP request, auth added ---
static int transmit_response (struct sip_pvt *p, char *msg, struct sip_request *req)
 transmit_response: Transmit response, no retransmits
static int transmit_response_reliable (struct sip_pvt *p, char *msg, struct sip_request *req, int fatal)
 transmit_response_reliable: Transmit response, Make sure you get a reply
static int transmit_response_with_allow (struct sip_pvt *p, char *msg, struct sip_request *req, int reliable)
 transmit_response_with_allow: Append Accept header, content length before transmitting response ---
static int transmit_response_with_auth (struct sip_pvt *p, char *msg, struct sip_request *req, char *rand, int reliable, char *header, int stale)
static int transmit_response_with_date (struct sip_pvt *p, char *msg, struct sip_request *req)
 transmit_response_with_date: Append date and content length before transmitting response ---
static int transmit_response_with_sdp (struct sip_pvt *p, char *msg, struct sip_request *req, int retrans)
 transmit_response_with_sdp: Used for 200 OK and 183 early media ---
static int transmit_response_with_unsupported (struct sip_pvt *p, char *msg, struct sip_request *req, char *unsupported)
 transmit_response_with_unsupported: Transmit response, no retransmits
static int transmit_sip_request (struct sip_pvt *p, struct sip_request *req)
 transmit_sip_request: Transmit SIP request
static int transmit_state_notify (struct sip_pvt *p, int state, int full, int substate)
 transmit_state_notify: Used in the SUBSCRIBE notification subsystem ----
static void try_suggested_sip_codec (struct sip_pvt *p)
 Try setting codec suggested by the SIP_CODEC channel variable.
int unload_module ()
 Cleanup all module structures, sockets, etc.
static int update_call_counter (struct sip_pvt *fup, int event)
 update_call_counter: Handle call_limit for SIP users Note: This is going to be replaced by app_groupcount Thought: For realtime, we should propably update storage with inuse counter...
static void update_peer (struct sip_peer *p, int expiry)
 update_peer: Update peer data in database (if used) ---
int usecount ()
 Provides a usecount.

Variables

static struct in_addr __ourip
static const struct cfalias aliases []
 Structure for conversion between compressed SIP and "normal" SIP.
int allow_external_domains
static int apeerobjs = 0
static char * app_dtmfmode = "SIPDtmfMode"
static char * app_sipaddheader = "SIPAddHeader"
static char * app_sipgetheader = "SIPGetHeader"
static struct sip_authauthl
static int autocreatepeer = 0
static struct sockaddr_in bindaddr = { 0, }
static int callevents = 0
static const char channeltype [] = "SIP"
static struct ast_custom_function checksipdomain_function
static int compactheaders = 0
static const char config [] = "sip.conf"
static char debug_usage []
static struct sockaddr_in debugaddr
static char default_callerid [AST_MAX_EXTENSION] = DEFAULT_CALLERID
static char default_context [AST_MAX_CONTEXT] = DEFAULT_CONTEXT
static int default_expiry = DEFAULT_DEFAULT_EXPIRY
static char default_fromdomain [AST_MAX_EXTENSION] = ""
static char default_language [MAX_LANGUAGE] = ""
static char default_notifymime [AST_MAX_EXTENSION] = DEFAULT_NOTIFYMIME
static int default_qualify = 0
static char default_subscribecontext [AST_MAX_CONTEXT]
static char default_useragent [AST_MAX_EXTENSION] = DEFAULT_USERAGENT
static const char desc [] = "Session Initiation Protocol (SIP)"
static char * descrip_dtmfmode = "SIPDtmfMode(inband|info|rfc2833): Changes the dtmfmode for a SIP call\n"
static char * descrip_sipaddheader
static char * descrip_sipgetheader
static int dumphistory = 0
static int expiry = DEFAULT_EXPIRY
static time_t externexpire = 0
static char externhost [MAXHOSTNAMELEN] = ""
static struct sockaddr_in externip
static int externrefresh = 10
static int global_allowguest = 1
static int global_capability = AST_FORMAT_ULAW | AST_FORMAT_ALAW | AST_FORMAT_GSM | AST_FORMAT_H263
 Codecs that we support by default:.
static struct ast_flags global_flags = {0}
static struct ast_flags global_flags_page2 = {0}
static char global_musicclass [MAX_MUSICCLASS] = ""
static int global_mwitime = DEFAULT_MWITIME
static int global_notifyringing = 1
static char global_realm [MAXHOSTNAMELEN] = DEFAULT_REALM
static int global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT
static int global_regattempts_max = 0
static int global_rtautoclear
static int global_rtpholdtimeout = 0
static int global_rtpkeepalive = 0
static int global_rtptimeout = 0
static char global_vmexten [AST_MAX_EXTENSION] = DEFAULT_VMEXTEN
static char history_usage []
static struct sip_pvtiflist
 sip_pvt: PVT structures are used for each SIP conversation, ie. a call
static struct io_contextio
static struct ast_halocaladdr
static char mandescr_show_peer []
static char mandescr_show_peers []
static int max_expiry = DEFAULT_MAX_EXPIRY
static pthread_t monitor_thread = AST_PTHREADT_NULL
 This is the thread for the monitor which checks for input on the channels which are not currently in use.
static struct ast_cli_entry my_clis []
static char no_debug_usage []
static char no_history_usage []
static int noncodeccapability = AST_RTP_DTMF
static const char notify_config [] = "sip_notify.conf"
ast_confignotify_types
static char notify_usage []
static int ourport
static struct sockaddr_in outboundproxyip
static int pedanticsipchecking = 0
static struct ast_peer_list peerl
 The peer list: Peers and Friends ---.
static struct ast_codec_pref prefs
static char prune_realtime_usage []
static int recordhistory = 0
static char regcontext [AST_MAX_CONTEXT] = ""
static struct ast_register_list regl
 The register list: Other SIP proxys we register with and call ---.
static int regobjs = 0
static int relaxdtmf = 0
static int rpeerobjs = 0
static int ruserobjs = 0
static struct sched_contextsched
static char show_channel_usage []
static char show_channels_usage []
static char show_domains_usage []
static char show_history_usage []
static char show_inuse_usage []
static char show_objects_usage []
static char show_peer_usage []
static char show_peers_usage []
static char show_reg_usage []
static char show_settings_usage []
static char show_subscriptions_usage []
static char show_user_usage []
static char show_users_usage []
static struct ast_custom_function sip_header_function
enum sipmethod sip_method_list
static const struct cfsip_methods sip_methods []
static const struct cfsip_options sip_options []
 List of well-known SIP options. If we get this in a require, we should check the list and answer accordingly.
static char sip_reload_usage []
static int sip_reloading = 0
static struct ast_rtp_protocol sip_rtp
 sip_rtp: Interface structure with callbacks used to connect to rtp module --
static const struct ast_channel_tech sip_tech
 Definition of this channel for PBX channel registration.
static struct ast_custom_function sipchaninfo_function
static int sipdebug = 0
ast_custom_function sippeer_function
static int sipsock = -1
static int speerobjs = 0
static int srvlookup = 0
static const struct cfsubscription_types subscription_types []
static int suserobjs = 0
static char * synopsis_dtmfmode = "Change the dtmfmode for a SIP call"
static char * synopsis_sipaddheader = "Add a SIP header to the outbound call"
static char * synopsis_sipgetheader = "Get a SIP header from an incoming call"
static int tos = 0
static int usecnt = 0
static struct ast_user_list userl
 The user list: Users and friends ---.
static int videosupport = 0


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.

Referenced by ael_debug_read(), and ast_ael_compile().

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

Referenced by reload_config().

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

Referenced by reload_config().

#define DEFAULT_MAX_FORWARDS   "70"
 

Definition at line 104 of file chan_sip.c.

Referenced by 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.

Referenced by reload_config().

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

Referenced by reload_config().

#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(), create_addr(), parse_ok_contact(), parse_register_contact(), reload_config(), set_destination(), 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.

#define EXPIRY_GUARD_PCT   0.20
 

Definition at line 115 of file chan_sip.c.

#define EXPIRY_GUARD_SECS   15
 

Definition at line 108 of file chan_sip.c.

#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 7822 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 7822 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 7822 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 7822 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 7822 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 7822 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.

Referenced by handle_response(), handle_response_invite(), and handle_response_register().

#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 registry_rerequest(), regstate2str(), and transmit_register().

#define REG_STATE_FAILED   7
 

Definition at line 809 of file chan_sip.c.

Referenced by regstate2str(), and sip_reg_timeout().

#define REG_STATE_NOAUTH   6
 

Definition at line 808 of file chan_sip.c.

Referenced by registry_rerequest(), and regstate2str().

#define REG_STATE_REGISTERED   3
 

Definition at line 805 of file chan_sip.c.

Referenced by handle_response_register(), iax2_ack_registry(), and regstate2str().

#define REG_STATE_REGSENT   1
 

Definition at line 803 of file chan_sip.c.

Referenced by iax2_do_register(), regstate2str(), and transmit_register().

#define REG_STATE_REJECTED   4
 

Definition at line 806 of file chan_sip.c.

Referenced by regstate2str(), and socket_read().

#define REG_STATE_TIMEOUT   5
 

Definition at line 807 of file chan_sip.c.

Referenced by attempt_transmit(), and regstate2str().

#define REG_STATE_UNREGISTERED   0
 

Definition at line 802 of file chan_sip.c.

Referenced by regstate2str(), and sip_reg_timeout().

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

Referenced by reload_config().

#define SIP_DEBUG_CONSOLE   1 << 1
 

Definition at line 414 of file chan_sip.c.

Referenced by sip_do_debug(), sip_do_debug_ip(), sip_do_debug_peer(), and sip_no_debug().

#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 check_user_full(), create_addr_from_peer(), dtmfmode2str(), handle_common_options(), process_sdp(), and sip_alloc().

#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(), sip_new(), sip_rtp_read(), 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 check_user_full(), create_addr_from_peer(), dtmfmode2str(), handle_common_options(), process_sdp(), reload_config(), sip_alloc(), sip_dtmfmode(), sip_rtp_read(), and sip_senddigit().

#define SIP_DYNAMIC   (1 << 15)
 

Is this a dynamic peer?

Definition at line 527 of file chan_sip.c.

Referenced by _sip_show_peer(), _sip_show_peers(), build_peer(), function_sippeer(), register_verify(), and temp_peer().

#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(), sip_poke_peer(), 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 add_blank_header(), add_header(), and 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 add_line(), and 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(), _sip_show_peers(), build_via(), check_user_full(), check_via(), copy_via_headers(), create_addr_from_peer(), handle_common_options(), parse_ok_contact(), parse_register_contact(), register_verify(), retrans_pkt(), send_request(), send_response(), sip_alloc(), sip_debug_test_pvt(), sip_show_channel(), and sip_show_settings().

#define SIP_NAT_ALWAYS   (3 << 18)
 

Definition at line 539 of file chan_sip.c.

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

#define SIP_NAT_NEVER   (0 << 18)
 

No nat support

Definition at line 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 build_via(), handle_common_options(), nat2str(), and reload_config().

#define SIP_NAT_ROUTE   (2 << 18)
 

Definition at line 538 of file chan_sip.c.

Referenced by __sip_xmit(), _sip_show_peers(), check_user_full(), check_via(), create_addr_from_peer(), handle_common_options(), nat2str(), parse_ok_contact(), parse_register_contact(), retrans_pkt(), send_request(), send_response(), sip_alloc(), and sip_debug_test_pvt().

#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 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_indicate(), and 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(), and sip_indicate().

#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(), and handle_common_options().

#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
 

Enumerator:
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
 

Enumerator:
PARSE_REGISTER_FAILED 
PARSE_REGISTER_UPDATE 
PARSE_REGISTER_QUERY 

Definition at line 5798 of file chan_sip.c.

enum sip_auth_type
 

Enumerator:
PROXY_AUTH 
WWW_AUTH 

Definition at line 200 of file chan_sip.c.

00200                    {
00201    PROXY_AUTH,
00202    WWW_AUTH,
00203 };

enum sipmethod
 

Enumerator:
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.

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
 

Enumerator:
NONE 
TIMEOUT 
XPIDF_XML 
DIALOG_INFO_XML 
CPIM_PIDF_XML 
PIDF_XML 

Definition at line 158 of file chan_sip.c.

00158                       { 
00159    NONE = 0,
00160    TIMEOUT,
00161    XPIDF_XML,
00162    DIALOG_INFO_XML,
00163    CPIM_PIDF_XML,
00164    PIDF_XML
00165 };


Function Documentation

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

Definition at line 2904 of file chan_sip.c.

References sip_request::header, sip_request::headers, pass, and pedanticsipchecking.

02905 {
02906    int pass;
02907 
02908    /*
02909     * Technically you can place arbitrary whitespace both before and after the ':' in
02910     * a header, although RFC3261 clearly says you shouldn't before, and place just
02911     * one afterwards.  If you shouldn't do it, what absolute idiot decided it was 
02912     * a good idea to say you can do it, and if you can do it, why in the hell would.
02913     * you say you shouldn't.
02914     * Anyways, pedanticsipchecking controls whether we allow spaces before ':',
02915     * and we always allow spaces after that for compatibility.
02916     */
02917    for (pass = 0; name && pass < 2;pass++) {
02918       int x, len = strlen(name);
02919       for (x=*start; x<req->headers; x++) {
02920          if (!strncasecmp(req->header[x], name, len)) {
02921             char *r = req->header[x] + len;  /* skip name */
02922             if (pedanticsipchecking)
02923                r = ast_skip_blanks(r);
02924 
02925             if (*r == ':') {
02926                *start = x+1;
02927                return ast_skip_blanks(r+1);
02928             }
02929          }
02930       }
02931       if (pass == 0) /* Try aliases */
02932          name = find_alias(name, NULL);
02933    }
02934 
02935    /* Don't return NULL, so get_header is always a valid pointer */
02936    return "";
02937 }

static 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, and cfsip_methods::text.

Referenced by __sip_pretend_ack(), handle_request(), and handle_response().

01356 {
01357    struct sip_pkt *cur, *prev = NULL;
01358    int res = -1;
01359    int resetinvite = 0;
01360    /* Just in case... */
01361    char *msg;
01362 
01363    msg = sip_methods[sipmethod].text;
01364 
01365    ast_mutex_lock(&p->lock);
01366    cur = p->packets;
01367    while(cur) {
01368       if ((cur->seqno == seqno) && ((ast_test_flag(cur, FLAG_RESPONSE)) == resp) &&
01369          ((ast_test_flag(cur, FLAG_RESPONSE)) || 
01370           (!strncasecmp(msg, cur->data, strlen(msg)) && (cur->data[strlen(msg)] < 33)))) {
01371          if (!resp && (seqno == p->pendinginvite)) {
01372             ast_log(LOG_DEBUG, "Acked pending invite %d\n", p->pendinginvite);
01373             p->pendinginvite = 0;
01374             resetinvite = 1;
01375          }
01376          /* this is our baby */
01377          if (prev)
01378             prev->next = cur->next;
01379          else
01380             p->packets = cur->next;
01381          if (cur->retransid > -1) {
01382             if (sipdebug && option_debug > 3)
01383                ast_log(LOG_DEBUG, "** SIP TIMER: Cancelling retransmit of packet (reply received) Retransid #%d\n", cur->retransid);
01384             ast_sched_del(sched, cur->retransid);
01385          }
01386          free(cur);
01387          res = 0;
01388          break;
01389       }
01390       prev = cur;
01391       cur = cur->next;
01392    }
01393    ast_mutex_unlock(&p->lock);
01394    ast_log(LOG_DEBUG, "Stopping retransmission on '%s' of %s %d: Match %s\n", p->callid, resp ? "Response" : "Request", seqno, res ? "Not Found" : "Found");
01395    return res;
01396 }

static 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, NONE, sip_pvt::owner, sip_destroy(), sip_pvt::subscribed, TIMEOUT, and transmit_state_notify().

Referenced by sip_scheddestroy().

01300 {
01301    struct sip_pvt *p = data;
01302 
01303 
01304    /* If this is a subscription, tell the phone that we got a timeout */
01305    if (p->subscribed) {
01306       p->subscribed = TIMEOUT;
01307       transmit_state_notify(p, AST_EXTENSION_DEACTIVATED, 1, 1);  /* Send first notification */
01308       p->subscribed = NONE;
01309       append_history(p, "Subscribestatus", "timeout");
01310       return 10000;  /* Reschedule this destruction so that we know that it's gone */
01311    }
01312 
01313    /* This scheduled event is now considered done. */
01314    p->autokillid = -1;
01315 
01316    ast_log(LOG_DEBUG, "Auto destroying call '%s'\n", p->callid);
01317    append_history(p, "AutoDestroy", "");
01318    if (p->owner) {
01319       ast_log(LOG_WARNING, "Autodestruct on call '%s' with owner in place\n", p->callid);
01320       ast_queue_hangup(p->owner);
01321    } else {
01322       sip_destroy(p);
01323    }
01324    return 0;
01325 }

static 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::callid, free, free_old_route(), iflist, LOG_DEBUG, LOG_WARNING, sip_pvt::next, oh323_pvt::next, sip_history::next, sip_pkt::retransid, sched, sip_debug_test_pvt(), sip_dump_history(), and sip_registry_destroy().

Referenced by do_monitor(), and sip_destroy().

02097 {
02098    struct sip_pvt *cur, *prev = NULL;
02099    struct sip_pkt *cp;
02100    struct sip_history *hist;
02101 
02102    if (sip_debug_test_pvt(p))
02103       ast_verbose("Destroying call '%s'\n", p->callid);
02104 
02105    if (dumphistory)
02106       sip_dump_history(p);
02107 
02108    if (p->options)
02109       free(p->options);
02110 
02111    if (p->stateid > -1)
02112       ast_extension_state_del(p->stateid, NULL);
02113    if (p->initid > -1)
02114       ast_sched_del(sched, p->initid);
02115    if (p->autokillid > -1)
02116       ast_sched_del(sched, p->autokillid);
02117 
02118    if (p->rtp) {
02119       ast_rtp_destroy(p->rtp);
02120    }
02121    if (p->vrtp) {
02122       ast_rtp_destroy(p->vrtp);
02123    }
02124    if (p->route) {
02125       free_old_route(p->route);
02126       p->route = NULL;
02127    }
02128    if (p->registry) {
02129       if (p->registry->call == p)
02130          p->registry->call = NULL;
02131       ASTOBJ_UNREF(p->registry,sip_registry_destroy);
02132    }
02133 
02134    if (p->rpid)
02135       free(p->rpid);
02136 
02137    if (p->rpid_from)
02138       free(p->rpid_from);
02139 
02140    /* Unlink us from the owner if we have one */
02141    if (p->owner) {
02142       if (lockowner)
02143          ast_mutex_lock(&p->owner->lock);
02144       ast_log(LOG_DEBUG, "Detaching from %s\n", p->owner->name);
02145       p->owner->tech_pvt = NULL;
02146       if (lockowner)
02147          ast_mutex_unlock(&p->owner->lock);
02148    }
02149    /* Clear history */
02150    while(p->history) {
02151       hist = p->history;
02152       p->history = p->history->next;
02153       free(hist);
02154    }
02155 
02156    cur = iflist;
02157    while(cur) {
02158       if (cur == p) {
02159          if (prev)
02160             prev->next = cur->next;
02161          else
02162             iflist = cur->next;
02163          break;
02164       }
02165       prev = cur;
02166       cur = cur->next;
02167    }
02168    if (!cur) {
02169       ast_log(LOG_WARNING, "Trying to destroy \"%s\", not found in dialog list?!?! \n", p->callid);
02170       return;
02171    } 
02172    if (p->initid > -1)
02173       ast_sched_del(sched, p->initid);
02174 
02175    while((cp = p->packets)) {
02176       p->packets = p->packets->next;
02177       if (cp->retransid > -1) {
02178          ast_sched_del(sched, cp->retransid);
02179       }
02180       free(cp);
02181    }
02182    if (p->chanvars) {
02183       ast_variables_destroy(p->chanvars);
02184       p->chanvars = NULL;
02185    }
02186    ast_mutex_destroy(&p->lock);
02187    free(p);
02188 }

static int __sip_do_register struct sip_registry r  )  [static]
 

__sip_do_register: Register with SIP proxy ---

Definition at line 5268 of file chan_sip.c.

References SIP_REGISTER, and transmit_register().

Referenced by sip_reregister().

05269 {
05270    int res;
05271 
05272    res = transmit_register(r, SIP_REGISTER, NULL, NULL);
05273    return res;
05274 }

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

static 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, DEFAULT_RETRANS, FLAG_FATAL, sip_pkt::flags, LOG_DEBUG, malloc, sip_pkt::method, sip_pkt::next, option_debug, sip_pkt::owner, sip_pkt::packetlen, sip_pvt::packets, sip_pvt::pendinginvite, retrans_pkt(), sched, sip_pkt::seqno, SIP_INVITE, sip_pvt::timer_t1, and sip_pkt::timer_t1.

Referenced by send_request(), and send_response().

01261 {
01262    struct sip_pkt *pkt;
01263    int siptimer_a = DEFAULT_RETRANS;
01264 
01265    pkt = malloc(sizeof(struct sip_pkt) + len + 1);
01266    if (!pkt)
01267       return -1;
01268    memset(pkt, 0, sizeof(struct sip_pkt));
01269    memcpy(pkt->data, data, len);
01270    pkt->method = sipmethod;
01271    pkt->packetlen = len;
01272    pkt->next = p->packets;
01273    pkt->owner = p;
01274    pkt->seqno = seqno;
01275    pkt->flags = resp;
01276    pkt->data[len] = '\0';
01277    pkt->timer_t1 = p->timer_t1;  /* Set SIP timer T1 */
01278    if (fatal)
01279       ast_set_flag(pkt, FLAG_FATAL);
01280    if (pkt->timer_t1)
01281       siptimer_a = pkt->timer_t1 * 2;
01282 
01283    /* Schedule retransmission */
01284    pkt->retransid = ast_sched_add_variable(sched, siptimer_a, retrans_pkt, pkt, 1);
01285    if (option_debug > 3 && sipdebug)
01286       ast_log(LOG_DEBUG, "*** SIP TIMER: Initalizing retransmit timer on packet: Id  #%d\n", pkt->retransid);
01287    pkt->next = p->packets;
01288    p->packets = pkt;
01289 
01290    __sip_xmit(pkt->owner, pkt->data, pkt->packetlen); /* Send packet */
01291    if (sipmethod == SIP_INVITE) {
01292       /* Note this is a pending invite */
01293       p->pendinginvite = seqno;
01294    }
01295    return 0;
01296 }

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

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

Definition at line 8278 of file chan_sip.c.

References ast_cli(), ast_extension_state2str(), ast_getformatname(), ast_inet_ntoa(), ast_mutex_lock(), ast_mutex_unlock(), ast_strlen_zero(), ast_test_flag, sip_pvt::callid, sip_pvt::cid_num, sip_pvt::exten, FORMAT, FORMAT2, FORMAT3, sip_pvt::icseq, iflist, sip_pvt::lastmsg, sip_pvt::laststate, ast_channel::nativeformats, sip_pvt::next, NONE, sip_pvt::ocseq, sip_pvt::owner, RESULT_SHOWUSAGE, RESULT_SUCCESS, sip_pvt::sa, SIP_CALL_ONHOLD, SIP_NEEDDESTROY, sip_pvt::subscribed, subscription_type2str(), and sip_pvt::username.

Referenced by sip_show_channels(), and sip_show_subscriptions().

08279 {
08280 #define FORMAT3 "%-15.15s  %-10.10s  %-11.11s  %-15.15s  %-13.13s  %-15.15s\n"
08281 #define FORMAT2 "%-15.15s  %-10.10s  %-11.11s  %-11.11s  %-4.4s  %-7.7s  %-15.15s\n"
08282 #define FORMAT  "%-15.15s  %-10.10s  %-11.11s  %5.5d/%5.5d  %-4.4s  %-3.3s %-3.3s  %-15.15s\n"
08283    struct sip_pvt *cur;
08284    char iabuf[INET_ADDRSTRLEN];
08285    int numchans = 0;
08286    if (argc != 3)
08287       return RESULT_SHOWUSAGE;
08288    ast_mutex_lock(&iflock);
08289    cur = iflist;
08290    if (!subscriptions)
08291       ast_cli(fd, FORMAT2, "Peer", "User/ANR", "Call ID", "Seq (Tx/Rx)", "Format", "Hold", "Last Message");
08292    else
08293       ast_cli(fd, FORMAT3, "Peer", "User", "Call ID", "Extension", "Last state", "Type");
08294    while (cur) {
08295       if (cur->subscribed == NONE && !subscriptions) {
08296          ast_cli(fd, FORMAT, ast_inet_ntoa(iabuf, sizeof(iabuf), cur->sa.sin_addr), 
08297             ast_strlen_zero(cur->username) ? ( ast_strlen_zero(cur->cid_num) ? "(None)" : cur->cid_num ) : cur->username, 
08298             cur->callid, 
08299             cur->ocseq, cur->icseq, 
08300             ast_getformatname(cur->owner ? cur->owner->nativeformats : 0), 
08301             ast_test_flag(cur, SIP_CALL_ONHOLD) ? "Yes" : "No",
08302             ast_test_flag(cur, SIP_NEEDDESTROY) ? "(d)" : "",
08303             cur->lastmsg );
08304          numchans++;
08305       }
08306       if (cur->subscribed != NONE && subscriptions) {
08307          ast_cli(fd, FORMAT3, ast_inet_ntoa(iabuf, sizeof(iabuf), cur->sa.sin_addr),
08308                  ast_strlen_zero(cur->username) ? ( ast_strlen_zero(cur->cid_num) ? "(None)" : cur->cid_num ) : cur->username, 
08309                  cur->callid, cur->exten, ast_extension_state2str(cur->laststate), 
08310                  subscription_type2str(cur->subscribed));
08311          numchans++;
08312       }
08313       cur = cur->next;
08314    }
08315    ast_mutex_unlock(&iflock);
08316    if (!subscriptions)
08317       ast_cli(fd, "%d active SIP channel%s\n", numchans, (numchans != 1) ? "s" : "");
08318    else
08319       ast_cli(fd, "%d active SIP subscription%s\n", numchans, (numchans != 1) ? "s" : "");
08320    return RESULT_SUCCESS;
08321 #undef FORMAT
08322 #undef FORMAT2
08323 #undef FORMAT3
08324 }

static 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, SIP_NAT_ROUTE, and sipsock.

Referenced by __sip_reliable_xmit(), retrans_pkt(), send_request(), and send_response().

01056 {
01057    int res;
01058    char iabuf[INET_ADDRSTRLEN];
01059 
01060    if (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE)
01061       res=sendto(sipsock, data, len, 0, (struct sockaddr *)&p->recv, sizeof(struct sockaddr_in));
01062    else
01063       res=sendto(sipsock, data, len, 0, (struct sockaddr *)&p->sa, sizeof(struct sockaddr_in));
01064 
01065    if (res != len) {
01066       ast_log(LOG_WARNING, "sip_xmit of %p (len %d) to %s:%d returned %d: %s\n", data, len, ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr), ntohs(p->sa.sin_port), res, strerror(errno));
01067    }
01068    return res;
01069 }

static 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 4131 of file chan_sip.c.

References add_blank_header(), add_header(), add_header_contentLength(), ast_cause2str(), ast_log(), get_header(), ast_channel::hangupcause, LOG_WARNING, sip_pvt::owner, respprep(), and send_response().

Referenced by transmit_response(), and transmit_response_reliable().

04132 {
04133    struct sip_request resp;
04134    int seqno = 0;
04135 
04136    if (reliable && (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1)) {
04137       ast_log(LOG_WARNING, "Unable to determine sequence number from '%s'\n", get_header(req, "CSeq"));
04138       return -1;
04139    }
04140    respprep(&resp, p, msg, req);
04141    add_header_contentLength(&resp, 0);
04142    /* If we are cancelling an incoming invite for some reason, add information
04143       about the reason why we are doing this in clear text */
04144    if (msg[0] != '1' && p->owner && p->owner->hangupcause) {
04145       add_header(&resp, "X-Asterisk-HangupCause", ast_cause2str(p->owner->hangupcause));
04146    }
04147    add_blank_header(&resp);
04148    return send_response(p, &resp, reliable, seqno);
04149 }

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

Definition at line 7885 of file chan_sip.c.

References sip_peer::accountcode, sip_peer::addr, sip_peer::amaflags, ast_callerid_merge(), ast_cdr_flags2str(), ast_cli(), ast_describe_caller_presentation(), ast_getformatname_multiple(), ast_inet_ntoa(), ast_strlen_zero(), ast_test_flag, astman_send_error(), ASTOBJ_UNREF, sip_peer::auth, sip_peer::call_limit, sip_peer::callgroup, sip_peer::callingpres, sip_peer::capability, sip_peer::chanvars, sip_peer::cid_name, sip_peer::cid_num, sip_peer::context, sip_peer::defaddr, dtmfmode2str(), sip_peer::expire, find_peer(), sip_peer::fromdomain, sip_peer::fromuser, sip_peer::fullcontact, sip_peer::ha, insecure2str(), sip_peer::language, sip_peer::lastmsg, sip_peer::lastmsgssent, sip_peer::mailbox, sip_auth::md5secret, sip_peer::md5secret, ast_variable::name, nat2str(), ast_variable::next, sip_auth::next, peer_status(), sip_peer::pickupgroup, sip_peer::prefs, print_codec_to_cli(), print_group(), sip_auth::realm, RESULT_SHOWUSAGE, s, sip_auth::secret, sip_peer::secret, SIP_CAN_REINVITE, sip_destroy_peer(), SIP_DTMF, SIP_DYNAMIC, SIP_INSECURE_INVITE, SIP_INSECURE_PORT, SIP_NAT, sip_options, SIP_PROMISCREDIR, SIP_SENDRPID, SIP_TRUSTRPID, SIP_USEREQPHONE, sip_peer::sipoptions, sip_peer::subscribecontext, text, sip_peer::tohost, sip_peer::useragent, sip_peer::username, sip_auth::username, ast_variable::value, and sip_peer::vmexten.

Referenced by manager_sip_show_peer(), and sip_show_peer().

07886 {
07887    char status[30] = "";
07888    char cbuf[256];
07889    char iabuf[INET_ADDRSTRLEN];
07890    struct sip_peer *peer;
07891    char codec_buf[512];
07892    struct ast_codec_pref *pref;
07893    struct ast_variable *v;
07894    struct sip_auth *auth;
07895    int x = 0, codec = 0, load_realtime = 0;
07896 
07897    if (argc < 4)
07898       return RESULT_SHOWUSAGE;
07899 
07900    load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? 1 : 0;
07901    peer = find_peer(argv[3], NULL, load_realtime);
07902    if (s) {    /* Manager */
07903       if (peer)
07904          ast_cli(s->fd, "Response: Success\r\n");
07905       else {
07906          snprintf (cbuf, sizeof(cbuf), "Peer %s not found.\n", argv[3]);
07907          astman_send_error(s, m, cbuf);
07908          return 0;
07909       }
07910    }
07911    if (peer && type==0 ) { /* Normal listing */
07912       ast_cli(fd,"\n\n");
07913       ast_cli(fd, "  * Name       : %s\n", peer->name);
07914       ast_cli(fd, "  Secret       : %s\n", ast_strlen_zero(peer->secret)?"<Not set>":"<Set>");
07915       ast_cli(fd, "  MD5Secret    : %s\n", ast_strlen_zero(peer->md5secret)?"<Not set>":"<Set>");
07916       auth = peer->auth;
07917       while(auth) {
07918          ast_cli(fd, "  Realm-auth   : Realm %-15.15s User %-10.20s ", auth->realm, auth->username);
07919          ast_cli(fd, "%s\n", !ast_strlen_zero(auth->secret)?"<Secret set>":(!ast_strlen_zero(auth->md5secret)?"<MD5secret set>" : "<Not set>"));
07920          auth = auth->next;
07921       }
07922       ast_cli(fd, "  Context      : %s\n", peer->context);
07923       ast_cli(fd, "  Subscr.Cont. : %s\n", ast_strlen_zero(peer->subscribecontext)?"<Not set>":peer->subscribecontext);
07924       ast_cli(fd, "  Language     : %s\n", peer->language);
07925       if (!ast_strlen_zero(peer->accountcode))
07926          ast_cli(fd, "  Accountcode  : %s\n", peer->accountcode);
07927       ast_cli(fd, "  AMA flags    : %s\n", ast_cdr_flags2str(peer->amaflags));
07928       ast_cli(fd, "  CallingPres  : %s\n", ast_describe_caller_presentation(peer->callingpres));
07929       if (!ast_strlen_zero(peer->fromuser))
07930          ast_cli(fd, "  FromUser     : %s\n", peer->fromuser);
07931       if (!ast_strlen_zero(peer->fromdomain))
07932          ast_cli(fd, "  FromDomain   : %s\n", peer->fromdomain);
07933       ast_cli(fd, "  Callgroup    : ");
07934       print_group(fd, peer->callgroup, 0);
07935       ast_cli(fd, "  Pickupgroup  : ");
07936       print_group(fd, peer->pickupgroup, 0);
07937       ast_cli(fd, "  Mailbox      : %s\n", peer->mailbox);
07938       ast_cli(fd, "  VM Extension : %s\n", peer->vmexten);
07939       ast_cli(fd, "  LastMsgsSent : %d\n", peer->lastmsgssent);
07940       ast_cli(fd, "  Call limit   : %d\n", peer->call_limit);
07941       ast_cli(fd, "  Dynamic      : %s\n", (ast_test_flag(peer, SIP_DYNAMIC)?"Yes":"No"));
07942       ast_cli(fd, "  Callerid     : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>"));
07943       ast_cli(fd, "  Expire       : %d\n", peer->expire);
07944       ast_cli(fd, "  Insecure     : %s\n", insecure2str(ast_test_flag(peer, SIP_INSECURE_PORT), ast_test_flag(peer, SIP_INSECURE_INVITE)));
07945       ast_cli(fd, "  Nat          : %s\n", nat2str(ast_test_flag(peer, SIP_NAT)));
07946       ast_cli(fd, "  ACL          : %s\n", (peer->ha?"Yes":"No"));
07947       ast_cli(fd, "  CanReinvite  : %s\n", (ast_test_flag(peer, SIP_CAN_REINVITE)?"Yes":"No"));
07948       ast_cli(fd, "  PromiscRedir : %s\n", (ast_test_flag(peer, SIP_PROMISCREDIR)?"Yes":"No"));
07949       ast_cli(fd, "  User=Phone   : %s\n", (ast_test_flag(peer, SIP_USEREQPHONE)?"Yes":"No"));
07950       ast_cli(fd, "  Trust RPID   : %s\n", (ast_test_flag(peer, SIP_TRUSTRPID) ? "Yes" : "No"));
07951       ast_cli(fd, "  Send RPID    : %s\n", (ast_test_flag(peer, SIP_SENDRPID) ? "Yes" : "No"));
07952 
07953       /* - is enumerated */
07954       ast_cli(fd, "  DTMFmode     : %s\n", dtmfmode2str(ast_test_flag(peer, SIP_DTMF)));
07955       ast_cli(fd, "  LastMsg      : %d\n", peer->lastmsg);
07956       ast_cli(fd, "  ToHost       : %s\n", peer->tohost);
07957       ast_cli(fd, "  Addr->IP     : %s Port %d\n",  peer->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), peer->addr.sin_addr) : "(Unspecified)", ntohs(peer->addr.sin_port));
07958       ast_cli(fd, "  Defaddr->IP  : %s Port %d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port));
07959       ast_cli(fd, "  Def. Username: %s\n", peer->username);
07960       ast_cli(fd, "  SIP Options  : ");
07961       if (peer->sipoptions) {
07962          for (x=0 ; (x < (sizeof(sip_options) / sizeof(sip_options[0]))); x++) {
07963             if (peer->sipoptions & sip_options[x].id)
07964                ast_cli(fd, "%s ", sip_options[x].text);
07965          }
07966       } else
07967          ast_cli(fd, "(none)");
07968 
07969       ast_cli(fd, "\n");
07970       ast_cli(fd, "  Codecs       : ");
07971       ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability);
07972       ast_cli(fd, "%s\n", codec_buf);
07973       ast_cli(fd, "  Codec Order  : (");
07974       print_codec_to_cli(fd, &peer->prefs);
07975 
07976       ast_cli(fd, ")\n");
07977 
07978       ast_cli(fd, "  Status       : ");
07979       peer_status(peer, status, sizeof(status));
07980       ast_cli(fd, "%s\n",status);
07981       ast_cli(fd, "  Useragent    : %s\n", peer->useragent);
07982       ast_cli(fd, "  Reg. Contact : %s\n", peer->fullcontact);
07983       if (peer->chanvars) {
07984          ast_cli(fd, "  Variables    :\n");
07985          for (v = peer->chanvars ; v ; v = v->next)
07986             ast_cli(fd, "                 %s = %s\n", v->name, v->value);
07987       }
07988       ast_cli(fd,"\n");
07989       ASTOBJ_UNREF(peer,sip_destroy_peer);
07990    } else  if (peer && type == 1) { /* manager listing */
07991       ast_cli(fd, "Channeltype: SIP\r\n");
07992       ast_cli(fd, "ObjectName: %s\r\n", peer->name);
07993       ast_cli(fd, "ChanObjectType: peer\r\n");
07994       ast_cli(fd, "SecretExist: %s\r\n", ast_strlen_zero(peer->secret)?"N":"Y");
07995       ast_cli(fd, "MD5SecretExist: %s\r\n", ast_strlen_zero(peer->md5secret)?"N":"Y");
07996       ast_cli(fd, "Context: %s\r\n", peer->context);
07997       ast_cli(fd, "Language: %s\r\n", peer->language);
07998       if (!ast_strlen_zero(peer->accountcode))
07999          ast_cli(fd, "Accountcode: %s\r\n", peer->accountcode);
08000       ast_cli(fd, "AMAflags: %s\r\n", ast_cdr_flags2str(peer->amaflags));
08001       ast_cli(fd, "CID-CallingPres: %s\r\n", ast_describe_caller_presentation(peer->callingpres));
08002       if (!ast_strlen_zero(peer->fromuser))
08003          ast_cli(fd, "SIP-FromUser: %s\r\n", peer->fromuser);
08004       if (!ast_strlen_zero(peer->fromdomain))
08005          ast_cli(fd, "SIP-FromDomain: %s\r\n", peer->fromdomain);
08006       ast_cli(fd, "Callgroup: ");
08007       print_group(fd, peer->callgroup, 1);
08008       ast_cli(fd, "Pickupgroup: ");
08009       print_group(fd, peer->pickupgroup, 1);
08010       ast_cli(fd, "VoiceMailbox: %s\r\n", peer->mailbox);
08011       ast_cli(fd, "LastMsgsSent: %d\r\n", peer->lastmsgssent);
08012       ast_cli(fd, "Call limit: %d\r\n", peer->call_limit);
08013       ast_cli(fd, "Dynamic: %s\r\n", (ast_test_flag(peer, SIP_DYNAMIC)?"Y":"N"));
08014       ast_cli(fd, "Callerid: %s\r\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, ""));
08015       ast_cli(fd, "RegExpire: %ld seconds\r\n", ast_sched_when(sched,peer->expire));
08016       ast_cli(fd, "SIP-AuthInsecure: %s\r\n", insecure2str(ast_test_flag(peer, SIP_INSECURE_PORT), ast_test_flag(peer, SIP_INSECURE_INVITE)));
08017       ast_cli(fd, "SIP-NatSupport: %s\r\n", nat2str(ast_test_flag(peer, SIP_NAT)));
08018       ast_cli(fd, "ACL: %s\r\n", (peer->ha?"Y":"N"));
08019       ast_cli(fd, "SIP-CanReinvite: %s\r\n", (ast_test_flag(peer, SIP_CAN_REINVITE)?"Y":"N"));
08020       ast_cli(fd, "SIP-PromiscRedir: %s\r\n", (ast_test_flag(peer, SIP_PROMISCREDIR)?"Y":"N"));
08021       ast_cli(fd, "SIP-UserPhone: %s\r\n", (ast_test_flag(peer, SIP_USEREQPHONE)?"Y":"N"));
08022 
08023       /* - is enumerated */
08024       ast_cli(fd, "SIP-DTMFmode: %s\r\n", dtmfmode2str(ast_test_flag(peer, SIP_DTMF)));
08025       ast_cli(fd, "SIPLastMsg: %d\r\n", peer->lastmsg);
08026       ast_cli(fd, "ToHost: %s\r\n", peer->tohost);
08027       ast_cli(fd, "Address-IP: %s\r\nAddress-Port: %d\r\n",  peer->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), peer->addr.sin_addr) : "", ntohs(peer->addr.sin_port));
08028       ast_cli(fd, "Default-addr-IP: %s\r\nDefault-addr-port: %d\r\n", ast_inet_ntoa(iabuf, sizeof(iabuf), peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port));
08029       ast_cli(fd, "Default-Username: %s\r\n", peer->username);
08030       ast_cli(fd, "Codecs: ");
08031       ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability);
08032       ast_cli(fd, "%s\r\n", codec_buf);
08033       ast_cli(fd, "CodecOrder: ");
08034       pref = &peer->prefs;
08035       for(x = 0; x < 32 ; x++) {
08036          codec = ast_codec_pref_index(pref,x);
08037          if (!codec)
08038             break;
08039          ast_cli(fd, "%s", ast_getformatname(codec));
08040          if (x < 31 && ast_codec_pref_index(pref,x+1))
08041             ast_cli(fd, ",");
08042       }
08043 
08044       ast_cli(fd, "\r\n");
08045       ast_cli(fd, "Status: ");
08046       peer_status(peer, status, sizeof(status));
08047       ast_cli(fd, "%s\r\n", status);
08048       ast_cli(fd, "SIP-Useragent: %s\r\n", peer->useragent);
08049       ast_cli(fd, "Reg-Contact : %s\r\n", peer->fullcontact);
08050       if (peer->chanvars) {
08051          for (v = peer->chanvars ; v ; v = v->next) {
08052             ast_cli(fd, "ChanVariable:\n");
08053             ast_cli(fd, " %s,%s\r\n", v->name, v->value);
08054          }
08055       }
08056 
08057       ASTOBJ_UNREF(peer,sip_destroy_peer);
08058 
08059    } else {
08060       ast_cli(fd,"Peer %s not found.\n", argv[3]);
08061       ast_cli(fd,"\n");
08062    }
08063 
08064    return RESULT_SUCCESS;
08065 }

static 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 7463 of file chan_sip.c.

References ast_cli(), ast_inet_ntoa(), ast_strlen_zero(), ast_test_flag, astman_get_header(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, FORMAT, FORMAT2, id, name, peer_status(), peerl, RESULT_SHOWUSAGE, s, SIP_DYNAMIC, SIP_NAT, and SIP_NAT_ROUTE.

Referenced by manager_sip_show_peers(), and sip_show_peers().

07464 {
07465    regex_t regexbuf;
07466    int havepattern = 0;
07467 
07468 #define FORMAT2 "%-25.25s  %-15.15s %-3.3s %-3.3s %-3.3s %-8s %-10s\n"
07469 #define FORMAT  "%-25.25s  %-15.15s %-3.3s %-3.3s %-3.3s %-8d %-10s\n"
07470 
07471    char name[256];
07472    char iabuf[INET_ADDRSTRLEN];
07473    int total_peers = 0;
07474    int peers_online = 0;
07475    int peers_offline = 0;
07476    char *id;
07477    char idtext[256] = "";
07478 
07479    if (s) { /* Manager - get ActionID */
07480       id = astman_get_header(m,"ActionID");
07481       if (!ast_strlen_zero(id))
07482          snprintf(idtext,256,"ActionID: %s\r\n",id);
07483    }
07484 
07485    switch (argc) {
07486    case 5:
07487       if (!strcasecmp(argv[3], "like")) {
07488          if (regcomp(&regexbuf, argv[4], REG_EXTENDED | REG_NOSUB))
07489             return RESULT_SHOWUSAGE;
07490          havepattern = 1;
07491       } else
07492          return RESULT_SHOWUSAGE;
07493    case 3:
07494       break;
07495    default:
07496       return RESULT_SHOWUSAGE;
07497    }
07498 
07499    if (!s) { /* Normal list */
07500       ast_cli(fd, FORMAT2, "Name/username", "Host", "Dyn", "Nat", "ACL", "Port", "Status");
07501    } 
07502    
07503    ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do {
07504       char status[20] = "";
07505       char srch[2000];
07506       char pstatus;
07507       
07508       ASTOBJ_RDLOCK(iterator);
07509 
07510       if (havepattern && regexec(&regexbuf, iterator->name, 0, NULL, 0)) {
07511          ASTOBJ_UNLOCK(iterator);
07512          continue;
07513       }
07514 
07515       if (!ast_strlen_zero(iterator->username) && !s)
07516          snprintf(name, sizeof(name), "%s/%s", iterator->name, iterator->username);
07517       else
07518          ast_copy_string(name, iterator->name, sizeof(name));
07519 
07520       pstatus = peer_status(iterator, status, sizeof(status));
07521       if (pstatus)   
07522          peers_online++;
07523       else  {
07524          if (pstatus == 0)
07525             peers_offline++;
07526          else {   /* Unmonitored */
07527             /* Checking if port is 0 */
07528             if ( ntohs(iterator->addr.sin_port) == 0 ) {
07529                peers_offline++;
07530             } else {
07531                peers_online++;
07532             }
07533          }
07534       }        
07535       
07536       snprintf(srch, sizeof(srch), FORMAT, name,
07537          iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), iterator->addr.sin_addr) : "(Unspecified)",
07538          ast_test_flag(iterator, SIP_DYNAMIC) ? " D " : "   ",    /* Dynamic or not? */
07539          (ast_test_flag(iterator, SIP_NAT) & SIP_NAT_ROUTE) ? " N " : "   ",  /* NAT=yes? */
07540          iterator->ha ? " A " : "   ",    /* permit/deny */
07541          ntohs(iterator->addr.sin_port), status);
07542 
07543       if (!s)  {/* Normal CLI list */
07544          ast_cli(fd, FORMAT, name, 
07545          iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), iterator->addr.sin_addr) : "(Unspecified)",
07546          ast_test_flag(iterator, SIP_DYNAMIC) ? " D " : "   ",  /* Dynamic or not? */
07547          (ast_test_flag(iterator, SIP_NAT) & SIP_NAT_ROUTE) ? " N " : "   ",  /* NAT=yes? */
07548          iterator->ha ? " A " : "   ",       /* permit/deny */
07549          
07550          ntohs(iterator->addr.sin_port), status);
07551       } else { /* Manager format */
07552          /* The names here need to be the same as other channels */
07553          ast_cli(fd, 
07554          "Event: PeerEntry\r\n%s"
07555          "Channeltype: SIP\r\n"
07556          "ObjectName: %s\r\n"
07557          "ChanObjectType: peer\r\n" /* "peer" or "user" */
07558          "IPaddress: %s\r\n"
07559          "IPport: %d\r\n"
07560          "Dynamic: %s\r\n"
07561          "Natsupport: %s\r\n"
07562          "ACL: %s\r\n"
07563          "Status: %s\r\n\r\n", 
07564          idtext,
07565          iterator->name, 
07566          iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), iterator->addr.sin_addr) : "-none-",
07567          ntohs(iterator->addr.sin_port), 
07568          ast_test_flag(iterator, SIP_DYNAMIC) ? "yes" : "no",  /* Dynamic or not? */
07569          (ast_test_flag(iterator, SIP_NAT) & SIP_NAT_ROUTE) ? "yes" : "no",   /* NAT=yes? */
07570          iterator->ha ? "yes" : "no",       /* permit/deny */
07571          status);
07572       }
07573 
07574       ASTOBJ_UNLOCK(iterator);
07575 
07576       total_peers++;
07577    } while(0) );
07578 
07579    if (!s) {
07580       ast_cli(fd,"%d sip peers [%d online , %d offline]\n",total_peers,peers_online,peers_offline);
07581    }
07582 
07583    if (havepattern)
07584       regfree(&regexbuf);
07585 
07586    if (total)
07587       *total = total_peers;
07588    
07589 
07590    return RESULT_SUCCESS;
07591 #undef FORMAT
07592 #undef FORMAT2
07593 }

static int add_blank_header struct sip_request req  )  [static]
 

add_blank_header: Add blank header to SIP message

Definition at line 3720 of file chan_sip.c.

References ast_log(), sip_request::data, sip_request::header, sip_request::headers, sip_request::len, sip_request::lines, LOG_WARNING, and SIP_MAX_HEADERS.

Referenced by __transmit_response(), sip_notify(), transmit_invite(), transmit_refer(), transmit_register(), transmit_request(), transmit_request_with_auth(), transmit_response_with_allow(), transmit_response_with_auth(), and transmit_response_with_date().

03721 {
03722    if (req->headers == SIP_MAX_HEADERS)  {
03723       ast_log(LOG_WARNING, "Out of SIP header space\n");
03724       return -1;
03725    }
03726    if (req->lines) {
03727       ast_log(LOG_WARNING, "Can't add more headers when lines have been added\n");
03728       return -1;
03729    }
03730    if (req->len >= sizeof(req->data) - 4) {
03731       ast_log(LOG_WARNING, "Out of space, can't add anymore\n");
03732       return -1;
03733    }
03734    req->header[req->headers] = req->data + req->len;
03735    snprintf(req->header[req->headers], sizeof(req->data) - req->len, "\r\n");
03736    req->len += strlen(req->header[req->headers]);
03737    req->headers++;
03738    return 0;   
03739 }

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

Definition at line 4272 of file chan_sip.c.

References ast_build_string(), AST_FORMAT_G729A, ast_getformatname(), ast_rtp_lookup_code(), ast_rtp_lookup_mime_subtype(), ast_verbose(), and sip_pvt::rtp.

Referenced by add_sdp().

04275 {
04276    int rtp_code;
04277 
04278    if (debug)
04279       ast_verbose("Adding codec 0x%x (%s) to SDP\n", codec, ast_getformatname(codec));
04280    if ((rtp_code = ast_rtp_lookup_code(p->rtp, 1, codec)) == -1)
04281       return;
04282 
04283    ast_build_string(m_buf, m_size, " %d", rtp_code);
04284    ast_build_string(a_buf, a_size, "a=rtpmap:%d %s/%d\r\n", rtp_code,
04285           ast_rtp_lookup_mime_subtype(1, codec),
04286           sample_rate);
04287    if (codec == AST_FORMAT_G729A)
04288       /* Indicate that we don't support VAD (G.729 annex B) */
04289       ast_build_string(a_buf, a_size, "a=fmtp:%d annexb=no\r\n", rtp_code);
04290 }

static int add_digit struct sip_request req,
char  digit
[static]
 

add_digit: add DTMF INFO tone to sip message ---

Definition at line 4241 of file chan_sip.c.

References add_header(), add_header_contentLength(), and add_line().

Referenced by transmit_info_with_digit().

04242 {
04243    char tmp[256];
04244 
04245    snprintf(tmp, sizeof(tmp), "Signal=%c\r\nDuration=250\r\n", digit);
04246    add_header(req, "Content-Type", "application/dtmf-relay");
04247    add_header_contentLength(req, strlen(tmp));
04248    add_line(req, tmp);
04249    return 0;
04250 }

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

add_header: Add header to SIP message

Definition at line 3676 of file chan_sip.c.

References aliases, ast_log(), compactheaders, sip_request::data, sip_request::header, sip_request::headers, sip_request::len, sip_request::lines, LOG_WARNING, and SIP_MAX_HEADERS.

03677 {
03678    int x = 0;
03679 
03680    if (req->headers == SIP_MAX_HEADERS) {
03681       ast_log(LOG_WARNING, "Out of SIP header space\n");
03682       return -1;
03683    }
03684 
03685    if (req->lines) {
03686       ast_log(LOG_WARNING, "Can't add more headers when lines have been added\n");
03687       return -1;
03688    }
03689 
03690    if (req->len >= sizeof(req->data) - 4) {
03691       ast_log(LOG_WARNING, "Out of space, can't add anymore (%s:%s)\n", var, value);
03692       return -1;
03693    }
03694 
03695    req->header[req->headers] = req->data + req->len;
03696 
03697    if (compactheaders) {
03698       for (x = 0; x < (sizeof(aliases) / sizeof(aliases[0])); x++)
03699          if (!strcasecmp(aliases[x].fullname, var))
03700             var = aliases[x].shortname;
03701    }
03702 
03703    snprintf(req->header[req->headers], sizeof(req->data) - req->len - 4, "%s: %s\r\n", var, value);
03704    req->len += strlen(req->header[req->headers]);
03705    req->headers++;
03706 
03707    return 0;   
03708 }

static int add_header_contentLength struct sip_request req,
int  len
[static]
 

add_header_contentLen: Add 'Content-Length' header to SIP message

Definition at line 3711 of file chan_sip.c.

References add_header().

Referenced by __transmit_response(), add_digit(), add_text(), add_vidupdate(), transmit_invite(), transmit_notify_with_mwi(), transmit_notify_with_sipfrag(), transmit_register(), transmit_request(), transmit_request_with_auth(), transmit_response_with_allow(), transmit_response_with_auth(), transmit_response_with_date(), and transmit_state_notify().

03712 {
03713    char clen[10];
03714 
03715    snprintf(clen, sizeof(clen), "%d", len);
03716    return add_header(req, "Content-Length", clen);
03717 }

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

add_line: Add content (not header) to SIP message

Definition at line 3742 of file chan_sip.c.

References ast_log(), sip_request::data, sip_request::len, sip_request::line, sip_request::lines, LOG_WARNING, and SIP_MAX_LINES.

03743 {
03744    if (req->lines == SIP_MAX_LINES)  {
03745       ast_log(LOG_WARNING, "Out of SIP line space\n");
03746       return -1;
03747    }
03748    if (!req->lines) {
03749       /* Add extra empty return */
03750       snprintf(req->data + req->len, sizeof(req->data) - req->len, "\r\n");
03751       req->len += strlen(req->data + req->len);
03752    }
03753    if (req->len >= sizeof(req->data) - 4) {
03754       ast_log(LOG_WARNING, "Out of space, can't add anymore\n");
03755       return -1;
03756    }
03757    req->line[req->lines] = req->data + req->len;
03758    snprintf(req->line[req->lines], sizeof(req->data) - req->len, "%s", line);
03759    req->len += strlen(req->line[req->lines]);
03760    req->lines++;
03761    return 0;   
03762 }

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

Definition at line 4292 of file chan_sip.c.

References ast_build_string(), AST_RTP_DTMF, ast_rtp_lookup_code(), ast_rtp_lookup_mime_subtype(), ast_verbose(), and sip_pvt::rtp.

04295 {
04296    int rtp_code;
04297 
04298    if (debug)
04299       ast_verbose("Adding non-codec 0x%x (%s) to SDP\n", format, ast_rtp_lookup_mime_subtype(0, format));
04300    if ((rtp_code = ast_rtp_lookup_code(p->rtp, 0, format)) == -1)
04301       return;
04302 
04303    ast_build_string(m_buf, m_size, " %d", rtp_code);
04304    ast_build_string(a_buf, a_size, "a=rtpmap:%d %s/%d\r\n", rtp_code,
04305           ast_rtp_lookup_mime_subtype(0, format),
04306           sample_rate);
04307    if (format == AST_RTP_DTMF)
04308       /* Indicate we support DTMF and FLASH... */
04309       ast_build_string(a_buf, a_size, "a=fmtp:%d 0-16\r\n", rtp_code);
04310 }

static 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 11799 of file chan_sip.c.

References ast_log(), ast_strlen_zero(), ast_verbose(), LOG_DEBUG, LOG_ERROR, LOG_WARNING, malloc, sip_auth::md5secret, sip_auth::next, option_verbose, sip_auth::realm, secret, strsep(), and username.

Referenced by build_peer(), and reload_config().

11800 {
11801    char authcopy[256];
11802    char *username=NULL, *realm=NULL, *secret=NULL, *md5secret=NULL;
11803    char *stringp;
11804    struct sip_auth *auth;
11805    struct sip_auth *b = NULL, *a = authlist;
11806 
11807    if (ast_strlen_zero(configuration))
11808       return authlist;
11809 
11810    ast_log(LOG_DEBUG, "Auth config ::  %s\n", configuration);
11811 
11812    ast_copy_string(authcopy, configuration, sizeof(authcopy));
11813    stringp = authcopy;
11814 
11815    username = stringp;
11816    realm = strrchr(stringp, '@');
11817    if (realm) {
11818       *realm = '\0';
11819       realm++;
11820    }
11821    if (ast_strlen_zero(username) || ast_strlen_zero(realm)) {
11822       ast_log(LOG_WARNING, "Format for authentication entry is user[:secret]@realm at line %d\n", lineno);
11823       return authlist;
11824    }
11825    stringp = username;
11826    username = strsep(&stringp, ":");
11827    if (username) {
11828       secret = strsep(&stringp, ":");
11829       if (!secret) {
11830          stringp = username;
11831          md5secret = strsep(&stringp,"#");
11832       }
11833    }
11834    auth = malloc(sizeof(struct sip_auth));
11835    if (auth) {
11836       memset(auth, 0, sizeof(struct sip_auth));
11837       ast_copy_string(auth->realm, realm, sizeof(auth->realm));
11838       ast_copy_string(auth->username, username, sizeof(auth->username));
11839       if (secret)
11840          ast_copy_string(auth->secret, secret, sizeof(auth->secret));
11841       if (md5secret)
11842          ast_copy_string(auth->md5secret, md5secret, sizeof(auth->md5secret));
11843    } else {
11844       ast_log(LOG_ERROR, "Allocation of auth structure failed, Out of memory\n");
11845       return authlist;
11846    }
11847 
11848    /* Add authentication to authl */
11849    if (!authlist) {  /* No existing list */
11850       return auth;
11851    } 
11852    while(a) {
11853       b = a;
11854       a = a->next;
11855    }
11856    b->next = auth;   /* Add structure add end of list */
11857 
11858    if (option_verbose > 2)
11859       ast_verbose("Added authentication for realm %s\n", realm);
11860 
11861    return authlist;
11862 
11863 }

static 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 3860 of file chan_sip.c.

References add_header(), sip_route::hop, n, and sip_route::next.

Referenced by reqprep().

03861 {
03862    char r[256], *p;
03863    int n, rem = sizeof(r);
03864 
03865    if (!route) return;
03866 
03867    p = r;
03868    while (route) {
03869       n = strlen(route->hop);
03870       if ((n+3)>rem) break;
03871       if (p != r) {
03872          *p++ = ',';
03873          --rem;
03874       }
03875       *p++ = '<';
03876       ast_copy_string(p, route->hop, rem);  p += n;
03877       *p++ = '>';
03878       rem -= (n+2);
03879       route = route->next;
03880    }
03881    *p = '\0';
03882    add_header(req, "Route", r);
03883 }

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

add_sdp: Add Session Description Protocol message ---

Definition at line 4313 of file chan_sip.c.

References add_codec_to_sdp(), ast_build_string(), ast_codec_pref_index(), AST_FORMAT_MAX_AUDIO, ast_inet_ntoa(), ast_log(), ast_rtp_get_us(), ast_verbose(), capability, debug, sip_pvt::jointcapability, sip_request::len, LOG_WARNING, sip_pvt::ourip, sip_pvt::prefcodec, sip_pvt::prefs, sip_pvt::redircodecs, sip_pvt::redirip, sip_pvt::rtp, s, sip_pvt::sessionid, sip_pvt::sessionversion, sip_debug_test_pvt(), t, sip_pvt::vredirip, and sip_pvt::vrtp.

04314 {
04315    int len = 0;
04316    int pref_codec;
04317    int alreadysent = 0;
04318    struct sockaddr_in sin;
04319    struct sockaddr_in vsin;
04320    char v[256];
04321    char s[256];
04322    char o[256];
04323    char c[256];
04324    char t[256];
04325    char m_audio[256];
04326    char m_video[256];
04327    char a_audio[1024];
04328    char a_video[1024];
04329    char *m_audio_next = m_audio;
04330    char *m_video_next = m_video;
04331    size_t m_audio_left = sizeof(m_audio);
04332    size_t m_video_left = sizeof(m_video);
04333    char *a_audio_next = a_audio;
04334    char *a_video_next = a_video;
04335    size_t a_audio_left = sizeof(a_audio);
04336    size_t a_video_left = sizeof(a_video);
04337    char iabuf[INET_ADDRSTRLEN];
04338    int x;
04339    int capability;
04340    struct sockaddr_in dest;
04341    struct sockaddr_in vdest = { 0, };
04342    int debug;
04343    
04344    debug = sip_debug_test_pvt(p);
04345 
04346    len = 0;
04347    if (!p->rtp) {
04348       ast_log(LOG_WARNING, "No way to add SDP without an RTP structure\n");
04349       return -1;
04350    }
04351    capability = p->jointcapability;
04352       
04353    if (!p->sessionid) {
04354       p->sessionid = getpid();
04355       p->sessionversion = p->sessionid;
04356    } else
04357       p->sessionversion++;
04358    ast_rtp_get_us(p->rtp, &sin);
04359    if (p->vrtp)
04360       ast_rtp_get_us(p->vrtp, &vsin);
04361 
04362    if (p->redirip.sin_addr.s_addr) {
04363       dest.sin_port = p->redirip.sin_port;
04364       dest.sin_addr = p->redirip.sin_addr;
04365       if (p->redircodecs)
04366          capability = p->redircodecs;
04367    } else {
04368       dest.sin_addr = p->ourip;
04369       dest.sin_port = sin.sin_port;
04370    }
04371 
04372    /* Determine video destination */
04373    if (p->vrtp) {
04374       if (p->vredirip.sin_addr.s_addr) {
04375          vdest.sin_port = p->vredirip.sin_port;
04376          vdest.sin_addr = p->vredirip.sin_addr;
04377       } else {
04378          vdest.sin_addr = p->ourip;
04379          vdest.sin_port = vsin.sin_port;
04380       }
04381    }
04382    if (debug){
04383       ast_verbose("We're at %s port %d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip), ntohs(sin.sin_port));   
04384       if (p->vrtp)
04385          ast_verbose("Video is at %s port %d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip), ntohs(vsin.sin_port));  
04386    }
04387 
04388    /* We break with the "recommendation" and send our IP, in order that our
04389       peer doesn't have to ast_gethostbyname() us */
04390 
04391    snprintf(v, sizeof(v), "v=0\r\n");
04392    snprintf(o, sizeof(o), "o=root %d %d IN IP4 %s\r\n", p->sessionid, p->sessionversion, ast_inet_ntoa(iabuf, sizeof(iabuf), dest.sin_addr));
04393    snprintf(s, sizeof(s), "s=session\r\n");
04394    snprintf(c, sizeof(c), "c=IN IP4 %s\r\n", ast_inet_ntoa(iabuf, sizeof(iabuf), dest.sin_addr));
04395    snprintf(t, sizeof(t), "t=0 0\r\n");
04396 
04397    ast_build_string(&m_audio_next, &m_audio_left, "m=audio %d RTP/AVP", ntohs(dest.sin_port));
04398    ast_build_string(&m_video_next, &m_video_left, "m=video %d RTP/AVP", ntohs(vdest.sin_port));
04399 
04400    /* Prefer the codec we were requested to use, first, no matter what */
04401    if (capability & p->prefcodec) {
04402       if (p->prefcodec <= AST_FORMAT_MAX_AUDIO)
04403          add_codec_to_sdp(p, p->prefcodec, 8000,
04404                 &m_audio_next, &m_audio_left,
04405                 &a_audio_next, &a_audio_left,
04406                 debug);
04407       else
04408          add_codec_to_sdp(p, p->prefcodec, 90000,
04409                 &m_video_next, &m_video_left,
04410                 &a_video_next, &a_video_left,
04411                 debug);
04412       alreadysent |= p->prefcodec;
04413    }
04414 
04415    /* Start by sending our preferred codecs */
04416    for (x = 0; x < 32; x++) {
04417       if (!(pref_codec = ast_codec_pref_index(&p->prefs, x)))
04418          break; 
04419 
04420       if (!(capability & pref_codec))
04421          continue;
04422 
04423       if (alreadysent & pref_codec)
04424          continue;
04425 
04426       if (pref_codec <= AST_FORMAT_MAX_AUDIO)
04427          add_codec_to_sdp(p, pref_codec, 8000,
04428                 &m_audio_next, &m_audio_left,
04429                 &a_audio_next, &a_audio_left,
04430                 debug);
04431       else
04432          add_codec_to_sdp(p, pref_codec, 90000,
04433                 &m_video_next, &m_video_left,
04434                 &a_video_next, &a_video_left,
04435                 debug);
04436       alreadysent |= pref_codec;
04437    }
04438 
04439    /* Now send any other common codecs, and non-codec formats: */
04440    for (x = 1; x <= ((videosupport && p->vrtp) ? AST_FORMAT_MAX_VIDEO : AST_FORMAT_MAX_AUDIO); x <<= 1) {
04441       if (!(capability & x))
04442          continue;
04443 
04444       if (alreadysent & x)
04445          continue;
04446 
04447       if (x <= AST_FORMAT_MAX_AUDIO)
04448          add_codec_to_sdp(p, x, 8000,
04449                 &m_audio_next, &m_audio_left,
04450                 &a_audio_next, &a_audio_left,
04451                 debug);
04452       else
04453          add_codec_to_sdp(p, x, 90000,
04454                 &m_video_next, &m_video_left,
04455                 &a_video_next, &a_video_left,
04456                 debug);
04457    }
04458 
04459    for (x = 1; x <= AST_RTP_MAX; x <<= 1) {
04460       if (!(p->noncodeccapability & x))
04461          continue;
04462 
04463       add_noncodec_to_sdp(p, x, 8000,
04464                 &m_audio_next, &m_audio_left,
04465                 &a_audio_next, &a_audio_left,
04466                 debug);
04467    }
04468 
04469    ast_build_string(&a_audio_next, &a_audio_left, "a=silenceSupp:off - - - -\r\n");
04470 
04471    if ((m_audio_left < 2) || (m_video_left < 2) || (a_audio_left == 0) || (a_video_left == 0))
04472       ast_log(LOG_WARNING, "SIP SDP may be truncated due to undersized buffer!!\n");
04473 
04474    ast_build_string(&m_audio_next, &m_audio_left, "\r\n");
04475    ast_build_string(&m_video_next, &m_video_left, "\r\n");
04476 
04477    len = strlen(v) + strlen(s) + strlen(o) + strlen(c) + strlen(t) + strlen(m_audio) + strlen(a_audio);
04478    if ((p->vrtp) && (!ast_test_flag(p, SIP_NOVIDEO)) && (capability & VIDEO_CODEC_MASK)) /* only if video response is appropriate */
04479       len += strlen(m_video) + strlen(a_video);
04480 
04481    add_header(resp, "Content-Type", "application/sdp");
04482    add_header_contentLength(resp, len);
04483    add_line(resp, v);
04484    add_line(resp, o);
04485    add_line(resp, s);
04486    add_line(resp, c);
04487    add_line(resp, t);
04488    add_line(resp, m_audio);
04489    add_line(resp, a_audio);
04490    if ((p->vrtp) && (!ast_test_flag(p, SIP_NOVIDEO)) && (capability & VIDEO_CODEC_MASK)) { /* only if video response is appropriate */
04491       add_line(resp, m_video);
04492       add_line(resp, a_video);
04493    }
04494 
04495    /* Update lastrtprx when we send our SDP */
04496    time(&p->lastrtprx);
04497    time(&p->lastrtptx);
04498 
04499    return 0;
04500 }

static 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 11732 of file chan_sip.c.

References AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), ast_strlen_zero(), calloc, list, LOG_DEBUG, LOG_ERROR, LOG_WARNING, and sipdebug.

Referenced by reload_config().

11733 {
11734    struct domain *d;
11735 
11736    if (ast_strlen_zero(domain)) {
11737       ast_log(LOG_WARNING, "Zero length domain.\n");
11738       return 1;
11739    }
11740 
11741    d = calloc(1, sizeof(*d));
11742    if (!d) {
11743       ast_log(LOG_ERROR, "Allocation of domain structure failed, Out of memory\n");
11744       return 0;
11745    }
11746 
11747    ast_copy_string(d->domain, domain, sizeof(d->domain));
11748 
11749    if (!ast_strlen_zero(context))
11750       ast_copy_string(d->context, context, sizeof(d->context));
11751 
11752    d->mode = mode;
11753 
11754    AST_LIST_LOCK(&domain_list);
11755    AST_LIST_INSERT_TAIL(&domain_list, d, list);
11756    AST_LIST_UNLOCK(&domain_list);
11757 
11758    if (sipdebug)  
11759       ast_log(LOG_DEBUG, "Added local SIP domain '%s'\n", domain);
11760 
11761    return 1;
11762 }

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

add_text: Add text body to SIP message ---

Definition at line 4230 of file chan_sip.c.

References add_header(), add_header_contentLength(), and add_line().

Referenced by transmit_message_with_text().

04231 {
04232    /* XXX Convert \n's to \r\n's XXX */
04233    add_header(req, "Content-Type", "text/plain");
04234    add_header_contentLength(req, strlen(text));
04235    add_line(req, text);
04236    return 0;
04237 }

static int add_vidupdate struct sip_request req  )  [static]
 

add_vidupdate: add XML encoded media control with update ---

Definition at line 4254 of file chan_sip.c.

References add_header(), add_header_contentLength(), and add_line().

Referenced by transmit_info_with_vidupdate().

04255 {
04256    const char *xml_is_a_huge_waste_of_space =
04257       "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\r\n"
04258       " <media_control>\r\n"
04259       "  <vc_primitive>\r\n"
04260       "   <to_encoder>\r\n"
04261       "    <picture_fast_update>\r\n"
04262       "    </picture_fast_update>\r\n"
04263       "   </to_encoder>\r\n"
04264       "  </vc_primitive>\r\n"
04265       " </media_control>\r\n";
04266    add_header(req, "Content-Type", "application/media_control+xml");
04267    add_header_contentLength(req, strlen(xml_is_a_huge_waste_of_space));
04268    add_line(req, xml_is_a_huge_waste_of_space);
04269    return 0;
04270 }

static void append_date struct sip_request req  )  [static]
 

append_date: Append date to SIP message ---

Definition at line 4174 of file chan_sip.c.

References add_header(), and t.

Referenced by build_csv_record(), transmit_invite(), transmit_response_with_date(), and transmit_response_with_unsupported().

04175 {
04176    char tmpdat[256];
04177    struct tm tm;
04178    time_t t;
04179 
04180    time(&t);
04181    gmtime_r(&t, &tm);
04182    strftime(tmpdat, sizeof(tmpdat), "%a, %d %b %Y %T GMT", &tm);
04183    add_header(req, "Date", tmpdat);
04184 }

static 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, and sip_history::next.

Referenced by __sip_autodestruct(), cb_extensionstate(), do_register_auth(), handle_request_subscribe(), process_sdp(), retrans_pkt(), send_request(), send_response(), sip_cancel_destroy(), sip_reregister(), sip_scheddestroy(), sipsock_read(), and transmit_register().

01123 {
01124    struct sip_history *hist, *prev;
01125    char *c;
01126 
01127    if (!recordhistory || !p)
01128       return 0;
01129    if(!(hist = malloc(sizeof(struct sip_history)))) {
01130       ast_log(LOG_WARNING, "Can't allocate memory for history");
01131       return 0;
01132    }
01133    memset(hist, 0, sizeof(struct sip_history));
01134    snprintf(hist->event, sizeof(hist->event), "%-15s %s", event, data);
01135    /* Trim up nicely */
01136    c = hist->event;
01137    while(*c) {
01138       if ((*c == '\r') || (*c == '\n')) {
01139          *c = '\0';
01140          break;
01141       }
01142       c++;
01143    }
01144    /* Enqueue into history */
01145    prev = p->history;
01146    if (prev) {
01147       while(prev->next)
01148          prev = prev->next;
01149       prev->next = hist;
01150    } else {
01151       p->history = hist;
01152    }
01153    return 0;
01154 }

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

static void ast_quiet_chan struct ast_channel chan  )  [static]
 

ast_quiet_chan: Turn off generator data

Definition at line 10128 of file chan_sip.c.

References ast_channel::_state, ast_deactivate_generator(), AST_STATE_UP, and ast_channel::generatordata.

Referenced by attempt_transfer().

10129 {
10130    if (chan && chan->_state == AST_STATE_UP) {
10131       if (chan->generatordata)
10132          ast_deactivate_generator(chan);
10133    }
10134 }

static 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, externrefresh, hp, localaddr, LOG_DEBUG, and LOG_NOTICE.

Referenced by sip_alloc(), sip_notify(), sip_poke_peer(), sip_request_call(), sip_send_mwi_to_peer(), and transmit_register().

01088 {
01089    /*
01090     * Using the localaddr structure built up with localnet statements
01091     * apply it to their address to see if we need to substitute our
01092     * externip or can get away with our internal bindaddr
01093     */
01094    struct sockaddr_in theirs;
01095    theirs.sin_addr = *them;
01096    if (localaddr && externip.sin_addr.s_addr &&
01097       ast_apply_ha(localaddr, &theirs)) {
01098       char iabuf[INET_ADDRSTRLEN];
01099       if (externexpire && (time(NULL) >= externexpire)) {
01100          struct ast_hostent ahp;
01101          struct hostent *hp;
01102          time(&externexpire);
01103          externexpire += externrefresh;
01104          if ((hp = ast_gethostbyname(externhost, &ahp))) {
01105             memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr));
01106          } else
01107             ast_log(LOG_NOTICE, "Warning: Re-lookup of '%s' failed!\n", externhost);
01108       }
01109       memcpy(us, &externip.sin_addr, sizeof(struct in_addr));
01110       ast_inet_ntoa(iabuf, sizeof(iabuf), *(struct in_addr *)&them->s_addr);
01111       ast_log(LOG_DEBUG, "Target address %s is not local, substituting externip\n", iabuf);
01112    }
01113    else if (bindaddr.sin_addr.s_addr)
01114       memcpy(us, &bindaddr.sin_addr, sizeof(struct in_addr));
01115    else
01116       return ast_ouraddrfor(them, us);
01117    return 0;
01118 }

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

attempt_transfer: Attempt transfer of SIP call ---

Definition at line 10137 of file chan_sip.c.

References ast_bridged_channel(), ast_cdr_append(), ast_channel_masquerade(), ast_log(), ast_quiet_chan(), AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), LOG_NOTICE, LOG_WARNING, and sip_pvt::owner.

10138 {
10139    int res = 0;
10140    struct ast_channel 
10141       *chana = NULL,
10142       *chanb = NULL,
10143       *bridgea = NULL,
10144       *bridgeb = NULL,
10145       *peera = NULL,
10146       *peerb = NULL,
10147       *peerc = NULL,
10148       *peerd = NULL;
10149 
10150    if (!p1->owner || !p2->owner) {
10151       ast_log(LOG_WARNING, "Transfer attempted without dual ownership?\n");
10152       return -1;
10153    }
10154    chana = p1->owner;
10155    chanb = p2->owner;
10156    bridgea = ast_bridged_channel(chana);
10157    bridgeb = ast_bridged_channel(chanb);
10158    
10159    if (bridgea) {
10160       peera = chana;
10161       peerb = chanb;
10162       peerc = bridgea;
10163       peerd = bridgeb;
10164    } else if (bridgeb) {
10165       peera = chanb;
10166       peerb = chana;
10167       peerc = bridgeb;
10168       peerd = bridgea;
10169    }
10170    
10171    if (peera && peerb && peerc && (peerb != peerc)) {
10172       ast_quiet_chan(peera);
10173       ast_quiet_chan(peerb);
10174       ast_quiet_chan(peerc);
10175       ast_quiet_chan(peerd);
10176 
10177       if (peera->cdr && peerb->cdr) {
10178          peerb->cdr = ast_cdr_append(peerb->cdr, peera->cdr);
10179       } else if (peera->cdr) {
10180          peerb->cdr = peera->cdr;
10181       }
10182       peera->cdr = NULL;
10183 
10184       if (peerb->cdr && peerc->cdr) {
10185          peerb->cdr = ast_cdr_append(peerb->cdr, peerc->cdr);
10186       } else if (peerc->cdr) {
10187          peerb->cdr = peerc->cdr;
10188       }
10189       peerc->cdr = NULL;
10190       
10191       if (ast_channel_masquerade(peerb, peerc)) {
10192          ast_log(LOG_WARNING, "Failed to masquerade %s into %s\n", peerb->name, peerc->name);
10193          res = -1;
10194       }
10195       return res;
10196    } else {
10197       ast_log(LOG_NOTICE, "Transfer attempted with no appropriate bridged calls to transfer\n");
10198       if (chana)
10199          ast_softhangup_nolock(chana, AST_SOFTHANGUP_DEV);
10200       if (chanb)
10201          ast_softhangup_nolock(chanb, AST_SOFTHANGUP_DEV);
10202       return -1;
10203    }
10204    return 0;
10205 }

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

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 }

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

build_callid: Build SIP CALLID header ---

Definition at line 3009 of file chan_sip.c.

References thread_safe_rand().

Referenced by sip_alloc(), sip_notify(), sip_poke_peer(), sip_request_call(), sip_send_mwi_to_peer(), and transmit_register().

03010 {
03011    int res;
03012    int val;
03013    int x;
03014    char iabuf[INET_ADDRSTRLEN];
03015    for (x=0; x<4; x++) {
03016       val = thread_safe_rand();
03017       res = snprintf(callid, len, "%08x", val);
03018       len -= res;
03019       callid += res;
03020    }
03021    if (!ast_strlen_zero(fromdomain))
03022       snprintf(callid, len, "@%s", fromdomain);
03023    else
03024    /* It's not important that we really use our right IP here... */
03025       snprintf(callid, len, "@%s", ast_inet_ntoa(iabuf, sizeof(iabuf), ourip));
03026 }

static void build_contact struct sip_pvt p  )  [static]
 

build_contact: Build contact header - the contact header we send out ---

Definition at line 4630 of file chan_sip.c.

References ast_inet_ntoa(), ast_strlen_zero(), sip_pvt::exten, sip_pvt::our_contact, sip_pvt::ourip, and ourport.

Referenced by check_user_full(), handle_request_invite(), handle_request_options(), handle_request_subscribe(), register_verify(), and transmit_register().

04631 {
04632    char iabuf[INET_ADDRSTRLEN];
04633 
04634    /* Construct Contact: header */
04635    if (ourport != 5060) /* Needs to be 5060, according to the RFC */
04636       snprintf(p->our_contact, sizeof(p->our_contact), "<sip:%s%s%s:%d>", p->exten, ast_strlen_zero(p->exten) ? "" : "@", ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip), ourport);
04637    else
04638       snprintf(p->our_contact, sizeof(p->our_contact), "<sip:%s%s%s>", p->exten, ast_strlen_zero(p->exten) ? "" : "@", ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip));
04639 }

static 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 12029 of file chan_sip.c.

References sip_peer::accountcode, add_realm_authentication(), sip_peer::addr, sip_peer::amaflags, ast_append_ha(), ast_callerid_split(), ast_cdr_amaflags2int(), ast_clear_flag, ast_copy_flags, ast_free_ha(), ast_get_group(), ast_get_ip(), ast_get_ip_or_srv(), ast_log(), ast_parse_allow_disallow(), ast_parse_caller_presentation(), ast_sched_del(), ast_set2_flag, ast_set_flag, ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_true(), ast_variable_new(), ast_variables_destroy(), ASTOBJ_CONTAINER_FIND_UNLINK_FULL, ASTOBJ_INIT, ASTOBJ_UNMARK, ASTOBJ_UNREF, sip_peer::auth, sip_peer::call_limit, sip_peer::callgroup, sip_peer::callingpres, sip_peer::capability, sip_peer::chanvars, sip_peer::cid_name, sip_peer::cid_num, sip_peer::context, sip_peer::defaddr, default_context, default_language, DEFAULT_MAXMS, default_qualify, DEFAULT_SIP_PORT, default_subscribecontext, destroy_association(), sip_peer::expire, ast_flags::flags, sip_peer::flags_page2, sip_peer::fromdomain, sip_peer::fromuser, sip_peer::fullcontact, global_capability, global_flags, global_flags_page2, global_musicclass, global_rtpholdtimeout, global_rtpkeepalive, global_rtptimeout, global_vmexten, sip_peer::ha, handle_common_options(), sip_peer::language, sip_peer::lastmsgssent, ast_variable::lineno, LOG_DEBUG, LOG_WARNING, sip_peer::mailbox, malloc, sip_peer::maxms, sip_peer::md5secret, sip_peer::musicclass, ast_variable::name, ast_variable::next, option_debug, peerl, sip_peer::pickupgroup, prefs, sip_peer::prefs, reg_source_db(), sip_peer::regexten, rpeerobjs, sip_peer::rtpholdtimeout, sip_peer::rtpkeepalive, sip_peer::rtptimeout, sip_peer::secret, sip_destroy_peer(), SIP_DYNAMIC, SIP_FLAGS_TO_COPY, SIP_PAGE2_IGNOREREGEXPIRE, SIP_PAGE2_RT_FROMCONTACT, SIP_REALTIME, SIP_USEREQPHONE, speerobjs, sip_peer::subscribecontext, sip_peer::tohost, sip_peer::username, ast_variable::value, and sip_peer::vmexten.

12030 {
12031    struct sip_peer *peer = NULL;
12032    struct ast_ha *oldha = NULL;
12033    int obproxyfound=0;
12034    int found=0;
12035    int format=0;     /* Ama flags */
12036    time_t regseconds;
12037    char *varname = NULL, *varval = NULL;
12038    struct ast_variable *tmpvar = NULL;
12039    struct ast_flags peerflags = {(0)};
12040    struct ast_flags mask = {(0)};
12041 
12042 
12043    if (!realtime)
12044       /* Note we do NOT use find_peer here, to avoid realtime recursion */
12045       /* We also use a case-sensitive comparison (unlike find_peer) so
12046          that case changes made to the peer name will be properly handled
12047          during reload
12048       */
12049       peer = ASTOBJ_CONTAINER_FIND_UNLINK_FULL(&peerl, name, name, 0, 0, strcmp);
12050 
12051    if (peer) {
12052       /* Already in the list, remove it and it will be added back (or FREE'd)  */
12053       found++;
12054    } else {
12055       peer = malloc(sizeof(*peer));
12056       if (peer) {
12057          memset(peer, 0, sizeof(*peer));
12058          if (realtime)
12059             rpeerobjs++;
12060          else
12061             speerobjs++;
12062          ASTOBJ_INIT(peer);
12063          peer->expire = -1;
12064          peer->pokeexpire = -1;
12065       } else {
12066          ast_log(LOG_WARNING, "Can't allocate SIP peer memory\n");
12067       }
12068    }
12069    /* Note that our peer HAS had its reference count incrased */
12070    if (!peer)
12071       return NULL;
12072 
12073    peer->lastmsgssent = -1;
12074    if (!found) {
12075       if (name)
12076          ast_copy_string(peer->name, name, sizeof(peer->name));
12077       peer->addr.sin_port = htons(DEFAULT_SIP_PORT);
12078       peer->addr.sin_family = AF_INET;
12079       peer->defaddr.sin_family = AF_INET;
12080    }
12081    /* If we have channel variables, remove them (reload) */
12082    if (peer->chanvars) {
12083       ast_variables_destroy(peer->chanvars);
12084       peer->chanvars = NULL;
12085    }
12086    strcpy(peer->context, default_context);
12087    strcpy(peer->subscribecontext, default_subscribecontext);
12088    strcpy(peer->vmexten, global_vmexten);
12089    strcpy(peer->language, default_language);
12090    strcpy(peer->musicclass, global_musicclass);
12091    ast_copy_flags(peer, &global_flags, SIP_USEREQPHONE);
12092    peer->secret[0] = '\0';
12093    peer->md5secret[0] = '\0';
12094    peer->cid_num[0] = '\0';
12095    peer->cid_name[0] = '\0';
12096    peer->fromdomain[0] = '\0';
12097    peer->fromuser[0] = '\0';
12098    peer->regexten[0] = '\0';
12099    peer->mailbox[0] = '\0';
12100    peer->callgroup = 0;
12101    peer->pickupgroup = 0;
12102    peer->rtpkeepalive = global_rtpkeepalive;
12103    peer->maxms = default_qualify;
12104    peer->prefs = prefs;
12105    oldha = peer->ha;
12106    peer->ha = NULL;
12107    peer->addr.sin_family = AF_INET;
12108    ast_copy_flags(peer, &global_flags, SIP_FLAGS_TO_COPY);
12109    peer->capability = global_capability;
12110    peer->rtptimeout = global_rtptimeout;
12111    peer->rtpholdtimeout = global_rtpholdtimeout;
12112    while(v) {
12113       if (handle_common_options(&peerflags, &mask, v)) {
12114          v = v->next;
12115          continue;
12116       }
12117 
12118       if (realtime && !strcasecmp(v->name, "regseconds")) {
12119          if (sscanf(v->value, "%ld", (time_t *)&regseconds) != 1)
12120             regseconds = 0;
12121       } else if (realtime && !strcasecmp(v->name, "ipaddr") && !ast_strlen_zero(v->value) ) {
12122          inet_aton(v->value, &(peer->addr.sin_addr));
12123       } else if (realtime && !strcasecmp(v->name, "name"))
12124          ast_copy_string(peer->name, v->value, sizeof(peer->name));
12125       else if (realtime && !strcasecmp(v->name, "fullcontact")) {
12126          ast_copy_string(peer->fullcontact, v->value, sizeof(peer->fullcontact));
12127          ast_set_flag((&peer->flags_page2), SIP_PAGE2_RT_FROMCONTACT);
12128       } else if (!strcasecmp(v->name, "secret")) 
12129          ast_copy_string(peer->secret, v->value, sizeof(peer->secret));
12130       else if (!strcasecmp(v->name, "md5secret")) 
12131          ast_copy_string(peer->md5secret, v->value, sizeof(peer->md5secret));
12132       else if (!strcasecmp(v->name, "auth"))
12133          peer->auth = add_realm_authentication(peer->auth, v->value, v->lineno);
12134       else if (!strcasecmp(v->name, "callerid")) {
12135          ast_callerid_split(v->value, peer->cid_name, sizeof(peer->cid_name), peer->cid_num, sizeof(peer->cid_num));
12136       } else if (!strcasecmp(v->name, "context")) {
12137          ast_copy_string(peer->context, v->value, sizeof(peer->context));
12138       } else if (!strcasecmp(v->name, "subscribecontext")) {
12139          ast_copy_string(peer->subscribecontext, v->value, sizeof(peer->subscribecontext));
12140       } else if (!strcasecmp(v->name, "fromdomain"))
12141          ast_copy_string(peer->fromdomain, v->value, sizeof(peer->fromdomain));
12142       else if (!strcasecmp(v->name, "usereqphone"))
12143          ast_set2_flag(peer, ast_true(v->value), SIP_USEREQPHONE);
12144       else if (!strcasecmp(v->name, "fromuser"))
12145          ast_copy_string(peer->fromuser, v->value, sizeof(peer->fromuser));
12146       else if (!strcasecmp(v->name, "host") || !strcasecmp(v->name, "outboundproxy")) {
12147          if (!strcasecmp(v->value, "dynamic")) {
12148             if (!strcasecmp(v->name, "outboundproxy") || obproxyfound) {
12149                ast_log(LOG_WARNING, "You can't have a dynamic outbound proxy, you big silly head at line %d.\n", v->lineno);
12150             } else {
12151                /* They'll register with us */
12152                ast_set_flag(peer, SIP_DYNAMIC);
12153                if (!found) {
12154                   /* Initialize stuff iff we're not found, otherwise
12155                      we keep going with what we had */
12156                   memset(&peer->addr.sin_addr, 0, 4);
12157                   if (peer->addr.sin_port) {
12158                      /* If we've already got a port, make it the default rather than absolute */
12159                      peer->defaddr.sin_port = peer->addr.sin_port;
12160                      peer->addr.sin_port = 0;
12161                   }
12162                }
12163             }
12164          } else {
12165             /* Non-dynamic.  Make sure we become that way if we're not */
12166             if (peer->expire > -1)
12167                ast_sched_del(sched, peer->expire);
12168             peer->expire = -1;
12169             ast_clear_flag(peer, SIP_DYNAMIC);  
12170             if (!obproxyfound || !strcasecmp(v->name, "outboundproxy")) {
12171                if (ast_get_ip_or_srv(&peer->addr, v->value, "_sip._udp")) {
12172                   ASTOBJ_UNREF(peer, sip_destroy_peer);
12173                   return NULL;
12174                }
12175             }
12176             if (!strcasecmp(v->name, "outboundproxy"))
12177                obproxyfound=1;
12178             else {
12179                ast_copy_string(peer->tohost, v->value, sizeof(peer->tohost));
12180                if (!peer->addr.sin_port)
12181                   peer->addr.sin_port = htons(DEFAULT_SIP_PORT);
12182             }
12183          }
12184       } else if (!strcasecmp(v->name, "defaultip")) {
12185          if (ast_get_ip(&peer->defaddr, v->value)) {
12186             ASTOBJ_UNREF(peer, sip_destroy_peer);
12187             return NULL;
12188          }
12189       } else if (!strcasecmp(v->name, "permit") || !strcasecmp(v->name, "deny")) {
12190          peer->ha = ast_append_ha(v->name, v->value, peer->ha);
12191       } else if (!strcasecmp(v->name, "port")) {
12192          if (!realtime && ast_test_flag(peer, SIP_DYNAMIC))
12193             peer->defaddr.sin_port = htons(atoi(v->value));
12194          else
12195             peer->addr.sin_port = htons(atoi(v->value));
12196       } else if (!strcasecmp(v->name, "callingpres")) {
12197          peer->callingpres = ast_parse_caller_presentation(v->value);
12198          if (peer->callingpres == -1)
12199             peer->callingpres = atoi(v->value);
12200       } else if (!strcasecmp(v->name, "username")) {
12201          ast_copy_string(peer->username, v->value, sizeof(peer->username));
12202       } else if (!strcasecmp(v->name, "language")) {
12203          ast_copy_string(peer->language, v->value, sizeof(peer->language));
12204       } else if (!strcasecmp(v->name, "regexten")) {
12205          ast_copy_string(peer->regexten, v->value, sizeof(peer->regexten));
12206       } else if (!strcasecmp(v->name, "call-limit") || !strcasecmp(v->name, "incominglimit")) {
12207          peer->call_limit = atoi(v->value);
12208          if (peer->call_limit < 0)
12209             peer->call_limit = 0;
12210       } else if (!strcasecmp(v->name, "amaflags")) {
12211          format = ast_cdr_amaflags2int(v->value);
12212          if (format < 0) {
12213             ast_log(LOG_WARNING, "Invalid AMA Flags for peer: %s at line %d\n", v->value, v->lineno);
12214          } else {
12215             peer->amaflags = format;
12216          }
12217       } else if (!strcasecmp(v->name, "accountcode")) {
12218          ast_copy_string(peer->accountcode, v->value, sizeof(peer->accountcode));
12219       } else if (!strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) {
12220          ast_copy_string(peer->musicclass, v->value, sizeof(peer->musicclass));
12221       } else if (!strcasecmp(v->name, "mailbox")) {
12222          ast_copy_string(peer->mailbox, v->value, sizeof(peer->mailbox));
12223       } else if (!strcasecmp(v->name, "vmexten")) {
12224          ast_copy_string(peer->vmexten, v->value, sizeof(peer->vmexten));
12225       } else if (!strcasecmp(v->name, "callgroup")) {
12226          peer->callgroup = ast_get_group(v->value);
12227       } else if (!strcasecmp(v->name, "pickupgroup")) {
12228          peer->pickupgroup = ast_get_group(v->value);
12229       } else if (!strcasecmp(v->name, "allow")) {
12230          ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1);
12231       } else if (!strcasecmp(v->name, "disallow")) {
12232          ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0);
12233       } else if (!strcasecmp(v->name, "rtptimeout")) {
12234          if ((sscanf(v->value, "%d", &peer->rtptimeout) != 1) || (peer->rtptimeout < 0)) {
12235             ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d.  Using default.\n", v->value, v->lineno);
12236             peer->rtptimeout = global_rtptimeout;
12237          }
12238       } else if (!strcasecmp(v->name, "rtpholdtimeout")) {
12239          if ((sscanf(v->value, "%d", &peer->rtpholdtimeout) != 1) || (peer->rtpholdtimeout < 0)) {
12240             ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d.  Using default.\n", v->value, v->lineno);
12241             peer->rtpholdtimeout = global_rtpholdtimeout;
12242          }
12243       } else if (!strcasecmp(v->name, "rtpkeepalive")) {
12244          if ((sscanf(v->value, "%d", &peer->rtpkeepalive) != 1) || (peer->rtpkeepalive < 0)) {
12245             ast_log(LOG_WARNING, "'%s' is not a valid RTP keepalive time at line %d.  Using default.\n", v->value, v->lineno);
12246             peer->rtpkeepalive = global_rtpkeepalive;
12247          }
12248       } else if (!strcasecmp(v->name, "setvar")) {
12249          /* Set peer channel variable */
12250          varname = ast_strdupa(v->value);
12251          if (varname && (varval = strchr(varname,'='))) {
12252             *varval = '\0';
12253             varval++;
12254             if ((tmpvar = ast_variable_new(varname, varval))) {
12255                tmpvar->next = peer->chanvars;
12256                peer->chanvars = tmpvar;
12257             }
12258          }
12259       } else if (!strcasecmp(v->name, "qualify")) {
12260          if (!strcasecmp(v->value, "no")) {
12261             peer->maxms = 0;
12262          } else if (!strcasecmp(v->value, "yes")) {
12263             peer->maxms = DEFAULT_MAXMS;
12264          } else if (sscanf(v->value, "%d", &peer->maxms) != 1) {
12265             ast_log(LOG_WARNING, "Qualification of peer '%s' should be 'yes', 'no', or a number of milliseconds at line %d of sip.conf\n", peer->name, v->lineno);
12266             peer->maxms = 0;
12267          }
12268       }
12269       /* else if (strcasecmp(v->name,"type"))
12270        * ast_log(LOG_WARNING, "Ignoring %s\n", v->name);
12271        */
12272       v=v->next;
12273    }
12274    if (!ast_test_flag((&global_flags_page2), SIP_PAGE2_IGNOREREGEXPIRE) && ast_test_flag(peer, SIP_DYNAMIC) && realtime) {
12275       time_t nowtime;
12276 
12277       time(&nowtime);
12278       if ((nowtime - regseconds) > 0) {
12279          destroy_association(peer);
12280          memset(&peer->addr, 0, sizeof(peer->addr));
12281          if (option_debug)
12282             ast_log(LOG_DEBUG, "Bah, we're expired (%d/%d/%d)!\n", (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
12283       }
12284    }
12285    ast_copy_flags(peer, &peerflags, mask.flags);
12286    if (!found && ast_test_flag(peer, SIP_DYNAMIC) && !ast_test_flag(peer, SIP_REALTIME))
12287       reg_source_db(peer);
12288    ASTOBJ_UNMARK(peer);
12289    ast_free_ha(oldha);
12290    return peer;
12291 }

static 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 8996 of file chan_sip.c.

References ast_inet_ntoa(), ast_log(), ast_md5_hash(), ast_strlen_zero(), authl, sip_pvt::authname, sip_pvt::callid, sip_pvt::domain, find_realm_authentication(), LOG_DEBUG, sip_auth::md5secret, sip_registry::md5secret, sip_pvt::nonce, sip_pvt::noncecount, sip_pvt::opaque, sip_pvt::peermd5secret, sip_pvt::peersecret, sip_pvt::qop, sip_pvt::realm, sip_pvt::sa, sip_auth::secret, secret, sip_methods, sipdebug, text, thread_safe_rand(), sip_pvt::uri, sip_auth::username, sip_pvt::username, and username.

Referenced by transmit_register(), and transmit_request_with_auth().

08997 {
08998    char a1[256];
08999    char a2[256];
09000    char a1_hash[256];
09001    char a2_hash[256];
09002    char resp[256];
09003    char resp_hash[256];
09004    char uri[256];
09005    char cnonce[80];
09006    char iabuf[INET_ADDRSTRLEN];
09007    char *username;
09008    char *secret;
09009    char *md5secret;
09010    struct sip_auth *auth = (struct sip_auth *) NULL;  /* Realm authentication */
09011 
09012    if (!ast_strlen_zero(p->domain))
09013       ast_copy_string(uri, p->domain, sizeof(uri));
09014    else if (!ast_strlen_zero(p->uri))
09015       ast_copy_string(uri, p->uri, sizeof(uri));
09016    else
09017       snprintf(uri, sizeof(uri), "sip:%s@%s",p->username, ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr));
09018 
09019    snprintf(cnonce, sizeof(cnonce), "%08x", thread_safe_rand());
09020 
09021    /* Check if we have separate auth credentials */
09022    if ((auth = find_realm_authentication(authl, p->realm))) {
09023       username = auth->username;
09024       secret = auth->secret;
09025       md5secret = auth->md5secret;
09026       if (sipdebug)
09027          ast_log(LOG_DEBUG,"Using realm %s authentication for call %s\n", p->realm, p->callid);
09028    } else {
09029       /* No authentication, use peer or register= config */
09030       username = p->authname;
09031       secret =  p->peersecret;
09032       md5secret = p->peermd5secret;
09033    }
09034    if (ast_strlen_zero(username))   /* We have no authentication */
09035       return -1;
09036  
09037 
09038    /* Calculate SIP digest response */
09039    snprintf(a1,sizeof(a1),"%s:%s:%s", username, p->realm, secret);
09040    snprintf(a2,sizeof(a2),"%s:%s", sip_methods[method].text, uri);
09041    if (!ast_strlen_zero(md5secret))
09042       ast_copy_string(a1_hash, md5secret, sizeof(a1_hash));
09043    else
09044       ast_md5_hash(a1_hash,a1);
09045    ast_md5_hash(a2_hash,a2);
09046 
09047    p->noncecount++;
09048    if (!ast_strlen_zero(p->qop))
09049       snprintf(resp,sizeof(resp),"%s:%s:%08x:%s:%s:%s", a1_hash, p->nonce, p->noncecount, cnonce, "auth", a2_hash);
09050    else
09051       snprintf(resp,sizeof(resp),"%s:%s:%s", a1_hash, p->nonce, a2_hash);
09052    ast_md5_hash(resp_hash, resp);
09053    /* XXX We hard code our qop to "auth" for now.  XXX */
09054    if (!ast_strlen_zero(p->qop))
09055       snprintf(digest, digest_len, "Digest username=\"%s\", realm=\"%s\", algorithm=MD5, uri=\"%s\", nonce=\"%s\", response=\"%s\", opaque=\"%s\", qop=auth, cnonce=\"%s\", nc=%08x", username, p->realm, uri, p->nonce, resp_hash, p->opaque, cnonce, p->noncecount);
09056    else
09057       snprintf(digest, digest_len, "Digest username=\"%s\", realm=\"%s\", algorithm=MD5, uri=\"%s\", nonce=\"%s\", response=\"%s\", opaque=\"%s\"", username, p->realm, uri, p->nonce, resp_hash, p->opaque);
09058 
09059    return 0;
09060 }

static 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 5981 of file chan_sip.c.

References __get_header(), ast_log(), free_old_route(), sip_route::hop, LOG_DEBUG, malloc, sip_route::next, sip_pvt::route, and sip_pvt::route_persistant.

Referenced by handle_request_invite(), and handle_response_invite().

05982 {
05983    struct sip_route *thishop, *head, *tail;
05984    int start = 0;
05985    int len;
05986    char *rr, *contact, *c;
05987 
05988    /* Once a persistant route is set, don't fool with it */
05989    if (p->route && p->route_persistant) {
05990       ast_log(LOG_DEBUG, "build_route: Retaining previous route: <%s>\n", p->route->hop);
05991       return;
05992    }
05993 
05994    if (p->route) {
05995       free_old_route(p->route);
05996       p->route = NULL;
05997    }
05998    
05999    p->route_persistant = backwards;
06000    
06001    /* We build up head, then assign it to p->route when we're done */
06002    head = NULL;  tail = head;
06003    /* 1st we pass through all the hops in any Record-Route headers */
06004    for (;;) {
06005       /* Each Record-Route header */
06006       rr = __get_header(req, "Record-Route", &start);
06007       if (*rr == '\0') break;
06008       for (;;) {
06009          /* Each route entry */
06010          /* Find < */
06011          rr = strchr(rr, '<');
06012          if (!rr) break; /* No more hops */
06013          ++rr;
06014          len = strcspn(rr, ">") + 1;
06015          /* Make a struct route */
06016          thishop = malloc(sizeof(*thishop) + len);
06017          if (thishop) {
06018             ast_copy_string(thishop->hop, rr, len);
06019             ast_log(LOG_DEBUG, "build_route: Record-Route hop: <%s>\n", thishop->hop);
06020             /* Link in */
06021             if (backwards) {
06022                /* Link in at head so they end up in reverse order */
06023                thishop->next = head;
06024                head = thishop;
06025                /* If this was the first then it'll be the tail */
06026                if (!tail) tail = thishop;
06027             } else {
06028                thishop->next = NULL;
06029                /* Link in at the end */
06030                if (tail)
06031                   tail->next = thishop;
06032                else
06033                   head = thishop;
06034                tail = thishop;
06035             }
06036          }
06037          rr += len;
06038       }
06039    }
06040 
06041    /* Only append the contact if we are dealing with a strict router */
06042    if (!head || (!ast_strlen_zero(head->hop) && strstr(head->hop,";lr") == NULL) ) {
06043       /* 2nd append the Contact: if there is one */
06044       /* Can be multiple Contact headers, comma separated values - we just take the first */
06045       contact = get_header(req, "Contact");
06046       if (!ast_strlen_zero(contact)) {
06047          ast_log(LOG_DEBUG, "build_route: Contact hop: %s\n", contact);
06048          /* Look for <: delimited address */
06049          c = strchr(contact, '<');
06050          if (c) {
06051             /* Take to > */
06052             ++c;
06053             len = strcspn(c, ">") + 1;
06054          } else {
06055             /* No <> - just take the lot */
06056             c = contact;
06057             len = strlen(contact) + 1;
06058          }
06059          thishop = malloc(sizeof(*thishop) + len);
06060          if (thishop) {
06061             ast_copy_string(thishop->hop, c, len);
06062             thishop->next = NULL;
06063             /* Goes at the end */
06064             if (tail)
06065                tail->next = thishop;
06066             else
06067                head = thishop;
06068          }
06069       }
06070    }
06071 
06072    /* Store as new route */
06073    p->route = head;
06074 
06075    /* For debugging dump what we ended up with */
06076    if (sip_debug_test_pvt(p))
06077       list_route(p->route);
06078 }

static void build_rpid struct sip_pvt p  )  [static]
 

build_rpid: Build the Remote Party-ID & From using callingpres options ---

Definition at line 4642 of file chan_sip.c.

References ast_inet_ntoa(), ast_log(), AST_PRES_ALLOWED, AST_PRES_ALLOWED_NETWORK_NUMBER, AST_PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN, AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED, AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN, AST_PRES_NUMBER_NOT_AVAILABLE, AST_PRES_PROHIB_NETWORK_NUMBER, AST_PRES_PROHIB_USER_NUMBER_FAILED_SCREEN, AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED, AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN, AST_PRES_RESTRICTION, ast_strlen_zero(), sip_pvt::callingpres, ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, default_callerid, sip_pvt::fromdomain, sip_pvt::fromuser, LOG_WARNING, sip_pvt::ourip, sip_pvt::owner, sip_pvt::rpid, sip_pvt::rpid_from, strdup, and sip_pvt::tag.

04643 {
04644    int send_pres_tags = 1;
04645    const char *privacy=NULL;
04646    const char *screen=NULL;
04647    char buf[256];
04648    const char *clid = default_callerid;
04649    const char *clin = NULL;
04650    char iabuf[INET_ADDRSTRLEN];
04651    const char *fromdomain;
04652 
04653    if (p->rpid || p->rpid_from)
04654       return;
04655 
04656    if (p->owner && p->owner->cid.cid_num)
04657       clid = p->owner->cid.cid_num;
04658    if (p->owner && p->owner->cid.cid_name)
04659       clin = p->owner->cid.cid_name;
04660    if (ast_strlen_zero(clin))
04661       clin = clid;
04662 
04663    switch (p->callingpres) {
04664    case AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED:
04665       privacy = "off";
04666       screen = "no";
04667       break;
04668    case AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN:
04669       privacy = "off";
04670       screen = "pass";
04671       break;
04672    case AST_PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN:
04673       privacy = "off";
04674       screen = "fail";
04675       break;
04676    case AST_PRES_ALLOWED_NETWORK_NUMBER:
04677       privacy = "off";
04678       screen = "yes";
04679       break;
04680    case AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED:
04681       privacy = "full";
04682       screen = "no";
04683       break;
04684    case AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN:
04685       privacy = "full";
04686       screen = "pass";
04687       break;
04688    case AST_PRES_PROHIB_USER_NUMBER_FAILED_SCREEN:
04689       privacy = "full";
04690       screen = "fail";
04691       break;
04692    case AST_PRES_PROHIB_NETWORK_NUMBER:
04693       privacy = "full";
04694       screen = "pass";
04695       break;
04696    case AST_PRES_NUMBER_NOT_AVAILABLE:
04697       send_pres_tags = 0;
04698       break;
04699    default:
04700       ast_log(LOG_WARNING, "Unsupported callingpres (%d)\n", p->callingpres);
04701       if ((p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED)
04702          privacy = "full";
04703       else
04704          privacy = "off";
04705       screen = "no";
04706       break;
04707    }
04708    
04709    fromdomain = ast_strlen_zero(p->fromdomain) ? ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip) : p->fromdomain;
04710 
04711    snprintf(buf, sizeof(buf), "\"%s\" <sip:%s@%s>", clin, clid, fromdomain);
04712    if (send_pres_tags)
04713       snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), ";privacy=%s;screen=%s", privacy, screen);
04714    p->rpid = strdup(buf);
04715 
04716    snprintf(buf, sizeof(buf), "\"%s\" <sip:%s@%s>;tag=%s", clin,
04717        ast_strlen_zero(p->fromuser) ? clid : p->fromuser,
04718        fromdomain, p->tag);
04719    p->rpid_from = strdup(buf);
04720 }

static 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 11896 of file chan_sip.c.

References ast_append_ha(), ast_callerid_split(), ast_cdr_amaflags2int(), ast_copy_flags, ast_free_ha(), ast_get_group(), ast_log(), ast_parse_allow_disallow(), ast_parse_caller_presentation(), ast_strdupa, ast_variable_new(), ASTOBJ_INIT, default_context, default_language, ast_flags::flags, format, global_capability, global_flags, global_musicclass, handle_common_options(), ast_variable::lineno, LOG_WARNING, malloc, ast_variable::name, ast_variable::next, prefs, SIP_FLAGS_TO_COPY, suserobjs, user, and ast_variable::value.

11897 {
11898    struct sip_user *user;
11899    int format;
11900    struct ast_ha *oldha = NULL;
11901    char *varname = NULL, *varval = NULL;
11902    struct ast_variable *tmpvar = NULL;
11903    struct ast_flags userflags = {(0)};
11904    struct ast_flags mask = {(0)};
11905 
11906 
11907    user = (struct sip_user *)malloc(sizeof(struct sip_user));
11908    if (!user) {
11909       return NULL;
11910    }
11911    memset(user, 0, sizeof(struct sip_user));
11912    suserobjs++;
11913    ASTOBJ_INIT(user);
11914    ast_copy_string(user->name, name, sizeof(user->name));
11915    oldha = user->ha;
11916    user->ha = NULL;
11917    ast_copy_flags(user, &global_flags, SIP_FLAGS_TO_COPY);
11918    user->capability = global_capability;
11919    user->prefs = prefs;
11920    /* set default context */
11921    strcpy(user->context, default_context);
11922    strcpy(user->language, default_language);
11923    strcpy(user->musicclass, global_musicclass);
11924    while(v) {
11925       if (handle_common_options(&userflags, &mask, v)) {
11926          v = v->next;
11927          continue;
11928       }
11929 
11930       if (!strcasecmp(v->name, "context")) {
11931          ast_copy_string(user->context, v->value, sizeof(user->context));
11932       } else if (!strcasecmp(v->name, "subscribecontext")) {
11933          ast_copy_string(user->subscribecontext, v->value, sizeof(user->subscribecontext));
11934       } else if (!strcasecmp(v->name, "setvar")) {
11935          varname = ast_strdupa(v->value);
11936          if (varname && (varval = strchr(varname,'='))) {
11937             *varval = '\0';
11938             varval++;
11939             if ((tmpvar = ast_variable_new(varname, varval))) {
11940                tmpvar->next = user->chanvars;
11941                user->chanvars = tmpvar;
11942             }
11943          }
11944       } else if (!strcasecmp(v->name, "permit") ||
11945                !strcasecmp(v->name, "deny")) {
11946          user->ha = ast_append_ha(v->name, v->value, user->ha);
11947       } else if (!strcasecmp(v->name, "secret")) {
11948          ast_copy_string(user->secret, v->value, sizeof(user->secret)); 
11949       } else if (!strcasecmp(v->name, "md5secret")) {
11950          ast_copy_string(user->md5secret, v->value, sizeof(user->md5secret));
11951       } else if (!strcasecmp(v->name, "callerid")) {
11952          ast_callerid_split(v->value, user->cid_name, sizeof(user->cid_name), user->cid_num, sizeof(user->cid_num));
11953       } else if (!strcasecmp(v->name, "callgroup")) {
11954          user->callgroup = ast_get_group(v->value);
11955       } else if (!strcasecmp(v->name, "pickupgroup")) {
11956          user->pickupgroup = ast_get_group(v->value);
11957       } else if (!strcasecmp(v->name, "language")) {
11958          ast_copy_string(user->language, v->value, sizeof(user->language));
11959       } else if (!strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) {
11960          ast_copy_string(user->musicclass, v->value, sizeof(user->musicclass));
11961       } else if (!strcasecmp(v->name, "accountcode")) {
11962          ast_copy_string(user->accountcode, v->value, sizeof(user->accountcode));
11963       } else if (!strcasecmp(v->name, "call-limit") || !strcasecmp(v->name, "incominglimit")) {
11964          user->call_limit = atoi(v->value);
11965          if (user->call_limit < 0)
11966             user->call_limit = 0;
11967       } else if (!strcasecmp(v->name, "amaflags")) {
11968          format = ast_cdr_amaflags2int(v->value);
11969          if (format < 0) {
11970             ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
11971          } else {
11972             user->amaflags = format;
11973          }
11974       } else if (!strcasecmp(v->name, "allow")) {
11975          ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1);
11976       } else if (!strcasecmp(v->name, "disallow")) {
11977          ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 0);
11978       } else if (!strcasecmp(v->name, "callingpres")) {
11979          user->callingpres = ast_parse_caller_presentation(v->value);
11980          if (user->callingpres == -1)
11981             user->callingpres = atoi(v->value);
11982       }
11983       /*else if (strcasecmp(v->name,"type"))
11984        * ast_log(LOG_WARNING, "Ignoring %s\n", v->name);
11985        */
11986       v = v->next;
11987    }
11988    ast_copy_flags(user, &userflags, mask.flags);
11989    ast_free_ha(oldha);
11990    return user;
11991 }

static 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, SIP_NAT, and SIP_NAT_RFC3581.

Referenced by reqprep(), sip_alloc(), sip_notify(), sip_poke_peer(), sip_request_call(), sip_send_mwi_to_peer(), transmit_invite(), and transmit_register().

01075 {
01076    char iabuf[INET_ADDRSTRLEN];
01077 
01078    /* z9hG4bK is a magic cookie.  See RFC 3261 section 8.1.1.7 */
01079    if (ast_test_flag(p, SIP_NAT) & SIP_NAT_RFC3581)
01080       snprintf(buf, len, "SIP/2.0/UDP %s:%d;branch=z9hG4bK%08x;rport", ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip), ourport, p->branch);
01081    else /* Work around buggy UNIDEN UIP200 firmware */
01082       snprintf(buf, len, "SIP/2.0/UDP %s:%d;branch=z9hG4bK%08x", ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip), ourport, p->branch);
01083 }

static 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 6324 of file chan_sip.c.

References append_history(), AST_EXTENSION_DEACTIVATED, AST_EXTENSION_REMOVED, ast_extension_state2str(), ast_verbose(), sip_pvt::autokillid, sip_pvt::laststate, NONE, option_debug, sip_cancel_destroy(), sip_scheddestroy(), sip_pvt::stateid, sip_pvt::subscribed, transmit_state_notify(), sip_pvt::username, VERBOSE_PREFIX_1, and VERBOSE_PREFIX_2.

Referenced by handle_request_subscribe().

06325 {
06326    struct sip_pvt *p = data;
06327 
06328    switch(state) {
06329    case AST_EXTENSION_DEACTIVATED:  /* Retry after a while */
06330    case AST_EXTENSION_REMOVED:   /* Extension is gone */
06331       if (p->autokillid > -1)
06332          sip_cancel_destroy(p);  /* Remove subscription expiry for renewals */
06333       sip_scheddestroy(p, 15000);   /* Delete subscription in 15 secs */
06334       ast_verbose(VERBOSE_PREFIX_2 "Extension state: Watcher for hint %s %s. Notify User %s\n", exten, state == AST_EXTENSION_DEACTIVATED ? "deactivated" : "removed", p->username);
06335       p->stateid = -1;
06336       p->subscribed = NONE;
06337       append_history(p, "Subscribestatus", state == AST_EXTENSION_REMOVED ? "HintRemoved" : "Deactivated");
06338       break;
06339    default: /* Tell user */
06340       p->laststate = state;
06341       break;
06342    }
06343    transmit_state_notify(p, state, 1, 1);
06344 
06345    if (option_debug > 1)
06346       ast_verbose(VERBOSE_PREFIX_1 "Extension Changed %s new state %s for Notify User %s\n", exten, ast_extension_state2str(state), p->username);
06347    return 0;
06348 }

static int check_auth struct sip_pvt p,
struct sip_request req,
char *  randdata,
int  randlen,
char *  username,
char *  secret,
char *  md5secret,
int  sipmethod,
char *  uri,
int  reliable,
int  ignore
[static]
 

check_auth: Check user authorization from peer definition ---

Definition at line 6099 of file chan_sip.c.

References ast_log(), ast_md5_hash(), ast_strlen_zero(), ast_test_flag, get_header(), global_allowguest, global_realm, LOG_DEBUG, LOG_NOTICE, sip_methods, SIP_OSPAUTH, SIP_OSPAUTH_EXCLUSIVE, SIP_OSPAUTH_GATEWAY, SIP_OSPAUTH_NO, SIP_OSPAUTH_PROXY, SIP_REGISTER, sip_scheddestroy(), SIP_SUBSCRIBE, sipdebug, text, thread_safe_rand(), and transmit_response_with_auth().

Referenced by check_user_full(), and register_verify().

06100 {
06101    int res = -1;
06102    char *response = "407 Proxy Authentication Required";
06103    char *reqheader = "Proxy-Authorization";
06104    char *respheader = "Proxy-Authenticate";
06105    char *authtoken;
06106 #ifdef OSP_SUPPORT
06107    char *osptoken;
06108 #endif
06109    /* Always OK if no secret */
06110    if (ast_strlen_zero(secret) && ast_strlen_zero(md5secret)
06111 #ifdef OSP_SUPPORT
06112        && !ast_test_flag(p, SIP_OSPAUTH)
06113        && global_allowguest != 2
06114 #endif
06115       )
06116       return 0;
06117    if (sipmethod == SIP_REGISTER || sipmethod == SIP_SUBSCRIBE) {
06118       /* On a REGISTER, we have to use 401 and its family of headers instead of 407 and its family
06119          of headers -- GO SIP!  Whoo hoo!  Two things that do the same thing but are used in
06120          different circumstances! What a surprise. */
06121       response = "401 Unauthorized";
06122       reqheader = "Authorization";
06123       respheader = "WWW-Authenticate";
06124    }
06125 #ifdef OSP_SUPPORT
06126    else {
06127       ast_log (LOG_DEBUG, "Checking OSP Authentication!\n");
06128       osptoken = get_header (req, "P-OSP-Auth-Token");
06129       switch (ast_test_flag (p, SIP_OSPAUTH)) {
06130          case SIP_OSPAUTH_NO:
06131             break;
06132          case SIP_OSPAUTH_GATEWAY:
06133             if (ast_strlen_zero (osptoken)) {
06134                if (ast_strlen_zero (secret) && ast_strlen_zero (md5secret)) {
06135                   return (0);
06136                }
06137             }
06138             else {
06139                return (check_osptoken (p, osptoken));
06140             }
06141             break;
06142          case SIP_OSPAUTH_PROXY:
06143             if (ast_strlen_zero (osptoken)) {
06144                return (0);
06145             } 
06146             else {
06147                return (check_osptoken (p, osptoken));
06148             }
06149             break;
06150          case SIP_OSPAUTH_EXCLUSIVE:
06151             if (ast_strlen_zero (osptoken)) {
06152                return (-1);
06153             }
06154             else {
06155                return (check_osptoken (p, osptoken));
06156             }
06157             break;
06158          default:
06159             return (-1);
06160       }
06161    }
06162 #endif   
06163    authtoken =  get_header(req, reqheader);  
06164    if (ignore && !ast_strlen_zero(randdata) && ast_strlen_zero(authtoken)) {
06165       /* This is a retransmitted invite/register/etc, don't reconstruct authentication
06166          information */
06167       if (!ast_strlen_zero(randdata)) {
06168          if (!reliable) {
06169             /* Resend message if this was NOT a reliable delivery.   Otherwise the
06170                retransmission should get it */
06171             transmit_response_with_auth(p, response, req, randdata, reliable, respheader, 0);
06172             /* Schedule auto destroy in 15 seconds */
06173             sip_scheddestroy(p, 15000);
06174          }
06175          res = 1;
06176       }
06177    } else if (ast_strlen_zero(randdata) || ast_strlen_zero(authtoken)) {
06178       snprintf(randdata, randlen, "%08x", thread_safe_rand());
06179       transmit_response_with_auth(p, response, req, randdata, reliable, respheader, 0);
06180       /* Schedule auto destroy in 15 seconds */
06181       sip_scheddestroy(p, 15000);
06182       res = 1;
06183    } else {
06184       /* Whoever came up with the authentication section of SIP can suck my %&#$&* for not putting
06185          an example in the spec of just what it is you're doing a hash on. */
06186       char a1[256];
06187       char a2[256];
06188       char a1_hash[256];
06189       char a2_hash[256];
06190       char resp[256];
06191       char resp_hash[256]="";
06192       char tmp[256];
06193       char *c;
06194       char *z;
06195       char *ua_hash ="";
06196       char *resp_uri ="";
06197       char *nonce = "";
06198       char *digestusername = "";
06199       int  wrongnonce = 0;
06200       char *usednonce = randdata;
06201 
06202       /* Find their response among the mess that we'r sent for comparison */
06203       ast_copy_string(tmp, authtoken, sizeof(tmp));
06204       c = tmp;
06205 
06206       while(c) {
06207          c = ast_skip_blanks(c);
06208          if (!*c)
06209             break;
06210          if (!strncasecmp(c, "response=", strlen("response="))) {
06211             c+= strlen("response=");
06212             if ((*c == '\"')) {
06213                ua_hash=++c;
06214                if ((c = strchr(c,'\"')))
06215                   *c = '\0';
06216 
06217             } else {
06218                ua_hash=c;
06219                if ((c = strchr(c,',')))
06220                   *c = '\0';
06221             }
06222 
06223          } else if (!strncasecmp(c, "uri=", strlen("uri="))) {
06224             c+= strlen("uri=");
06225             if ((*c == '\"')) {
06226                resp_uri=++c;
06227                if ((c = strchr(c,'\"')))
06228                   *c = '\0';
06229             } else {
06230                resp_uri=c;
06231                if ((c = strchr(c,',')))
06232                   *c = '\0';
06233             }
06234 
06235          } else if (!strncasecmp(c, "username=", strlen("username="))) {
06236             c+= strlen("username=");
06237             if ((*c == '\"')) {
06238                digestusername=++c;
06239                if((c = strchr(c,'\"')))
06240                   *c = '\0';
06241             } else {
06242                digestusername=c;
06243                if((c = strchr(c,',')))
06244                   *c = '\0';
06245             }
06246          } else if (!strncasecmp(c, "nonce=", strlen("nonce="))) {
06247             c+= strlen("nonce=");
06248             if ((*c == '\"')) {
06249                nonce=++c;
06250                if ((c = strchr(c,'\"')))
06251                   *c = '\0';
06252             } else {
06253                nonce=c;
06254                if ((c = strchr(c,',')))
06255                   *c = '\0';
06256             }
06257 
06258          } else
06259             if ((z = strchr(c,' ')) || (z = strchr(c,','))) c=z;
06260          if (c)
06261             c++;
06262       }
06263       /* Verify that digest username matches  the username we auth as */
06264       if (strcmp(username, digestusername)) {
06265          /* Oops, we're trying something here */
06266          return -2;
06267       }
06268 
06269       /* Verify nonce from request matches our nonce.  If not, send 401 with new nonce */
06270       if (strncasecmp(randdata, nonce, randlen)) {
06271          wrongnonce = 1;
06272          usednonce = nonce;
06273       }
06274 
06275       snprintf(a1, sizeof(a1), "%s:%s:%s", username, global_realm, secret);
06276 
06277       if (!ast_strlen_zero(resp_uri))
06278          snprintf(a2, sizeof(a2), "%s:%s", sip_methods[sipmethod].text, resp_uri);
06279       else
06280          snprintf(a2, sizeof(a2), "%s:%s", sip_methods[sipmethod].text, uri);
06281 
06282       if (!ast_strlen_zero(md5secret))
06283          snprintf(a1_hash, sizeof(a1_hash), "%s", md5secret);
06284       else
06285          ast_md5_hash(a1_hash, a1);
06286 
06287       ast_md5_hash(a2_hash, a2);
06288 
06289       snprintf(resp, sizeof(resp), "%s:%s:%s", a1_hash, usednonce, a2_hash);
06290       ast_md5_hash(resp_hash, resp);
06291 
06292       if (wrongnonce) {
06293 
06294          snprintf(randdata, randlen, "%08x", thread_safe_rand());
06295          if (ua_hash && !strncasecmp(ua_hash, resp_hash, strlen(resp_hash))) {
06296             if (sipdebug)
06297                ast_log(LOG_NOTICE, "stale nonce received from '%s'\n", get_header(req, "To"));
06298             /* We got working auth token, based on stale nonce . */
06299             transmit_response_with_auth(p, response, req, randdata, reliable, respheader, 1);
06300          } else {
06301             /* Everything was wrong, so give the device one more try with a new challenge */
06302             if (sipdebug)
06303                ast_log(LOG_NOTICE, "Bad authentication received from '%s'\n", get_header(req, "To"));
06304             transmit_response_with_auth(p, response, req, randdata, reliable, respheader, 0);
06305          }
06306 
06307          /* Schedule auto destroy in 15 seconds */
06308          sip_scheddestroy(p, 15000);
06309          return 1;
06310       } 
06311       /* resp_hash now has the expected response, compare the two */
06312       if (ua_hash && !strncasecmp(ua_hash, resp_hash, strlen(resp_hash))) {
06313          /* Auth is OK */
06314          res = 0;
06315       }
06316    }
06317    /* Failure */
06318    return res;
06319 }

static void check_pendings struct sip_pvt p  )  [static]
 

check_pendings: Check pending actions on SIP call ---

Definition at line 9434 of file chan_sip.c.

References ast_clear_flag, ast_log(), ast_set_flag, ast_test_flag, sip_pvt::callid, LOG_DEBUG, SIP_BYE, SIP_NEEDDESTROY, SIP_NEEDREINVITE, SIP_PENDINGBYE, transmit_reinvite_with_sdp(), and transmit_request_with_auth().

Referenced by handle_request(), and handle_response_invite().

09435 {
09436    /* Go ahead and send bye at this point */
09437    if (ast_test_flag(p, SIP_PENDINGBYE)) {
09438       transmit_request_with_auth(p, SIP_BYE, 0, 1, 1);
09439       ast_set_flag(p, SIP_NEEDDESTROY);   
09440       ast_clear_flag(p, SIP_NEEDREINVITE);   
09441    } else if (ast_test_flag(p, SIP_NEEDREINVITE)) {
09442       ast_log(LOG_DEBUG, "Sending pending reinvite on '%s'\n", p->callid);
09443       /* Didn't get to reinvite yet, so do it now */
09444       transmit_reinvite_with_sdp(p);
09445       ast_clear_flag(p, SIP_NEEDREINVITE);   
09446    }
09447 }

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

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

Definition at line 11765 of file chan_sip.c.

References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_strlen_zero(), domain::context, domain::domain, list, and result.

Referenced by func_check_sipdomain(), get_destination(), and register_verify().

11766 {
11767    struct domain *d;
11768    int result = 0;
11769 
11770    AST_LIST_LOCK(&domain_list);
11771    AST_LIST_TRAVERSE(&domain_list, d, list) {
11772       if (strcasecmp(d->domain, domain))
11773          continue;
11774 
11775       if (len && !ast_strlen_zero(d->context))
11776          ast_copy_string(context, d->context, len);
11777       
11778       result = 1;
11779       break;
11780    }
11781    AST_LIST_UNLOCK(&domain_list);
11782 
11783    return result;
11784 }

static 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 7219 of file chan_sip.c.

References check_user_full().

Referenced by handle_request_invite().

07220 {
07221    return check_user_full(p, req, sipmethod, uri, reliable, sin, ignore, NULL, 0);
07222 }

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

check_user_full: Check if matching user or peer is defined ---

Definition at line 6956 of file chan_sip.c.

References sip_peer::accountcode, sip_peer::amaflags, ast_apply_ha(), ast_copy_flags, ast_inet_ntoa(), ast_log(), AST_RTP_DTMF, ast_rtp_setnat(), ast_set_flag, ast_shrink_phone_number(), ast_strlen_zero(), ast_test_flag, ast_uri_decode(), ast_variable_new(), ast_verbose(), ASTOBJ_UNREF, build_contact(), sip_peer::call_limit, sip_peer::callgroup, sip_peer::callingpres, sip_pvt::callingpres, sip_peer::capability, sip_peer::chanvars, check_auth(), sip_peer::cid_name, sip_pvt::cid_name, sip_peer::cid_num, sip_pvt::cid_num, sip_peer::context, debug, sip_pvt::exten, find_peer(), find_user(), sip_pvt::from, sip_peer::fullcontact, get_calleridname(), get_header(), get_in_brackets(), get_rpid_num(), global_allowguest, global_flags, sip_peer::language, sip_peer::lastms, LOG_DEBUG, LOG_NOTICE, sip_peer::mailbox, sip_peer::maxms, sip_peer::md5secret, ast_variable::next, sip_pvt::our_contact, pedanticsipchecking, sip_pvt::peermd5secret, sip_pvt::peersecret, sip_peer::pickupgroup, sip_peer::prefs, sip_pvt::randdata, sip_pvt::recv, sip_pvt::rtp, sip_peer::secret, SIP_CALL_LIMIT, sip_cancel_destroy(), sip_debug_test_addr(), sip_destroy_peer(), sip_destroy_user(), SIP_DTMF, SIP_DTMF_AUTO, SIP_DTMF_RFC2833, SIP_FLAGS_TO_COPY, SIP_INSECURE_INVITE, SIP_NAT, SIP_NAT_ROUTE, SIP_OSPAUTH, SIP_SUBSCRIBE, SIP_TRUSTRPID, sip_peer::sipoptions, sip_pvt::sipoptions, sip_peer::subscribecontext, sip_pvt::subscribecontext, t, sip_pvt::timer_t1, user, sip_peer::username, and sip_pvt::vrtp.

Referenced by check_user(), and handle_request_subscribe().

06957 {
06958    struct sip_user *user = NULL;
06959    struct sip_peer *peer;
06960    char *of, from[256], *c;
06961    char *rpid,rpid_num[50];
06962    char iabuf[INET_ADDRSTRLEN];
06963    int res = 0;
06964    char *t;
06965    char calleridname[50];
06966    int debug=sip_debug_test_addr(sin);
06967    struct ast_variable *tmpvar = NULL, *v = NULL;
06968 
06969    /* Terminate URI */
06970    t = uri;
06971    while(*t && (*t > 32) && (*t != ';'))
06972       t++;
06973    *t = '\0';
06974    of = get_header(req, "From");
06975    if (pedanticsipchecking)
06976       ast_uri_decode(of);
06977 
06978    ast_copy_string(from, of, sizeof(from));
06979    
06980    memset(calleridname,0,sizeof(calleridname));
06981    get_calleridname(from, calleridname, sizeof(calleridname));
06982    if (calleridname[0])
06983       ast_copy_string(p->cid_name, calleridname, sizeof(p->cid_name));
06984 
06985    rpid = get_header(req, "Remote-Party-ID");
06986    memset(rpid_num,0,sizeof(rpid_num));
06987    if (!ast_strlen_zero(rpid)) 
06988       p->callingpres = get_rpid_num(rpid,rpid_num, sizeof(rpid_num));
06989 
06990    of = get_in_brackets(from);
06991    if (ast_strlen_zero(p->exten)) {
06992       t = uri;
06993       if (!strncmp(t, "sip:", 4))
06994          t+= 4;
06995       ast_copy_string(p->exten, t, sizeof(p->exten));
06996       t = strchr(p->exten, '@');
06997       if (t)
06998          *t = '\0';
06999       if (ast_strlen_zero(p->our_contact))
07000          build_contact(p);
07001    }
07002    /* save the URI part of the From header */
07003    ast_copy_string(p->from, of, sizeof(p->from));
07004    if (strncmp(of, "sip:", 4)) {
07005       ast_log(LOG_NOTICE, "From address missing 'sip:', using it anyway\n");
07006    } else
07007       of += 4;
07008    /* Get just the username part */
07009    if ((c = strchr(of, '@'))) {
07010       *c = '\0';
07011       if ((c = strchr(of, ':')))
07012          *c = '\0';
07013       ast_copy_string(p->cid_num, of, sizeof(p->cid_num));
07014       ast_shrink_phone_number(p->cid_num);
07015    }
07016    if (ast_strlen_zero(of))
07017       return 0;
07018 
07019    if (!mailbox)  /* If it's a mailbox SUBSCRIBE, don't check users */
07020       user = find_user(of, 1);
07021 
07022    /* Find user based on user name in the from header */
07023    if (user && ast_apply_ha(user->ha, sin)) {
07024       ast_copy_flags(p, user, SIP_FLAGS_TO_COPY);
07025       /* copy channel vars */
07026       for (v = user->chanvars ; v ; v = v->next) {
07027          if ((tmpvar = ast_variable_new(v->name, v->value))) {
07028             tmpvar->next = p->chanvars; 
07029             p->chanvars = tmpvar;
07030          }
07031       }
07032       p->prefs = user->prefs;
07033       /* replace callerid if rpid found, and not restricted */
07034       if (!ast_strlen_zero(rpid_num) && ast_test_flag(p, SIP_TRUSTRPID)) {
07035          if (*calleridname)
07036             ast_copy_string(p->cid_name, calleridname, sizeof(p->cid_name));
07037          ast_copy_string(p->cid_num, rpid_num, sizeof(p->cid_num));
07038          ast_shrink_phone_number(p->cid_num);
07039       }
07040 
07041       if (p->rtp) {
07042          ast_log(LOG_DEBUG, "Setting NAT on RTP to %d\n", (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE));
07043          ast_rtp_setnat(p->rtp, (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE));
07044       }
07045       if (p->vrtp) {
07046          ast_log(LOG_DEBUG, "Setting NAT on VRTP to %d\n", (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE));
07047          ast_rtp_setnat(p->vrtp, (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE));
07048       }
07049       if (!(res = check_auth(p, req, p->randdata, sizeof(p->randdata), user->name, user->secret, user->md5secret, sipmethod, uri, reliable, ignore))) {
07050          sip_cancel_destroy(p);
07051          ast_copy_flags(p, user, SIP_FLAGS_TO_COPY);
07052          /* Copy SIP extensions profile from INVITE */
07053          if (p->sipoptions)
07054             user->sipoptions = p->sipoptions;
07055 
07056          /* If we have a call limit, set flag */
07057          if (user->call_limit)
07058             ast_set_flag(p, SIP_CALL_LIMIT);
07059          if (!ast_strlen_zero(user->context))
07060             ast_copy_string(p->context, user->context, sizeof(p->context));
07061          if (!ast_strlen_zero(user->cid_num) && !ast_strlen_zero(p->cid_num))  {
07062             ast_copy_string(p->cid_num, user->cid_num, sizeof(p->cid_num));
07063             ast_shrink_phone_number(p->cid_num);
07064          }
07065          if (!ast_strlen_zero(user->cid_name) && !ast_strlen_zero(p->cid_num)) 
07066             ast_copy_string(p->cid_name, user->cid_name, sizeof(p->cid_name));
07067          ast_copy_string(p->username, user->name, sizeof(p->username));
07068          ast_copy_string(p->peersecret, user->secret, sizeof(p->peersecret));
07069          ast_copy_string(p->subscribecontext, user->subscribecontext, sizeof(p->subscribecontext));
07070          ast_copy_string(p->peermd5secret, user->md5secret, sizeof(p->peermd5secret));
07071          ast_copy_string(p->accountcode, user->accountcode, sizeof(p->accountcode));
07072          ast_copy_string(p->language, user->language, sizeof(p->language));
07073          ast_copy_string(p->musicclass, user->musicclass, sizeof(p->musicclass));
07074          p->amaflags = user->amaflags;
07075          p->callgroup = user->callgroup;
07076          p->pickupgroup = user->pickupgroup;
07077          p->callingpres = user->callingpres;
07078          p->capability = user->capability;
07079          p->jointcapability = user->capability;
07080          if (p->peercapability)
07081             p->jointcapability &= p->peercapability;
07082          if ((ast_test_flag(p, SIP_DTMF) == SIP_DTMF_RFC2833) || (ast_test_flag(p, SIP_DTMF) == SIP_DTMF_AUTO))
07083             p->noncodeccapability |= AST_RTP_DTMF;
07084          else
07085             p->noncodeccapability &= ~AST_RTP_DTMF;
07086       }
07087       if (user && debug)
07088          ast_verbose("Found user '%s'\n", user->name);
07089    } else {
07090       if (user) {
07091          if (!mailbox && debug)
07092             ast_verbose("Found user '%s', but fails host access\n", user->name);
07093          ASTOBJ_UNREF(user,sip_destroy_user);
07094       }
07095       user = NULL;
07096    }
07097 
07098    if (!user) {
07099       /* If we didn't find a user match, check for peers */
07100       if (sipmethod == SIP_SUBSCRIBE)
07101          /* For subscribes, match on peer name only */
07102          peer = find_peer(of, NULL, 1);
07103       else
07104          /* Look for peer based on the IP address we received data from */
07105          /* If peer is registered from this IP address or have this as a default
07106             IP address, this call is from the peer 
07107          */
07108          peer = find_peer(NULL, &p->recv, 1);
07109 
07110       if (peer) {
07111          if (debug)
07112             ast_verbose("Found peer '%s'\n", peer->name);
07113          /* Take the peer */
07114          ast_copy_flags(p, peer, SIP_FLAGS_TO_COPY);
07115 
07116          /* Copy SIP extensions profile to peer */
07117          if (p->sipoptions)
07118             peer->sipoptions = p->sipoptions;
07119 
07120          /* replace callerid if rpid found, and not restricted */
07121          if (!ast_strlen_zero(rpid_num) && ast_test_flag(p, SIP_TRUSTRPID)) {
07122             if (*calleridname)
07123                ast_copy_string(p->cid_name, calleridname, sizeof(p->cid_name));
07124             ast_copy_string(p->cid_num, rpid_num, sizeof(p->cid_num));
07125             ast_shrink_phone_number(p->cid_num);
07126          }
07127          if (p->rtp) {
07128             ast_log(LOG_DEBUG, "Setting NAT on RTP to %d\n", (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE));
07129             ast_rtp_setnat(p->rtp, (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE));
07130          }
07131          if (p->vrtp) {
07132             ast_log(LOG_DEBUG, "Setting NAT on VRTP to %d\n", (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE));
07133             ast_rtp_setnat(p->vrtp, (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE));
07134          }
07135          ast_copy_string(p->peersecret, peer->secret, sizeof(p->peersecret));
07136          p->peersecret[sizeof(p->peersecret)-1] = '\0';
07137          ast_copy_string(p->subscribecontext, peer->subscribecontext, sizeof(p->subscribecontext));
07138          ast_copy_string(p->peermd5secret, peer->md5secret, sizeof(p->peermd5secret));
07139          p->peermd5secret[sizeof(p->peermd5secret)-1] = '\0';
07140          p->callingpres = peer->callingpres;
07141          if (peer->maxms && peer->lastms)
07142             p->timer_t1 = peer->lastms;
07143          if (ast_test_flag(peer, SIP_INSECURE_INVITE)) {
07144             /* Pretend there is no required authentication */
07145             p->peersecret[0] = '\0';
07146             p->peermd5secret[0] = '\0';
07147          }
07148          if (!(res = check_auth(p, req, p->randdata, sizeof(p->randdata), peer->name, p->peersecret, p->peermd5secret, sipmethod, uri, reliable, ignore))) {
07149             ast_copy_flags(p, peer, SIP_FLAGS_TO_COPY);
07150             /* If we have a call limit, set flag */
07151             if (peer->call_limit)
07152                ast_set_flag(p, SIP_CALL_LIMIT);
07153             ast_copy_string(p->peername, peer->name, sizeof(p->peername));
07154             ast_copy_string(p->authname, peer->name, sizeof(p->authname));
07155             /* copy channel vars */
07156             for (v = peer->chanvars ; v ; v = v->next) {
07157                if ((tmpvar = ast_variable_new(v->name, v->value))) {
07158                   tmpvar->next = p->chanvars; 
07159                   p->chanvars = tmpvar;
07160                }
07161             }
07162             if (mailbox)
07163                snprintf(mailbox, mailboxlen, ",%s,", peer->mailbox);
07164             if (!ast_strlen_zero(peer->username)) {
07165                ast_copy_string(p->username, peer->username, sizeof(p->username));
07166                /* Use the default username for authentication on outbound calls */
07167                ast_copy_string(p->authname, peer->username, sizeof(p->authname));
07168             }
07169             if (!ast_strlen_zero(peer->cid_num) && !ast_strlen_zero(p->cid_num))  {
07170                ast_copy_string(p->cid_num, peer->cid_num, sizeof(p->cid_num));
07171                ast_shrink_phone_number(p->cid_num);
07172             }
07173             if (!ast_strlen_zero(peer->cid_name) && !ast_strlen_zero(p->cid_name)) 
07174                ast_copy_string(p->cid_name, peer->cid_name, sizeof(p->cid_name));
07175             ast_copy_string(p->fullcontact, peer->fullcontact, sizeof(p->fullcontact));
07176             if (!ast_strlen_zero(peer->context))
07177                ast_copy_string(p->context, peer->context, sizeof(p->context));
07178             ast_copy_string(p->peersecret, peer->secret, sizeof(p->peersecret));
07179             ast_copy_string(p->peermd5secret, peer->md5secret, sizeof(p->peermd5secret));
07180             ast_copy_string(p->language, peer->language, sizeof(p->language));
07181             ast_copy_string(p->accountcode, peer->accountcode, sizeof(p->accountcode));
07182             p->amaflags = peer->amaflags;
07183             p->callgroup = peer->callgroup;
07184             p->pickupgroup = peer->pickupgroup;
07185             p->capability = peer->capability;
07186             p->prefs = peer->prefs;
07187             p->jointcapability = peer->capability;
07188             if (p->peercapability)
07189                p->jointcapability &= p->peercapability;
07190             if ((ast_test_flag(p, SIP_DTMF) == SIP_DTMF_RFC2833) || (ast_test_flag(p, SIP_DTMF) == SIP_DTMF_AUTO))
07191                p->noncodeccapability |= AST_RTP_DTMF;
07192             else
07193                p->noncodeccapability &= ~AST_RTP_DTMF;
07194          }
07195          ASTOBJ_UNREF(peer,sip_destroy_peer);
07196       } else { 
07197          if (debug)
07198             ast_verbose("Found no matching peer or user for '%s:%d'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), p->recv.sin_addr), ntohs(p->recv.sin_port));
07199 
07200          /* do we allow guests? */
07201          if (!global_allowguest)
07202             res = -1;  /* we don't want any guests, authentication will fail */
07203 #ifdef OSP_SUPPORT         
07204          else if (global_allowguest == 2) {
07205             ast_copy_flags(p, &global_flags, SIP_OSPAUTH);
07206             res = check_auth(p, req, p->randdata, sizeof(p->randdata), "", "", "", sipmethod, uri, reliable, ignore); 
07207          }
07208 #endif
07209       }
07210 
07211    }
07212 
07213    if (user)
07214       ASTOBJ_UNREF(user,sip_destroy_user);
07215    return res;
07216 }

static 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 6832 of file chan_sip.c.

References ahp, ast_gethostbyname(), ast_inet_ntoa(), ast_log(), ast_set_flag, ast_test_flag, ast_verbose(), DEFAULT_SIP_PORT, get_header(), hp, LOG_WARNING, sip_pvt::sa, sip_debug_test_pvt(), SIP_NAT, and SIP_NAT_ROUTE.

Referenced by handle_request_bye(), handle_request_cancel(), handle_request_invite(), handle_request_register(), and handle_request_subscribe().

06833 {
06834    char via[256];
06835    char iabuf[INET_ADDRSTRLEN];
06836    char *c, *pt;
06837    struct hostent *hp;
06838    struct ast_hostent ahp;
06839 
06840    ast_copy_string(via, get_header(req, "Via"), sizeof(via));
06841 
06842    /* Check for rport */
06843    c = strstr(via, ";rport");
06844    if (c && (c[6] != '=')) /* rport query, not answer */
06845       ast_set_flag(p, SIP_NAT_ROUTE);
06846 
06847    c = strchr(via, ';');
06848    if (c) 
06849       *c = '\0';
06850 
06851    c = strchr(via, ' ');
06852    if (c) {
06853       *c = '\0';
06854       c = ast_skip_blanks(c+1);
06855       if (strcasecmp(via, "SIP/2.0/UDP")) {
06856          ast_log(LOG_WARNING, "Don't know how to respond via '%s'\n", via);
06857          return -1;
06858       }
06859       pt = strchr(c, ':');
06860       if (pt)
06861          *pt++ = '\0';  /* remember port pointer */
06862       hp = ast_gethostbyname(c, &ahp);
06863       if (!hp) {
06864          ast_log(LOG_WARNING, "'%s' is not a valid host\n", c);
06865          return -1;
06866       }
06867       memset(&p->sa, 0, sizeof(p->sa));
06868       p->sa.sin_family = AF_INET;
06869       memcpy(&p->sa.sin_addr, hp->h_addr, sizeof(p->sa.sin_addr));
06870       p->sa.sin_port = htons(pt ? atoi(pt) : DEFAULT_SIP_PORT);
06871 
06872       if (sip_debug_test_pvt(p)) {
06873          c = (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE) ? "NAT" : "non-NAT";
06874          ast_verbose("Sending to %s : %d (%s)\n", ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr), ntohs(p->sa.sin_port), c);
06875       }
06876    }
06877    return 0;
06878 }

static int clear_realm_authentication struct sip_auth authlist  )  [static]
 

clear_realm_authentication: Clear realm authentication list (at reload) ---

Definition at line 11866 of file chan_sip.c.

References free, and sip_auth::next.

Referenced by sip_destroy_peer(), sip_do_reload(), and unload_module().

11867 {
11868    struct sip_auth *a = authlist;
11869    struct sip_auth *b;
11870 
11871    while (a) {
11872       b = a;
11873       a = a->next;
11874       free(b);
11875    }
11876 
11877    return 1;
11878 }

static void clear_sip_domains void   )  [static]
 

clear_sip_domains: Clear our domain list (at reload)

Definition at line 11787 of file chan_sip.c.

References AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, free, and list.

Referenced by sip_do_reload(), and unload_module().

11788 {
11789    struct domain *d;
11790 
11791    AST_LIST_LOCK(&domain_list);
11792    while ((d = AST_LIST_REMOVE_HEAD(&domain_list, list)))
11793       free(d);
11794    AST_LIST_UNLOCK(&domain_list);
11795 }

static 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 8378 of file chan_sip.c.

References complete_sip_peer().

08379 {
08380    if (pos == 3)
08381       return complete_sip_peer(word, state, 0);
08382 
08383    return NULL;
08384 }

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

complete_sip_peer: Do completion on peer name ---

Definition at line 8349 of file chan_sip.c.

References ast_test_flag, ASTOBJ_CONTAINER_TRAVERSE, peerl, result, and strdup.

Referenced by complete_sip_debug_peer(), complete_sip_prune_realtime_peer(), complete_sip_show_peer(), and complete_sipnotify().

08350 {
08351    char *result = NULL;
08352    int wordlen = strlen(word);
08353    int which = 0;
08354 
08355    ASTOBJ_CONTAINER_TRAVERSE(&peerl, !result, do {
08356       /* locking of the object is not required because only the name and flags are being compared */
08357       if (!strncasecmp(word, iterator->name, wordlen)) {
08358          if (flags2 && !ast_test_flag((&iterator->flags_page2), flags2))
08359             continue;
08360          if (++which > state) {
08361             result = strdup(iterator->name);
08362          }
08363       }
08364    } while(0) );
08365    return result;
08366 }

static 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 8449 of file chan_sip.c.

References complete_sip_peer(), and SIP_PAGE2_RTCACHEFRIENDS.

08450 {
08451    if (pos == 4)
08452       return complete_sip_peer(word, state, SIP_PAGE2_RTCACHEFRIENDS);
08453    return NULL;
08454 }

static 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 8457 of file chan_sip.c.

References complete_sip_user(), and SIP_PAGE2_RTCACHEFRIENDS.

08458 {
08459    if (pos == 4)
08460       return complete_sip_user(word, state, SIP_PAGE2_RTCACHEFRIENDS);
08461 
08462    return NULL;
08463 }

static 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 8369 of file chan_sip.c.

References complete_sip_peer().

08370 {
08371    if (pos == 3)
08372       return complete_sip_peer(word, state, 0);
08373 
08374    return NULL;
08375 }

static 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 8407 of file chan_sip.c.

References complete_sip_user().

08408 {
08409    if (pos == 3)
08410       return complete_sip_user(word, state, 0);
08411 
08412    return NULL;
08413 }

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

complete_sip_user: Do completion on user name ---

Definition at line 8387 of file chan_sip.c.

References ast_test_flag, ASTOBJ_CONTAINER_TRAVERSE, result, strdup, and userl.

Referenced by complete_sip_prune_realtime_user(), and complete_sip_show_user().

08388 {
08389    char *result = NULL;
08390    int wordlen = strlen(word);
08391    int which = 0;
08392 
08393    ASTOBJ_CONTAINER_TRAVERSE(&userl, !result, do {
08394       /* locking of the object is not required because only the name and flags are being compared */
08395       if (!strncasecmp(word, iterator->name, wordlen)) {
08396          if (flags2 && !ast_test_flag(&(iterator->flags_page2), flags2))
08397             continue;
08398          if (++which > state) {
08399             result = strdup(iterator->name);
08400          }
08401       }
08402    } while(0) );
08403    return result;
08404 }

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

complete_sipch: Support routine for 'sip show channel' CLI ---

Definition at line 8327 of file chan_sip.c.

References ast_mutex_lock(), ast_mutex_unlock(), sip_pvt::callid, iflist, sip_pvt::next, and strdup.

08328 {
08329    int which=0;
08330    struct sip_pvt *cur;
08331    char *c = NULL;
08332 
08333    ast_mutex_lock(&iflock);
08334    cur = iflist;
08335    while(cur) {
08336       if (!strncasecmp(word, cur->callid, strlen(word))) {
08337          if (++which > state) {
08338             c = strdup(cur->callid);
08339             break;
08340          }
08341       }
08342       cur = cur->next;
08343    }
08344    ast_mutex_unlock(&iflock);
08345    return c;
08346 }

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

complete_sipnotify: Support routine for 'sip notify' CLI ---

Definition at line 8416 of file chan_sip.c.

References ast_category_browse(), complete_sip_peer(), notify_types, and strdup.

08417 {
08418    char *c = NULL;
08419 
08420    if (pos == 2) {
08421       int which = 0;
08422       char *cat;
08423 
08424       /* do completion for notify type */
08425 
08426       if (!notify_types)
08427          return NULL;
08428       
08429       cat = ast_category_browse(notify_types, NULL);
08430       while(cat) {
08431          if (!strncasecmp(word, cat, strlen(word))) {
08432             if (++which > state) {
08433                c = strdup(cat);
08434                break;
08435             }
08436          }
08437          cat = ast_category_browse(notify_types, cat);
08438       }
08439       return c;
08440    }
08441 
08442    if (pos > 2)
08443       return complete_sip_peer(word, state, 0);
08444 
08445    return NULL;
08446 }

static 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 3778 of file chan_sip.c.

References __get_header(), add_header(), and ast_strlen_zero().

Referenced by respprep().

03779 {
03780    char *tmp;
03781    int start = 0;
03782    int copied = 0;
03783    for (;;) {
03784       tmp = __get_header(orig, field, &start);
03785       if (!ast_strlen_zero(tmp)) {
03786          /* Add what we're responding to */
03787          add_header(req, field, tmp);
03788          copied++;
03789       } else
03790          break;
03791    }
03792    return copied ? 0 : -1;
03793 }

static 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 3765 of file chan_sip.c.

References add_header(), ast_log(), ast_strlen_zero(), get_header(), and LOG_NOTICE.

Referenced by reqprep(), and respprep().

03766 {
03767    char *tmp;
03768    tmp = get_header(orig, field);
03769    if (!ast_strlen_zero(tmp)) {
03770       /* Add what we're responding to */
03771       return add_header(req, field, tmp);
03772    }
03773    ast_log(LOG_NOTICE, "No field '%s' present to copy\n", field);
03774    return -1;
03775 }

static 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 4503 of file chan_sip.c.

References offset.

Referenced by handle_request_bye(), handle_request_invite(), handle_request_register(), handle_request_subscribe(), sip_park(), sip_park_thread(), transmit_invite(), transmit_notify_with_mwi(), transmit_notify_with_sipfrag(), transmit_register(), transmit_reinvite_with_sdp(), and transmit_sip_request().

04504 {
04505    long offset;
04506    int x;
04507    offset = ((void *)dst) - ((void *)src);
04508    /* First copy stuff */
04509    memcpy(dst, src, sizeof(*dst));
04510    /* Now fix pointer arithmetic */
04511    for (x=0; x < src->headers; x++)
04512       dst->header[x] += offset;
04513    for (x=0; x < src->lines; x++)
04514       dst->line[x] += offset;
04515 }

static 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 3801 of file chan_sip.c.

References __get_header(), add_header(), ast_inet_ntoa(), ast_strlen_zero(), ast_test_flag, sip_pvt::recv, SIP_NAT, and SIP_NAT_ALWAYS.

Referenced by respprep().

03802 {
03803    char tmp[256], *oh, *end;
03804    int start = 0;
03805    int copied = 0;
03806    char iabuf[INET_ADDRSTRLEN];
03807 
03808    for (;;) {
03809       oh = __get_header(orig, field, &start);
03810       if (!ast_strlen_zero(oh)) {
03811          if (!copied) { /* Only check for empty rport in topmost via header */
03812             char *rport;
03813             char new[256];
03814 
03815             /* Find ;rport;  (empty request) */
03816             rport = strstr(oh, ";rport");
03817             if (rport && *(rport+6) == '=') 
03818                rport = NULL;     /* We already have a parameter to rport */
03819 
03820             if (rport && (ast_test_flag(p, SIP_NAT) == SIP_NAT_ALWAYS)) {
03821                /* We need to add received port - rport */
03822                ast_copy_string(tmp, oh, sizeof(tmp));
03823 
03824                rport = strstr(tmp, ";rport");
03825 
03826                if (rport) {
03827                   end = strchr(rport + 1, ';');
03828                   if (end)
03829                      memmove(rport, end, strlen(end) + 1);
03830                   else
03831                      *rport = '\0';
03832                }
03833 
03834                /* Add rport to first VIA header if requested */
03835                /* Whoo hoo!  Now we can indicate port address translation too!  Just
03836                      another RFC (RFC3581). I'll leave the original comments in for
03837                      posterity.  */
03838                snprintf(new, sizeof(new), "%s;received=%s;rport=%d", tmp, ast_inet_ntoa(iabuf, sizeof(iabuf), p->recv.sin_addr), ntohs(p->recv.sin_port));
03839             } else {
03840                /* We should *always* add a received to the topmost via */
03841                snprintf(new, sizeof(new), "%s;received=%s", oh, ast_inet_ntoa(iabuf, sizeof(iabuf), p->recv.sin_addr));
03842             }
03843             add_header(req, field, new);
03844          } else {
03845             /* Add the following via headers untouched */
03846             add_header(req, field, oh);
03847          }
03848          copied++;
03849       } else
03850          break;
03851    }
03852    if (!copied) {
03853       ast_log(LOG_NOTICE, "No header field '%s' present to copy\n", field);
03854       return -1;
03855    }
03856    return 0;
03857 }

static 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(), DEFAULT_SIP_PORT, find_peer(), host, hp, LOG_WARNING, portno, sip_pvt::recv, sip_pvt::sa, sip_destroy_peer(), sip_pvt::timer_t1, and sip_pvt::tohost.

01920 {
01921    struct hostent *hp;
01922    struct ast_hostent ahp;
01923    struct sip_peer *p;
01924    int found=0;
01925    char *port;
01926    int portno;
01927    char host[MAXHOSTNAMELEN], *hostn;
01928    char peer[256];
01929 
01930    ast_copy_string(peer, opeer, sizeof(peer));
01931    port = strchr(peer, ':');
01932    if (port) {
01933       *port = '\0';
01934       port++;
01935    }
01936    dialog->sa.sin_family = AF_INET;
01937    dialog->timer_t1 = 500; /* Default SIP retransmission timer T1 (RFC 3261) */
01938    p = find_peer(peer, NULL, 1);
01939 
01940    if (p) {
01941       found++;
01942       if (create_addr_from_peer(dialog, p))
01943          ASTOBJ_UNREF(p, sip_destroy_peer);
01944    }
01945    if (!p) {
01946       if (found)
01947          return -1;
01948 
01949       hostn = peer;
01950       if (port)
01951          portno = atoi(port);
01952       else
01953          portno = DEFAULT_SIP_PORT;
01954       if (srvlookup) {
01955          char service[MAXHOSTNAMELEN];
01956          int tportno;
01957          int ret;
01958          snprintf(service, sizeof(service), "_sip._udp.%s", peer);
01959          ret = ast_get_srv(NULL, host, sizeof(host), &tportno, service);
01960          if (ret > 0) {
01961             hostn = host;
01962             portno = tportno;
01963          }
01964       }
01965       hp = ast_gethostbyname(hostn, &ahp);
01966       if (hp) {
01967          ast_copy_string(dialog->tohost, peer, sizeof(dialog->tohost));
01968          memcpy(&dialog->sa.sin_addr, hp->h_addr, sizeof(dialog->sa.sin_addr));
01969          dialog->sa.sin_port = htons(portno);
01970          memcpy(&dialog->recv, &dialog->sa, sizeof(dialog->recv));
01971          return 0;
01972       } else {
01973          ast_log(LOG_WARNING, "No such host: %s\n", peer);
01974          return -1;
01975       }
01976    } else {
01977       ASTOBJ_UNREF(p, sip_destroy_peer);
01978       return 0;
01979    }
01980 }

static 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_DTMF, ast_rtp_setnat(), ast_set_flag, ast_strlen_zero(), ast_test_flag, sip_pvt::authname, sip_peer::call_limit, sip_peer::callgroup, sip_pvt::callgroup, sip_pvt::callid, sip_peer::capability, sip_pvt::capability, sip_peer::context, sip_pvt::context, sip_peer::defaddr, sip_pvt::fromdomain, sip_peer::fromdomain, sip_pvt::fromuser, sip_peer::fromuser, sip_peer::fullcontact, sip_pvt::fullcontact, sip_request::headers, sip_pvt::initreq, sip_peer::lastms, LOG_DEBUG, sip_peer::maxms, sip_pvt::maxtime, sip_peer::md5secret, sip_pvt::noncodeccapability, sip_pvt::peermd5secret, sip_pvt::peername, sip_pvt::peersecret, sip_peer::pickupgroup, sip_pvt::pickupgroup, sip_peer::prefs, sip_pvt::prefs, sip_pvt::recv, sip_pvt::rtp, sip_peer::rtpholdtimeout, sip_pvt::rtpholdtimeout, sip_peer::rtpkeepalive, sip_pvt::rtpkeepalive, sip_peer::rtptimeout, sip_pvt::rtptimeout, sip_pvt::sa, sip_peer::secret, SIP_CALL_LIMIT, SIP_DTMF, SIP_DTMF_AUTO, SIP_DTMF_RFC2833, SIP_FLAGS_TO_COPY, SIP_NAT, SIP_NAT_ROUTE, sip_pvt::timer_t1, sip_peer::tohost, sip_pvt::tohost, sip_pvt::username, sip_peer::username, and sip_pvt::vrtp.

Referenced by create_addr(), and sip_send_mwi_to_peer().

01844 {
01845    char *callhost;
01846 
01847    if ((peer->addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr) &&
01848        (!peer->maxms || ((peer->lastms >= 0)  && (peer->lastms <= peer->maxms)))) {
01849       if (peer->addr.sin_addr.s_addr) {
01850          r->sa.sin_family = peer->addr.sin_family;
01851          r->sa.sin_addr = peer->addr.sin_addr;
01852          r->sa.sin_port = peer->addr.sin_port;
01853       } else {
01854          r->sa.sin_family = peer->defaddr.sin_family;
01855          r->sa.sin_addr = peer->defaddr.sin_addr;
01856          r->sa.sin_port = peer->defaddr.sin_port;
01857       }
01858       memcpy(&r->recv, &r->sa, sizeof(r->recv));
01859    } else {
01860       return -1;
01861    }
01862 
01863    ast_copy_flags(r, peer, SIP_FLAGS_TO_COPY);
01864    r->capability = peer->capability;
01865    r->prefs = peer->prefs;
01866    if (r->rtp) {
01867       ast_log(LOG_DEBUG, "Setting NAT on RTP to %d\n", (ast_test_flag(r, SIP_NAT) & SIP_NAT_ROUTE));
01868       ast_rtp_setnat(r->rtp, (ast_test_flag(r, SIP_NAT) & SIP_NAT_ROUTE));
01869    }
01870    if (r->vrtp) {
01871       ast_log(LOG_DEBUG, "Setting NAT on VRTP to %d\n", (ast_test_flag(r, SIP_NAT) & SIP_NAT_ROUTE));
01872       ast_rtp_setnat(r->vrtp, (ast_test_flag(r, SIP_NAT) & SIP_NAT_ROUTE));
01873    }
01874    ast_copy_string(r->peername, peer->username, sizeof(r->peername));
01875    ast_copy_string(r->authname, peer->username, sizeof(r->authname));
01876    ast_copy_string(r->username, peer->username, sizeof(r->username));
01877    ast_copy_string(r->peersecret, peer->secret, sizeof(r->peersecret));
01878    ast_copy_string(r->peermd5secret, peer->md5secret, sizeof(r->peermd5secret));
01879    ast_copy_string(r->tohost, peer->tohost, sizeof(r->tohost));
01880    ast_copy_string(r->fullcontact, peer->fullcontact, sizeof(r->fullcontact));
01881    if (!r->initreq.headers && !ast_strlen_zero(peer->fromdomain)) {
01882       if ((callhost = strchr(r->callid, '@'))) {
01883          strncpy(callhost + 1, peer->fromdomain, sizeof(r->callid) - (callhost - r->callid) - 2);
01884       }
01885    }
01886    if (ast_strlen_zero(r->tohost)) {
01887       if (peer->addr.sin_addr.s_addr)
01888          ast_inet_ntoa(r->tohost, sizeof(r->tohost), peer->addr.sin_addr);
01889       else
01890          ast_inet_ntoa(r->tohost, sizeof(r->tohost), peer->defaddr.sin_addr);
01891    }
01892    if (!ast_strlen_zero(peer->fromdomain))
01893       ast_copy_string(r->fromdomain, peer->fromdomain, sizeof(r->fromdomain));
01894    if (!ast_strlen_zero(peer->fromuser))
01895       ast_copy_string(r->fromuser, peer->fromuser, sizeof(r->fromuser));
01896    r->maxtime = peer->maxms;
01897    r->callgroup = peer->callgroup;
01898    r->pickupgroup = peer->pickupgroup;
01899    /* Set timer T1 to RTT for this peer (if known by qualify=) */
01900    if (peer->maxms && peer->lastms)
01901       r->timer_t1 = peer->lastms;
01902    if ((ast_test_flag(r, SIP_DTMF) == SIP_DTMF_RFC2833) || (ast_test_flag(r, SIP_DTMF) == SIP_DTMF_AUTO))
01903       r->noncodeccapability |= AST_RTP_DTMF;
01904    else
01905       r->noncodeccapability &= ~AST_RTP_DTMF;
01906    ast_copy_string(r->context, peer->context,sizeof(r->context));
01907    r->rtptimeout = peer->rtptimeout;
01908    r->rtpholdtimeout = peer->rtpholdtimeout;
01909    r->rtpkeepalive = peer->rtpkeepalive;
01910    if (peer->call_limit)
01911       ast_set_flag(r, SIP_CALL_LIMIT);
01912 
01913    return 0;
01914 }

char* description void   ) 
 

Provides a description of the module.

Returns:
a short description of your module

Definition at line 13279 of file chan_sip.c.

References desc.

13280 {
13281    return (char *) desc;
13282 }

static void destroy_association struct sip_peer peer  )  [static]
 

Definition at line 5625 of file chan_sip.c.

References ast_db_del(), ast_test_flag, ast_update_realtime(), sip_peer::flags_page2, global_flags_page2, SIP_PAGE2_IGNOREREGEXPIRE, and SIP_PAGE2_RT_FROMCONTACT.

Referenced by build_peer(), expire_register(), and parse_register_contact().

05626 {
05627    if (!ast_test_flag((&global_flags_page2), SIP_PAGE2_IGNOREREGEXPIRE)) {
05628       if (ast_test_flag(&(peer->flags_page2), SIP_PAGE2_RT_FROMCONTACT)) {
05629          ast_update_realtime("sippeers", "name", peer->name, "fullcontact", "", "ipaddr", "", "port", "", "regseconds", "0", "username", "", NULL);
05630       } else {
05631          ast_db_del("SIP/Registry", peer->name);
05632       }
05633    }
05634 }

static int determine_firstline_parts struct sip_request req  )  [static]
 

determine_firstline_parts: parse first line of incoming SIP request

Definition at line 4538 of file chan_sip.c.

References sip_request::header, sip_request::len, sip_request::rlPart1, and sip_request::rlPart2.

Referenced by parse_request(), transmit_notify_with_mwi(), transmit_notify_with_sipfrag(), transmit_register(), and transmit_sip_request().

04539 {
04540    char *e, *cmd;
04541    int len;
04542   
04543    cmd = ast_skip_blanks(req->header[0]);
04544    if (!*cmd)
04545       return -1;
04546    req->rlPart1 = cmd;
04547    e = ast_skip_nonblanks(cmd);
04548    /* Get the command */
04549    if (*e)
04550       *e++ = '\0';
04551    e = ast_skip_blanks(e);
04552    if ( !*e )
04553       return -1;
04554 
04555    if ( !strcasecmp(cmd, "SIP/2.0") ) {
04556       /* We have a response */
04557       req->rlPart2 = e;
04558       len = strlen( req->rlPart2 );
04559       if ( len < 2 ) { 
04560          return -1;
04561       }
04562       ast_trim_blanks(e);
04563    } else {
04564       /* We have a request */
04565       if ( *e == '<' ) { 
04566          e++;
04567          if ( !*e ) { 
04568             return -1; 
04569          }  
04570       }
04571       req->rlPart2 = e; /* URI */
04572       if ( ( e= strrchr( req->rlPart2, 'S' ) ) == NULL ) {
04573          return -1;
04574       }
04575       /* XXX maybe trim_blanks() ? */
04576       while( isspace( *(--e) ) ) {}
04577       if ( *e == '>' ) {
04578          *e = '\0';
04579       } else {
04580          *(++e)= '\0';
04581       }
04582    }
04583    return 1;
04584 }

static void* do_monitor void *  data  )  [static]
 

do_monitor: The SIP monitoring thread ---

Definition at line 11227 of file chan_sip.c.

References __sip_destroy(), ast_channel::_state, ast_io_add(), AST_IO_IN, ast_io_wait(), ast_log(), ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_rtp_get_peer(), ast_rtp_sendcng(), ast_sched_runq(), ast_sched_wait(), ast_softhangup(), AST_SOFTHANGUP_DEV, AST_STATE_UP, ast_strlen_zero(), ast_test_flag, ast_verbose(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_REF, global_mwitime, iflist, io, sip_pvt::lastrtprx, sip_pvt::lastrtptx, ast_channel::lock, sip_pvt::lock, LOG_DEBUG, LOG_NOTICE, ast_channel::name, sip_pvt::next, option_verbose, sip_pvt::owner, sip_pvt::packets, peerl, sip_pvt::redirip, sip_pvt::rtp, sip_pvt::rtpholdtimeout, sip_pvt::rtpkeepalive, sip_pvt::rtptimeout, sip_do_reload(), SIP_NEEDDESTROY, sip_reloading, sipsock, sipsock_read(), t, and VERBOSE_PREFIX_1.

11228 {
11229    int res;
11230    struct sip_pvt *sip;
11231    struct sip_peer *peer = NULL;
11232    time_t t;
11233    int fastrestart =0;
11234    int lastpeernum = -1;
11235    int curpeernum;
11236    int reloading;
11237 
11238    /* Add an I/O event to our UDP socket */
11239    if (sipsock > -1) 
11240       ast_io_add(io, sipsock, sipsock_read, AST_IO_IN, NULL);
11241    
11242    /* This thread monitors all the frame relay interfaces which are not yet in use
11243       (and thus do not have a separate thread) indefinitely */
11244    /* From here on out, we die whenever asked */
11245    for(;;) {
11246       /* Check for a reload request */
11247       ast_mutex_lock(&sip_reload_lock);
11248       reloading = sip_reloading;
11249       sip_reloading = 0;
11250       ast_mutex_unlock(&sip_reload_lock);
11251       if (reloading) {
11252          if (option_verbose > 0)
11253             ast_verbose(VERBOSE_PREFIX_1 "Reloading SIP\n");
11254          sip_do_reload();
11255       }
11256       /* Check for interfaces needing to be killed */
11257       ast_mutex_lock(&iflock);
11258 restartsearch:    
11259       time(&t);
11260       sip = iflist;
11261       while(sip) {
11262          ast_mutex_lock(&sip->lock);
11263          if (sip->rtp && sip->owner && (sip->owner->_state == AST_STATE_UP) && !sip->redirip.sin_addr.s_addr) {
11264             if (sip->lastrtptx && sip->rtpkeepalive && t > sip->lastrtptx + sip->rtpkeepalive) {
11265                /* Need to send an empty RTP packet */
11266                time(&sip->lastrtptx);
11267                ast_rtp_sendcng(sip->rtp, 0);
11268             }
11269             if (sip->lastrtprx && (sip->rtptimeout || sip->rtpholdtimeout) && t > sip->lastrtprx + sip->rtptimeout) {
11270                /* Might be a timeout now -- see if we're on hold */
11271                struct sockaddr_in sin;
11272                ast_rtp_get_peer(sip->rtp, &sin);
11273                if (sin.sin_addr.s_addr || 
11274                      (sip->rtpholdtimeout && 
11275                        (t > sip->lastrtprx + sip->rtpholdtimeout))) {
11276                   /* Needs a hangup */
11277                   if (sip->rtptimeout) {
11278                      while(sip->owner && ast_mutex_trylock(&sip->owner->lock)) {
11279                         ast_mutex_unlock(&sip->lock);
11280                         usleep(1);
11281                         ast_mutex_lock(&sip->lock);
11282                      }
11283                      if (sip->owner) {
11284                         ast_log(LOG_NOTICE, "Disconnecting call '%s' for lack of RTP activity in %ld seconds\n", sip->owner->name, (long)(t - sip->lastrtprx));
11285                         /* Issue a softhangup */
11286                         ast_softhangup(sip->owner, AST_SOFTHANGUP_DEV);
11287                         ast_mutex_unlock(&sip->owner->lock);
11288                      }
11289                   }
11290                }
11291             }
11292          }
11293          if (ast_test_flag(sip, SIP_NEEDDESTROY) && !sip->packets && !sip->owner) {
11294             ast_mutex_unlock(&sip->lock);
11295             __sip_destroy(sip, 1);
11296             goto restartsearch;
11297          }
11298          ast_mutex_unlock(&sip->lock);
11299          sip = sip->next;
11300       }
11301       ast_mutex_unlock(&iflock);
11302       /* Don't let anybody kill us right away.  Nobody should lock the interface list
11303          and wait for the monitor list, but the other way around is okay. */
11304       ast_mutex_lock(&monlock);
11305       /* Lock the network interface */
11306       ast_mutex_lock(&netlock);
11307       /* Okay, now that we know what to do, release the network lock */
11308       ast_mutex_unlock(&netlock);
11309       /* And from now on, we're okay to be killed, so release the monitor lock as well */
11310       ast_mutex_unlock(&monlock);
11311       pthread_testcancel();
11312       /* Wait for sched or io */
11313       res = ast_sched_wait(sched);
11314       if ((res < 0) || (res > 1000))
11315          res = 1000;
11316       /* If we might need to send more mailboxes, don't wait long at all.*/
11317       if (fastrestart)
11318          res = 1;
11319       res = ast_io_wait(io, res);
11320       if (res > 20)
11321          ast_log(LOG_DEBUG, "chan_sip: ast_io_wait ran %d all at once\n", res);
11322       ast_mutex_lock(&monlock);
11323       if (res >= 0)  {
11324          res = ast_sched_runq(sched);
11325          if (res >= 20)
11326             ast_log(LOG_DEBUG, "chan_sip: ast_sched_runq ran %d all at once\n", res);
11327       }
11328 
11329       /* needs work to send mwi to realtime peers */
11330       time(&t);
11331       fastrestart = 0;
11332       curpeernum = 0;
11333       peer = NULL;
11334       ASTOBJ_CONTAINER_TRAVERSE(&peerl, !peer, do {
11335          if ((curpeernum > lastpeernum) && !ast_strlen_zero(iterator->mailbox) && ((t - iterator->lastmsgcheck) > global_mwitime)) {
11336             fastrestart = 1;
11337             lastpeernum = curpeernum;
11338             peer = ASTOBJ_REF(iterator);
11339          };
11340          curpeernum++;
11341       } while (0)
11342       );
11343       if (peer) {
11344          ASTOBJ_WRLOCK(peer);
11345          sip_send_mwi_to_peer(peer);
11346          ASTOBJ_UNLOCK(peer);
11347          ASTOBJ_UNREF(peer,sip_destroy_peer);
11348       } else {
11349          /* Reset where we come from */
11350          lastpeernum = -1;
11351       }
11352       ast_mutex_unlock(&monlock);
11353    }
11354    /* Never reached */
11355    return NULL;
11356    
11357 }

static 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 8889 of file chan_sip.c.

References ast_log(), sip_invite_param::auth, sip_invite_param::authheader, sip_pvt::authtries, calloc, LOG_DEBUG, LOG_ERROR, option_debug, sip_pvt::options, reply_digest(), SIP_INVITE, sip_methods, cfsip_methods::text, and transmit_invite().

Referenced by handle_response(), and handle_response_invite().

08890 {
08891    char digest[1024];
08892 
08893    if (!p->options) {
08894       p->options = calloc(1, sizeof(*p->options));
08895       if (!p->options) {
08896          ast_log(LOG_ERROR, "Out of memory\n");
08897          return -2;
08898       }
08899    }
08900 
08901    p->authtries++;
08902    if (option_debug > 1)
08903       ast_log(LOG_DEBUG, "Auth attempt %d on %s\n", p->authtries, sip_methods[sipmethod].text);
08904    memset(digest, 0, sizeof(digest));
08905    if (reply_digest(p, req, header, sipmethod, digest, sizeof(digest) )) {
08906       /* No way to authenticate */
08907       return -1;
08908    }
08909    /* Now we have a reply digest */
08910    p->options->auth = digest;
08911    p->options->authheader = respheader;
08912    return transmit_invite(p, sipmethod, sipmethod == SIP_INVITE, init); 
08913 }

static 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 8865 of file chan_sip.c.

References append_history(), ast_verbose(), sip_pvt::authtries, sip_registry::hostname, recordhistory, sip_pvt::registry, reply_digest(), sip_debug_test_pvt(), SIP_REGISTER, and transmit_register().

Referenced by handle_response_register().

08866 {
08867    char digest[1024];
08868    p->authtries++;
08869    memset(digest,0,sizeof(digest));
08870    if (reply_digest(p, req, header, SIP_REGISTER, digest, sizeof(digest))) {
08871       /* There's nothing to use for authentication */
08872       /* No digest challenge in request */
08873       if (sip_debug_test_pvt(p) && p->registry)
08874          ast_verbose("No authentication challenge, sending blank registration to domain/host name %s\n", p->registry->hostname);
08875          /* No old challenge */
08876       return -1;
08877    }
08878    if (recordhistory) {
08879       char tmp[80];
08880       snprintf(tmp, sizeof(tmp), "Try: %d", p->authtries);
08881       append_history(p, "RegistryAuth", tmp);
08882    }
08883    if (sip_debug_test_pvt(p) && p->registry)
08884       ast_verbose("Responding to challenge, registration to domain/host name %s\n", p->registry->hostname);
08885    return transmit_register(p->registry, SIP_REGISTER, digest, respheader); 
08886 }

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

Definition at line 7809 of file chan_sip.c.

References SIP_DOMAIN_AUTO, and SIP_DOMAIN_CONFIG.

Referenced by sip_show_domains().

07810 {
07811    switch (mode) {
07812    case SIP_DOMAIN_AUTO:
07813       return "[Automatic]";
07814    case SIP_DOMAIN_CONFIG:
07815       return "[Configured]";
07816    }
07817 
07818    return "";
07819 }

static const char* dtmfmode2str int  mode  )  [static]
 

dtmfmode2str: Convert DTMF mode to printable string ---

Definition at line 7617 of file chan_sip.c.

References SIP_DTMF_AUTO, SIP_DTMF_INBAND, SIP_DTMF_INFO, and SIP_DTMF_RFC2833.

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

07618 {
07619    switch (mode) {
07620    case SIP_DTMF_RFC2833:
07621       return "rfc2833";
07622    case SIP_DTMF_INFO:
07623       return "info";
07624    case SIP_DTMF_INBAND:
07625       return "inband";
07626    case SIP_DTMF_AUTO:
07627       return "auto";
07628    }
07629    return "<error>";
07630 }

static int expire_register void *  data  )  [static]
 

expire_register: Expire registration of SIP peer ---

Definition at line 5637 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().

05638 {
05639    struct sip_peer *peer = data;
05640 
05641    memset(&peer->addr, 0, sizeof(peer->addr));
05642 
05643    destroy_association(peer);
05644    
05645    manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name);
05646    register_peer_exten(peer, 0);
05647    peer->expire = -1;
05648    ast_device_state_changed("SIP/%s", peer->name);
05649    if (ast_test_flag(peer, SIP_SELFDESTRUCT) || ast_test_flag((&peer->flags_page2), SIP_PAGE2_RTAUTOCLEAR)) {
05650       peer = ASTOBJ_CONTAINER_UNLINK(&peerl, peer);
05651       ASTOBJ_UNREF(peer, sip_destroy_peer);
05652    }
05653 
05654    return 0;
05655 }

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

extract_uri: Check Contact: URI of SIP message ---

Definition at line 4616 of file chan_sip.c.

References ast_strlen_zero(), get_header(), get_in_brackets(), n, and sip_pvt::uri.

Referenced by handle_request(), and handle_request_invite().

04617 {
04618    char stripped[256];
04619    char *c, *n;
04620    ast_copy_string(stripped, get_header(req, "Contact"), sizeof(stripped));
04621    c = get_in_brackets(stripped);
04622    n = strchr(c, ';');
04623    if (n)
04624       *n = '\0';
04625    if (!ast_strlen_zero(c))
04626       ast_copy_string(p->uri, c, sizeof(p->uri));
04627 }

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

Definition at line 2895 of file chan_sip.c.

References aliases.

02896 {
02897    int x;
02898    for (x=0;x<sizeof(aliases) / sizeof(aliases[0]); x++) 
02899       if (!strcasecmp(aliases[x].fullname, name))
02900          return aliases[x].shortname;
02901    return _default;
02902 }

static 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 3127 of file chan_sip.c.

References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_strlen_zero(), sip_pvt::callid, get_header(), gettag(), iflist, sip_pvt::lock, LOG_DEBUG, sip_request::method, sip_pvt::next, option_debug, pedanticsipchecking, sip_alloc(), sip_methods, SIP_PKT_WITH_TOTAG, SIP_REGISTER, SIP_RESPONSE, sip_pvt::tag, and sip_pvt::theirtag.

Referenced by sipsock_read().

03128 {
03129    struct sip_pvt *p;
03130    char *callid;
03131    char *tag = "";
03132    char totag[128];
03133    char fromtag[128];
03134 
03135    callid = get_header(req, "Call-ID");
03136 
03137    if (pedanticsipchecking) {
03138       /* In principle Call-ID's uniquely identify a call, but with a forking SIP proxy
03139          we need more to identify a branch - so we have to check branch, from
03140          and to tags to identify a call leg.
03141          For Asterisk to behave correctly, you need to turn on pedanticsipchecking
03142          in sip.conf
03143          */
03144       if (gettag(req, "To", totag, sizeof(totag)))
03145          ast_set_flag(req, SIP_PKT_WITH_TOTAG); /* Used in handle_request/response */
03146       gettag(req, "From", fromtag, sizeof(fromtag));
03147 
03148       if (req->method == SIP_RESPONSE)
03149          tag = totag;
03150       else
03151          tag = fromtag;
03152          
03153 
03154       if (option_debug > 4 )
03155          ast_log(LOG_DEBUG, "= Looking for  Call ID: %s (Checking %s) --From tag %s --To-tag %s  \n", callid, req->method==SIP_RESPONSE ? "To" : "From", fromtag, totag);
03156    }
03157 
03158    ast_mutex_lock(&iflock);
03159    p = iflist;
03160    while(p) {  /* In pedantic, we do not want packets with bad syntax to be connected to a PVT */
03161       int found = 0;
03162       if (req->method == SIP_REGISTER)
03163          found = (!strcmp(p->callid, callid));
03164       else 
03165          found = (!strcmp(p->callid, callid) && 
03166          (!pedanticsipchecking || !tag || ast_strlen_zero(p->theirtag) || !strcmp(p->theirtag, tag))) ;
03167 
03168       if (option_debug > 4)
03169          ast_log(LOG_DEBUG, "= %s Their Call ID: %s Their Tag %s Our tag: %s\n", found ? "Found" : "No match", p->callid, p->theirtag, p->tag);
03170 
03171       /* If we get a new request within an existing to-tag - check the to tag as well */
03172       if (pedanticsipchecking && found  && req->method != SIP_RESPONSE) {  /* SIP Request */
03173          if (p->tag[0] == '\0' && totag[0]) {
03174             /* We have no to tag, but they have. Wrong dialog */
03175             found = 0;
03176          } else if (totag[0]) {        /* Both have tags, compare them */
03177             if (strcmp(totag, p->tag)) {
03178                found = 0;     /* This is not our packet */
03179             }
03180          }
03181          if (!found && option_debug > 4)
03182             ast_log(LOG_DEBUG, "= Being pedantic: This is not our match on request: Call ID: %s Ourtag <null> Totag %s Method %s\n", p->callid, totag, sip_methods[req->method].text);
03183       }
03184 
03185 
03186       if (found) {
03187          /* Found the call */
03188          ast_mutex_lock(&p->lock);
03189          ast_mutex_unlock(&iflock);
03190          return p;
03191       }
03192       p = p->next;
03193    }
03194    ast_mutex_unlock(&iflock);
03195    p = sip_alloc(callid, sin, 1, intended_method);
03196    if (p)
03197       ast_mutex_lock(&p->lock);
03198    return p;
03199 }

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

static 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 11881 of file chan_sip.c.

References sip_auth::next, and sip_auth::realm.

Referenced by build_reply_digest().

11882 {
11883    struct sip_auth *a = authlist;   /* First entry in auth list */
11884 
11885    while (a) {
11886       if (!strcasecmp(a->realm, realm)){
11887          break;
11888       }
11889       a = a->next;
11890    }
11891    
11892    return a;
11893 }

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 }

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

find_subscription_type: Find subscription type in array

Definition at line 8252 of file chan_sip.c.

References subscription_types, and type.

Referenced by transmit_state_notify().

08252                                                                                                 {
08253    int i;
08254 
08255    for (i = 1; (i < (sizeof(subscription_types) / sizeof(subscription_types[0]))); i++) {
08256       if (subscription_types[i].type == subtype) {
08257          return &subscription_types[i];
08258       }
08259    }
08260    return &subscription_types[0];
08261 }

static 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, 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 }

static void free_old_route struct sip_route route  )  [static]
 

free_old_route: Remove route from route list ---

Definition at line 5957 of file chan_sip.c.

References free, and sip_route::next.

Referenced by __sip_destroy(), and build_route().

05958 {
05959    struct sip_route *next;
05960    while (route) {
05961       next = route->next;
05962       free(route);
05963       route = next;
05964    }
05965 }

static 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 9206 of file chan_sip.c.

References ast_log(), ast_strlen_zero(), check_sip_domain(), and LOG_WARNING.

09207 {
09208    if (ast_strlen_zero(data)) {
09209       ast_log(LOG_WARNING, "CHECKSIPDOMAIN requires an argument - A domain name\n");
09210       return buf;
09211    }
09212    if (check_sip_domain(data, NULL, 0))
09213       ast_copy_string(buf, data, len);
09214    else
09215       buf[0] = '\0';
09216    return buf;
09217 }

static 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 9159 of file chan_sip.c.

References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_strlen_zero(), channeltype, get_header(), sip_pvt::initreq, ast_channel::lock, LOG_WARNING, ast_channel::tech_pvt, and ast_channel::type.

09160 {
09161    struct sip_pvt *p;
09162    char *content;
09163    
09164    if (!data) {
09165       ast_log(LOG_WARNING, "This function requires a header name.\n");
09166       return NULL;
09167    }
09168 
09169    ast_mutex_lock(&chan->lock);
09170    if (chan->type != channeltype) {
09171       ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n");
09172       ast_mutex_unlock(&chan->lock);
09173       return NULL;
09174    }
09175 
09176    p = chan->tech_pvt;
09177 
09178    /* If there is no private structure, this channel is no longer alive */
09179    if (!p) {
09180       ast_mutex_unlock(&chan->lock);
09181       return NULL;
09182    }
09183 
09184    content = get_header(&p->initreq, data);
09185 
09186    if (ast_strlen_zero(content)) {
09187       ast_mutex_unlock(&chan->lock);
09188       return NULL;
09189    }
09190 
09191    ast_copy_string(buf, content, len);
09192    ast_mutex_unlock(&chan->lock);
09193 
09194    return buf;
09195 }

static 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 9333 of file chan_sip.c.

References ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), channeltype, sip_pvt::from, ast_channel::lock, LOG_WARNING, sip_pvt::peername, sip_pvt::recv, sip_pvt::sa, ast_channel::tech_pvt, ast_channel::type, sip_pvt::uri, and sip_pvt::useragent.

09334 {
09335    struct sip_pvt *p;
09336    char iabuf[INET_ADDRSTRLEN];
09337 
09338    *buf = 0;
09339    
09340    if (!data) {
09341       ast_log(LOG_WARNING, "This function requires a parameter name.\n");
09342       return NULL;
09343    }
09344 
09345    ast_mutex_lock(&chan->lock);
09346    if (chan->type != channeltype) {
09347       ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n");
09348       ast_mutex_unlock(&chan->lock);
09349       return NULL;
09350    }
09351 
09352 /*    ast_verbose("function_sipchaninfo_read: %s\n", data); */
09353    p = chan->tech_pvt;
09354 
09355    /* If there is no private structure, this channel is no longer alive */
09356    if (!p) {
09357       ast_mutex_unlock(&chan->lock);
09358       return NULL;
09359    }
09360 
09361    if (!strcasecmp(data, "peerip")) {
09362       ast_copy_string(buf, p->sa.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr) : "", len);
09363    } else  if (!strcasecmp(data, "recvip")) {
09364       ast_copy_string(buf, p->recv.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), p->recv.sin_addr) : "", len);
09365    } else  if (!strcasecmp(data, "from")) {
09366       ast_copy_string(buf, p->from, len);
09367    } else  if (!strcasecmp(data, "uri")) {
09368       ast_copy_string(buf, p->uri, len);
09369    } else  if (!strcasecmp(data, "useragent")) {
09370       ast_copy_string(buf, p->useragent, len);
09371    } else  if (!strcasecmp(data, "peername")) {
09372       ast_copy_string(buf, p->peername, len);
09373    } else {
09374       ast_mutex_unlock(&chan->lock);
09375       return NULL;
09376    }
09377    ast_mutex_unlock(&chan->lock);
09378 
09379    return buf;
09380 }

static 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 9232 of file chan_sip.c.

References sip_peer::accountcode, sip_peer::addr, ast_codec_pref_index(), ast_getformatname(), ast_getformatname_multiple(), ast_inet_ntoa(), ast_log(), ast_strdupa, ast_test_flag, ASTOBJ_UNREF, sip_peer::call_limit, sip_peer::capability, sip_peer::cid_name, sip_peer::cid_num, sip_peer::context, sip_peer::expire, find_peer(), sip_peer::inUse, sip_peer::language, LOG_ERROR, sip_peer::mailbox, peer_status(), sip_peer::prefs, sip_peer::regexten, sip_destroy_peer(), SIP_DYNAMIC, and sip_peer::useragent.

09233 {
09234    char *ret = NULL;
09235    struct sip_peer *peer;
09236    char *peername, *colname;
09237    char iabuf[INET_ADDRSTRLEN];
09238 
09239    if (!(peername = ast_strdupa(data))) {
09240       ast_log(LOG_ERROR, "Memory Error!\n");
09241       return ret;
09242    }
09243 
09244    if ((colname = strchr(peername, ':'))) {
09245       *colname = '\0';
09246       colname++;
09247    } else {
09248       colname = "ip";
09249    }
09250    if (!(peer = find_peer(peername, NULL, 1)))
09251       return ret;
09252 
09253    if (!strcasecmp(colname, "ip")) {
09254       ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), peer->addr.sin_addr) : "", len);
09255    } else  if (!strcasecmp(colname, "status")) {
09256       peer_status(peer, buf, sizeof(buf));
09257    } else  if (!strcasecmp(colname, "language")) {
09258       ast_copy_string(buf, peer->language, len);
09259    } else  if (!strcasecmp(colname, "regexten")) {
09260       ast_copy_string(buf, peer->regexten, len);
09261    } else  if (!strcasecmp(colname, "limit")) {
09262       snprintf(buf, len, "%d", peer->call_limit);
09263    } else  if (!strcasecmp(colname, "curcalls")) {
09264       snprintf(buf, len, "%d", peer->inUse);
09265    } else  if (!strcasecmp(colname, "accountcode")) {
09266       ast_copy_string(buf, peer->accountcode, len);
09267    } else  if (!strcasecmp(colname, "useragent")) {
09268       ast_copy_string(buf, peer->useragent, len);
09269    } else  if (!strcasecmp(colname, "mailbox")) {
09270       ast_copy_string(buf, peer->mailbox, len);
09271    } else  if (!strcasecmp(colname, "context")) {
09272       ast_copy_string(buf, peer->context, len);
09273    } else  if (!strcasecmp(colname, "expire")) {
09274       snprintf(buf, len, "%d", peer->expire);
09275    } else  if (!strcasecmp(colname, "dynamic")) {
09276       ast_copy_string(buf, (ast_test_flag(peer, SIP_DYNAMIC) ? "yes" : "no"), len);
09277    } else  if (!strcasecmp(colname, "callerid_name")) {
09278       ast_copy_string(buf, peer->cid_name, len);
09279    } else  if (!strcasecmp(colname, "callerid_num")) {
09280       ast_copy_string(buf, peer->cid_num, len);
09281    } else  if (!strcasecmp(colname, "codecs")) {
09282       ast_getformatname_multiple(buf, len -1, peer->capability);
09283    } else  if (!strncasecmp(colname, "codec[", 6)) {
09284       char *codecnum, *ptr;
09285       int index = 0, codec = 0;
09286       
09287       codecnum = strchr(colname, '[');
09288       *codecnum = '\0';
09289       codecnum++;
09290       if ((ptr = strchr(codecnum, ']'))) {
09291          *ptr = '\0';
09292       }
09293       index = atoi(codecnum);
09294       if((codec = ast_codec_pref_index(&peer->prefs, index))) {
09295          ast_copy_string(buf, ast_getformatname(codec), len);
09296       }
09297    }
09298    ret = buf;
09299 
09300    ASTOBJ_UNREF(peer, sip_destroy_peer);
09301 
09302    return ret;
09303 }

static 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 6790 of file chan_sip.c.

References ast_canmatch_extension(), ast_exists_extension(), ast_log(), ast_verbose(), sip_pvt::context, get_header(), get_in_brackets(), sip_pvt::initreq, LOG_DEBUG, LOG_WARNING, sip_pvt::refer_call, sip_pvt::refer_contact, sip_pvt::refer_to, sip_pvt::referred_by, and sip_debug_test_pvt().

Referenced by handle_request_bye().

06791 {
06792    char tmp[256], *c, *a;
06793    struct sip_request *req;
06794    
06795    req = oreq;
06796    if (!req)
06797       req = &p->initreq;
06798    ast_copy_string(tmp, get_header(req, "Also"), sizeof(tmp));
06799    
06800    c = get_in_brackets(tmp);
06801    
06802       
06803    if (strncmp(c, "sip:", 4)) {
06804       ast_log(LOG_WARNING, "Huh?  Not a SIP header (%s)?\n", c);
06805       return -1;
06806    }
06807    c += 4;
06808    if ((a = strchr(c, '@')))
06809       *a = '\0';
06810    if ((a = strchr(c, ';'))) 
06811       *a = '\0';
06812    
06813    if (sip_debug_test_pvt(p)) {
06814       ast_verbose("Looking for %s in %s\n", c, p->context);
06815    }
06816    if (ast_exists_extension(NULL, p->context, c, 1, NULL)) {
06817       /* This is an unsupervised transfer */
06818       ast_log(LOG_DEBUG,"Assigning Extension %s to REFER-TO\n", c);
06819       ast_copy_string(p->refer_to, c, sizeof(p->refer_to));
06820       ast_copy_string(p->referred_by, "", sizeof(p->referred_by));
06821       ast_copy_string(p->refer_contact, "", sizeof(p->refer_contact));
06822       p->refer_call = NULL;
06823       return 0;
06824    } else if (ast_canmatch_extension(NULL, p->context, c, 1, NULL)) {
06825       return 1;
06826    }
06827 
06828    return -1;
06829 }

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

get_calleridname: Get caller id name from SIP headers ---

Definition at line 6881 of file chan_sip.c.

Referenced by check_user_full().

06882 {
06883    char *end = strchr(input,'<');
06884    char *tmp = strchr(input,'\"');
06885    int bytes = 0;
06886    int maxbytes = outputsize - 1;
06887 
06888    if (!end || (end == input)) return NULL;
06889    /* move away from "<" */
06890    end--;
06891    /* we found "name" */
06892    if (tmp && tmp < end) {
06893       end = strchr(tmp+1, '\"');
06894       if (!end) return NULL;
06895       bytes = (int) (end - tmp);
06896       /* protect the output buffer */
06897       if (bytes > maxbytes)
06898          bytes = maxbytes;
06899       ast_copy_string(output, tmp + 1, bytes);
06900    } else {
06901       /* we didn't find "name" */
06902       /* clear the empty characters in the begining*/
06903       input = ast_skip_blanks(input);
06904       /* clear the empty characters in the end */
06905       while(*end && (*end < 33) && end > input)
06906          end--;
06907       if (end >= input) {
06908          bytes = (int) (end - input) + 2;
06909          /* protect the output buffer */
06910          if (bytes > maxbytes) {
06911             bytes = maxbytes;
06912          }
06913          ast_copy_string(output, input, bytes);
06914       }
06915       else
06916          return NULL;
06917    }
06918    return output;
06919 }

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

get_destination: Find out who the call is for --

Definition at line 6523 of file chan_sip.c.

References allow_external_domains, ast_canmatch_extension(), ast_exists_extension(), AST_LIST_EMPTY, ast_log(), AST_MAX_EXTENSION, ast_pickup_ext(), ast_strlen_zero(), ast_uri_decode(), ast_verbose(), check_sip_domain(), sip_pvt::context, sip_pvt::domain, sip_pvt::exten, sip_pvt::fromdomain, get_header(), get_in_brackets(), sip_pvt::initreq, LOG_DEBUG, LOG_WARNING, sip_request::method, pedanticsipchecking, sip_request::rlPart2, sip_debug_test_pvt(), SIP_INVITE, sip_methods, and SIP_REFER.

Referenced by handle_request_invite(), handle_request_options(), and handle_request_subscribe().

06524 {
06525    char tmp[256] = "", *uri, *a;
06526    char tmpf[256], *from;
06527    struct sip_request *req;
06528    char *colon;
06529    
06530    req = oreq;
06531    if (!req)
06532       req = &p->initreq;
06533    if (req->rlPart2)
06534       ast_copy_string(tmp, req->rlPart2, sizeof(tmp));
06535    uri = get_in_brackets(tmp);
06536    
06537    ast_copy_string(tmpf, get_header(req, "From"), sizeof(tmpf));
06538 
06539    from = get_in_brackets(tmpf);
06540    
06541    if (strncmp(uri, "sip:", 4)) {
06542       ast_log(LOG_WARNING, "Huh?  Not a SIP header (%s)?\n", uri);
06543       return -1;
06544    }
06545    uri += 4;
06546    if (!ast_strlen_zero(from)) {
06547       if (strncmp(from, "sip:", 4)) {
06548          ast_log(LOG_WARNING, "Huh?  Not a SIP header (%s)?\n", from);
06549          return -1;
06550       }
06551       from += 4;
06552    } else
06553       from = NULL;
06554 
06555    if (pedanticsipchecking) {
06556       ast_uri_decode(uri);
06557       ast_uri_decode(from);
06558    }
06559 
06560    /* Skip any options */
06561    if ((a = strchr(uri, ';'))) {
06562       *a = '\0';
06563    }
06564 
06565    /* Get the target domain */
06566    if ((a = strchr(uri, '@'))) {
06567       *a = '\0';
06568       a++;
06569    } else { /* No username part */
06570       a = uri;
06571       uri = "s";  /* Set extension to "s" */
06572    }
06573    colon = strchr(a, ':'); /* Remove :port */
06574    if (colon)
06575       *colon = '\0';
06576 
06577    ast_copy_string(p->domain, a, sizeof(p->domain));
06578 
06579    if (!AST_LIST_EMPTY(&domain_list)) {
06580       char domain_context[AST_MAX_EXTENSION];
06581 
06582       domain_context[0] = '\0';
06583       if (!check_sip_domain(p->domain, domain_context, sizeof(domain_context))) {
06584          if (!allow_external_domains && (req->method == SIP_INVITE || req->method == SIP_REFER)) {
06585             ast_log(LOG_DEBUG, "Got SIP %s to non-local domain '%s'; refusing request.\n", sip_methods[req->method].text, p->domain);
06586             return -2;
06587          }
06588       }
06589       /* If we have a context defined, overwrite the original context */
06590       if (!ast_strlen_zero(domain_context))
06591          ast_copy_string(p->context, domain_context, sizeof(p->context));
06592    }
06593 
06594    if (from) {
06595       if ((a = strchr(from, ';')))
06596          *a = '\0';
06597       if ((a = strchr(from, '@'))) {
06598          *a = '\0';
06599          ast_copy_string(p->fromdomain, a + 1, sizeof(p->fromdomain));
06600       } else
06601          ast_copy_string(p->fromdomain, from, sizeof(p->fromdomain));
06602    }
06603    if (sip_debug_test_pvt(p))
06604       ast_verbose("Looking for %s in %s (domain %s)\n", uri, p->context, p->domain);
06605 
06606    /* Return 0 if we have a matching extension */
06607    if (ast_exists_extension(NULL, p->context, uri, 1, from) ||
06608       !strcmp(uri, ast_pickup_ext())) {
06609       if (!oreq)
06610          ast_copy_string(p->exten, uri, sizeof(p->exten));
06611       return 0;
06612    }
06613 
06614    /* Return 1 for overlap dialling support */
06615    if (ast_canmatch_extension(NULL, p->context, uri, 1, from) ||
06616        !strncmp(uri, ast_pickup_ext(),strlen(uri))) {
06617       return 1;
06618    }
06619    
06620    return -1;
06621 }

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

get_header: Get header from SIP request ---

Definition at line 2940 of file chan_sip.c.

References __get_header().

02941 {
02942    int start = 0;
02943    return __get_header(req, name, &start);
02944 }

static 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(), LOG_WARNING, and parse().

Referenced by check_user_full(), extract_uri(), get_also_info(), get_destination(), get_rdnis(), get_refer_info(), parse_moved_contact(), parse_ok_contact(), parse_register_contact(), register_verify(), reqprep(), transmit_refer(), and transmit_state_notify().

01533 {
01534    char *parse;
01535    char *first_quote;
01536    char *first_bracket;
01537    char *second_bracket;
01538    char last_char;
01539 
01540    parse = tmp;
01541    while (1) {
01542       first_quote = strchr(parse, '"');
01543       first_bracket = strchr(parse, '<');
01544       if (first_quote && first_bracket && (first_quote < first_bracket)) {
01545          last_char = '\0';
01546          for (parse = first_quote + 1; *parse; parse++) {
01547             if ((*parse == '"') && (last_char != '\\'))
01548                break;
01549             last_char = *parse;
01550          }
01551          if (!*parse) {
01552             ast_log(LOG_WARNING, "No closing quote found in '%s'\n", tmp);
01553             return tmp;
01554          }
01555          parse++;
01556          continue;
01557       }
01558       if (first_bracket) {
01559          second_bracket = strchr(first_bracket + 1, '>');
01560          if (second_bracket) {
01561             *second_bracket = '\0';
01562             return first_bracket + 1;
01563          } else {
01564             ast_log(LOG_WARNING, "No closing bracket found in '%s'\n", tmp);
01565             return tmp;
01566          }
01567       }
01568       return tmp;
01569    }
01570 }

static 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 7225 of file chan_sip.c.

References sip_request::line, and sip_request::lines.

Referenced by receive_message().

07226 {
07227    int x;
07228    int y;
07229 
07230    buf[0] = '\0';
07231    y = len - strlen(buf) - 5;
07232    if (y < 0)
07233       y = 0;
07234    for (x=0;x<req->lines;x++) {
07235       strncat(buf, req->line[x], y); /* safe */
07236       y -= strlen(req->line[x]) + 1;
07237       if (y < 0)
07238          y = 0;
07239       if (y != 0)
07240          strcat(buf, "\n"); /* safe */
07241    }
07242    return 0;
07243 }

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

get_rdnis: get referring dnis ---

Definition at line 6495 of file chan_sip.c.

References ast_log(), ast_strlen_zero(), ast_verbose(), get_header(), get_in_brackets(), sip_pvt::initreq, LOG_WARNING, sip_pvt::rdnis, and sip_debug_test_pvt().

Referenced by handle_request_invite().

06496 {
06497    char tmp[256], *c, *a;
06498    struct sip_request *req;
06499    
06500    req = oreq;
06501    if (!req)
06502       req = &p->initreq;
06503    ast_copy_string(tmp, get_header(req, "Diversion"), sizeof(tmp));
06504    if (ast_strlen_zero(tmp))
06505       return 0;
06506    c = get_in_brackets(tmp);
06507    if (strncmp(c, "sip:", 4)) {
06508       ast_log(LOG_WARNING, "Huh?  Not an RDNIS SIP header (%s)?\n", c);
06509       return -1;
06510    }
06511    c += 4;
06512    if ((a = strchr(c, '@')) || (a = strchr(c, ';'))) {
06513       *a = '\0';
06514    }
06515    if (sip_debug_test_pvt(p))
06516       ast_verbose("RDNIS is %s\n", c);
06517    ast_copy_string(p->rdnis, c, sizeof(p->rdnis));
06518 
06519    return 0;
06520 }

static 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 6653 of file chan_sip.c.

References ast_bridged_channel(), ast_canmatch_extension(), ast_exists_extension(), ast_log(), ast_parking_ext(), ast_strdupa, ast_strlen_zero(), ast_uri_decode(), ast_verbose(), sip_pvt::callid, sip_pvt::context, get_header(), get_in_brackets(), get_sip_pvt_byid_locked(), sip_pvt::initreq, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, ast_channel::name, sip_pvt::owner, pbx_builtin_setvar_helper(), pedanticsipchecking, sip_pvt::refer_call, sip_pvt::refer_contact, sip_pvt::refer_to, sip_pvt::referred_by, and sip_debug_test_pvt().

Referenced by handle_request_refer().

06654 {
06655 
06656    char *p_refer_to = NULL, *p_referred_by = NULL, *h_refer_to = NULL, *h_referred_by = NULL, *h_contact = NULL;
06657    char *replace_callid = "", *refer_to = NULL, *referred_by = NULL, *ptr = NULL;
06658    struct sip_request *req = NULL;
06659    struct sip_pvt *sip_pvt_ptr = NULL;
06660    struct ast_channel *chan = NULL, *peer = NULL;
06661 
06662    req = outgoing_req;
06663 
06664    if (!req) {
06665       req = &sip_pvt->initreq;
06666    }
06667    
06668    if (!( (p_refer_to = get_header(req, "Refer-To")) && (h_refer_to = ast_strdupa(p_refer_to)) )) {
06669       ast_log(LOG_WARNING, "No Refer-To Header That's illegal\n");
06670       return -1;
06671    }
06672 
06673    refer_to = get_in_brackets(h_refer_to);
06674 
06675    if (!( (p_referred_by = get_header(req, "Referred-By")) && (h_referred_by = ast_strdupa(p_referred_by)) )) {
06676       ast_log(LOG_WARNING, "No Referrred-By Header That's not illegal\n");
06677       return -1;
06678    } else {
06679       if (pedanticsipchecking) {
06680          ast_uri_decode(h_referred_by);
06681       }
06682       referred_by = get_in_brackets(h_referred_by);
06683    }
06684    h_contact = get_header(req, "Contact");
06685    
06686    if (strncmp(refer_to, "sip:", 4)) {
06687       ast_log(LOG_WARNING, "Refer-to: Huh?  Not a SIP header (%s)?\n", refer_to);
06688       return -1;
06689    }
06690 
06691    if (strncmp(referred_by, "sip:", 4)) {
06692       ast_log(LOG_WARNING, "Referred-by: Huh?  Not a SIP header (%s) Ignoring?\n", referred_by);
06693       referred_by = NULL;
06694    }
06695 
06696    if (refer_to)
06697       refer_to += 4;
06698 
06699    if (referred_by)
06700       referred_by += 4;
06701    
06702    if ((ptr = strchr(refer_to, '?'))) {
06703       /* Search for arguments */
06704       *ptr = '\0';
06705       ptr++;
06706       if (!strncasecmp(ptr, "REPLACES=", 9)) {
06707          char *p;
06708          replace_callid = ast_strdupa(ptr + 9);
06709          /* someday soon to support invite/replaces properly!
06710             replaces_header = ast_strdupa(replace_callid); 
06711             -anthm
06712          */
06713          ast_uri_decode(replace_callid);
06714          if ((ptr = strchr(replace_callid, '%'))) 
06715             *ptr = '\0';
06716          if ((ptr = strchr(replace_callid, ';'))) 
06717             *ptr = '\0';
06718          /* Skip leading whitespace XXX memmove behaviour with overlaps ? */
06719          p = ast_skip_blanks(replace_callid);
06720          if (p != replace_callid)
06721             memmove(replace_callid, p, strlen(p));
06722       }
06723    }
06724    
06725    if ((ptr = strchr(refer_to, '@')))  /* Skip domain (should be saved in SIPDOMAIN) */
06726       *ptr = '\0';
06727    if ((ptr = strchr(refer_to, ';'))) 
06728       *ptr = '\0';
06729    
06730    if (referred_by) {
06731       if ((ptr = strchr(referred_by, '@')))
06732          *ptr = '\0';
06733       if ((ptr = strchr(referred_by, ';'))) 
06734          *ptr = '\0';
06735    }
06736    
06737    if (sip_debug_test_pvt(sip_pvt)) {
06738       ast_verbose("Transfer to %s in %s\n", refer_to, sip_pvt->context);
06739       if (referred_by)
06740          ast_verbose("Transfer from %s in %s\n", referred_by, sip_pvt->context);
06741    }
06742    if (!ast_strlen_zero(replace_callid)) {   
06743       /* This is a supervised transfer */
06744       ast_log(LOG_DEBUG,"Assigning Replace-Call-ID Info %s to REPLACE_CALL_ID\n",replace_callid);
06745       
06746       ast_copy_string(sip_pvt->refer_to, "", sizeof(sip_pvt->refer_to));
06747       ast_copy_string(sip_pvt->referred_by, "", sizeof(sip_pvt->referred_by));
06748       ast_copy_string(sip_pvt->refer_contact, "", sizeof(sip_pvt->refer_contact));
06749       sip_pvt->refer_call = NULL;
06750       if ((sip_pvt_ptr = get_sip_pvt_byid_locked(replace_callid))) {
06751          sip_pvt->refer_call = sip_pvt_ptr;
06752          if (sip_pvt->refer_call == sip_pvt) {
06753             ast_log(LOG_NOTICE, "Supervised transfer attempted to transfer into same call id (%s == %s)!\n", replace_callid, sip_pvt->callid);
06754             sip_pvt->refer_call = NULL;
06755          } else
06756             return 0;
06757       } else {
06758          ast_log(LOG_NOTICE, "Supervised transfer requested, but unable to find callid '%s'.  Both legs must reside on Asterisk box to transfer at this time.\n", replace_callid);
06759          /* XXX The refer_to could contain a call on an entirely different machine, requiring an 
06760               INVITE with a replaces header -anthm XXX */
06761          /* The only way to find out is to use the dialplan - oej */
06762       }
06763    } else if (ast_exists_extension(NULL, sip_pvt->context, refer_to, 1, NULL) || !strcmp(refer_to, ast_parking_ext())) {
06764       /* This is an unsupervised transfer (blind transfer) */
06765       
06766       ast_log(LOG_DEBUG,"Unsupervised transfer to (Refer-To): %s\n", refer_to);
06767       if (referred_by)
06768          ast_log(LOG_DEBUG,"Transferred by  (Referred-by: ) %s \n", referred_by);
06769       ast_log(LOG_DEBUG,"Transfer Contact Info %s (REFER_CONTACT)\n", h_contact);
06770       ast_copy_string(sip_pvt->refer_to, refer_to, sizeof(sip_pvt->refer_to));
06771       if (referred_by)
06772          ast_copy_string(sip_pvt->referred_by, referred_by, sizeof(sip_pvt->referred_by));
06773       if (h_contact) {
06774          ast_copy_string(sip_pvt->refer_contact, h_contact, sizeof(sip_pvt->refer_contact));
06775       }
06776       sip_pvt->refer_call = NULL;
06777       if ((chan = sip_pvt->owner) && (peer = ast_bridged_channel(sip_pvt->owner))) {
06778          pbx_builtin_setvar_helper(chan, "BLINDTRANSFER", peer->name);
06779          pbx_builtin_setvar_helper(peer, "BLINDTRANSFER", chan->name);
06780       }
06781       return 0;
06782    } else if (ast_canmatch_extension(NULL, sip_pvt->context, refer_to, 1, NULL)) {
06783       return 1;
06784    }
06785 
06786    return -1;
06787 }

static 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 6925 of file chan_sip.c.

References AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED.

Referenced by check_user_full().

06926 {
06927    char *start;
06928    char *end;
06929 
06930    start = strchr(input,':');
06931    if (!start) {
06932       output[0] = '\0';
06933       return 0;
06934    }
06935    start++;
06936 
06937    /* we found "number" */
06938    ast_copy_string(output,start,maxlen);
06939    output[maxlen-1] = '\0';
06940 
06941    end = strchr(output,'@');
06942    if (end)
06943       *end = '\0';
06944    else
06945       output[0] = '\0';
06946    if (strstr(input,"privacy=full") || strstr(input,"privacy=uri"))
06947       return AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED;
06948 
06949    return 0;
06950 }

static 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 2861 of file chan_sip.c.

References get_sdp_by_line(), sip_request::line, and sip_request::lines.

02862 {
02863    int x;
02864    int len = strlen(name);
02865    char *r;
02866 
02867    for (x=0; x<req->lines; x++) {
02868       r = get_sdp_by_line(req->line[x], name, len);
02869       if (r[0] != '\0')
02870          return r;
02871    }
02872    return "";
02873 }

static 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 2851 of file chan_sip.c.

02852 {
02853    if (strncasecmp(line, name, nameLen) == 0 && line[nameLen] == '=') {
02854       return ast_skip_blanks(line + nameLen + 1);
02855    }
02856    return "";
02857 }

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

Definition at line 2881 of file chan_sip.c.

References get_sdp_by_line(), and sip_request::line.

02883 {
02884    int len = strlen(name);
02885    char *r;
02886 
02887    while (*iterator < req->lines) {
02888       r = get_sdp_by_line(req->line[(*iterator)++], name, len);
02889       if (r[0] != '\0')
02890          return r;
02891    }
02892    return "";
02893 }

static 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 6624 of file chan_sip.c.

References ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), sip_pvt::callid, iflist, ast_channel::lock, sip_pvt::lock, sip_pvt::next, and sip_pvt::owner.

Referenced by get_refer_info().

06625 {
06626    struct sip_pvt *sip_pvt_ptr = NULL;
06627    
06628    /* Search interfaces and find the match */
06629    ast_mutex_lock(&iflock);
06630    sip_pvt_ptr = iflist;
06631    while(sip_pvt_ptr) {
06632       if (!strcmp(sip_pvt_ptr->callid, callid)) {
06633          /* Go ahead and lock it (and its owner) before returning */
06634          ast_mutex_lock(&sip_pvt_ptr->lock);
06635          if (sip_pvt_ptr->owner) {
06636             while(ast_mutex_trylock(&sip_pvt_ptr->owner->lock)) {
06637                ast_mutex_unlock(&sip_pvt_ptr->lock);
06638                usleep(1);
06639                ast_mutex_lock(&sip_pvt_ptr->lock);
06640                if (!sip_pvt_ptr->owner)
06641                   break;
06642             }
06643          }
06644          break;
06645       }
06646       sip_pvt_ptr = sip_pvt_ptr->next;
06647    }
06648    ast_mutex_unlock(&iflock);
06649    return sip_pvt_ptr;
06650 }

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

gettag: Get tag from packet

Definition at line 10208 of file chan_sip.c.

References get_header(), and strcasestr().

Referenced by find_call(), handle_request(), and handle_response().

10209 {
10210 
10211    char *thetag, *sep;
10212    
10213 
10214    if (!tagbuf)
10215       return NULL;
10216    tagbuf[0] = '\0';    /* reset the buffer */
10217    thetag = get_header(req, header);
10218    thetag = strcasestr(thetag, ";tag=");
10219    if (thetag) {
10220       thetag += 5;
10221       ast_copy_string(tagbuf, thetag, tagbufsize);
10222       sep = strchr(tagbuf, ';');
10223       if (sep)
10224          *sep = '\0';
10225    }
10226    return thetag;
10227 }

static 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 11623 of file chan_sip.c.

References ast_clear_flag, ast_false(), ast_log(), ast_set2_flag, ast_set_flag, ast_true(), ast_channel::flags, global_allowguest, ast_variable::lineno, LOG_WARNING, ast_variable::name, ast_channel::next, SIP_CAN_REINVITE, SIP_DTMF, SIP_DTMF_AUTO, SIP_DTMF_INBAND, SIP_DTMF_INFO, SIP_DTMF_RFC2833, SIP_INSECURE_INVITE, SIP_INSECURE_PORT, SIP_NAT, SIP_NAT_ALWAYS, SIP_NAT_NEVER, SIP_NAT_RFC3581, SIP_NAT_ROUTE, SIP_OSPAUTH, SIP_OSPAUTH_EXCLUSIVE, SIP_OSPAUTH_GATEWAY, SIP_OSPAUTH_PROXY, SIP_PROG_INBAND, SIP_PROG_INBAND_NO, SIP_PROG_INBAND_YES, SIP_PROMISCREDIR, SIP_REINVITE, SIP_REINVITE_UPDATE, SIP_SENDRPID, SIP_TRUSTRPID, SIP_USECLIENTCODE, strsep(), and ast_variable::value.

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

11624 {
11625    int res = 0;
11626 
11627    if (!strcasecmp(v->name, "trustrpid")) {
11628       ast_set_flag(mask, SIP_TRUSTRPID);
11629       ast_set2_flag(flags, ast_true(v->value), SIP_TRUSTRPID);
11630       res = 1;
11631    } else if (!strcasecmp(v->name, "sendrpid")) {
11632       ast_set_flag(mask, SIP_SENDRPID);
11633       ast_set2_flag(flags, ast_true(v->value), SIP_SENDRPID);
11634       res = 1;
11635    } else if (!strcasecmp(v->name, "useclientcode")) {
11636       ast_set_flag(mask, SIP_USECLIENTCODE);
11637       ast_set2_flag(flags, ast_true(v->value), SIP_USECLIENTCODE);
11638       res = 1;
11639    } else if (!strcasecmp(v->name, "dtmfmode")) {
11640       ast_set_flag(mask, SIP_DTMF);
11641       ast_clear_flag(flags, SIP_DTMF);
11642       if (!strcasecmp(v->value, "inband"))
11643          ast_set_flag(flags, SIP_DTMF_INBAND);
11644       else if (!strcasecmp(v->value, "rfc2833"))
11645          ast_set_flag(flags, SIP_DTMF_RFC2833);
11646       else if (!strcasecmp(v->value, "info"))
11647          ast_set_flag(flags, SIP_DTMF_INFO);
11648       else if (!strcasecmp(v->value, "auto"))
11649          ast_set_flag(flags, SIP_DTMF_AUTO);
11650       else {
11651          ast_log(LOG_WARNING, "Unknown dtmf mode '%s' on line %d, using rfc2833\n", v->value, v->lineno);
11652          ast_set_flag(flags, SIP_DTMF_RFC2833);
11653       }
11654    } else if (!strcasecmp(v->name, "nat")) {
11655       ast_set_flag(mask, SIP_NAT);
11656       ast_clear_flag(flags, SIP_NAT);
11657       if (!strcasecmp(v->value, "never"))
11658          ast_set_flag(flags, SIP_NAT_NEVER);
11659       else if (!strcasecmp(v->value, "route"))
11660          ast_set_flag(flags, SIP_NAT_ROUTE);
11661       else if (ast_true(v->value))
11662          ast_set_flag(flags, SIP_NAT_ALWAYS);
11663       else
11664          ast_set_flag(flags, SIP_NAT_RFC3581);
11665    } else if (!strcasecmp(v->name, "canreinvite")) {
11666       ast_set_flag(mask, SIP_REINVITE);
11667       ast_clear_flag(flags, SIP_REINVITE);
11668       if (!strcasecmp(v->value, "update"))
11669          ast_set_flag(flags, SIP_REINVITE_UPDATE | SIP_CAN_REINVITE);
11670       else
11671          ast_set2_flag(flags, ast_true(v->value), SIP_CAN_REINVITE);
11672    } else if (!strcasecmp(v->name, "insecure")) {
11673       ast_set_flag(mask, SIP_INSECURE_PORT | SIP_INSECURE_INVITE);
11674       ast_clear_flag(flags, SIP_INSECURE_PORT | SIP_INSECURE_INVITE);
11675       if (!strcasecmp(v->value, "very"))
11676          ast_set_flag(flags, SIP_INSECURE_PORT | SIP_INSECURE_INVITE);
11677       else if (ast_true(v->value))
11678          ast_set_flag(flags, SIP_INSECURE_PORT);
11679       else if (!ast_false(v->value)) {
11680          char buf[64];
11681          char *word, *next;
11682 
11683          ast_copy_string(buf, v->value, sizeof(buf));
11684          next = buf;
11685          while ((word = strsep(&next, ","))) {
11686             if (!strcasecmp(word, "port"))
11687                ast_set_flag(flags, SIP_INSECURE_PORT);
11688             else if (!strcasecmp(word, "invite"))
11689                ast_set_flag(flags, SIP_INSECURE_INVITE);
11690             else
11691                ast_log(LOG_WARNING, "Unknown insecure mode '%s' on line %d\n", v->value, v->lineno);
11692          }
11693       }
11694    } else if (!strcasecmp(v->name, "progressinband")) {
11695       ast_set_flag(mask, SIP_PROG_INBAND);
11696       ast_clear_flag(flags, SIP_PROG_INBAND);
11697       if (ast_true(v->value))
11698          ast_set_flag(flags, SIP_PROG_INBAND_YES);
11699       else if (strcasecmp(v->value, "never"))
11700          ast_set_flag(flags, SIP_PROG_INBAND_NO);
11701    } else if (!strcasecmp(v->name, "allowguest")) {
11702 #ifdef OSP_SUPPORT
11703       if (!strcasecmp(v->value, "osp"))
11704          global_allowguest = 2;
11705       else 
11706 #endif
11707          if (ast_true(v->value)) 
11708             global_allowguest = 1;
11709          else
11710             global_allowguest = 0;
11711 #ifdef OSP_SUPPORT
11712    } else if (!strcasecmp(v->name, "ospauth")) {
11713       ast_set_flag(mask, SIP_OSPAUTH);
11714       ast_clear_flag(flags, SIP_OSPAUTH);
11715       if (!strcasecmp(v->value, "proxy"))
11716          ast_set_flag(flags, SIP_OSPAUTH_PROXY);
11717       else if (!strcasecmp(v->value, "gateway"))
11718          ast_set_flag(flags, SIP_OSPAUTH_GATEWAY);
11719       else if(!strcasecmp (v->value, "exclusive"))
11720          ast_set_flag(flags, SIP_OSPAUTH_EXCLUSIVE);
11721 #endif
11722    } else if (!strcasecmp(v->name, "promiscredir")) {
11723       ast_set_flag(mask, SIP_PROMISCREDIR);
11724       ast_set2_flag(flags, ast_true(v->value), SIP_PROMISCREDIR);
11725       res = 1;
11726    }
11727 
11728    return res;
11729 }

static 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 10897 of file chan_sip.c.

References __sip_ack(), ast_inet_ntoa(), ast_log(), ast_set_flag, ast_strlen_zero(), ast_test_flag, ast_verbose(), check_pendings(), debug, error(), extract_uri(), FLAG_RESPONSE, get_header(), gettag(), handle_request_bye(), handle_request_cancel(), handle_request_info(), handle_request_invite(), handle_request_message(), handle_request_options(), handle_request_refer(), handle_request_register(), handle_request_subscribe(), handle_response(), sip_request::header, sip_request::headers, sip_pvt::icseq, sip_pvt::initreq, sip_pvt::lastinvite, sip_pvt::lastmsg, sip_request::len, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, LOG_WARNING, sip_pvt::method, sip_request::method, sip_pvt::ocseq, option_debug, pedanticsipchecking, sip_pvt::pendinginvite, process_sdp(), sip_pvt::randdata, sip_request::rlPart1, sip_request::rlPart2, sip_pvt::sa, SIP_ACK, SIP_ALREADYGONE, SIP_BYE, SIP_CANCEL, sip_debug_test_pvt(), SIP_INFO, SIP_INVITE, SIP_MESSAGE, sip_methods, SIP_NEEDDESTROY, SIP_NOTIFY, SIP_OPTIONS, SIP_PKT_WITH_TOTAG, SIP_REFER, SIP_REGISTER, SIP_RESPONSE, SIP_SUBSCRIBE, sip_pvt::theirtag, transmit_response(), transmit_response_reliable(), transmit_response_with_allow(), and sip_pvt::useragent.

10898 {
10899    /* Called with p->lock held, as well as p->owner->lock if appropriate, keeping things
10900       relatively static */
10901    struct sip_request resp;
10902    char *cmd;
10903    char *cseq;
10904    char *useragent;
10905    int seqno;
10906    int len;
10907    int ignore=0;
10908    int respid;
10909    int res = 0;
10910    char iabuf[INET_ADDRSTRLEN];
10911    int debug = sip_debug_test_pvt(p);
10912    char *e;
10913    int error = 0;
10914 
10915    /* Clear out potential response */
10916    memset(&resp, 0, sizeof(resp));
10917 
10918    /* Get Method and Cseq */
10919    cseq = get_header(req, "Cseq");
10920    cmd = req->header[0];
10921 
10922    /* Must have Cseq */
10923    if (ast_strlen_zero(cmd) || ast_strlen_zero(cseq)) {
10924       ast_log(LOG_ERROR, "Missing Cseq. Dropping this SIP message, it's incomplete.\n");
10925       error = 1;
10926    }
10927    if (!error && sscanf(cseq, "%d%n", &seqno, &len) != 1) {
10928       ast_log(LOG_ERROR, "No seqno in '%s'. Dropping incomplete message.\n", cmd);
10929       error = 1;
10930    }
10931    if (error) {
10932       if (!p->initreq.header) /* New call */
10933          ast_set_flag(p, SIP_NEEDDESTROY);   /* Make sure we destroy this dialog */
10934       return -1;
10935    }
10936    /* Get the command XXX */
10937 
10938    cmd = req->rlPart1;
10939    e = req->rlPart2;
10940 
10941    /* Save useragent of the client */
10942    useragent = get_header(req, "User-Agent");
10943    if (!ast_strlen_zero(useragent))
10944       ast_copy_string(p->useragent, useragent, sizeof(p->useragent));
10945 
10946    /* Find out SIP method for incoming request */
10947    if (req->method == SIP_RESPONSE) {  /* Response to our request */
10948       /* Response to our request -- Do some sanity checks */   
10949       if (!p->initreq.headers) {
10950          ast_log(LOG_DEBUG, "That's odd...  Got a response on a call we dont know about. Cseq %d Cmd %s\n", seqno, cmd);
10951          ast_set_flag(p, SIP_NEEDDESTROY);   
10952          return 0;
10953       } else if (p->ocseq && (p->ocseq < seqno)) {
10954          ast_log(LOG_DEBUG, "Ignoring out of order response %d (expecting %d)\n", seqno, p->ocseq);
10955          return -1;
10956       } else if (p->ocseq && (p->ocseq != seqno)) {
10957          /* ignore means "don't do anything with it" but still have to 
10958             respond appropriately  */
10959          ignore=1;
10960       }
10961    
10962       e = ast_skip_blanks(e);
10963       if (sscanf(e, "%d %n", &respid, &len) != 1) {
10964          ast_log(LOG_WARNING, "Invalid response: '%s'\n", e);
10965       } else {
10966          /* More SIP ridiculousness, we have to ignore bogus contacts in 100 etc responses */
10967          if ((respid == 200) || ((respid >= 300) && (respid <= 399)))
10968             extract_uri(p, req);
10969          handle_response(p, respid, e + len, req, ignore, seqno);
10970       }
10971       return 0;
10972    }
10973 
10974    /* New SIP request coming in 
10975       (could be new request in existing SIP dialog as well...) 
10976     */         
10977    
10978    p->method = req->method;   /* Find out which SIP method they are using */
10979    if (option_debug > 2)
10980       ast_log(LOG_DEBUG, "**** Received %s (%d) - Command in SIP %s\n", sip_methods[p->method].text, sip_methods[p->method].id, cmd); 
10981 
10982    if (p->icseq && (p->icseq > seqno)) {
10983       if (option_debug)
10984          ast_log(LOG_DEBUG, "Ignoring too old SIP packet packet %d (expecting >= %d)\n", seqno, p->icseq);
10985       if (req->method != SIP_ACK)
10986          transmit_response(p, "503 Server error", req);  /* We must respond according to RFC 3261 sec 12.2 */
10987       return -1;
10988    } else if (p->icseq && (p->icseq == seqno) && req->method != SIP_ACK &&(p->method != SIP_CANCEL|| ast_test_flag(p, SIP_ALREADYGONE))) {
10989       /* ignore means "don't do anything with it" but still have to 
10990          respond appropriately.  We do this if we receive a repeat of
10991          the last sequence number  */
10992       ignore=2;
10993       if (option_debug > 2)
10994          ast_log(LOG_DEBUG, "Ignoring SIP message because of retransmit (%s Seqno %d, ours %d)\n", sip_methods[p->method].text, p->icseq, seqno);
10995    }
10996       
10997    if (seqno >= p->icseq)
10998       /* Next should follow monotonically (but not necessarily 
10999          incrementally -- thanks again to the genius authors of SIP --
11000          increasing */
11001       p->icseq = seqno;
11002 
11003    /* Find their tag if we haven't got it */
11004    if (ast_strlen_zero(p->theirtag)) {
11005       gettag(req, "From", p->theirtag, sizeof(p->theirtag));
11006    }
11007    snprintf(p->lastmsg, sizeof(p->lastmsg), "Rx: %s", cmd);
11008 
11009    if (pedanticsipchecking) {
11010       /* If this is a request packet without a from tag, it's not
11011          correct according to RFC 3261  */
11012       /* Check if this a new request in a new dialog with a totag already attached to it,
11013          RFC 3261 - section 12.2 - and we don't want to mess with recovery  */
11014       if (!p->initreq.headers && ast_test_flag(req, SIP_PKT_WITH_TOTAG)) {
11015          /* If this is a first request and it got a to-tag, it is not for us */
11016          if (!ignore && req->method == SIP_INVITE) {
11017             transmit_response_reliable(p, "481 Call/Transaction Does Not Exist", req, 1);
11018             /* Will cease to exist after ACK */
11019          } else {
11020             transmit_response(p, "481 Call/Transaction Does Not Exist", req);
11021             ast_set_flag(p, SIP_NEEDDESTROY);
11022          }
11023          return res;
11024       }
11025    }
11026 
11027    /* Handle various incoming SIP methods in requests */
11028    switch (p->method) {
11029    case SIP_OPTIONS:
11030       res = handle_request_options(p, req, debug);
11031       break;
11032    case SIP_INVITE:
11033       res = handle_request_invite(p, req, debug, ignore, seqno, sin, recount, e);
11034       break;
11035    case SIP_REFER:
11036       res = handle_request_refer(p, req, debug, ignore, seqno, nounlock);
11037       break;
11038    case SIP_CANCEL:
11039       res = handle_request_cancel(p, req, debug, ignore);
11040       break;
11041    case SIP_BYE:
11042       res = handle_request_bye(p, req, debug, ignore);
11043       break;
11044    case SIP_MESSAGE:
11045       res = handle_request_message(p, req, debug, ignore);
11046       break;
11047    case SIP_SUBSCRIBE:
11048       res = handle_request_subscribe(p, req, debug, ignore, sin, seqno, e);
11049       break;
11050    case SIP_REGISTER:
11051       res = handle_request_register(p, req, debug, ignore, sin, e);
11052       break;
11053    case SIP_INFO:
11054       if (!ignore) {
11055          if (debug)
11056             ast_verbose("Receiving INFO!\n");
11057          handle_request_info(p, req);
11058       } else { /* if ignoring, transmit response */
11059          transmit_response(p, "200 OK", req);
11060       }
11061       break;
11062    case SIP_NOTIFY:
11063       /* XXX we get NOTIFY's from some servers. WHY?? Maybe we should
11064          look into this someday XXX */
11065       transmit_response(p, "200 OK", req);
11066       if (!p->lastinvite) 
11067          ast_set_flag(p, SIP_NEEDDESTROY);   
11068       break;
11069    case SIP_ACK:
11070       /* Make sure we don't ignore this */
11071       if (seqno == p->pendinginvite) {
11072          p->pendinginvite = 0;
11073          __sip_ack(p, seqno, FLAG_RESPONSE, 0);
11074          if (!ast_strlen_zero(get_header(req, "Content-Type"))) {
11075             if (process_sdp(p, req))
11076                return -1;
11077          } 
11078          check_pendings(p);
11079       }
11080       if (!p->lastinvite && ast_strlen_zero(p->randdata))
11081          ast_set_flag(p, SIP_NEEDDESTROY);   
11082       break;
11083    default:
11084       transmit_response_with_allow(p, "501 Method Not Implemented", req, 0);
11085       ast_log(LOG_NOTICE, "Unknown SIP command '%s' from '%s'\n", 
11086          cmd, ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr));
11087       /* If this is some new method, and we don't have a call, destroy it now */
11088       if (!p->initreq.headers)
11089          ast_set_flag(p, SIP_NEEDDESTROY);   
11090       break;
11091    }
11092    return res;
11093 }

static 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 10609 of file chan_sip.c.

References ast_async_goto(), ast_bridged_channel(), ast_inet_ntoa(), ast_log(), ast_moh_stop(), ast_queue_hangup(), ast_rtp_stop(), ast_set_flag, ast_strlen_zero(), ast_test_flag, check_via(), copy_request(), default_context, get_also_info(), get_header(), sip_pvt::initreq, LOG_NOTICE, LOG_WARNING, sip_pvt::pendinginvite, SIP_ALREADYGONE, SIP_NEEDDESTROY, SIP_OUTGOING, transmit_response(), and transmit_response_reliable().

Referenced by handle_request().

10610 {
10611    struct ast_channel *c=NULL;
10612    int res;
10613    struct ast_channel *bridged_to;
10614    char iabuf[INET_ADDRSTRLEN];
10615    
10616    if (p->pendinginvite && !ast_test_flag(p, SIP_OUTGOING) && !ignore)
10617       transmit_response_reliable(p, "487 Request Terminated", &p->initreq, 1);
10618 
10619    copy_request(&p->initreq, req);
10620    check_via(p, req);
10621    ast_set_flag(p, SIP_ALREADYGONE);   
10622    if (p->rtp) {
10623       /* Immediately stop RTP */
10624       ast_rtp_stop(p->rtp);
10625    }
10626    if (p->vrtp) {
10627       /* Immediately stop VRTP */
10628       ast_rtp_stop(p->vrtp);
10629    }
10630    if (!ast_strlen_zero(get_header(req, "Also"))) {
10631       ast_log(LOG_NOTICE, "Client '%s' using deprecated BYE/Also transfer method.  Ask vendor to support REFER instead\n",
10632          ast_inet_ntoa(iabuf, sizeof(iabuf), p->recv.sin_addr));
10633       if (ast_strlen_zero(p->context))
10634          strcpy(p->context, default_context);
10635       res = get_also_info(p, req);
10636       if (!res) {
10637          c = p->owner;
10638          if (c) {
10639             bridged_to = ast_bridged_channel(c);
10640             if (bridged_to) {
10641                /* Don't actually hangup here... */
10642                ast_moh_stop(bridged_to);
10643                ast_async_goto(bridged_to, p->context, p->refer_to,1);
10644             } else
10645                ast_queue_hangup(p->owner);
10646          }
10647       } else {
10648          ast_log(LOG_WARNING, "Invalid transfer information from '%s'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), p->recv.sin_addr));
10649          if (p->owner)
10650             ast_queue_hangup(p->owner);
10651       }
10652    } else if (p->owner)
10653       ast_queue_hangup(p->owner);
10654    else
10655       ast_set_flag(p, SIP_NEEDDESTROY);   
10656    transmit_response(p, "200 OK", req);
10657 
10658    return 1;
10659 }

static 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 10580 of file chan_sip.c.

References ast_queue_hangup(), ast_rtp_stop(), ast_set_flag, check_via(), sip_pvt::initreq, sip_request::len, sip_pvt::owner, sip_pvt::rtp, SIP_ALREADYGONE, SIP_NEEDDESTROY, transmit_response(), transmit_response_reliable(), and sip_pvt::vrtp.

Referenced by handle_request().

10581 {
10582       
10583    check_via(p, req);
10584    ast_set_flag(p, SIP_ALREADYGONE);   
10585    if (p->rtp) {
10586       /* Immediately stop RTP */
10587       ast_rtp_stop(p->rtp);
10588    }
10589    if (p->vrtp) {
10590       /* Immediately stop VRTP */
10591       ast_rtp_stop(p->vrtp);
10592    }
10593    if (p->owner)
10594       ast_queue_hangup(p->owner);
10595    else
10596       ast_set_flag(p, SIP_NEEDDESTROY);   
10597    if (p->initreq.len > 0) {
10598       if (!ignore)
10599          transmit_response_reliable(p, "487 Request Terminated", &p->initreq, 1);
10600       transmit_response(p, "200 OK", req);
10601       return 1;
10602    } else {
10603       transmit_response(p, "481 Call Leg Does Not Exist", req);
10604       return 0;
10605    }
10606 }

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

handle_request_info: Receive SIP INFO Message ---

Definition at line 8605 of file chan_sip.c.

References ast_bridged_channel(), ast_cdr_setuserfield(), AST_CONTROL_FLASH, AST_CONTROL_VIDUPDATE, AST_FRAME_CONTROL, AST_FRAME_DTMF, ast_log(), ast_queue_control(), ast_queue_frame(), ast_set_flag, ast_strlen_zero(), ast_test_flag, ast_verbose(), sip_pvt::callid, ast_channel::cdr, sip_history::event, get_header(), get_sdp(), LOG_WARNING, sip_pvt::owner, SIP_NEEDDESTROY, SIP_USECLIENTCODE, sipdebug, ast_frame::subclass, and transmit_response().

Referenced by handle_request().

08606 {
08607    char buf[1024];
08608    unsigned int event;
08609    char *c;
08610    
08611    /* Need to check the media/type */
08612    if (!strcasecmp(get_header(req, "Content-Type"), "application/dtmf-relay") ||
08613        !strcasecmp(get_header(req, "Content-Type"), "application/vnd.nortelnetworks.digits")) {
08614 
08615       /* Try getting the "signal=" part */
08616       if (ast_strlen_zero(c = get_sdp(req, "Signal")) && ast_strlen_zero(c = get_sdp(req, "d"))) {
08617          ast_log(LOG_WARNING, "Unable to retrieve DTMF signal from INFO message from %s\n", p->callid);
08618          transmit_response(p, "200 OK", req); /* Should return error */
08619          return;
08620       } else {
08621          ast_copy_string(buf, c, sizeof(buf));
08622       }
08623    
08624       if (!p->owner) {  /* not a PBX call */
08625          transmit_response(p, "481 Call leg/transaction does not exist", req);
08626          ast_set_flag(p, SIP_NEEDDESTROY);
08627          return;
08628       }
08629 
08630       if (ast_strlen_zero(buf)) {
08631          transmit_response(p, "200 OK", req);
08632          return;
08633       }
08634 
08635       if (buf[0] == '*')
08636          event = 10;
08637       else if (buf[0] == '#')
08638          event = 11;
08639       else if ((buf[0] >= 'A') && (buf[0] <= 'D'))
08640          event = 12 + buf[0] - 'A';
08641       else
08642          event = atoi(buf);
08643       if (event == 16) {
08644          /* send a FLASH event */
08645          struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_FLASH, };
08646          ast_queue_frame(p->owner, &f);
08647          if (sipdebug)
08648             ast_verbose("* DTMF-relay event received: FLASH\n");
08649       } else {
08650          /* send a DTMF event */
08651          struct ast_frame f = { AST_FRAME_DTMF, };
08652          if (event < 10) {
08653             f.subclass = '0' + event;
08654          } else if (event < 11) {
08655             f.subclass = '*';
08656          } else if (event < 12) {
08657             f.subclass = '#';
08658          } else if (event < 16) {
08659             f.subclass = 'A' + (event - 12);
08660          }
08661          ast_queue_frame(p->owner, &f);
08662          if (sipdebug)
08663             ast_verbose("* DTMF-relay event received: %c\n", f.subclass);
08664       }
08665       transmit_response(p, "200 OK", req);
08666       return;
08667    } else if (!strcasecmp(get_header(req, "Content-Type"), "application/media_control+xml")) {
08668       /* Eh, we'll just assume it's a fast picture update for now */
08669       if (p->owner)
08670          ast_queue_control(p->owner, AST_CONTROL_VIDUPDATE);
08671       transmit_response(p, "200 OK", req);
08672       return;
08673    } else if ((c = get_header(req, "X-ClientCode"))) {
08674       /* Client code (from SNOM phone) */
08675       if (ast_test_flag(p, SIP_USECLIENTCODE)) {
08676          if (p->owner && p->owner->cdr)
08677             ast_cdr_setuserfield(p->owner, c);
08678          if (p->owner && ast_bridged_channel(p->owner) && ast_bridged_channel(p->owner)->cdr)
08679             ast_cdr_setuserfield(ast_bridged_channel(p->owner), c);
08680          transmit_response(p, "200 OK", req);
08681       } else {
08682          transmit_response(p, "403 Unauthorized", req);
08683       }
08684       return;
08685    }
08686    /* Other type of INFO message, not really understood by Asterisk */
08687    /* if (get_msg_text(buf, sizeof(buf), req)) { */
08688 
08689    ast_log(LOG_WARNING, "Unable to parse INFO message from %s. Content %s\n", p->callid, buf);
08690    transmit_response(p, "415 Unsupported media type", req);
08691    return;
08692 }

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

handle_request_invite: Handle incoming INVITE request

Definition at line 10254 of file chan_sip.c.

References ast_channel::_state, ast_channel_setwhentohangup(), ast_clear_flag, AST_FRAME_NULL, ast_hangup(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_PBX_CALL_LIMIT, AST_PBX_FAILED, ast_pbx_start(), AST_PBX_SUCCESS, ast_pickup_call(), ast_pickup_ext(), ast_queue_frame(), ast_set_flag, ast_setstate(), AST_STATE_DOWN, AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, ast_strlen_zero(), ast_test_flag, ast_verbose(), build_contact(), build_route(), sip_pvt::callid, sip_pvt::capability, check_user(), check_via(), sip_pvt::context, copy_request(), DEC_CALL_LIMIT, default_context, sip_pvt::exten, extract_uri(), get_destination(), get_header(), get_rdnis(), INC_CALL_LIMIT, sip_pvt::initreq, sip_pvt::jointcapability, sip_pvt::lastinvite, sip_pvt::lock, ast_channel::lock, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, make_our_tag(), option_debug, sip_pvt::owner, parse_sip_options(), sip_pvt::pendinginvite, process_sdp(), SIP_ALREADYGONE, sip_cancel_destroy(), SIP_INVITE, SIP_NEEDDESTROY, sip_new(), SIP_OUTGOING, sipdebug, sip_pvt::sipoptions, sip_pvt::tag, transmit_response(), transmit_response_reliable(), transmit_response_with_sdp(), transmit_response_with_unsupported(), update_call_counter(), and sip_pvt::username.

Referenced by handle_request().

10255 {
10256    int res = 1;
10257    struct ast_channel *c=NULL;
10258    int gotdest;
10259    struct ast_frame af = { AST_FRAME_NULL, };
10260    char *supported;
10261    char *required;
10262    unsigned int required_profile = 0;
10263 
10264    /* Find out what they support */
10265    if (!p->sipoptions) {
10266       supported = get_header(req, "Supported");
10267       if (supported)
10268          parse_sip_options(p, supported);
10269    }
10270    required = get_header(req, "Required");
10271    if (!ast_strlen_zero(required)) {
10272       required_profile = parse_sip_options(NULL, required);
10273       if (required_profile) {    /* They require something */
10274          /* At this point we support no extensions, so fail */
10275          transmit_response_with_unsupported(p, "420 Bad extension", req, required);
10276          if (!p->lastinvite)
10277             ast_set_flag(p, SIP_NEEDDESTROY);   
10278          return -1;
10279          
10280       }
10281    }
10282 
10283    /* Check if this is a loop */
10284    /* This happens since we do not properly support SIP domain
10285       handling yet... -oej */
10286    if (ast_test_flag(p, SIP_OUTGOING) && p->owner && (p->owner->_state != AST_STATE_UP)) {
10287       /* This is a call to ourself.  Send ourselves an error code and stop
10288          processing immediately, as SIP really has no good mechanism for
10289          being able to call yourself */
10290       transmit_response(p, "482 Loop Detected", req);
10291       /* We do NOT destroy p here, so that our response will be accepted */
10292       return 0;
10293    }
10294    if (!ignore) {
10295       /* Use this as the basis */
10296       if (debug)
10297          ast_verbose("Using INVITE request as basis request - %s\n", p->callid);
10298       sip_cancel_destroy(p);
10299       /* This call is no longer outgoing if it ever was */
10300       ast_clear_flag(p, SIP_OUTGOING);
10301       /* This also counts as a pending invite */
10302       p->pendinginvite = seqno;
10303       copy_request(&p->initreq, req);
10304       check_via(p, req);
10305       if (p->owner) {
10306          /* Handle SDP here if we already have an owner */
10307          if (!strcasecmp(get_header(req, "Content-Type"), "application/sdp")) {
10308             if (process_sdp(p, req)) {
10309                transmit_response(p, "488 Not acceptable here", req);
10310                if (!p->lastinvite)
10311                   ast_set_flag(p, SIP_NEEDDESTROY);   
10312                return -1;
10313             }
10314          } else {
10315             p->jointcapability = p->capability;
10316             ast_log(LOG_DEBUG, "Hm....  No sdp for the moment\n");
10317          }
10318       }
10319    } else if (debug)
10320       ast_verbose("Ignoring this INVITE request\n");
10321    if (!p->lastinvite && !ignore && !p->owner) {
10322       /* Handle authentication if this is our first invite */
10323       res = check_user(p, req, SIP_INVITE, e, 1, sin, ignore);
10324       if (res) {
10325          if (res < 0) {
10326             ast_log(LOG_NOTICE, "Failed to authenticate user %s\n", get_header(req, "From"));
10327             if (ignore)
10328                transmit_response(p, "403 Forbidden", req);
10329             else
10330                transmit_response_reliable(p, "403 Forbidden", req, 1);
10331             ast_set_flag(p, SIP_NEEDDESTROY);   
10332             p->theirtag[0] = '\0'; /* Forget their to-tag, we'll get a new one */
10333          }
10334          return 0;
10335       }
10336       /* Process the SDP portion */
10337       if (!ast_strlen_zero(get_header(req, "Content-Type"))) {
10338          if (process_sdp(p, req)) {
10339             transmit_response(p, "488 Not acceptable here", req);
10340             ast_set_flag(p, SIP_NEEDDESTROY);   
10341             return -1;
10342          }
10343       } else {
10344          p->jointcapability = p->capability;
10345          ast_log(LOG_DEBUG, "Hm....  No sdp for the moment\n");
10346       }
10347       /* Queue NULL frame to prod ast_rtp_bridge if appropriate */
10348       if (p->owner)
10349          ast_queue_frame(p->owner, &af);
10350       /* Initialize the context if it hasn't been already */
10351       if (ast_strlen_zero(p->context))
10352          strcpy(p->context, default_context);
10353       /* Check number of concurrent calls -vs- incoming limit HERE */
10354       ast_log(LOG_DEBUG, "Checking SIP call limits for device %s\n", p->username);
10355       res = update_call_counter(p, INC_CALL_LIMIT);
10356       if (res) {
10357          if (res < 0) {
10358             ast_log(LOG_NOTICE, "Failed to place call for user %s, too many calls\n", p->username);
10359             if (ignore)
10360                transmit_response(p, "480 Temporarily Unavailable (Call limit)", req);
10361             else
10362                transmit_response_reliable(p, "480 Temporarily Unavailable (Call limit) ", req, 1);
10363             ast_set_flag(p, SIP_NEEDDESTROY);   
10364          }
10365          return 0;
10366       }
10367       /* Get destination right away */
10368       gotdest = get_destination(p, NULL);
10369 
10370       get_rdnis(p, NULL);
10371       extract_uri(p, req);
10372       build_contact(p);
10373 
10374       if (gotdest) {
10375          if (gotdest < 0) {
10376             if (ignore)
10377                transmit_response(p, "404 Not Found", req);
10378             else
10379                transmit_response_reliable(p, "404 Not Found", req, 1);
10380             update_call_counter(p, DEC_CALL_LIMIT);
10381          } else {
10382             if (ignore)
10383                transmit_response(p, "484 Address Incomplete", req);
10384             else
10385                transmit_response_reliable(p, "484 Address Incomplete", req, 1);
10386             update_call_counter(p, DEC_CALL_LIMIT);
10387          }
10388          ast_set_flag(p, SIP_NEEDDESTROY);      
10389       } else {
10390          /* If no extension was specified, use the s one */
10391          if (ast_strlen_zero(p->exten))
10392             ast_copy_string(p->exten, "s", sizeof(p->exten));
10393          /* Initialize tag */ 
10394          make_our_tag(p->tag, sizeof(p->tag));
10395          /* First invitation */
10396          c = sip_new(p, AST_STATE_DOWN, ast_strlen_zero(p->username) ? NULL : p->username );
10397          *recount = 1;
10398          /* Save Record-Route for any later requests we make on this dialogue */
10399          build_route(p, req, 0);
10400          if (c) {
10401             /* Pre-lock the call */
10402             ast_mutex_lock(&c->lock);
10403          }
10404       }
10405       
10406    } else {
10407       if (option_debug > 1 && sipdebug)
10408          ast_log(LOG_DEBUG, "Got a SIP re-invite for call %s\n", p->callid);
10409       c = p->owner;
10410    }
10411    if (!ignore && p)
10412       p->lastinvite = seqno;
10413    if (c) {
10414 #ifdef OSP_SUPPORT
10415       ast_channel_setwhentohangup (c, p->osptimelimit);
10416 #endif
10417       switch(c->_state) {
10418       case AST_STATE_DOWN:
10419          transmit_response(p, "100 Trying", req);
10420          ast_setstate(c, AST_STATE_RING);
10421          if (strcmp(p->exten, ast_pickup_ext())) {
10422             enum ast_pbx_result res;
10423 
10424             res = ast_pbx_start(c);
10425 
10426             switch (res) {
10427             case AST_PBX_FAILED:
10428                ast_log(LOG_WARNING, "Failed to start PBX :(\n");
10429                if (ignore)
10430                   transmit_response(p, "503 Unavailable", req);
10431                else
10432                   transmit_response_reliable(p, "503 Unavailable", req, 1);
10433                break;
10434             case AST_PBX_CALL_LIMIT:
10435                ast_log(LOG_WARNING, "Failed to start PBX (call limit reached) \n");
10436                if (ignore)
10437                   transmit_response(p, "480 Temporarily Unavailable", req);
10438                else
10439                   transmit_response_reliable(p, "480 Temporarily Unavailable", req, 1);
10440                break;
10441             case AST_PBX_SUCCESS:
10442                /* nothing to do */
10443                break;
10444             }
10445 
10446             if (res) {
10447                ast_log(LOG_WARNING, "Failed to start PBX :(\n");
10448                /* Unlock locks so ast_hangup can do its magic */
10449                ast_mutex_unlock(&c->lock);
10450                ast_mutex_unlock(&p->lock);
10451                ast_hangup(c);
10452                ast_mutex_lock(&p->lock);
10453                c = NULL;
10454             }
10455          } else {
10456             ast_mutex_unlock(&c->lock);
10457             if (ast_pickup_call(c)) {
10458                ast_log(LOG_NOTICE, "Nothing to pick up\n");
10459                if (ignore)
10460                   transmit_response(p, "503 Unavailable", req);
10461                else
10462                   transmit_response_reliable(p, "503 Unavailable", req, 1);
10463                ast_set_flag(p, SIP_ALREADYGONE);   
10464                /* Unlock locks so ast_hangup can do its magic */
10465                ast_mutex_unlock(&p->lock);
10466                ast_hangup(c);
10467                ast_mutex_lock(&p->lock);
10468                c = NULL;
10469             } else {
10470                ast_mutex_unlock(&p->lock);
10471                ast_setstate(c, AST_STATE_DOWN);
10472                ast_hangup(c);
10473                ast_mutex_lock(&p->lock);
10474                c = NULL;
10475             }
10476          }
10477          break;
10478       case AST_STATE_RING:
10479          transmit_response(p, "100 Trying", req);
10480          break;
10481       case AST_STATE_RINGING:
10482          transmit_response(p, "180 Ringing", req);
10483          break;
10484       case AST_STATE_UP:
10485          transmit_response_with_sdp(p, "200 OK", req, 1);
10486          break;
10487       default:
10488          ast_log(LOG_WARNING, "Don't know how to handle INVITE in state %d\n", c->_state);
10489          transmit_response(p, "100 Trying", req);
10490       }
10491    } else {
10492       if (p && !ast_test_flag(p, SIP_NEEDDESTROY) && !ignore) {
10493          if (!p->jointcapability) {
10494             if (ignore)
10495                transmit_response(p, "488 Not Acceptable Here (codec error)", req);
10496             else
10497                transmit_response_reliable(p, "488 Not Acceptable Here (codec error)", req, 1);
10498             ast_set_flag(p, SIP_NEEDDESTROY);   
10499          } else {
10500             ast_log(LOG_NOTICE, "Unable to create/find channel\n");
10501             if (ignore)
10502                transmit_response(p, "503 Unavailable", req);
10503             else
10504                transmit_response_reliable(p, "503 Unavailable", req, 1);
10505             ast_set_flag(p, SIP_NEEDDESTROY);   
10506          }
10507       }
10508    }
10509    return res;
10510 }

static 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 10662 of file chan_sip.c.

References ast_verbose(), receive_message(), and transmit_response().

Referenced by handle_request().

10663 {
10664    if (!ignore) {
10665       if (debug)
10666          ast_verbose("Receiving message!\n");
10667       receive_message(p, req);
10668    } else {
10669       transmit_response(p, "202 Accepted", req);
10670    }
10671    return 1;
10672 }

static 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 10230 of file chan_sip.c.

References ast_set_flag, ast_strlen_zero(), build_contact(), sip_pvt::context, default_context, get_destination(), sip_pvt::lastinvite, SIP_NEEDDESTROY, and transmit_response_with_allow().

Referenced by handle_request().

10231 {
10232    int res;
10233 
10234    res = get_destination(p, req);
10235    build_contact(p);
10236    /* XXX Should we authenticate OPTIONS? XXX */
10237    if (ast_strlen_zero(p->context))
10238       strcpy(p->context, default_context);
10239    if (res < 0)
10240       transmit_response_with_allow(p, "404 Not Found", req, 0);
10241    else if (res > 0)
10242       transmit_response_with_allow(p, "484 Address Incomplete", req, 0);
10243    else 
10244       transmit_response_with_allow(p, "200 OK", req, 0);
10245    /* Destroy if this OPTIONS was the opening request, but not if
10246       it's in the middle of a normal call flow. */
10247    if (!p->lastinvite)
10248       ast_set_flag(p, SIP_NEEDDESTROY);   
10249 
10250    return res;
10251 }

static 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 10513 of file chan_sip.c.

References ast_async_goto(), ast_bridged_channel(), ast_log(), ast_moh_stop(), ast_mutex_unlock(), ast_parking_ext(), ast_queue_hangup(), ast_set_flag, ast_strlen_zero(), attempt_transfer(), sip_pvt::callid, sip_pvt::context, default_context, get_refer_info(), sip_pvt::lock, ast_channel::lock, LOG_DEBUG, ast_channel::name, option_debug, sip_pvt::owner, sip_pvt::refer_call, sip_pvt::refer_to, SIP_ALREADYGONE, SIP_BYE, SIP_GOTREFER, sip_park(), transmit_notify_with_sipfrag(), transmit_request_with_auth(), transmit_response(), and transmit_response_with_allow().

Referenced by handle_request().

10514 {
10515    struct ast_channel *c=NULL;
10516    int res;
10517    struct ast_channel *transfer_to;
10518 
10519    if (option_debug > 2)
10520       ast_log(LOG_DEBUG, "SIP call transfer received for call %s (REFER)!\n", p->callid);
10521    if (ast_strlen_zero(p->context))
10522       strcpy(p->context, default_context);
10523    res = get_refer_info(p, req);
10524    if (res < 0)
10525       transmit_response_with_allow(p, "404 Not Found", req, 1);
10526    else if (res > 0)
10527       transmit_response_with_allow(p, "484 Address Incomplete", req, 1);
10528    else {
10529       int nobye = 0;
10530       if (!ignore) {
10531          if (p->refer_call) {
10532             ast_log(LOG_DEBUG,"202 Accepted (supervised)\n");
10533             attempt_transfer(p, p->refer_call);
10534             if (p->refer_call->owner)
10535                ast_mutex_unlock(&p->refer_call->owner->lock);
10536             ast_mutex_unlock(&p->refer_call->lock);
10537             p->refer_call = NULL;
10538             ast_set_flag(p, SIP_GOTREFER);   
10539          } else {
10540             ast_log(LOG_DEBUG,"202 Accepted (blind)\n");
10541             c = p->owner;
10542             if (c) {
10543                transfer_to = ast_bridged_channel(c);
10544                if (transfer_to) {
10545                   ast_log(LOG_DEBUG, "Got SIP blind transfer, applying to '%s'\n", transfer_to->name);
10546                   ast_moh_stop(transfer_to);
10547                   if (!strcmp(p->refer_to, ast_parking_ext())) {
10548                      /* Must release c's lock now, because it will not longer
10549                          be accessible after the transfer! */
10550                      *nounlock = 1;
10551                      ast_mutex_unlock(&c->lock);
10552                      sip_park(transfer_to, c, req);
10553                      nobye = 1;
10554                   } else {
10555                      /* Must release c's lock now, because it will not longer
10556                          be accessible after the transfer! */
10557                      *nounlock = 1;
10558                      ast_mutex_unlock(&c->lock);
10559                      ast_async_goto(transfer_to,p->context, p->refer_to,1);
10560                   }
10561                } else {
10562                   ast_log(LOG_DEBUG, "Got SIP blind transfer but nothing to transfer to.\n");
10563                   ast_queue_hangup(p->owner);
10564                }
10565             }
10566             ast_set_flag(p, SIP_GOTREFER);   
10567          }
10568          transmit_response(p, "202 Accepted", req);
10569          transmit_notify_with_sipfrag(p, seqno);
10570          /* Always increment on a BYE */
10571          if (!nobye) {
10572             transmit_request_with_auth(p, SIP_BYE, 0, 1, 1);
10573             ast_set_flag(p, SIP_ALREADYGONE);   
10574          }
10575       }
10576    }
10577    return res;
10578 }

static 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 10875 of file chan_sip.c.

References ast_inet_ntoa(), ast_log(), ast_verbose(), check_via(), copy_request(), get_header(), sip_pvt::initreq, LOG_NOTICE, register_verify(), and sip_scheddestroy().

Referenced by handle_request().

10876 {
10877    int res = 0;
10878    char iabuf[INET_ADDRSTRLEN];
10879 
10880    /* Use this as the basis */
10881    if (debug)
10882       ast_verbose("Using latest REGISTER request as basis request\n");
10883    copy_request(&p->initreq, req);
10884    check_via(p, req);
10885    if ((res = register_verify(p, sin, req, e, ignore)) < 0) 
10886       ast_log(LOG_NOTICE, "Registration from '%s' failed for '%s' - %s\n", get_header(req, "To"), ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr), (res == -1) ? "Wrong password" : (res == -2 ? "Username/auth name mismatch" : "Not a local SIP domain"));
10887    if (res < 1) {
10888       /* Destroy the session, but keep us around for just a bit in case they don't
10889          get our 200 OK */
10890       sip_scheddestroy(p, 15*1000);
10891    }
10892    return res;
10893 }

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

handle_request_subscribe: Handle incoming SUBSCRIBE request ---

Definition at line 10674 of file chan_sip.c.

References append_history(), ast_clear_flag, AST_EXTENSION_REMOVED, ast_extension_state(), ast_extension_state2str(), ast_extension_state_add(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_strlen_zero(), ast_test_flag, ast_verbose(), sip_pvt::autokillid, build_contact(), sip_pvt::callid, cb_extensionstate(), check_user_full(), check_via(), sip_pvt::context, copy_request(), CPIM_PIDF_XML, default_context, DIALOG_INFO_XML, sip_pvt::expiry, sip_pvt::exten, get_destination(), get_header(), sip_request::headers, iflist, sip_pvt::initreq, sip_pvt::lastinvite, sip_pvt::lock, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, mailbox, make_our_tag(), max_expiry, sip_request::method, sip_pvt::next, NONE, option_debug, PIDF_XML, sip_cancel_destroy(), sip_methods, SIP_NEEDDESTROY, SIP_OUTGOING, sip_scheddestroy(), SIP_SUBSCRIBE, sipdebug, sip_pvt::stateid, sip_pvt::subscribecontext, sip_pvt::subscribed, sip_pvt::tag, cfsip_methods::text, transmit_response(), transmit_state_notify(), sip_pvt::useragent, sip_pvt::username, and XPIDF_XML.

Referenced by handle_request().

10675 {
10676    int gotdest;
10677    int res = 0;
10678    int firststate = AST_EXTENSION_REMOVED;
10679 
10680    if (p->initreq.headers) {  
10681       /* We already have a dialog */
10682       if (p->initreq.method != SIP_SUBSCRIBE) {
10683          /* This is a SUBSCRIBE within another SIP dialog, which we do not support */
10684          /* For transfers, this could happen, but since we haven't seen it happening, let us just refuse this */
10685          transmit_response(p, "403 Forbidden (within dialog)", req);
10686          /* Do not destroy session, since we will break the call if we do */
10687          ast_log(LOG_DEBUG, "Got a subscription within the context of another call, can't handle that - %s (Method %s)\n", p->callid, sip_methods[p->initreq.method].text);
10688          return 0;
10689       } else {
10690          if (debug)
10691             ast_log(LOG_DEBUG, "Got a re-subscribe on existing subscription %s\n", p->callid);
10692       }
10693    }
10694    if (!ignore && !p->initreq.headers) {
10695       /* Use this as the basis */
10696       if (debug)
10697          ast_verbose("Using latest SUBSCRIBE request as basis request\n");
10698       /* This call is no longer outgoing if it ever was */
10699       ast_clear_flag(p, SIP_OUTGOING);
10700       copy_request(&p->initreq, req);
10701       check_via(p, req);
10702    } else if (debug && ignore)
10703       ast_verbose("Ignoring this SUBSCRIBE request\n");
10704 
10705    if (!p->lastinvite) {
10706       char mailboxbuf[256]="";
10707       int found = 0;
10708       char *mailbox = NULL;
10709       int mailboxsize = 0;
10710       char *eventparam;
10711 
10712       char *event = get_header(req, "Event");   /* Get Event package name */
10713       char *accept = get_header(req, "Accept");
10714 
10715       /* Find parameters to Event: header value and remove them for now */
10716       eventparam = strchr(event, ';');
10717       if (eventparam) {
10718          *eventparam = '\0';
10719          eventparam++;
10720       }
10721 
10722       if (!strcmp(event, "message-summary") && !strcmp(accept, "application/simple-message-summary")) {
10723          mailbox = mailboxbuf;
10724          mailboxsize = sizeof(mailboxbuf);
10725       }
10726       /* Handle authentication if this is our first subscribe */
10727       res = check_user_full(p, req, SIP_SUBSCRIBE, e, 0, sin, ignore, mailbox, mailboxsize);
10728       if (res) {
10729          if (res < 0) {
10730             ast_log(LOG_NOTICE, "Failed to authenticate user %s for SUBSCRIBE\n", get_header(req, "From"));
10731             ast_set_flag(p, SIP_NEEDDESTROY);   
10732          }
10733          return 0;
10734       }
10735       /* Initialize the context if it hasn't been already */
10736       if (!ast_strlen_zero(p->subscribecontext))
10737          ast_copy_string(p->context, p->subscribecontext, sizeof(p->context));
10738       else if (ast_strlen_zero(p->context))
10739          strcpy(p->context, default_context);
10740       /* Get destination right away */
10741       gotdest = get_destination(p, NULL);
10742       build_contact(p);
10743       if (gotdest) {
10744          if (gotdest < 0)
10745             transmit_response(p, "404 Not Found", req);
10746          else
10747             transmit_response(p, "484 Address Incomplete", req);  /* Overlap dialing on SUBSCRIBE?? */
10748          ast_set_flag(p, SIP_NEEDDESTROY);   
10749       } else {
10750 
10751          /* Initialize tag for new subscriptions */   
10752          if (ast_strlen_zero(p->tag))
10753             make_our_tag(p->tag, sizeof(p->tag));
10754 
10755          if (!strcmp(event, "presence") || !strcmp(event, "dialog")) { /* Presence, RFC 3842 */
10756 
10757             /* Header from Xten Eye-beam Accept: multipart/related, application/rlmi+xml, application/pidf+xml, application/xpidf+xml */
10758             if (strstr(accept, "application/pidf+xml")) {
10759                p->subscribed = PIDF_XML;         /* RFC 3863 format */
10760             } else if (strstr(accept, "application/dialog-info+xml")) {
10761                p->subscribed = DIALOG_INFO_XML;
10762                /* IETF draft: draft-ietf-sipping-dialog-package-05.txt */
10763             } else if (strstr(accept, "application/cpim-pidf+xml")) {
10764                p->subscribed = CPIM_PIDF_XML;    /* RFC 3863 format */
10765             } else if (strstr(accept, "application/xpidf+xml")) {
10766                p->subscribed = XPIDF_XML;        /* Early pre-RFC 3863 format with MSN additions (Microsoft Messenger) */
10767             } else if (strstr(p->useragent, "Polycom")) {
10768                p->subscribed = XPIDF_XML;        /*  Polycoms subscribe for "event: dialog" but don't include an "accept:" header */
10769             } else {
10770                /* Can't find a format for events that we know about */
10771                transmit_response(p, "489 Bad Event", req);
10772                ast_set_flag(p, SIP_NEEDDESTROY);   
10773                return 0;
10774             }
10775          } else if (!strcmp(event, "message-summary") && !strcmp(accept, "application/simple-message-summary")) {
10776             /* Looks like they actually want a mailbox status */
10777 
10778             /* At this point, we should check if they subscribe to a mailbox that
10779               has the same extension as the peer or the mailbox id. If we configure
10780               the context to be the same as a SIP domain, we could check mailbox
10781               context as well. To be able to securely accept subscribes on mailbox
10782               IDs, not extensions, we need to check the digest auth user to make
10783               sure that the user has access to the mailbox.
10784              
10785               Since we do not act on this subscribe anyway, we might as well 
10786               accept any authenticated peer with a mailbox definition in their 
10787               config section.
10788             
10789             */
10790             if (!ast_strlen_zero(mailbox)) {
10791                found++;
10792             }
10793 
10794             if (found){
10795                transmit_response(p, "200 OK", req);
10796                ast_set_flag(p, SIP_NEEDDESTROY);   
10797             } else {
10798                transmit_response(p, "404 Not found", req);
10799                ast_set_flag(p, SIP_NEEDDESTROY);   
10800             }
10801             return 0;
10802          } else { /* At this point, Asterisk does not understand the specified event */
10803             transmit_response(p, "489 Bad Event", req);
10804             if (option_debug > 1)
10805                ast_log(LOG_DEBUG, "Received SIP subscribe for unknown event package: %s\n", event);
10806             ast_set_flag(p, SIP_NEEDDESTROY);   
10807             return 0;
10808          }
10809          if (p->subscribed != NONE)
10810             p->stateid = ast_extension_state_add(p->context, p->exten, cb_extensionstate, p);
10811       }
10812    }
10813 
10814    if (!ignore && p)
10815       p->lastinvite = seqno;
10816    if (p && !ast_test_flag(p, SIP_NEEDDESTROY)) {
10817       p->expiry = atoi(get_header(req, "Expires"));
10818 
10819       /* The next 4 lines can be removed if the SNOM Expires bug is fixed */
10820       if (p->subscribed == DIALOG_INFO_XML) {  
10821          if (p->expiry > max_expiry)
10822             p->expiry = max_expiry;
10823       }
10824       if (sipdebug || option_debug > 1)
10825          ast_log(LOG_DEBUG, "Adding subscription for extension %s context %s for peer %s\n", p->exten, p->context, p->username);
10826       if (p->autokillid > -1)
10827          sip_cancel_destroy(p);  /* Remove subscription expiry for renewals */
10828       sip_scheddestroy(p, (p->expiry + 10) * 1000);   /* Set timer for destruction of call at expiration */
10829 
10830       if ((firststate = ast_extension_state(NULL, p->context, p->exten)) < 0) {
10831          ast_log(LOG_ERROR, "Got SUBSCRIBE for extensions without hint. Please add hint to %s in context %s\n", p->exten, p->context);
10832          transmit_response(p, "404 Not found", req);
10833          ast_set_flag(p, SIP_NEEDDESTROY);   
10834          return 0;
10835       } else {
10836          struct sip_pvt *p_old;
10837 
10838          transmit_response(p, "200 OK", req);
10839          transmit_state_notify(p, firststate, 1, 1);  /* Send first notification */
10840          append_history(p, "Subscribestatus", ast_extension_state2str(firststate));
10841 
10842          /* remove any old subscription from this peer for the same exten/context,
10843             as the peer has obviously forgotten about it and it's wasteful to wait
10844             for it to expire and send NOTIFY messages to the peer only to have them
10845             ignored (or generate errors)
10846          */
10847          ast_mutex_lock(&iflock);
10848          for (p_old = iflist; p_old; p_old = p_old->next) {
10849             if (p_old == p)
10850                continue;
10851             if (p_old->initreq.method != SIP_SUBSCRIBE)
10852                continue;
10853             if (p_old->subscribed == NONE)
10854                continue;
10855             ast_mutex_lock(&p_old->lock);
10856             if (!strcmp(p_old->username, p->username)) {
10857                if (!strcmp(p_old->exten, p->exten) &&
10858                    !strcmp(p_old->context, p->context)) {
10859                   ast_set_flag(p_old, SIP_NEEDDESTROY);
10860                   ast_mutex_unlock(&p_old->lock);
10861                   break;
10862                }
10863             }
10864             ast_mutex_unlock(&p_old->lock);
10865          }
10866          ast_mutex_unlock(&iflock);
10867       }
10868       if (!p->expiry)
10869          ast_set_flag(p, SIP_NEEDDESTROY);
10870    }
10871    return 1;
10872 }

static 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 9761 of file chan_sip.c.

References __sip_ack(), __sip_semi_ack(), AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_PROGRESS, ast_inet_ntoa(), ast_log(), ast_queue_control(), ast_queue_hangup(), ast_rtp_stop(), ast_sched_del(), ast_set_flag, ast_strlen_zero(), ast_test_flag, ast_verbose(), sip_request::debug, DEC_CALL_LIMIT, do_proxy_auth(), find_sip_method(), get_header(), gettag(), handle_response_invite(), handle_response_peerpoke(), handle_response_register(), hangup_sip2cause(), ast_channel::hangupcause, sip_pvt::initid, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, MAX_AUTHTRIES, NONE, option_verbose, sip_pvt::owner, parse_moved_contact(), sip_pvt::peerpoke, process_sdp(), SIP_ACK, SIP_ALREADYGONE, SIP_BYE, SIP_CANCEL, sip_cancel_destroy(), SIP_INVITE, SIP_MESSAGE, sip_methods, SIP_NEEDDESTROY, SIP_NOTIFY, SIP_OUTGOING, SIP_REFER, SIP_REGISTER, text, sip_pvt::theirtag, transmit_request(), update_call_counter(), and VERBOSE_PREFIX_3.

09762 {
09763    char *msg, *c;
09764    struct ast_channel *owner;
09765    char iabuf[INET_ADDRSTRLEN];
09766    int sipmethod;
09767    int res = 1;
09768 
09769    c = get_header(req, "Cseq");
09770    msg = strchr(c, ' ');
09771    if (!msg)
09772       msg = "";
09773    else
09774       msg++;
09775    sipmethod = find_sip_method(msg);
09776 
09777    owner = p->owner;
09778    if (owner) 
09779       owner->hangupcause = hangup_sip2cause(resp);
09780 
09781    /* Acknowledge whatever it is destined for */
09782    if ((resp >= 100) && (resp <= 199))
09783       __sip_semi_ack(p, seqno, 0, sipmethod);
09784    else
09785       __sip_ack(p, seqno, 0, sipmethod);
09786 
09787    /* Get their tag if we haven't already */
09788    if (ast_strlen_zero(p->theirtag) || (resp >= 200)) {
09789       gettag(req, "To", p->theirtag, sizeof(p->theirtag));
09790    }
09791    if (p->peerpoke) {
09792       /* We don't really care what the response is, just that it replied back. 
09793          Well, as long as it's not a 100 response...  since we might
09794          need to hang around for something more "definitive" */
09795 
09796       res = handle_response_peerpoke(p, resp, rest, req, ignore, seqno, sipmethod);
09797    } else if (ast_test_flag(p, SIP_OUTGOING)) {
09798       /* Acknowledge sequence number */
09799       if (p->initid > -1) {
09800          /* Don't auto congest anymore since we've gotten something useful back */
09801          ast_sched_del(sched, p->initid);
09802          p->initid = -1;
09803       }
09804       switch(resp) {
09805       case 100:   /* 100 Trying */
09806          if (sipmethod == SIP_INVITE) 
09807             handle_response_invite(p, resp, rest, req, ignore, seqno);
09808          break;
09809       case 183:   /* 183 Session Progress */
09810          if (sipmethod == SIP_INVITE) 
09811             handle_response_invite(p, resp, rest, req, ignore, seqno);
09812          break;
09813       case 180:   /* 180 Ringing */
09814          if (sipmethod == SIP_INVITE) 
09815             handle_response_invite(p, resp, rest, req, ignore, seqno);
09816          break;
09817       case 200:   /* 200 OK */
09818          p->authtries = 0; /* Reset authentication counter */
09819          if (sipmethod == SIP_MESSAGE) {
09820             /* We successfully transmitted a message */
09821             ast_set_flag(p, SIP_NEEDDESTROY);   
09822          } else if (sipmethod == SIP_NOTIFY) {
09823             /* They got the notify, this is the end */
09824             if (p->owner) {
09825                ast_log(LOG_WARNING, "Notify answer on an owned channel?\n");
09826                ast_queue_hangup(p->owner);
09827             } else {
09828                if (p->subscribed == NONE) {
09829                   ast_set_flag(p, SIP_NEEDDESTROY); 
09830                }
09831             }
09832          } else if (sipmethod == SIP_INVITE) {
09833             handle_response_invite(p, resp, rest, req, ignore, seqno);
09834          } else if (sipmethod == SIP_REGISTER) {
09835             res = handle_response_register(p, resp, rest, req, ignore, seqno);
09836          } 
09837          break;
09838       case 401: /* Not www-authorized on SIP method */
09839          if (sipmethod == SIP_INVITE) {
09840             handle_response_invite(p, resp, rest, req, ignore, seqno);
09841          } else if (p->registry && sipmethod == SIP_REGISTER) {
09842             res = handle_response_register(p, resp, rest, req, ignore, seqno);
09843          } else {
09844             ast_log(LOG_WARNING, "Got authentication request (401) on unknown %s to '%s'\n", sip_methods[sipmethod].text, get_header(req, "To"));
09845             ast_set_flag(p, SIP_NEEDDESTROY);   
09846          }
09847          break;
09848       case 403: /* Forbidden - we failed authentication */
09849          if (sipmethod == SIP_INVITE) {
09850             handle_response_invite(p, resp, rest, req, ignore, seqno);
09851          } else if (p->registry && sipmethod == SIP_REGISTER) {
09852             res = handle_response_register(p, resp, rest, req, ignore, seqno);
09853          } else {
09854             ast_log(LOG_WARNING, "Forbidden - wrong password on authentication for %s\n", msg);
09855          }
09856          break;
09857       case 404: /* Not found */
09858          if (p->registry && sipmethod == SIP_REGISTER) {
09859             res = handle_response_register(p, resp, rest, req, ignore, seqno);
09860          } else if (sipmethod == SIP_INVITE) {
09861             handle_response_invite(p, resp, rest, req, ignore, seqno);
09862          } else if (owner)
09863             ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
09864          break;
09865       case 407: /* Proxy auth required */
09866          if (sipmethod == SIP_INVITE) {
09867             handle_response_invite(p, resp, rest, req, ignore, seqno);
09868          } else if (sipmethod == SIP_BYE || sipmethod == SIP_REFER) {
09869             if (ast_strlen_zero(p->authname))
09870                ast_log(LOG_WARNING, "Asked to authenticate %s, to %s:%d but we have no matching peer!\n",
09871                      msg, ast_inet_ntoa(iabuf, sizeof(iabuf), p->recv.sin_addr), ntohs(p->recv.sin_port));
09872                ast_set_flag(p, SIP_NEEDDESTROY);   
09873             if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, "Proxy-Authenticate", "Proxy-Authorization", sipmethod, 0)) {
09874                ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From"));
09875                ast_set_flag(p, SIP_NEEDDESTROY);   
09876             }
09877          } else if (p->registry && sipmethod == SIP_REGISTER) {
09878             res = handle_response_register(p, resp, rest, req, ignore, seqno);
09879          } else   /* We can't handle this, giving up in a bad way */
09880             ast_set_flag(p, SIP_NEEDDESTROY);   
09881 
09882          break;
09883       case 491: /* Pending */
09884          if (sipmethod == SIP_INVITE) {
09885             handle_response_invite(p, resp, rest, req, ignore, seqno);
09886          }
09887       case 501: /* Not Implemented */
09888          if (sipmethod == SIP_INVITE) {
09889             handle_response_invite(p, resp, rest, req, ignore, seqno);
09890          } else
09891             ast_log(LOG_WARNING, "Host '%s' does not implement '%s'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr), msg);
09892          break;
09893       default:
09894          if ((resp >= 300) && (resp < 700)) {
09895             if ((option_verbose > 2) && (resp != 487))
09896                ast_verbose(VERBOSE_PREFIX_3 "Got SIP response %d \"%s\" back from %s\n", resp, rest, ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr));
09897             ast_set_flag(p, SIP_ALREADYGONE);   
09898             if (p->rtp) {
09899                /* Immediately stop RTP */
09900                ast_rtp_stop(p->rtp);
09901             }
09902             if (p->vrtp) {
09903                /* Immediately stop VRTP */
09904                ast_rtp_stop(p->vrtp);
09905             }
09906             /* XXX Locking issues?? XXX */
09907             switch(resp) {
09908             case 300: /* Multiple Choices */
09909             case 301: /* Moved permenantly */
09910             case 302: /* Moved temporarily */
09911             case 305: /* Use Proxy */
09912                parse_moved_contact(p, req);
09913                /* Fall through */
09914             case 486: /* Busy here */
09915             case 600: /* Busy everywhere */
09916             case 603: /* Decline */
09917                if (p->owner)
09918                   ast_queue_control(p->owner, AST_CONTROL_BUSY);
09919                break;
09920             case 487:
09921                /* channel now destroyed - dec the inUse counter */
09922                update_call_counter(p, DEC_CALL_LIMIT);
09923                break;
09924             case 482: /* SIP is incapable of performing a hairpin call, which
09925                          is yet another failure of not having a layer 2 (again, YAY
09926                       IETF for thinking ahead).  So we treat this as a call
09927                       forward and hope we end up at the right place... */
09928                ast_log(LOG_DEBUG, "Hairpin detected, setting up call forward for what it's worth\n");
09929                if (p->owner)
09930                   snprintf(p->owner->call_forward, sizeof(p->owner->call_forward), "Local/%s@%s", p->username, p->context);
09931                /* Fall through */
09932             case 488: /* Not acceptable here - codec error */
09933             case 480: /* Temporarily Unavailable */
09934             case 404: /* Not Found */
09935             case 410: /* Gone */
09936             case 400: /* Bad Request */
09937             case 500: /* Server error */
09938             case 503: /* Service Unavailable */
09939                if (owner)
09940                   ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
09941                break;
09942             default:
09943                /* Send hangup */ 
09944                if (owner)
09945                   ast_queue_hangup(p->owner);
09946                break;
09947             }
09948             /* ACK on invite */
09949             if (sipmethod == SIP_INVITE) 
09950                transmit_request(p, SIP_ACK, seqno, 0, 0);
09951             ast_set_flag(p, SIP_ALREADYGONE);   
09952             if (!p->owner)
09953                ast_set_flag(p, SIP_NEEDDESTROY);   
09954          } else if ((resp >= 100) && (resp < 200)) {
09955             if (sipmethod == SIP_INVITE) {
09956                sip_cancel_destroy(p);
09957                if (!ast_strlen_zero(get_header(req, "Content-Type")))
09958                   process_sdp(p, req);
09959                if (p->owner) {
09960                   /* Queue a progress frame */
09961                   ast_queue_control(p->owner, AST_CONTROL_PROGRESS);
09962                }
09963             }
09964          } else
09965             ast_log(LOG_NOTICE, "Dont know how to handle a %d %s response from %s\n", resp, rest, p->owner ? p->owner->name : ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr));
09966       }
09967    } else { 
09968       /* Responses to OUTGOING SIP requests on INCOMING calls 
09969          get handled here. As well as out-of-call message responses */
09970       if (req->debug)
09971          ast_verbose("SIP Response message for INCOMING dialog %s arrived\n", msg);
09972       if (resp == 200) {
09973          /* Tags in early session is replaced by the tag in 200 OK, which is 
09974          the final reply to our INVITE */
09975          gettag(req, "To", p->theirtag, sizeof(p->theirtag));
09976       }
09977 
09978       switch(resp) {
09979       case 200:
09980          if (sipmethod == SIP_INVITE) {
09981             handle_response_invite(p, resp, rest, req, ignore, seqno);
09982          } else if (sipmethod == SIP_CANCEL) {
09983             ast_log(LOG_DEBUG, "Got 200 OK on CANCEL\n");
09984          } else if (sipmethod == SIP_MESSAGE)
09985             /* We successfully transmitted a message */
09986             ast_set_flag(p, SIP_NEEDDESTROY);   
09987          break;
09988       case 401:   /* www-auth */
09989       case 407:
09990          if (sipmethod == SIP_BYE || sipmethod == SIP_REFER) {
09991             char *auth, *auth2;
09992 
09993             if (resp == 407) {
09994                auth = "Proxy-Authenticate";
09995                auth2 = "Proxy-Authorization";
09996             } else {
09997                auth = "WWW-Authenticate";
09998                auth2 = "Authorization";
09999             }
10000             if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, auth, auth2, sipmethod, 0)) {
10001                ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From"));
10002                ast_set_flag(p, SIP_NEEDDESTROY);   
10003             }
10004          } else if (sipmethod == SIP_INVITE) {
10005             handle_response_invite(p, resp, rest, req, ignore, seqno);
10006          }
10007          break;
10008       case 481:   /* Call leg does not exist */
10009          if (sipmethod == SIP_INVITE) {
10010             /* Re-invite failed */
10011             handle_response_invite(p, resp, rest, req, ignore, seqno);
10012          }
10013          break;
10014       default: /* Errors without handlers */
10015          if ((resp >= 100) && (resp < 200)) {
10016             if (sipmethod == SIP_INVITE) {   /* re-invite */
10017                sip_cancel_destroy(p);
10018             }
10019          }
10020          if ((resp >= 300) && (resp < 700)) {
10021             if ((option_verbose > 2) && (resp != 487))
10022                ast_verbose(VERBOSE_PREFIX_3 "Incoming call: Got SIP response %d \"%s\" back from %s\n", resp, rest, ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr));
10023             switch(resp) {
10024             case 488: /* Not acceptable here - codec error */
10025             case 603: /* Decline */
10026             case 500: /* Server error */
10027             case 503: /* Service Unavailable */
10028 
10029                if (sipmethod == SIP_INVITE) {   /* re-invite failed */
10030                   sip_cancel_destroy(p);
10031                }
10032                break;
10033             }
10034          }
10035          break;
10036       }
10037    }
10038 }

static 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 9450 of file chan_sip.c.

References ast_channel::_state, AST_CONTROL_ANSWER, AST_CONTROL_CONGESTION, AST_CONTROL_PROGRESS, AST_CONTROL_RINGING, AST_FRAME_NULL, ast_log(), ast_queue_control(), ast_queue_frame(), ast_set_flag, ast_setstate(), AST_STATE_RINGING, AST_STATE_UP, ast_test_flag, authenticate(), build_route(), sip_pvt::callid, check_pendings(), do_proxy_auth(), get_header(), LOG_DEBUG, LOG_NOTICE, LOG_WARNING, MAX_AUTHTRIES, option_debug, sip_pvt::owner, parse_ok_contact(), process_sdp(), PROXY_AUTH, SIP_ACK, SIP_ALREADYGONE, sip_cancel_destroy(), SIP_INVITE, SIP_NEEDDESTROY, SIP_OUTGOING, SIP_PENDINGBYE, transmit_request(), and WWW_AUTH.

Referenced by handle_response().

09451 {
09452    int outgoing = ast_test_flag(p, SIP_OUTGOING);
09453    
09454    if (option_debug > 3) {
09455       int reinvite = (p->owner && p->owner->_state == AST_STATE_UP);
09456       if (reinvite)
09457          ast_log(LOG_DEBUG, "SIP response %d to RE-invite on %s call %s\n", resp, outgoing ? "outgoing" : "incoming", p->callid);
09458       else
09459          ast_log(LOG_DEBUG, "SIP response %d to standard invite\n", resp);
09460    }
09461 
09462    if (ast_test_flag(p, SIP_ALREADYGONE)) { /* This call is already gone */
09463       ast_log(LOG_DEBUG, "Got response on call that is already terminated: %s (ignoring)\n", p->callid);
09464       return;
09465    }
09466 
09467    switch (resp) {
09468    case 100:   /* Trying */
09469       sip_cancel_destroy(p);
09470       break;
09471    case 180:   /* 180 Ringing */
09472       sip_cancel_destroy(p);
09473       if (!ignore && p->owner) {
09474          ast_queue_control(p->owner, AST_CONTROL_RINGING);
09475          if (p->owner->_state != AST_STATE_UP)
09476             ast_setstate(p->owner, AST_STATE_RINGING);
09477       }
09478       if (!strcasecmp(get_header(req, "Content-Type"), "application/sdp")) {
09479          process_sdp(p, req);
09480          if (!ignore && p->owner) {
09481             /* Queue a progress frame only if we have SDP in 180 */
09482             ast_queue_control(p->owner, AST_CONTROL_PROGRESS);
09483          }
09484       }
09485       break;
09486    case 183:   /* Session progress */
09487       sip_cancel_destroy(p);
09488       /* Ignore 183 Session progress without SDP */
09489       if (!strcasecmp(get_header(req, "Content-Type"), "application/sdp")) {
09490          process_sdp(p, req);
09491          if (!ignore && p->owner) {
09492             /* Queue a progress frame */
09493             ast_queue_control(p->owner, AST_CONTROL_PROGRESS);
09494          }
09495       }
09496       break;
09497    case 200:   /* 200 OK on invite - someone's answering our call */
09498       sip_cancel_destroy(p);
09499       p->authtries = 0;
09500       if (!strcasecmp(get_header(req, "Content-Type"), "application/sdp")) {
09501          process_sdp(p, req);
09502       }
09503 
09504       /* Parse contact header for continued conversation */
09505       /* When we get 200 OK, we know which device (and IP) to contact for this call */
09506       /* This is important when we have a SIP proxy between us and the phone */
09507       if (outgoing) {
09508          parse_ok_contact(p, req);
09509 
09510          /* Save Record-Route for any later requests we make on this dialogue */
09511          build_route(p, req, 1);
09512       }
09513       
09514       if (!ignore && p->owner) {
09515          if (p->owner->_state != AST_STATE_UP) {
09516 #ifdef OSP_SUPPORT   
09517             time(&p->ospstart);
09518 #endif
09519             ast_queue_control(p->owner, AST_CONTROL_ANSWER);
09520          } else { /* RE-invite */
09521             struct ast_frame af = { AST_FRAME_NULL, };
09522             ast_queue_frame(p->owner, &af);
09523          }
09524       } else {
09525           /* It's possible we're getting an ACK after we've tried to disconnect
09526               by sending CANCEL */
09527          /* THIS NEEDS TO BE CHECKED: OEJ */
09528          if (!ignore)
09529             ast_set_flag(p, SIP_PENDINGBYE); 
09530       }
09531       /* If I understand this right, the branch is different for a non-200 ACK only */
09532       transmit_request(p, SIP_ACK, seqno, 0, 1);
09533       check_pendings(p);
09534       break;
09535    case 407: /* Proxy authentication */
09536    case 401: /* Www auth */
09537       /* First we ACK */
09538       transmit_request(p, SIP_ACK, seqno, 0, 0);
09539       if (p->options)
09540          p->options->auth_type = (resp == 401 ? WWW_AUTH : PROXY_AUTH);
09541 
09542       /* Then we AUTH */
09543       p->theirtag[0]='\0'; /* forget their old tag, so we don't match tags when getting response */
09544       if (!ignore) {
09545          char *authenticate = (resp == 401 ? "WWW-Authenticate" : "Proxy-Authenticate");
09546          char *authorization = (resp == 401 ? "Authorization" : "Proxy-Authorization");
09547          if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, authenticate, authorization, SIP_INVITE, 1)) {
09548             ast_log(LOG_NOTICE, "Failed to authenticate on INVITE to '%s'\n", get_header(&p->initreq, "From"));
09549             ast_set_flag(p, SIP_NEEDDESTROY);   
09550             ast_set_flag(p, SIP_ALREADYGONE);   
09551             if (p->owner)
09552                ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
09553          }
09554       }
09555       break;
09556    case 403: /* Forbidden */
09557       /* First we ACK */
09558       transmit_request(p, SIP_ACK, seqno, 0, 0);
09559       ast_log(LOG_WARNING, "Forbidden - wrong password on authentication for INVITE to '%s'\n", get_header(&p->initreq, "From"));
09560       if (!ignore && p->owner)
09561          ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
09562       ast_set_flag(p, SIP_NEEDDESTROY);   
09563       ast_set_flag(p, SIP_ALREADYGONE);   
09564       break;
09565    case 404: /* Not found */
09566       transmit_request(p, SIP_ACK, seqno, 0, 0);
09567       if (p->owner && !ignore)
09568          ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
09569       ast_set_flag(p, SIP_ALREADYGONE);   
09570       break;
09571    case 481: /* Call leg does not exist */
09572       /* Could be REFER or INVITE */
09573       ast_log(LOG_WARNING, "Re-invite to non-existing call leg on other UA. SIP dialog '%s'. Giving up.\n", p->callid);
09574       transmit_request(p, SIP_ACK, seqno, 0, 0);
09575       break;
09576    case 491: /* Pending */
09577       /* we have to wait a while, then retransmit */
09578       /* Transmission is rescheduled, so everything should be taken care of.
09579          We should support the retry-after at some point */
09580       break;
09581    case 501: /* Not implemented */
09582       if (p->owner)
09583          ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
09584       break;
09585    }
09586 }

static 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 9705 of file chan_sip.c.

References ast_device_state_changed(), ast_log(), ast_sched_add(), ast_sched_del(), ast_set_flag, sip_peer::call, DEFAULT_FREQ_NOTOK, DEFAULT_FREQ_OK, EVENT_FLAG_SYSTEM, sip_peer::lastms, LOG_NOTICE, manager_event(), sip_peer::maxms, sip_pvt::peerpoke, sip_peer::pokeexpire, sip_peer::ps, SIP_ACK, SIP_INVITE, SIP_NEEDDESTROY, sip_poke_peer_s(), and transmit_request().

Referenced by handle_response().

09706 {
09707    struct sip_peer *peer;
09708    int pingtime;
09709    struct timeval tv;
09710 
09711    if (resp != 100) {
09712       int statechanged = 0;
09713       int newstate = 0;
09714       peer = p->peerpoke;
09715       gettimeofday(&tv, NULL);
09716       pingtime = ast_tvdiff_ms(tv, peer->ps);
09717       if (pingtime < 1)
09718          pingtime = 1;
09719       if ((peer->lastms < 0)  || (peer->lastms > peer->maxms)) {
09720          if (pingtime <= peer->maxms) {
09721             ast_log(LOG_NOTICE, "Peer '%s' is now REACHABLE! (%dms / %dms)\n", peer->name, pingtime, peer->maxms);
09722             statechanged = 1;
09723             newstate = 1;
09724          }
09725       } else if ((peer->lastms > 0) && (peer->lastms <= peer->maxms)) {
09726          if (pingtime > peer->maxms) {
09727             ast_log(LOG_NOTICE, "Peer '%s' is now TOO LAGGED! (%dms / %dms)\n", peer->name, pingtime, peer->maxms);
09728             statechanged = 1;
09729             newstate = 2;
09730          }
09731       }
09732       if (!peer->lastms)
09733          statechanged = 1;
09734       peer->lastms = pingtime;
09735       peer->call = NULL;
09736       if (statechanged) {
09737          ast_device_state_changed("SIP/%s", peer->name);
09738          if (newstate == 2) {
09739             manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Lagged\r\nTime: %d\r\n", peer->name, pingtime);
09740          } else {
09741             manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Reachable\r\nTime: %d\r\n", peer->name, pingtime);
09742          }
09743       }
09744 
09745       if (peer->pokeexpire > -1)
09746          ast_sched_del(sched, peer->pokeexpire);
09747       if (sipmethod == SIP_INVITE)  /* Does this really happen? */
09748          transmit_request(p, SIP_ACK, seqno, 0, 0);
09749       ast_set_flag(p, SIP_NEEDDESTROY);   
09750 
09751       /* Try again eventually */
09752       if ((peer->lastms < 0)  || (peer->lastms > peer->maxms))
09753          peer->pokeexpire = ast_sched_add(sched, DEFAULT_FREQ_NOTOK, sip_poke_peer_s, peer);
09754       else
09755          peer->pokeexpire = ast_sched_add(sched, DEFAULT_FREQ_OK, sip_poke_peer_s, peer);
09756    }
09757    return 1;
09758 }

static 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 9589 of file chan_sip.c.

References __get_header(), ast_log(), ast_sched_del(), ast_set_flag, ast_strlen_zero(), sip_pvt::authtries, sip_registry::call, sip_registry::contact, do_register_auth(), EVENT_FLAG_SYSTEM, sip_registry::expire, get_header(), global_regattempts_max, sip_registry::hostname, sip_pvt::initreq, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, manager_event(), MAX_AUTHTRIES, sip_pvt::our_contact, REG_STATE_REGISTERED, sip_registry::regattempts, sip_pvt::registry, sip_registry::regstate, regstate2str(), SIP_NEEDDESTROY, sip_scheddestroy(), sip_registry::timeout, and sip_registry::username.

Referenced by handle_response().

09590 {
09591    int expires, expires_ms;
09592    struct sip_registry *r;
09593    r=p->registry;
09594 
09595    switch (resp) {
09596    case 401:   /* Unauthorized */
09597       if ((p->authtries == MAX_AUTHTRIES) || do_register_auth(p, req, "WWW-Authenticate", "Authorization")) {
09598          ast_log(LOG_NOTICE, "Failed to authenticate on REGISTER to '%s@%s' (Tries %d)\n", p->registry->username, p->registry->hostname, p->authtries);
09599          ast_set_flag(p, SIP_NEEDDESTROY);   
09600          }
09601       break;
09602    case 403:   /* Forbidden */
09603       ast_log(LOG_WARNING, "Forbidden - wrong password on authentication for REGISTER for '%s' to '%s'\n", p->registry->username, p->registry->hostname);
09604       if (global_regattempts_max)
09605          p->registry->regattempts = global_regattempts_max+1;
09606       ast_sched_del(sched, r->timeout);
09607       ast_set_flag(p, SIP_NEEDDESTROY);   
09608       break;
09609    case 404:   /* Not found */
09610       ast_log(LOG_WARNING, "Got 404 Not found on SIP register to service %s@%s, giving up\n", p->registry->username,p->registry->hostname);
09611       if (global_regattempts_max)
09612          p->registry->regattempts = global_regattempts_max+1;
09613       ast_set_flag(p, SIP_NEEDDESTROY);   
09614       r->call = NULL;
09615       ast_sched_del(sched, r->timeout);
09616       break;
09617    case 407:   /* Proxy auth */
09618       if ((p->authtries == MAX_AUTHTRIES) || do_register_auth(p, req, "Proxy-Authenticate", "Proxy-Authorization")) {
09619          ast_log(LOG_NOTICE, "Failed to authenticate on REGISTER to '%s' (tries '%d')\n", get_header(&p->initreq, "From"), p->authtries);
09620          ast_set_flag(p, SIP_NEEDDESTROY);   
09621       }
09622       break;
09623    case 479:   /* SER: Not able to process the URI - address is wrong in register*/
09624       ast_log(LOG_WARNING, "Got error 479 on register to %s@%s, giving up (check config)\n", p->registry->username,p->registry->hostname);
09625       if (global_regattempts_max)
09626          p->registry->regattempts = global_regattempts_max+1;
09627       ast_set_flag(p, SIP_NEEDDESTROY);   
09628       r->call = NULL;
09629       ast_sched_del(sched, r->timeout);
09630       break;
09631    case 200:   /* 200 OK */
09632       if (!r) {
09633          ast_log(LOG_WARNING, "Got 200 OK on REGISTER that isn't a register\n");
09634          ast_set_flag(p, SIP_NEEDDESTROY);   
09635          return 0;
09636       }
09637 
09638       r->regstate=REG_STATE_REGISTERED;
09639       manager_event(EVENT_FLAG_SYSTEM, "Registry", "Channel: SIP\r\nDomain: %s\r\nStatus: %s\r\n", r->hostname, regstate2str(r->regstate));
09640       r->regattempts = 0;
09641       ast_log(LOG_DEBUG, "Registration successful\n");
09642       if (r->timeout > -1) {
09643          ast_log(LOG_DEBUG, "Cancelling timeout %d\n", r->timeout);
09644          ast_sched_del(sched, r->timeout);
09645       }
09646       r->timeout=-1;
09647       r->call = NULL;
09648       p->registry = NULL;
09649       /* Let this one hang around until we have all the responses */
09650       sip_scheddestroy(p, 32000);
09651       /* ast_set_flag(p, SIP_NEEDDESTROY);   */
09652 
09653       /* set us up for re-registering */
09654       /* figure out how long we got registered for */
09655       if (r->expire > -1)
09656          ast_sched_del(sched, r->expire);
09657       /* according to section 6.13 of RFC, contact headers override
09658          expires headers, so check those first */
09659       expires = 0;
09660       if (!ast_strlen_zero(get_header(req, "Contact"))) {
09661          char *contact = NULL;
09662          char *tmptmp = NULL;
09663          int start = 0;
09664          for(;;) {
09665             contact = __get_header(req, "Contact", &start);
09666             /* this loop ensures we get a contact header about our register request */
09667             if(!ast_strlen_zero(contact)) {
09668                if( (tmptmp=strstr(contact, p->our_contact))) {
09669                   contact=tmptmp;
09670                   break;
09671                }
09672             } else
09673                break;
09674          }
09675          tmptmp = strcasestr(contact, "expires=");
09676          if (tmptmp) {
09677             if (sscanf(tmptmp + 8, "%d;", &expires) != 1)
09678                expires = 0;
09679          }
09680 
09681       }
09682       if (!expires) 
09683          expires=atoi(get_header(req, "expires"));
09684       if (!expires)
09685          expires=default_expiry;
09686 
09687       expires_ms = expires * 1000;
09688       if (expires <= EXPIRY_GUARD_LIMIT)
09689          expires_ms -= MAX((expires_ms * EXPIRY_GUARD_PCT),EXPIRY_GUARD_MIN);
09690       else
09691          expires_ms -= EXPIRY_GUARD_SECS * 1000;
09692       if (sipdebug)
09693          ast_log(LOG_NOTICE, "Outbound Registration: Expiry for %s is %d sec (Scheduling reregistration in %d s)\n", r->hostname, expires, expires_ms/1000); 
09694 
09695       r->refresh= (int) expires_ms / 1000;
09696 
09697       /* Schedule re-registration before we expire */
09698       r->expire=ast_sched_add(sched, expires_ms, sip_reregister, r); 
09699       ASTOBJ_UNREF(r, sip_registry_destroy);
09700    }
09701    return 1;
09702 }

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

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

References AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_BUSY, AST_CAUSE_CALL_REJECTED, AST_CAUSE_CONGESTION, AST_CAUSE_DESTINATION_OUT_OF_ORDER, AST_CAUSE_FACILITY_REJECTED, AST_CAUSE_FAILURE, AST_CAUSE_NO_ANSWER, AST_CAUSE_NO_USER_RESPONSE, AST_CAUSE_NORMAL, and AST_CAUSE_UNALLOCATED.

Referenced by handle_response().

02283 {
02284 /* Possible values taken from causes.h */
02285 
02286    switch(cause) {
02287       case 603:   /* Declined */
02288       case 403:   /* Not found */
02289          return AST_CAUSE_CALL_REJECTED;
02290       case 404:   /* Not found */
02291          return AST_CAUSE_UNALLOCATED;
02292       case 408:   /* No reaction */
02293          return AST_CAUSE_NO_USER_RESPONSE;
02294       case 480:   /* No answer */
02295          return AST_CAUSE_FAILURE;
02296       case 483:   /* Too many hops */
02297          return AST_CAUSE_NO_ANSWER;
02298       case 486:   /* Busy everywhere */
02299          return AST_CAUSE_BUSY;
02300       case 488:   /* No codecs approved */
02301          return AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;
02302       case 500:   /* Server internal failure */
02303          return AST_CAUSE_FAILURE;
02304       case 501:   /* Call rejected */
02305          return AST_CAUSE_FACILITY_REJECTED;
02306       case 502:   
02307          return AST_CAUSE_DESTINATION_OUT_OF_ORDER;
02308       case 503:   /* Service unavailable */
02309          return AST_CAUSE_CONGESTION;
02310       default:
02311          return AST_CAUSE_NORMAL;
02312    }
02313    /* Never reached */
02314    return 0;
02315 }

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

init_req: Initialize SIP request ---

Definition at line 3965 of file chan_sip.c.

References ast_log(), sip_request::data, sip_request::header, sip_request::headers, sip_request::len, LOG_WARNING, sip_request::method, sip_methods, and cfsip_methods::text.

03966 {
03967    /* Initialize a response */
03968    if (req->headers || req->len) {
03969       ast_log(LOG_WARNING, "Request already initialized?!?\n");
03970       return -1;
03971    }
03972    req->header[req->headers] = req->data + req->len;
03973    snprintf(req->header[req->headers], sizeof(req->data) - req->len, "%s %s SIP/2.0\r\n", sip_methods[sipmethod].text, recip);
03974    req->len += strlen(req->header[req->headers]);
03975    req->headers++;
03976    req->method = sipmethod;
03977    return 0;
03978 }

static 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 3949 of file chan_sip.c.

References ast_log(), sip_request::data, sip_request::header, sip_request::headers, sip_request::len, LOG_WARNING, sip_request::method, and SIP_RESPONSE.

03950 {
03951    /* Initialize a response */
03952    if (req->headers || req->len) {
03953       ast_log(LOG_WARNING, "Request already initialized?!?\n");
03954       return -1;
03955    }
03956    req->method = SIP_RESPONSE;
03957    req->header[req->headers] = req->data + req->len;
03958    snprintf(req->header[req->headers], sizeof(req->data) - req->len, "SIP/2.0 %s\r\n", resp);
03959    req->len += strlen(req->header[req->headers]);
03960    req->headers++;
03961    return 0;
03962 }

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

initreqprep: Initiate new SIP request to peer/user ---

Definition at line 4723 of file chan_sip.c.

References AST_DIGIT_ANYNUM, ast_test_flag, n, SIP_USEREQPHONE, and sip_pvt::username.

Referenced by sip_notify(), transmit_invite(), and transmit_notify_with_mwi().

04724 {
04725    char invite_buf[256] = "";
04726    char *invite = invite_buf;
04727    size_t invite_max = sizeof(invite_buf);
04728    char from[256];
04729    char to[256];
04730    char tmp[BUFSIZ/2];
04731    char tmp2[BUFSIZ/2];
04732    char iabuf[INET_ADDRSTRLEN];
04733    char *l = NULL, *n = NULL;
04734    int x;
04735    char urioptions[256]="";
04736 
04737    if (ast_test_flag(p, SIP_USEREQPHONE)) {
04738       char onlydigits = 1;
04739       x=0;
04740 
04741       /* Test p->username against allowed characters in AST_DIGIT_ANY
04742       If it matches the allowed characters list, then sipuser = ";user=phone"
04743       If not, then sipuser = ""
04744          */
04745          /* + is allowed in first position in a tel: uri */
04746          if (p->username && p->username[0] == '+')
04747          x=1;
04748 
04749       for (; x < strlen(p->username); x++) {
04750          if (!strchr(AST_DIGIT_ANYNUM, p->username[x])) {
04751                      onlydigits = 0;
04752             break;
04753          }
04754       }
04755 
04756       /* If we have only digits, add ;user=phone to the uri */
04757       if (onlydigits)
04758          strcpy(urioptions, ";user=phone");
04759    }
04760 
04761 
04762    snprintf(p->lastmsg, sizeof(p->lastmsg), "Init: %s", sip_methods[sipmethod].text);
04763 
04764    if (p->owner) {
04765       l = p->owner->cid.cid_num;
04766       n = p->owner->cid.cid_name;
04767    }
04768    /* if we are not sending RPID and user wants his callerid restricted */
04769    if (!ast_test_flag(p, SIP_SENDRPID) && ((p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED)) {
04770       l = CALLERID_UNKNOWN;
04771       n = l;
04772    }
04773    if (!l)
04774       l = default_callerid;
04775    if (ast_strlen_zero(n))
04776       n = l;
04777    /* Allow user to be overridden */
04778    if (!ast_strlen_zero(p->fromuser))
04779       l = p->fromuser;
04780    else /* Save for any further attempts */
04781       ast_copy_string(p->fromuser, l, sizeof(p->fromuser));
04782 
04783    /* Allow user to be overridden */
04784    if (!ast_strlen_zero(p->fromname))
04785       n = p->fromname;
04786    else /* Save for any further attempts */
04787       ast_copy_string(p->fromname, n, sizeof(p->fromname));
04788 
04789    if (pedanticsipchecking) {
04790       ast_uri_encode(n, tmp, sizeof(tmp), 0);
04791       n = tmp;
04792       ast_uri_encode(l, tmp2, sizeof(tmp2), 0);
04793       l = tmp2;
04794    }
04795 
04796    if ((ourport != 5060) && ast_strlen_zero(p->fromdomain)) /* Needs to be 5060 */
04797       snprintf(from, sizeof(from), "\"%s\" <sip:%s@%s:%d>;tag=%s", n, l, ast_strlen_zero(p->fromdomain) ? ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip) : p->fromdomain, ourport, p->tag);
04798    else
04799       snprintf(from, sizeof(from), "\"%s\" <sip:%s@%s>;tag=%s", n, l, ast_strlen_zero(p->fromdomain) ? ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip) : p->fromdomain, p->tag);
04800 
04801    /* If we're calling a registered SIP peer, use the fullcontact to dial to the peer */
04802    if (!ast_strlen_zero(p->fullcontact)) {
04803       /* If we have full contact, trust it */
04804       ast_build_string(&invite, &invite_max, "%s", p->fullcontact);
04805    } else {
04806       /* Otherwise, use the username while waiting for registration */
04807       ast_build_string(&invite, &invite_max, "sip:");
04808       if (!ast_strlen_zero(p->username)) {
04809          n = p->username;
04810          if (pedanticsipchecking) {
04811             ast_uri_encode(n, tmp, sizeof(tmp), 0);
04812             n = tmp;
04813          }
04814          ast_build_string(&invite, &invite_max, "%s@", n);
04815       }
04816       ast_build_string(&invite, &invite_max, "%s", p->tohost);
04817       if (ntohs(p->sa.sin_port) != 5060)     /* Needs to be 5060 */
04818          ast_build_string(&invite, &invite_max, ":%d", ntohs(p->sa.sin_port));
04819       ast_build_string(&invite, &invite_max, "%s", urioptions);
04820    }
04821 
04822    /* If custom URI options have been provided, append them */
04823    if (p->options && p->options->uri_options)
04824       ast_build_string(&invite, &invite_max, ";%s", p->options->uri_options);
04825 
04826    ast_copy_string(p->uri, invite_buf, sizeof(p->uri));
04827 
04828    if (sipmethod == SIP_NOTIFY && !ast_strlen_zero(p->theirtag)) { 
04829       /* If this is a NOTIFY, use the From: tag in the subscribe (RFC 3265) */
04830       snprintf(to, sizeof(to), "<sip:%s>;tag=%s", p->uri, p->theirtag);
04831    } else if (p->options && p->options->vxml_url) {
04832       /* If there is a VXML URL append it to the SIP URL */
04833       snprintf(to, sizeof(to), "<%s>;%s", p->uri, p->options->vxml_url);
04834    } else {
04835       snprintf(to, sizeof(to), "<%s>", p->uri);
04836    }
04837    
04838    memset(req, 0, sizeof(struct sip_request));
04839    init_req(req, sipmethod, p->uri);
04840    snprintf(tmp, sizeof(tmp), "%d %s", ++p->ocseq, sip_methods[sipmethod].text);
04841 
04842    add_header(req, "Via", p->via);
04843    /* SLD: FIXME?: do Route: here too?  I think not cos this is the first request.
04844     * OTOH, then we won't have anything in p->route anyway */
04845    /* Build Remote Party-ID and From */
04846    if (ast_test_flag(p, SIP_SENDRPID) && (sipmethod == SIP_INVITE)) {
04847       build_rpid(p);
04848       add_header(req, "From", p->rpid_from);
04849    } else {
04850       add_header(req, "From", from);
04851    }
04852    add_header(req, "To", to);
04853    ast_copy_string(p->exten, l, sizeof(p->exten));
04854    build_contact(p);
04855    add_header(req, "Contact", p->our_contact);
04856    add_header(req, "Call-ID", p->callid);
04857    add_header(req, "CSeq", tmp);
04858    add_header(req, "User-Agent", default_useragent);
04859    add_header(req, "Max-Forwards", DEFAULT_MAX_FORWARDS);
04860    if (p->rpid)
04861       add_header(req, "Remote-Party-ID", p->rpid);
04862 }

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

insecure2str: Convert Insecure setting to printable string ---

Definition at line 7633 of file chan_sip.c.

Referenced by _sip_show_peer().

07634 {
07635    if (port && invite)
07636       return "port,invite";
07637    else if (port)
07638       return "port";
07639    else if (invite)
07640       return "invite";
07641    else
07642       return "no";
07643 }

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 13274 of file chan_sip.c.

References ASTERISK_GPL_KEY.

13275 {
13276    return ASTERISK_GPL_KEY;
13277 }

static void list_route struct sip_route route  )  [static]
 

list_route: List all routes - mostly for debugging ---

Definition at line 5968 of file chan_sip.c.

References ast_verbose(), sip_route::hop, and sip_route::next.

05969 {
05970    if (!route) {
05971       ast_verbose("list_route: no route\n");
05972       return;
05973    }
05974    while (route) {
05975       ast_verbose("list_route: hop: <%s>\n", route->hop);
05976       route = route->next;
05977    }
05978 }

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 13122 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(), my_clis, peerl, regl, reload_config(), restart_monitor(), 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.

13123 {
13124    ASTOBJ_CONTAINER_INIT(&userl);   /* User object list */
13125    ASTOBJ_CONTAINER_INIT(&peerl);   /* Peer object list */
13126    ASTOBJ_CONTAINER_INIT(&regl); /* Registry object list */
13127 
13128    sched = sched_context_create();
13129    if (!sched) {
13130       ast_log(LOG_WARNING, "Unable to create schedule context\n");
13131    }
13132 
13133    io = io_context_create();
13134    if (!io) {
13135       ast_log(LOG_WARNING, "Unable to create I/O context\n");
13136    }
13137 
13138    reload_config();  /* Load the configuration from sip.conf */
13139 
13140    /* Make sure we can register our sip channel type */
13141    if (ast_channel_register(&sip_tech)) {
13142       ast_log(LOG_ERROR, "Unable to register channel type %s\n", channeltype);
13143       return -1;
13144    }
13145 
13146    /* Register all CLI functions for SIP */
13147    ast_cli_register_multiple(my_clis, sizeof(my_clis)/ sizeof(my_clis[0]));
13148 
13149    /* Tell the RTP subdriver that we're here */
13150    ast_rtp_proto_register(&sip_rtp);
13151 
13152    /* Register dialplan applications */
13153    ast_register_application(app_dtmfmode, sip_dtmfmode, synopsis_dtmfmode, descrip_dtmfmode);
13154 
13155    /* These will be removed soon */
13156    ast_register_application(app_sipaddheader, sip_addheader, synopsis_sipaddheader, descrip_sipaddheader);
13157    ast_register_application(app_sipgetheader, sip_getheader, synopsis_sipgetheader, descrip_sipgetheader);
13158 
13159    /* Register dialplan functions */
13160    ast_custom_function_register(&sip_header_function);
13161    ast_custom_function_register(&sippeer_function);
13162    ast_custom_function_register(&sipchaninfo_function);
13163    ast_custom_function_register(&checksipdomain_function);
13164 
13165    /* Register manager commands */
13166    ast_manager_register2("SIPpeers", EVENT_FLAG_SYSTEM, manager_sip_show_peers,
13167          "List SIP peers (text format)", mandescr_show_peers);
13168    ast_manager_register2("SIPshowpeer", EVENT_FLAG_SYSTEM, manager_sip_show_peer,
13169          "Show SIP peer (text format)", mandescr_show_peer);
13170 
13171    sip_poke_all_peers();   
13172    sip_send_all_registers();
13173    
13174    /* And start the monitor for the first time */
13175    restart_monitor();
13176 
13177    return 0;
13178 }

static int lws2sws char *  msgbuf,
int  len
[static]
 

lws2sws: Parse multiline SIP headers into one header

Definition at line 3276 of file chan_sip.c.

References t.

Referenced by sipsock_read().

03277 { 
03278    int h = 0, t = 0; 
03279    int lws = 0; 
03280 
03281    for (; h < len;) { 
03282       /* Eliminate all CRs */ 
03283       if (msgbuf[h] == '\r') { 
03284          h++; 
03285          continue; 
03286       } 
03287       /* Check for end-of-line */ 
03288       if (msgbuf[h] == '\n') { 
03289          /* Check for end-of-message */ 
03290          if (h + 1 == len) 
03291             break; 
03292          /* Check for a continuation line */ 
03293          if (msgbuf[h + 1] == ' ' || msgbuf[h + 1] == '\t') { 
03294             /* Merge continuation line */ 
03295             h++; 
03296             continue; 
03297          } 
03298          /* Propagate LF and start new line */ 
03299          msgbuf[t++] = msgbuf[h++]; 
03300          lws = 0;
03301          continue; 
03302       } 
03303       if (msgbuf[h] == ' ' || msgbuf[h] == '\t') { 
03304          if (lws) { 
03305             h++; 
03306             continue; 
03307          } 
03308          msgbuf[t++] = msgbuf[h++]; 
03309          lws = 1; 
03310          continue; 
03311       } 
03312       msgbuf[t++] = msgbuf[h++]; 
03313       if (lws) 
03314          lws = 0; 
03315    } 
03316    msgbuf[t] = '\0'; 
03317    return t; 
03318 }

static void make_our_tag char *  tagbuf,
size_t  len
[static]
 

Definition at line 3028 of file chan_sip.c.

References thread_safe_rand().

Referenced by handle_request_invite(), handle_request_subscribe(), sip_alloc(), and transmit_register().

03029 {
03030    snprintf(tagbuf, len, "as%08x", thread_safe_rand());
03031 }

static 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 7853 of file chan_sip.c.

References _sip_show_peer(), ast_cli(), ast_strlen_zero(), astman_get_header(), astman_send_error(), and s.

Referenced by load_module().

07854 {
07855    char *id = astman_get_header(m,"ActionID");
07856    char *a[4];
07857    char *peer;
07858    int ret;
07859 
07860    peer = astman_get_header(m,"Peer");
07861    if (ast_strlen_zero(peer)) {
07862       astman_send_error(s, m, "Peer: <name> missing.\n");
07863       return 0;
07864    }
07865    a[0] = "sip";
07866    a[1] = "show";
07867    a[2] = "peer";
07868    a[3] = peer;
07869 
07870    if (!ast_strlen_zero(id))
07871       ast_cli(s->fd, "ActionID: %s\r\n",id);
07872    ret = _sip_show_peer(1, s->fd, s, m, 4, a );
07873    ast_cli( s->fd, "\r\n\r\n" );
07874    return ret;
07875 }

static 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 7434 of file chan_sip.c.

References _sip_show_peers(), ast_cli(), ast_strlen_zero(), astman_get_header(), astman_send_ack(), s, and total.

Referenced by load_module().

07435 {
07436    char *id = astman_get_header(m,"ActionID");
07437    char *a[] = { "sip", "show", "peers" };
07438    char idtext[256] = "";
07439    int total = 0;
07440 
07441    if (!ast_strlen_zero(id))
07442       snprintf(idtext,256,"ActionID: %s\r\n",id);
07443 
07444    astman_send_ack(s, m, "Peer status list will follow");
07445    /* List the peers in separate manager events */
07446    _sip_show_peers(s->fd, &total, s, m, 3, a);
07447    /* Send final confirmation */
07448    ast_cli(s->fd,
07449    "Event: PeerlistComplete\r\n"
07450    "ListItems: %d\r\n"
07451    "%s"
07452    "\r\n", total, idtext);
07453    return 0;
07454 }

static char* nat2str int  nat  )  [static]
 

nat2str: Convert NAT setting to text string

Definition at line 7336 of file chan_sip.c.

References SIP_NAT_ALWAYS, SIP_NAT_NEVER, SIP_NAT_RFC3581, and SIP_NAT_ROUTE.

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

07337 {
07338    switch(nat) {
07339    case SIP_NAT_NEVER:
07340       return "No";
07341    case SIP_NAT_ROUTE:
07342       return "Route";
07343    case SIP_NAT_ALWAYS:
07344       return "Always";
07345    case SIP_NAT_RFC3581:
07346       return "RFC3581";
07347    default:
07348       return "Unknown";
07349    }
07350 }

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

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

parse_moved_contact: Parse 302 Moved temporalily response

Definition at line 9400 of file chan_sip.c.

References ast_log(), ast_test_flag, ast_channel::call_forward, get_header(), get_in_brackets(), LOG_DEBUG, sip_pvt::owner, s, and SIP_PROMISCREDIR.

Referenced by handle_response().

09401 {
09402    char tmp[256];
09403    char *s, *e;
09404    ast_copy_string(tmp, get_header(req, "Contact"), sizeof(tmp));
09405    s = get_in_brackets(tmp);
09406    e = strchr(s, ';');
09407    if (e)
09408       *e = '\0';
09409    if (ast_test_flag(p, SIP_PROMISCREDIR)) {
09410       if (!strncasecmp(s, "sip:", 4))
09411          s += 4;
09412       e = strchr(s, '/');
09413       if (e)
09414          *e = '\0';
09415       ast_log(LOG_DEBUG, "Found promiscuous redirection to 'SIP/%s'\n", s);
09416       if (p->owner)
09417          snprintf(p->owner->call_forward, sizeof(p->owner->call_forward), "SIP/%s", s);
09418    } else {
09419       e = strchr(tmp, '@');
09420       if (e)
09421          *e = '\0';
09422       e = strchr(tmp, '/');
09423       if (e)
09424          *e = '\0';
09425       if (!strncasecmp(s, "sip:", 4))
09426          s += 4;
09427       ast_log(LOG_DEBUG, "Found 302 Redirect to extension '%s'\n", s);
09428       if (p->owner)
09429          ast_copy_string(p->owner->call_forward, s, sizeof(p->owner->call_forward));
09430    }
09431 }

static 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 5729 of file chan_sip.c.

References ahp, ast_gethostbyname(), ast_log(), ast_test_flag, DEFAULT_SIP_PORT, sip_pvt::fullcontact, get_header(), get_in_brackets(), hp, LOG_NOTICE, LOG_WARNING, sip_pvt::okcontacturi, sip_pvt::recv, sip_pvt::sa, SIP_NAT, and SIP_NAT_ROUTE.

Referenced by handle_response_invite().

05730 {
05731    char contact[250]; 
05732    char *c, *n, *pt;
05733    int port;
05734    struct hostent *hp;
05735    struct ast_hostent ahp;
05736    struct sockaddr_in oldsin;
05737 
05738    /* Look for brackets */
05739    ast_copy_string(contact, get_header(req, "Contact"), sizeof(contact));
05740    c = get_in_brackets(contact);
05741 
05742    /* Save full contact to call pvt for later bye or re-invite */
05743    ast_copy_string(pvt->fullcontact, c, sizeof(pvt->fullcontact));   
05744 
05745    /* Save URI for later ACKs, BYE or RE-invites */
05746    ast_copy_string(pvt->okcontacturi, c, sizeof(pvt->okcontacturi));
05747    
05748    /* Make sure it's a SIP URL */
05749    if (strncasecmp(c, "sip:", 4)) {
05750       ast_log(LOG_NOTICE, "'%s' is not a valid SIP contact (missing sip:) trying to use anyway\n", c);
05751    } else
05752       c += 4;
05753 
05754    /* Ditch arguments */
05755    n = strchr(c, ';');
05756    if (n) 
05757       *n = '\0';
05758 
05759    /* Grab host */
05760    n = strchr(c, '@');
05761    if (!n) {
05762       n = c;
05763       c = NULL;
05764    } else {
05765       *n = '\0';
05766       n++;
05767    }
05768    pt = strchr(n, ':');
05769    if (pt) {
05770       *pt = '\0';
05771       pt++;
05772       port = atoi(pt);
05773    } else
05774       port = DEFAULT_SIP_PORT;
05775 
05776    memcpy(&oldsin, &pvt->sa, sizeof(oldsin));
05777 
05778    if (!(ast_test_flag(pvt, SIP_NAT) & SIP_NAT_ROUTE)) {
05779       /* XXX This could block for a long time XXX */
05780       /* We should only do this if it's a name, not an IP */
05781       hp = ast_gethostbyname(n, &ahp);
05782       if (!hp)  {
05783          ast_log(LOG_WARNING, "Invalid host '%s'\n", n);
05784          return -1;
05785       }
05786       pvt->sa.sin_family = AF_INET;
05787       memcpy(&pvt->sa.sin_addr, hp->h_addr, sizeof(pvt->sa.sin_addr));
05788       pvt->sa.sin_port = htons(port);
05789    } else {
05790       /* Don't trust the contact field.  Just use what they came to us
05791          with. */
05792       memcpy(&pvt->sa, &pvt->recv, sizeof(pvt->sa));
05793    }
05794    return 0;
05795 }

static 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 5805 of file chan_sip.c.

References sip_peer::addr, ahp, ast_db_put(), ast_gethostbyname(), ast_inet_ntoa(), ast_log(), ast_sched_add(), ast_sched_del(), ast_sched_when(), ast_strlen_zero(), ast_test_flag, ast_verbose(), default_expiry, DEFAULT_SIP_PORT, destroy_association(), EVENT_FLAG_SYSTEM, sip_peer::expire, expire_register(), sip_pvt::expiry, expiry, sip_peer::flags_page2, sip_peer::fullcontact, get_header(), get_in_brackets(), hp, inaddrcmp(), sip_peer::lastms, LOG_NOTICE, LOG_WARNING, manager_event(), max_expiry, option_verbose, sip_pvt::our_contact, PARSE_REGISTER_FAILED, PARSE_REGISTER_QUERY, PARSE_REGISTER_UPDATE, sip_pvt::recv, register_peer_exten(), SIP_NAT, SIP_NAT_ROUTE, SIP_PAGE2_RT_FROMCONTACT, sip_poke_peer(), SIP_REALTIME, sip_pvt::sipoptions, sip_peer::sipoptions, strcasestr(), sip_peer::useragent, sip_peer::username, and VERBOSE_PREFIX_3.

Referenced by register_verify().

05806 {
05807    char contact[80]; 
05808    char data[256];
05809    char iabuf[INET_ADDRSTRLEN];
05810    char *expires = get_header(req, "Expires");
05811    int expiry = atoi(expires);
05812    char *c, *n, *pt;
05813    int port;
05814    char *useragent;
05815    struct hostent *hp;
05816    struct ast_hostent ahp;
05817    struct sockaddr_in oldsin;
05818 
05819    if (ast_strlen_zero(expires)) {  /* No expires header */
05820       expires = strcasestr(get_header(req, "Contact"), ";expires=");
05821       if (expires) {
05822          char *ptr;
05823          if ((ptr = strchr(expires, ';')))
05824             *ptr = '\0';
05825          if (sscanf(expires + 9, "%d", &expiry) != 1)
05826             expiry = default_expiry;
05827       } else {
05828          /* Nothing has been specified */
05829          expiry = default_expiry;
05830       }
05831    }
05832    /* Look for brackets */
05833    ast_copy_string(contact, get_header(req, "Contact"), sizeof(contact));
05834    if (strchr(contact, '<') == NULL) { /* No <, check for ; and strip it */
05835       char *ptr = strchr(contact, ';');   /* This is Header options, not URI options */
05836       if (ptr)
05837          *ptr = '\0';
05838    }
05839    c = get_in_brackets(contact);
05840 
05841    /* if they did not specify Contact: or Expires:, they are querying
05842       what we currently have stored as their contact address, so return
05843       it
05844    */
05845    if (ast_strlen_zero(c) && ast_strlen_zero(expires)) {
05846       /* If we have an active registration, tell them when the registration is going to expire */
05847       if ((p->expire > -1) && !ast_strlen_zero(p->fullcontact)) {
05848          pvt->expiry = ast_sched_when(sched, p->expire);
05849       } 
05850       return PARSE_REGISTER_QUERY;
05851    } else if (!strcasecmp(c, "*") || !expiry) { /* Unregister this peer */
05852       /* This means remove all registrations and return OK */
05853       memset(&p->addr, 0, sizeof(p->addr));
05854       if (p->expire > -1)
05855          ast_sched_del(sched, p->expire);
05856       p->expire = -1;
05857 
05858       destroy_association(p);
05859       
05860       register_peer_exten(p, 0);
05861       p->fullcontact[0] = '\0';
05862       p->useragent[0] = '\0';
05863       p->sipoptions = 0;
05864       p->lastms = 0;
05865 
05866       if (option_verbose > 2)
05867          ast_verbose(VERBOSE_PREFIX_3 "Unregistered SIP '%s'\n", p->name);
05868          manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unregistered\r\n", p->name);
05869       return PARSE_REGISTER_UPDATE;
05870    }
05871    ast_copy_string(p->fullcontact, c, sizeof(p->fullcontact));
05872    /* For the 200 OK, we should use the received contact */
05873    snprintf(pvt->our_contact, sizeof(pvt->our_contact) - 1, "<%s>", c);
05874    /* Make sure it's a SIP URL */
05875    if (strncasecmp(c, "sip:", 4)) {
05876       ast_log(LOG_NOTICE, "'%s' is not a valid SIP contact (missing sip:) trying to use anyway\n", c);
05877    } else
05878       c += 4;
05879    /* Ditch q */
05880    n = strchr(c, ';');
05881    if (n) {
05882       *n = '\0';
05883    }
05884    /* Grab host */
05885    n = strchr(c, '@');
05886    if (!n) {
05887       n = c;
05888       c = NULL;
05889    } else {
05890       *n = '\0';
05891       n++;
05892    }
05893    pt = strchr(n, ':');
05894    if (pt) {
05895       *pt = '\0';
05896       pt++;
05897       port = atoi(pt);
05898    } else
05899       port = DEFAULT_SIP_PORT;
05900    memcpy(&oldsin, &p->addr, sizeof(oldsin));
05901    if (!(ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE)) {
05902       /* XXX This could block for a long time XXX */
05903       hp = ast_gethostbyname(n, &ahp);
05904       if (!hp)  {
05905          ast_log(LOG_WARNING, "Invalid host '%s'\n", n);
05906          return PARSE_REGISTER_FAILED;
05907       }
05908       p->addr.sin_family = AF_INET;
05909       memcpy(&p->addr.sin_addr, hp->h_addr, sizeof(p->addr.sin_addr));
05910       p->addr.sin_port = htons(port);
05911    } else {
05912       /* Don't trust the contact field.  Just use what they came to us
05913          with */
05914       memcpy(&p->addr, &pvt->recv, sizeof(p->addr));
05915    }
05916 
05917    if (c)   /* Overwrite the default username from config at registration */
05918       ast_copy_string(p->username, c, sizeof(p->username));
05919    else
05920       p->username[0] = '\0';
05921 
05922    if (p->expire > -1)
05923       ast_sched_del(sched, p->expire);
05924    if ((expiry < 1) || (expiry > max_expiry))
05925       expiry = max_expiry;
05926    if (!ast_test_flag(p, SIP_REALTIME))
05927       p->expire = ast_sched_add(sched, (expiry + 10) * 1000, expire_register, p);
05928    else
05929       p->expire = -1;
05930    pvt->expiry = expiry;
05931    snprintf(data, sizeof(data), "%s:%d:%d:%s:%s", ast_inet_ntoa(iabuf, sizeof(iabuf), p->addr.sin_addr), ntohs(p->addr.sin_port), expiry, p->username, p->fullcontact);
05932    if (!ast_test_flag((&p->flags_page2), SIP_PAGE2_RT_FROMCONTACT)) 
05933       ast_db_put("SIP/Registry", p->name, data);
05934    manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Registered\r\n", p->name);
05935    if (inaddrcmp(&p->addr, &oldsin)) {
05936       sip_poke_peer(p);
05937       if (option_verbose > 2)
05938          ast_verbose(VERBOSE_PREFIX_3 "Registered SIP '%s' at %s port %d expires %d\n", p->name, ast_inet_ntoa(iabuf, sizeof(iabuf), p->addr.sin_addr), ntohs(p->addr.sin_port), expiry);
05939       register_peer_exten(p, 1);
05940    }
05941    
05942    /* Save SIP options profile */
05943    p->sipoptions = pvt->sipoptions;
05944 
05945    /* Save User agent */
05946    useragent = get_header(req, "User-Agent");
05947    if (useragent && strcasecmp(useragent, p->useragent)) {
05948       ast_copy_string(p->useragent, useragent, sizeof(p->useragent));
05949       if (option_verbose > 3) {
05950          ast_verbose(VERBOSE_PREFIX_3 "Saved useragent \"%s\" for peer %s\n",p->useragent,p->name);  
05951       }
05952    }
05953    return PARSE_REGISTER_UPDATE;
05954 }

static void parse_request struct sip_request req  )  [static]
 

parse_request: Parse a SIP message ----

Definition at line 3321 of file chan_sip.c.

References ast_log(), ast_strlen_zero(), sip_request::data, determine_firstline_parts(), sip_request::header, sip_request::headers, sip_request::line, sip_request::lines, LOG_DEBUG, LOG_WARNING, option_debug, SIP_MAX_HEADERS, SIP_MAX_LINES, and sipdebug.

Referenced by parse_copy(), sipsock_read(), transmit_invite(), transmit_notify_with_mwi(), transmit_notify_with_sipfrag(), transmit_register(), transmit_reinvite_with_sdp(), and transmit_sip_request().

03322 {
03323    /* Divide fields by NULL's */
03324    char *c;
03325    int f = 0;
03326 
03327    c = req->data;
03328 
03329    /* First header starts immediately */
03330    req->header[f] = c;
03331    while(*c) {
03332       if (*c == '\n') {
03333          /* We've got a new header */
03334          *c = 0;
03335 
03336          if (sipdebug && option_debug > 3)
03337             ast_log(LOG_DEBUG, "Header %d: %s (%d)\n", f, req->header[f], (int) strlen(req->header[f]));
03338          if (ast_strlen_zero(req->header[f])) {
03339             /* Line by itself means we're now in content */
03340             c++;
03341             break;
03342          }
03343          if (f >= SIP_MAX_HEADERS - 1) {
03344             ast_log(LOG_WARNING, "Too many SIP headers. Ignoring.\n");
03345          } else
03346             f++;
03347          req->header[f] = c + 1;
03348       } else if (*c == '\r') {
03349          /* Ignore but eliminate \r's */
03350          *c = 0;
03351       }
03352       c++;
03353    }
03354    /* Check for last header */
03355    if (!ast_strlen_zero(req->header[f])) {
03356       if (sipdebug && option_debug > 3)
03357          ast_log(LOG_DEBUG, "Header %d: %s (%d)\n", f, req->header[f], (int) strlen(req->header[f]));
03358       f++;
03359    }
03360    req->headers = f;
03361    /* Now we process any mime content */
03362    f = 0;
03363    req->line[f] = c;
03364    while(*c) {
03365       if (*c == '\n') {
03366          /* We've got a new line */
03367          *c = 0;
03368          if (sipdebug && option_debug > 3)
03369             ast_log(LOG_DEBUG, "Line: %s (%d)\n", req->line[f], (int) strlen(req->line[f]));
03370          if (f >= SIP_MAX_LINES - 1) {
03371             ast_log(LOG_WARNING, "Too many SDP lines. Ignoring.\n");
03372          } else
03373             f++;
03374          req->line[f] = c + 1;
03375       } else if (*c == '\r') {
03376          /* Ignore and eliminate \r's */
03377          *c = 0;
03378       }
03379       c++;
03380    }
03381    /* Check for last line */
03382    if (!ast_strlen_zero(req->line[f])) 
03383       f++;
03384    req->lines = f;
03385    if (*c) 
03386       ast_log(LOG_WARNING, "Odd content, extra stuff left over ('%s')\n", c);
03387    /* Split up the first line parts */
03388    determine_firstline_parts(req);
03389 }

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(), LOG_DEBUG, option_debug, sip_options, and text.

Referenced by handle_request_invite().

00986 {
00987    char *next = NULL;
00988    char *sep = NULL;
00989    char *temp = ast_strdupa(supported);
00990    int i;
00991    unsigned int profile = 0;
00992 
00993    if (ast_strlen_zero(supported) )
00994       return 0;
00995 
00996    if (option_debug > 2 && sipdebug)
00997       ast_log(LOG_DEBUG, "Begin: parsing SIP \"Supported: %s\"\n", supported);
00998 
00999    next = temp;
01000    while (next) {
01001       char res=0;
01002       if ( (sep = strchr(next, ',')) != NULL) {
01003          *sep = '\0';
01004          sep++;
01005       }
01006       while (*next == ' ') /* Skip spaces */
01007          next++;
01008       if (option_debug > 2 && sipdebug)
01009          ast_log(LOG_DEBUG, "Found SIP option: -%s-\n", next);
01010       for (i=0; (i < (sizeof(sip_options) / sizeof(sip_options[0]))) && !res; i++) {
01011          if (!strcasecmp(next, sip_options[i].text)) {
01012             profile |= sip_options[i].id;
01013             res = 1;
01014             if (option_debug > 2 && sipdebug)
01015                ast_log(LOG_DEBUG, "Matched SIP option: %s\n", next);
01016          }
01017       }
01018       if (!res) 
01019          if (option_debug > 2 && sipdebug)
01020             ast_log(LOG_DEBUG, "Found no match for SIP option: %s (Please file bug report!)\n", next);
01021       next = sep;
01022    }
01023    if (pvt) {
01024       pvt->sipoptions = profile;
01025       if (option_debug)
01026          ast_log(LOG_DEBUG, "* SIP extension value: %d for call %s\n", profile, pvt->callid);
01027    }
01028    return profile;
01029 }

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

peer_status: Report Peer status in character string

Definition at line 7354 of file chan_sip.c.

References sip_peer::lastms, and sip_peer::maxms.

07355 {
07356    int res = 0;
07357    if (peer->maxms) {
07358       if (peer->lastms < 0) {
07359          ast_copy_string(status, "UNREACHABLE", statuslen);
07360       } else if (peer->lastms > peer->maxms) {
07361          snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms);
07362          res = 1;
07363       } else if (peer->lastms) {
07364          snprintf(status, statuslen, "OK (%d ms)", peer->lastms);
07365          res = 1;
07366       } else {
07367          ast_copy_string(status, "UNKNOWN", statuslen);
07368       }
07369    } else { 
07370       ast_copy_string(status, "Unmonitored", statuslen);
07371       /* Checking if port is 0 */
07372       res = -1;
07373    }
07374    return res;
07375 }

static 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 7793 of file chan_sip.c.

References ast_cli(), ast_codec_pref_index(), and ast_getformatname().

Referenced by _sip_show_peer(), and sip_show_settings().

07794 {
07795    int x, codec;
07796 
07797    for(x = 0; x < 32 ; x++) {
07798       codec = ast_codec_pref_index(pref, x);
07799       if (!codec)
07800          break;
07801       ast_cli(fd, "%s", ast_getformatname(codec));
07802       if (x < 31 && ast_codec_pref_index(pref, x + 1))
07803          ast_cli(fd, ",");
07804    }
07805    if (!x)
07806       ast_cli(fd, "none");
07807 }

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

print_group: Print call group and pickup group ---

Definition at line 7610 of file chan_sip.c.

References ast_cli(), and ast_print_group().

Referenced by _sip_show_peer(), and sip_show_user().

07611 {
07612    char buf[256];
07613    ast_cli(fd, crlf ? "%s\r\n" : "%s\n", ast_print_group(buf, sizeof(buf), group) );
07614 }

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

process_sdp: Process SIP SDP and activate RTP channels---

Definition at line 3392 of file chan_sip.c.

References ahp, append_history(), ast_bridged_channel(), ast_clear_flag, ast_codec_choose(), AST_FRAME_NULL, ast_getformatname_multiple(), ast_gethostbyname(), ast_inet_ntoa(), ast_log(), ast_moh_start(), ast_moh_stop(), ast_queue_frame(), AST_RTP_DTMF, ast_rtp_get_current_formats(), ast_rtp_lookup_mime_multiple(), ast_rtp_pt_clear(), ast_rtp_set_m_type(), ast_rtp_set_peer(), ast_rtp_set_rtpmap_type(), ast_rtp_stop(), ast_set_flag, ast_set_read_format(), ast_set_write_format(), ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_verbose(), callevents, sip_pvt::capability, sip_request::data, debug, EVENT_FLAG_CALL, get_header(), get_sdp(), get_sdp_iterate(), host, hp, sip_pvt::jointcapability, sip_pvt::lastrtprx, sip_pvt::lastrtptx, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, LOG_WARNING, manager_event(), ast_channel::name, ast_channel::nativeformats, noncodeccapability, sip_pvt::noncodeccapability, sip_pvt::owner, pedanticsipchecking, sip_pvt::peercapability, portno, sip_pvt::prefs, ast_channel::readformat, sip_pvt::rtp, sdpLineNum_iterator_init(), SIP_CALL_ONHOLD, sip_debug_test_pvt(), SIP_DTMF, SIP_DTMF_AUTO, SIP_DTMF_INBAND, SIP_DTMF_RFC2833, SIP_NOVIDEO, ast_channel::uniqueid, sip_pvt::vrtp, and ast_channel::writeformat.

03393 {
03394    char *m;
03395    char *c;
03396    char *a;
03397    char host[258];
03398    char iabuf[INET_ADDRSTRLEN];
03399    int len = -1;
03400    int portno = -1;
03401    int vportno = -1;
03402    int peercapability, peernoncodeccapability;
03403    int vpeercapability=0, vpeernoncodeccapability=0;
03404    struct sockaddr_in sin;
03405    char *codecs;
03406    struct hostent *hp;
03407    struct ast_hostent ahp;
03408    int codec;
03409    int destiterator = 0;
03410    int iterator;
03411    int sendonly = 0;
03412    int x,y;
03413    int debug=sip_debug_test_pvt(p);
03414    struct ast_channel *bridgepeer = NULL;
03415 
03416    if (!p->rtp) {
03417       ast_log(LOG_ERROR, "Got SDP but have no RTP session allocated.\n");
03418       return -1;
03419    }
03420 
03421    /* Update our last rtprx when we receive an SDP, too */
03422    time(&p->lastrtprx);
03423    time(&p->lastrtptx);
03424 
03425    /* Get codec and RTP info from SDP */
03426    if (strcasecmp(get_header(req, "Content-Type"), "application/sdp")) {
03427       ast_log(LOG_NOTICE, "Content is '%s', not 'application/sdp'\n", get_header(req, "Content-Type"));
03428       return -1;
03429    }
03430    m = get_sdp(req, "m");
03431    sdpLineNum_iterator_init(&destiterator);
03432    c = get_sdp_iterate(&destiterator, req, "c");
03433    if (ast_strlen_zero(m) || ast_strlen_zero(c)) {
03434       ast_log(LOG_WARNING, "Insufficient information for SDP (m = '%s', c = '%s')\n", m, c);
03435       return -1;
03436    }
03437    if (sscanf(c, "IN IP4 %256s", host) != 1) {
03438       ast_log(LOG_WARNING, "Invalid host in c= line, '%s'\n", c);
03439       return -1;
03440    }
03441    /* XXX This could block for a long time, and block the main thread! XXX */
03442    hp = ast_gethostbyname(host, &ahp);
03443    if (!hp) {
03444       ast_log(LOG_WARNING, "Unable to lookup host in c= line, '%s'\n", c);
03445       return -1;
03446    }
03447    sdpLineNum_iterator_init(&iterator);
03448    ast_set_flag(p, SIP_NOVIDEO); 
03449    while ((m = get_sdp_iterate(&iterator, req, "m"))[0] != '\0') {
03450       int found = 0;
03451       if ((sscanf(m, "audio %d/%d RTP/AVP %n", &x, &y, &len) == 2) ||
03452           (sscanf(m, "audio %d RTP/AVP %n", &x, &len) == 1)) {
03453          found = 1;
03454          portno = x;
03455          /* Scan through the RTP payload types specified in a "m=" line: */
03456          ast_rtp_pt_clear(p->rtp);
03457          codecs = m + len;
03458          while(!ast_strlen_zero(codecs)) {
03459             if (sscanf(codecs, "%d%n", &codec, &len) != 1) {
03460                ast_log(LOG_WARNING, "Error in codec string '%s'\n", codecs);
03461                return -1;
03462             }
03463             if (debug)
03464                ast_verbose("Found RTP audio format %d\n", codec);
03465             ast_rtp_set_m_type(p->rtp, codec);
03466             codecs = ast_skip_blanks(codecs + len);
03467          }
03468       }
03469       if (p->vrtp)
03470          ast_rtp_pt_clear(p->vrtp);  /* Must be cleared in case no m=video line exists */
03471 
03472       if (p->vrtp && (sscanf(m, "video %d RTP/AVP %n", &x, &len) == 1)) {
03473          found = 1;
03474          ast_clear_flag(p, SIP_NOVIDEO);  
03475          vportno = x;
03476          /* Scan through the RTP payload types specified in a "m=" line: */
03477          codecs = m + len;
03478          while(!ast_strlen_zero(codecs)) {
03479             if (sscanf(codecs, "%d%n", &codec, &len) != 1) {
03480                ast_log(LOG_WARNING, "Error in codec string '%s'\n", codecs);
03481                return -1;
03482             }
03483             if (debug)
03484                ast_verbose("Found RTP video format %d\n", codec);
03485             ast_rtp_set_m_type(p->vrtp, codec);
03486             codecs = ast_skip_blanks(codecs + len);
03487          }
03488       }
03489       if (!found )
03490          ast_log(LOG_WARNING, "Unknown SDP media type in offer: %s\n", m);
03491    }
03492    if (portno == -1 && vportno == -1) {
03493       /* No acceptable offer found in SDP */
03494       return -2;
03495    }
03496    /* Check for Media-description-level-address for audio */
03497    if (pedanticsipchecking) {
03498       c = get_sdp_iterate(&destiterator, req, "c");
03499       if (!ast_strlen_zero(c)) {
03500          if (sscanf(c, "IN IP4 %256s", host) != 1) {
03501             ast_log(LOG_WARNING, "Invalid secondary host in c= line, '%s'\n", c);
03502          } else {
03503             /* XXX This could block for a long time, and block the main thread! XXX */
03504             hp = ast_gethostbyname(host, &ahp);
03505             if (!hp) {
03506                ast_log(LOG_WARNING, "Unable to lookup host in secondary c= line, '%s'\n", c);
03507             }
03508          }
03509       }
03510    }
03511    /* RTP addresses and ports for audio and video */
03512    sin.sin_family = AF_INET;
03513    memcpy(&sin.sin_addr, hp->h_addr, sizeof(sin.sin_addr));
03514 
03515    /* Setup audio port number */
03516    sin.sin_port = htons(portno);
03517    if (p->rtp && sin.sin_port) {
03518       ast_rtp_set_peer(p->rtp, &sin);
03519       if (debug) {
03520          ast_verbose("Peer audio RTP is at port %s:%d\n", ast_inet_ntoa(iabuf,sizeof(iabuf), sin.sin_addr), ntohs(sin.sin_port));
03521          ast_log(LOG_DEBUG,"Peer audio RTP is at port %s:%d\n",ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), ntohs(sin.sin_port));
03522       }
03523    }
03524    /* Check for Media-description-level-address for video */
03525    if (pedanticsipchecking) {
03526       c = get_sdp_iterate(&destiterator, req, "c");
03527       if (!ast_strlen_zero(c)) {
03528          if (sscanf(c, "IN IP4 %256s", host) != 1) {
03529             ast_log(LOG_WARNING, "Invalid secondary host in c= line, '%s'\n", c);
03530          } else {
03531             /* XXX This could block for a long time, and block the main thread! XXX */
03532             hp = ast_gethostbyname(host, &ahp);
03533             if (!hp) {
03534                ast_log(LOG_WARNING, "Unable to lookup host in secondary c= line, '%s'\n", c);
03535             }
03536          }
03537       }
03538    }
03539    /* Setup video port number */
03540    sin.sin_port = htons(vportno);
03541    if (p->vrtp && sin.sin_port) {
03542       ast_rtp_set_peer(p->vrtp, &sin);
03543       if (debug) {
03544          ast_verbose("Peer video RTP is at port %s:%d\n", ast_inet_ntoa(iabuf,sizeof(iabuf), sin.sin_addr), ntohs(sin.sin_port));
03545          ast_log(LOG_DEBUG,"Peer video RTP is at port %s:%d\n",ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), ntohs(sin.sin_port));
03546       }
03547    }
03548 
03549    /* Next, scan through each "a=rtpmap:" line, noting each
03550     * specified RTP payload type (with corresponding MIME subtype):
03551     */
03552    sdpLineNum_iterator_init(&iterator);
03553    while ((a = get_sdp_iterate(&iterator, req, "a"))[0] != '\0') {
03554       char* mimeSubtype = ast_strdupa(a); /* ensures we have enough space */
03555       if (!strcasecmp(a, "sendonly")) {
03556          sendonly=1;
03557          continue;
03558       }
03559       if (!strcasecmp(a, "sendrecv")) {
03560          sendonly=0;
03561       }
03562       if (sscanf(a, "rtpmap: %u %[^/]/", &codec, mimeSubtype) != 2) continue;
03563       if (debug)
03564          ast_verbose("Found description format %s\n", mimeSubtype);
03565       /* Note: should really look at the 'freq' and '#chans' params too */
03566       ast_rtp_set_rtpmap_type(p->rtp, codec, "audio", mimeSubtype);
03567       if (p->vrtp)
03568          ast_rtp_set_rtpmap_type(p->vrtp, codec, "video", mimeSubtype);
03569    }
03570 
03571    /* Now gather all of the codecs that were asked for: */
03572    ast_rtp_get_current_formats(p->rtp,
03573             &peercapability, &peernoncodeccapability);
03574    if (p->vrtp)
03575       ast_rtp_get_current_formats(p->vrtp,
03576             &vpeercapability, &vpeernoncodeccapability);
03577    p->jointcapability = p->capability & (peercapability | vpeercapability);
03578    p->peercapability = (peercapability | vpeercapability);
03579    p->noncodeccapability = noncodeccapability & peernoncodeccapability;
03580    
03581    if (ast_test_flag(p, SIP_DTMF) == SIP_DTMF_AUTO) {
03582       ast_clear_flag(p, SIP_DTMF);
03583       if (p->noncodeccapability & AST_RTP_DTMF) {
03584          /* XXX Would it be reasonable to drop the DSP at this point? XXX */
03585          ast_set_flag(p, SIP_DTMF_RFC2833);
03586       } else {
03587          ast_set_flag(p, SIP_DTMF_INBAND);
03588       }
03589    }
03590    
03591    if (debug) {
03592       /* shame on whoever coded this.... */
03593       const unsigned slen=512;
03594       char s1[slen], s2[slen], s3[slen], s4[slen];
03595 
03596       ast_verbose("Capabilities: us - %s, peer - audio=%s/video=%s, combined - %s\n",
03597          ast_getformatname_multiple(s1, slen, p->capability),
03598          ast_getformatname_multiple(s2, slen, peercapability),
03599          ast_getformatname_multiple(s3, slen, vpeercapability),
03600          ast_getformatname_multiple(s4, slen, p->jointcapability));
03601 
03602       ast_verbose("Non-codec capabilities: us - %s, peer - %s, combined - %s\n",
03603          ast_rtp_lookup_mime_multiple(s1, slen, noncodeccapability, 0),
03604          ast_rtp_lookup_mime_multiple(s2, slen, peernoncodeccapability, 0),
03605          ast_rtp_lookup_mime_multiple(s3, slen, p->noncodeccapability, 0));
03606    }
03607    if (!p->jointcapability) {
03608       ast_log(LOG_NOTICE, "No compatible codecs!\n");
03609       return -1;
03610    }
03611 
03612    if (!p->owner)    /* There's no open channel owning us */
03613       return 0;
03614 
03615    if (!(p->owner->nativeformats & p->jointcapability)) {
03616       const unsigned slen=512;
03617       char s1[slen], s2[slen];
03618       ast_log(LOG_DEBUG, "Oooh, we need to change our formats since our peer supports only %s and not %s\n", 
03619             ast_getformatname_multiple(s1, slen, p->jointcapability),
03620             ast_getformatname_multiple(s2, slen, p->owner->nativeformats));
03621       p->owner->nativeformats = ast_codec_choose(&p->prefs, p->jointcapability, 1);
03622       ast_set_read_format(p->owner, p->owner->readformat);
03623       ast_set_write_format(p->owner, p->owner->writeformat);
03624    }
03625    if ((bridgepeer=ast_bridged_channel(p->owner))) {
03626       /* We have a bridge */
03627       /* Turn on/off music on hold if we are holding/unholding */
03628       struct ast_frame af = { AST_FRAME_NULL, };
03629       if (sin.sin_addr.s_addr && !sendonly) {
03630          ast_moh_stop(bridgepeer);
03631       
03632          /* Activate a re-invite */
03633          ast_queue_frame(p->owner, &af);
03634       } else {
03635          /* No address for RTP, we're on hold */
03636          
03637          ast_moh_start(bridgepeer, NULL);
03638          if (sendonly)
03639             ast_rtp_stop(p->rtp);
03640          /* Activate a re-invite */
03641          ast_queue_frame(p->owner, &af);
03642       }
03643    }
03644 
03645    /* Manager Hold and Unhold events must be generated, if necessary */
03646    if (sin.sin_addr.s_addr && !sendonly) {           
03647            append_history(p, "Unhold", req->data);
03648 
03649       if (callevents && ast_test_flag(p, SIP_CALL_ONHOLD)) {
03650          manager_event(EVENT_FLAG_CALL, "Unhold",
03651             "Channel: %s\r\n"
03652             "Uniqueid: %s\r\n",
03653             p->owner->name, 
03654             p->owner->uniqueid);
03655 
03656             }
03657       ast_clear_flag(p, SIP_CALL_ONHOLD);
03658    } else {         
03659       /* No address for RTP, we're on hold */
03660            append_history(p, "Hold", req->data);
03661 
03662            if (callevents && !ast_test_flag(p, SIP_CALL_ONHOLD)) {
03663          manager_event(EVENT_FLAG_CALL, "Hold",
03664             "Channel: %s\r\n"
03665                   "Uniqueid: %s\r\n",
03666             p->owner->name, 
03667             p->owner->uniqueid);
03668       }
03669       ast_set_flag(p, SIP_CALL_ONHOLD);
03670    }
03671 
03672    return 0;
03673 }

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

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 }

static 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(), ast_update_realtime(), and ipaddr.

01593 {
01594    char port[10];
01595    char ipaddr[20];
01596    char regseconds[20];
01597    time_t nowtime;
01598    
01599    time(&nowtime);
01600    nowtime += expirey;
01601    snprintf(regseconds, sizeof(regseconds), "%d", (int)nowtime);  /* Expiration time */
01602    ast_inet_ntoa(ipaddr, sizeof(ipaddr), sin->sin_addr);
01603    snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port));
01604    
01605    if (fullcontact)
01606       ast_update_realtime("sippeers", "name", peername, "ipaddr", ipaddr, "port", port, "regseconds", regseconds, "username", username, "fullcontact", fullcontact, NULL);
01607    else
01608       ast_update_realtime("sippeers", "name", peername, "ipaddr", ipaddr, "port", port, "regseconds", regseconds, "username", username, NULL);
01609 }

static 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(), global_flags_page2, ast_variable::name, ast_variable::next, SIP_PAGE2_RTCACHEFRIENDS, SIP_REALTIME, user, userl, ast_variable::value, and var.

01785 {
01786    struct ast_variable *var;
01787    struct ast_variable *tmp;
01788    struct sip_user *user = NULL;
01789 
01790    var = ast_load_realtime("sipusers", "name", username, NULL);
01791 
01792    if (!var)
01793       return NULL;
01794 
01795    tmp = var;
01796    while (tmp) {
01797       if (!strcasecmp(tmp->name, "type") &&
01798          !strcasecmp(tmp->value, "peer")) {
01799          ast_variables_destroy(var);
01800          return NULL;
01801       }
01802       tmp = tmp->next;
01803    }
01804    
01805 
01806 
01807    user = build_user(username, var, !ast_test_flag((&global_flags_page2), SIP_PAGE2_RTCACHEFRIENDS));
01808    
01809    if (!user) {   /* No user found */
01810       ast_variables_destroy(var);
01811       return NULL;
01812    }
01813 
01814    if (ast_test_flag((&global_flags_page2), SIP_PAGE2_RTCACHEFRIENDS)) {
01815       ast_set_flag((&user->flags_page2), SIP_PAGE2_RTCACHEFRIENDS);
01816       suserobjs++;
01817       ASTOBJ_CONTAINER_LINK(&userl,user);
01818    } else {
01819       /* Move counter from s to r... */
01820       suserobjs--;
01821       ruserobjs++;
01822       ast_set_flag(user, SIP_REALTIME);
01823    }
01824    ast_variables_destroy(var);
01825    return user;
01826 }

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

receive_message: Receive SIP MESSAGE method messages ---

Definition at line 7249 of file chan_sip.c.

References AST_FRAME_TEXT, ast_log(), ast_queue_frame(), ast_set_flag, ast_verbose(), sip_pvt::callid, get_header(), get_msg_text(), LOG_WARNING, sip_pvt::owner, sip_debug_test_pvt(), SIP_NEEDDESTROY, and transmit_response().

Referenced by handle_request_message().

07250 {
07251    char buf[1024];
07252    struct ast_frame f;
07253    char *content_type;
07254 
07255    content_type = get_header(req, "Content-Type");
07256    if (strcmp(content_type, "text/plain")) { /* No text/plain attachment */
07257       transmit_response(p, "415 Unsupported Media Type", req); /* Good enough, or? */
07258       ast_set_flag(p, SIP_NEEDDESTROY);
07259       return;
07260    }
07261 
07262    if (get_msg_text(buf, sizeof(buf), req)) {
07263       ast_log(LOG_WARNING, "Unable to retrieve text from %s\n", p->callid);
07264       transmit_response(p, "202 Accepted", req);
07265       ast_set_flag(p, SIP_NEEDDESTROY);
07266       return;
07267    }
07268 
07269    if (p->owner) {
07270       if (sip_debug_test_pvt(p))
07271          ast_verbose("Message received: '%s'\n", buf);
07272       memset(&f, 0, sizeof(f));
07273       f.frametype = AST_FRAME_TEXT;
07274       f.subclass = 0;
07275       f.offset = 0;
07276       f.data = buf;
07277       f.datalen = strlen(buf);
07278       ast_queue_frame(p->owner, &f);
07279       transmit_response(p, "202 Accepted", req); /* We respond 202 accepted, since we relay the message */
07280    } else { /* Message outside of a call, we do not support that */
07281       ast_log(LOG_WARNING,"Received message to %s from %s, dropped it...\n  Content-Type:%s\n  Message: %s\n", get_header(req,"To"), get_header(req,"From"), content_type, buf);
07282       transmit_response(p, "405 Method Not Allowed", req); /* Good enough, or? */
07283    }
07284    ast_set_flag(p, SIP_NEEDDESTROY);
07285    return;
07286 }

static void reg_source_db struct sip_peer peer  )  [static]
 

reg_source_db: Get registration details from Asterisk DB ---

Definition at line 5668 of file chan_sip.c.

References sip_peer::addr, ast_db_get(), ast_inet_ntoa(), ast_sched_add(), ast_sched_del(), ast_test_flag, ast_verbose(), sip_peer::expire, expire_register(), expiry, sip_peer::flags_page2, sip_peer::fullcontact, option_verbose, sip_peer::pokeexpire, register_peer_exten(), SIP_PAGE2_RT_FROMCONTACT, sip_poke_peer(), sip_poke_peer_s(), sipsock, strsep(), thread_safe_rand(), sip_peer::username, username, and VERBOSE_PREFIX_3.

05669 {
05670    char data[256];
05671    char iabuf[INET_ADDRSTRLEN];
05672    struct in_addr in;
05673    int expiry;
05674    int port;
05675    char *scan, *addr, *port_str, *expiry_str, *username, *contact;
05676 
05677    if (ast_test_flag(&(peer->flags_page2), SIP_PAGE2_RT_FROMCONTACT)) 
05678       return;
05679    if (ast_db_get("SIP/Registry", peer->name, data, sizeof(data)))
05680       return;
05681 
05682    scan = data;
05683    addr = strsep(&scan, ":");
05684    port_str = strsep(&scan, ":");
05685    expiry_str = strsep(&scan, ":");
05686    username = strsep(&scan, ":");
05687    contact = scan;   /* Contact include sip: and has to be the last part of the database entry as long as we use : as a separator */
05688 
05689    if (!inet_aton(addr, &in))
05690       return;
05691 
05692    if (port_str)
05693       port = atoi(port_str);
05694    else
05695       return;
05696 
05697    if (expiry_str)
05698       expiry = atoi(expiry_str);
05699    else
05700       return;
05701 
05702    if (username)
05703       ast_copy_string(peer->username, username, sizeof(peer->username));
05704    if (contact)
05705       ast_copy_string(peer->fullcontact, contact, sizeof(peer->fullcontact));
05706 
05707    if (option_verbose > 2)
05708       ast_verbose(VERBOSE_PREFIX_3 "SIP Seeding peer from astdb: '%s' at %s@%s:%d for %d\n",
05709              peer->name, peer->username, ast_inet_ntoa(iabuf, sizeof(iabuf), in), port, expiry);
05710 
05711    memset(&peer->addr, 0, sizeof(peer->addr));
05712    peer->addr.sin_family = AF_INET;
05713    peer->addr.sin_addr = in;
05714    peer->addr.sin_port = htons(port);
05715    if (sipsock < 0) {
05716       /* SIP isn't up yet, so schedule a poke only, pretty soon */
05717       if (peer->pokeexpire > -1)
05718          ast_sched_del(sched, peer->pokeexpire);
05719       peer->pokeexpire = ast_sched_add(sched, thread_safe_rand() % 5000 + 1, sip_poke_peer_s, peer);
05720    } else
05721       sip_poke_peer(peer);
05722    if (peer->expire > -1)
05723       ast_sched_del(sched, peer->expire);
05724    peer->expire = ast_sched_add(sched, (expiry + 10) * 1000, expire_register, peer);
05725    register_peer_exten(peer, 1);
05726 }

static 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(), free, sip_peer::regexten, strdup, and strsep().

01613 {
01614    char multi[256];
01615    char *stringp, *ext;
01616    if (!ast_strlen_zero(regcontext)) {
01617       ast_copy_string(multi, ast_strlen_zero(peer->regexten) ? peer->name : peer->regexten, sizeof(multi));
01618       stringp = multi;
01619       while((ext = strsep(&stringp, "&"))) {
01620          if (onoff)
01621             ast_add_extension(regcontext, 1, ext, 1, NULL, NULL, "Noop", strdup(peer->name), free, channeltype);
01622          else
01623             ast_context_remove_extension(regcontext, ext, 1, NULL);
01624       }
01625    }
01626 }

static 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 6351 of file chan_sip.c.

References ast_apply_ha(), ast_copy_flags, ast_device_state_changed(), ast_inet_ntoa(), AST_LIST_EMPTY, ast_log(), ast_test_flag, ast_uri_decode(), ASTOBJ_CONTAINER_LINK, ASTOBJ_UNREF, autocreatepeer, build_contact(), check_auth(), check_sip_domain(), EVENT_FLAG_SYSTEM, sip_pvt::exten, find_peer(), get_header(), get_in_brackets(), sip_peer::ha, sip_pvt::initreq, sip_peer::lastmsgssent, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, LOG_WARNING, manager_event(), sip_peer::md5secret, name, option_debug, parse_register_contact(), PARSE_REGISTER_FAILED, PARSE_REGISTER_QUERY, PARSE_REGISTER_UPDATE, pedanticsipchecking, peerl, sip_pvt::randdata, sip_peer::secret, sip_cancel_destroy(), sip_destroy_peer(), SIP_DYNAMIC, SIP_NAT, SIP_REGISTER, t, temp_peer(), transmit_response(), transmit_response_with_date(), and update_peer().

06352 {
06353    int res = -3;
06354    struct sip_peer *peer;
06355    char tmp[256];
06356    char iabuf[INET_ADDRSTRLEN];
06357    char *name, *c;
06358    char *t;
06359    char *domain;
06360 
06361    /* Terminate URI */
06362    t = uri;
06363    while(*t && (*t > 32) && (*t != ';'))
06364       t++;
06365    *t = '\0';
06366    
06367    ast_copy_string(tmp, get_header(req, "To"), sizeof(tmp));
06368    if (pedanticsipchecking)
06369       ast_uri_decode(tmp);
06370 
06371    c = get_in_brackets(tmp);
06372    /* Ditch ;user=phone */
06373    name = strchr(c, ';');
06374    if (name)
06375       *name = '\0';
06376 
06377    if (!strncmp(c, "sip:", 4)) {
06378       name = c + 4;
06379    } else {
06380       name = c;
06381       ast_log(LOG_NOTICE, "Invalid to address: '%s' from %s (missing sip:) trying to use anyway...\n", c, ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr));
06382    }
06383 
06384    /* Strip off the domain name */
06385    if ((c = strchr(name, '@'))) {
06386       *c++ = '\0';
06387       domain = c;
06388       if ((c = strchr(domain, ':')))   /* Remove :port */
06389          *c = '\0';
06390       if (!AST_LIST_EMPTY(&domain_list)) {
06391          if (!check_sip_domain(domain, NULL, 0)) {
06392             transmit_response(p, "404 Not found (unknown domain)", &p->initreq);
06393             return -3;
06394          }
06395       }
06396    }
06397 
06398    ast_copy_string(p->exten, name, sizeof(p->exten));
06399    build_contact(p);
06400    peer = find_peer(name, NULL, 1);
06401    if (!(peer && ast_apply_ha(peer->ha, sin))) {
06402       if (peer)
06403          ASTOBJ_UNREF(peer,sip_destroy_peer);
06404    }
06405    if (peer) {
06406       if (!ast_test_flag(peer, SIP_DYNAMIC)) {
06407          ast_log(LOG_ERROR, "Peer '%s' is trying to register, but not configured as host=dynamic\n", peer->name);
06408       } else {
06409          ast_copy_flags(p, peer, SIP_NAT);
06410          transmit_response(p, "100 Trying", req);
06411          if (!(res = check_auth(p, req, p->randdata, sizeof(p->randdata), peer->name, peer->secret, peer->md5secret, SIP_REGISTER, uri, 0, ignore))) {
06412             sip_cancel_destroy(p);
06413             switch (parse_register_contact(p, peer, req)) {
06414             case PARSE_REGISTER_FAILED:
06415                ast_log(LOG_WARNING, "Failed to parse contact info\n");
06416                break;
06417             case PARSE_REGISTER_QUERY:
06418                transmit_response_with_date(p, "200 OK", req);
06419                peer->lastmsgssent = -1;
06420                res = 0;
06421                break;
06422             case PARSE_REGISTER_UPDATE:
06423                update_peer(peer, p->expiry);
06424                /* Say OK and ask subsystem to retransmit msg counter */
06425                transmit_response_with_date(p, "200 OK", req);
06426                peer->lastmsgssent = -1;
06427                res = 0;
06428                break;
06429             }
06430          } 
06431       }
06432    }
06433    if (!peer && autocreatepeer) {
06434       /* Create peer if we have autocreate mode enabled */
06435       peer = temp_peer(name);
06436       if (peer) {
06437          ASTOBJ_CONTAINER_LINK(&peerl, peer);
06438          peer->lastmsgssent = -1;
06439          sip_cancel_destroy(p);
06440          switch (parse_register_contact(p, peer, req)) {
06441          case PARSE_REGISTER_FAILED:
06442             ast_log(LOG_WARNING, "Failed to parse contact info\n");
06443             break;
06444          case PARSE_REGISTER_QUERY:
06445             transmit_response_with_date(p, "200 OK", req);
06446             peer->lastmsgssent = -1;
06447             res = 0;
06448             break;
06449          case PARSE_REGISTER_UPDATE:
06450             /* Say OK and ask subsystem to retransmit msg counter */
06451             transmit_response_with_date(p, "200 OK", req);
06452             manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Registered\r\n", peer->name);
06453             peer->lastmsgssent = -1;
06454             res = 0;
06455             break;
06456          }
06457       }
06458    }
06459    if (!res) {
06460       ast_device_state_changed("SIP/%s", peer->name);
06461    }
06462    if (res < 0) {
06463       switch (res) {
06464       case -1:
06465          /* Wrong password in authentication. Go away, don't try again until you fixed it */
06466          transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq);
06467          break;
06468       case -2:
06469          /* Username and digest username does not match. 
06470             Asterisk uses the From: username for authentication. We need the
06471             users to use the same authentication user name until we support
06472             proper authentication by digest auth name */
06473          transmit_response(p, "403 Authentication user name does not match account name", &p->initreq);
06474          break;
06475       case -3:
06476          /* URI not found */
06477          transmit_response(p, "404 Not found", &p->initreq);
06478          /* Set res back to -2 because we don't want to return an invalid domain message. That check already happened up above. */
06479          res = -2;
06480          break;
06481       }
06482       if (option_debug > 1) {
06483          ast_log(LOG_DEBUG, "SIP REGISTER attempt failed for %s : %s\n",
06484             peer->name,
06485             (res == -1) ? "Bad password" : ((res == -2 ) ? "Bad digest user" : "Peer not found"));
06486       }
06487    }
06488    if (peer)
06489       ASTOBJ_UNREF(peer,sip_destroy_peer);
06490 
06491    return res;
06492 }

static char* regstate2str int  regstate  )  [static]
 

Definition at line 5215 of file chan_sip.c.

References REG_STATE_AUTHSENT, REG_STATE_FAILED, REG_STATE_NOAUTH, REG_STATE_REGISTERED, REG_STATE_REGSENT, REG_STATE_REJECTED, REG_STATE_TIMEOUT, and REG_STATE_UNREGISTERED.

05216 {
05217    switch(regstate) {
05218    case REG_STATE_FAILED:
05219       return "Failed";
05220    case REG_STATE_UNREGISTERED:
05221       return "Unregistered";
05222    case REG_STATE_REGSENT:
05223       return "Request Sent";
05224    case REG_STATE_AUTHSENT:
05225       return "Auth. Sent";
05226    case REG_STATE_REGISTERED:
05227       return "Registered";
05228    case REG_STATE_REJECTED:
05229       return "Rejected";
05230    case REG_STATE_TIMEOUT:
05231       return "Timeout";
05232    case REG_STATE_NOAUTH:
05233       return "No Authentication";
05234    default:
05235       return "Unknown";
05236    }
05237 }

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 13086 of file chan_sip.c.

References sip_reload().

13087 {
13088    return sip_reload(0, 0, NULL);
13089 }

static int reload_config void   )  [static]
 

reload_config: Re-read SIP.conf config file ---

Definition at line 12299 of file chan_sip.c.

References __ourip, add_realm_authentication(), add_sip_domain(), ahp, allow_external_domains, ast_append_ha(), ast_category_browse(), ast_clear_flag, ast_config_destroy(), ast_config_load(), ast_context_create(), ast_context_find(), ast_find_ourip(), AST_FLAGS_ALL, ast_get_ip_or_srv(), ast_gethostbyname(), ast_inet_ntoa(), AST_LIST_EMPTY, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_parse_allow_disallow(), ast_set2_flag, ast_set_flag, ast_str2tos(), ast_strdupa, ast_strlen_zero(), ast_true(), ast_variable_browse(), ast_variable_retrieve(), ast_verbose(), ASTOBJ_CONTAINER_LINK, ASTOBJ_UNREF, authl, autocreatepeer, bindaddr, build_peer(), build_user(), callevents, cfg, channeltype, compactheaders, config, context, DEFAULT_CALLERID, default_callerid, DEFAULT_CONTEXT, default_context, DEFAULT_DEFAULT_EXPIRY, default_expiry, DEFAULT_EXPIRY, default_fromdomain, default_language, DEFAULT_MAX_EXPIRY, DEFAULT_MAXMS, DEFAULT_MWITIME, DEFAULT_NOTIFYMIME, default_notifymime, default_qualify, DEFAULT_REALM, DEFAULT_REGISTRATION_TIMEOUT, DEFAULT_SIP_PORT, default_subscribecontext, DEFAULT_USERAGENT, default_useragent, DEFAULT_VMEXTEN, dumphistory, expiry, externexpire, externhost, externip, externrefresh, global_allowguest, global_capability, global_flags, global_flags_page2, global_musicclass, global_mwitime, global_notifyringing, global_realm, global_reg_timeout, global_regattempts_max, global_rtautoclear, global_rtpholdtimeout, global_rtpkeepalive, global_rtptimeout, global_vmexten, handle_common_options(), hp, ast_variable::lineno, localaddr, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, max_expiry, ast_variable::name, ast_variable::next, notify_config, notify_types, option_verbose, ourport, outboundproxyip, pedanticsipchecking, peerl, prefs, recordhistory, regcontext, relaxdtmf, SIP_CAN_REINVITE, SIP_DEBUG_CONFIG, sip_destroy_peer(), sip_destroy_user(), SIP_DOMAIN_AUTO, SIP_DOMAIN_CONFIG, SIP_DTMF_RFC2833, SIP_NAT_RFC3581, SIP_PAGE2_IGNOREREGEXPIRE, SIP_PAGE2_RTAUTOCLEAR, SIP_PAGE2_RTCACHEFRIENDS, SIP_PAGE2_RTUPDATE, sip_register(), SIP_USEREQPHONE, sipdebug, sipsock, srvlookup, tos, user, userl, ast_variable::value, VERBOSE_PREFIX_2, and videosupport.

12300 {
12301    struct ast_config *cfg;
12302    struct ast_variable *v;
12303    struct sip_peer *peer;
12304    struct sip_user *user;
12305    struct ast_hostent ahp;
12306    char *cat;
12307    char *utype;
12308    struct hostent *hp;
12309    int format;
12310    char iabuf[INET_ADDRSTRLEN];
12311    struct ast_flags dummy;
12312    int auto_sip_domains = 0;
12313    struct sockaddr_in old_bindaddr = bindaddr;
12314 
12315    cfg = ast_config_load(config);
12316 
12317    /* We *must* have a config file otherwise stop immediately */
12318    if (!cfg) {
12319       ast_log(LOG_NOTICE, "Unable to load config %s\n", config);
12320       return -1;
12321    }
12322    
12323    /* Reset IP addresses  */
12324    memset(&bindaddr, 0, sizeof(bindaddr));
12325    memset(&localaddr, 0, sizeof(localaddr));
12326    memset(&externip, 0, sizeof(externip));
12327    memset(&prefs, 0 , sizeof(prefs));
12328    sipdebug &= ~SIP_DEBUG_CONFIG;
12329 
12330    /* Initialize some reasonable defaults at SIP reload */
12331    ast_copy_string(default_context, DEFAULT_CONTEXT, sizeof(default_context));
12332    default_subscribecontext[0] = '\0';
12333    default_language[0] = '\0';
12334    default_fromdomain[0] = '\0';
12335    default_qualify = 0;
12336    allow_external_domains = 1;   /* Allow external invites */
12337    externhost[0] = '\0';
12338    externexpire = 0;
12339    externrefresh = 10;
12340    ast_copy_string(default_useragent, DEFAULT_USERAGENT, sizeof(default_useragent));
12341    ast_copy_string(default_notifymime, DEFAULT_NOTIFYMIME, sizeof(default_notifymime));
12342    global_notifyringing = 1;
12343    ast_copy_string(global_realm, DEFAULT_REALM, sizeof(global_realm));
12344    ast_copy_string(global_musicclass, "default", sizeof(global_musicclass));
12345    ast_copy_string(default_callerid, DEFAULT_CALLERID, sizeof(default_callerid));
12346    memset(&outboundproxyip, 0, sizeof(outboundproxyip));
12347    outboundproxyip.sin_port = htons(DEFAULT_SIP_PORT);
12348    outboundproxyip.sin_family = AF_INET;  /* Type of address: IPv4 */
12349    videosupport = 0;
12350    compactheaders = 0;
12351    dumphistory = 0;
12352    recordhistory = 0;
12353    relaxdtmf = 0;
12354    callevents = 0;
12355    ourport = DEFAULT_SIP_PORT;
12356    global_rtptimeout = 0;
12357    global_rtpholdtimeout = 0;
12358    global_rtpkeepalive = 0;
12359    global_rtautoclear = 120;
12360    pedanticsipchecking = 0;
12361    global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT;
12362    global_regattempts_max = 0;
12363    ast_clear_flag(&global_flags, AST_FLAGS_ALL);
12364    ast_clear_flag(&global_flags_page2, AST_FLAGS_ALL);
12365    ast_set_flag(&global_flags, SIP_DTMF_RFC2833);
12366    ast_set_flag(&global_flags, SIP_NAT_RFC3581);
12367    ast_set_flag(&global_flags, SIP_CAN_REINVITE);
12368    ast_set_flag(&global_flags_page2, SIP_PAGE2_RTUPDATE);
12369    global_mwitime = DEFAULT_MWITIME;
12370    strcpy(global_vmexten, DEFAULT_VMEXTEN);
12371    srvlookup = 0;
12372    autocreatepeer = 0;
12373    regcontext[0] = '\0';
12374    tos = 0;
12375    expiry = DEFAULT_EXPIRY;
12376    global_allowguest = 1;
12377 
12378    /* Read the [general] config section of sip.conf (or from realtime config) */
12379    v = ast_variable_browse(cfg, "general");
12380    while(v) {
12381       if (handle_common_options(&global_flags, &dummy, v)) {
12382          v = v->next;
12383          continue;
12384       }
12385 
12386       /* Create the interface list */
12387       if (!strcasecmp(v->name, "context")) {
12388          ast_copy_string(default_context, v->value, sizeof(default_context));
12389       } else if (!strcasecmp(v->name, "realm")) {
12390          ast_copy_string(global_realm, v->value, sizeof(global_realm));
12391       } else if (!strcasecmp(v->name, "useragent")) {
12392          ast_copy_string(default_useragent, v->value, sizeof(default_useragent));
12393          ast_log(LOG_DEBUG, "Setting User Agent Name to %s\n",
12394             default_useragent);
12395       } else if (!strcasecmp(v->name, "rtcachefriends")) {
12396          ast_set2_flag((&global_flags_page2), ast_true(v->value), SIP_PAGE2_RTCACHEFRIENDS); 
12397       } else if (!strcasecmp(v->name, "rtupdate")) {
12398          ast_set2_flag((&global_flags_page2), ast_true(v->value), SIP_PAGE2_RTUPDATE); 
12399       } else if (!strcasecmp(v->name, "ignoreregexpire")) {
12400          ast_set2_flag((&global_flags_page2), ast_true(v->value), SIP_PAGE2_IGNOREREGEXPIRE);   
12401       } else if (!strcasecmp(v->name, "rtautoclear")) {
12402          int i = atoi(v->value);
12403          if (i > 0)
12404             global_rtautoclear = i;
12405          else
12406             i = 0;
12407          ast_set2_flag((&global_flags_page2), i || ast_true(v->value), SIP_PAGE2_RTAUTOCLEAR);
12408       } else if (!strcasecmp(v->name, "usereqphone")) {
12409          ast_set2_flag((&global_flags), ast_true(v->value), SIP_USEREQPHONE); 
12410       } else if (!strcasecmp(v->name, "relaxdtmf")) {
12411          relaxdtmf = ast_true(v->value);
12412       } else if (!strcasecmp(v->name, "checkmwi")) {
12413          if ((sscanf(v->value, "%d", &global_mwitime) != 1) || (global_mwitime < 0)) {
12414             ast_log(LOG_WARNING, "'%s' is not a valid MWI time setting at line %d.  Using default (10).\n", v->value, v->lineno);
12415             global_mwitime = DEFAULT_MWITIME;
12416          }
12417       } else if (!strcasecmp(v->name, "vmexten")) {
12418          ast_copy_string(global_vmexten, v->value, sizeof(global_vmexten));
12419       } else if (!strcasecmp(v->name, "rtptimeout")) {
12420          if ((sscanf(v->value, "%d", &global_rtptimeout) != 1) || (global_rtptimeout < 0)) {
12421             ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d.  Using default.\n", v->value, v->lineno);
12422             global_rtptimeout = 0;
12423          }
12424       } else if (!strcasecmp(v->name, "rtpholdtimeout")) {
12425          if ((sscanf(v->value, "%d", &global_rtpholdtimeout) != 1) || (global_rtpholdtimeout < 0)) {
12426             ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d.  Using default.\n", v->value, v->lineno);
12427             global_rtpholdtimeout = 0;
12428          }
12429       } else if (!strcasecmp(v->name, "rtpkeepalive")) {
12430          if ((sscanf(v->value, "%d", &global_rtpkeepalive) != 1) || (global_rtpkeepalive < 0)) {
12431             ast_log(LOG_WARNING, "'%s' is not a valid RTP keepalive time at line %d.  Using default.\n", v->value, v->lineno);
12432             global_rtpkeepalive = 0;
12433          }
12434       } else if (!strcasecmp(v->name, "videosupport")) {
12435          videosupport = ast_true(v->value);
12436       } else if (!strcasecmp(v->name, "compactheaders")) {
12437          compactheaders = ast_true(v->value);
12438       } else if (!strcasecmp(v->name, "notifymimetype")) {
12439          ast_copy_string(default_notifymime, v->value, sizeof(default_notifymime));
12440       } else if (!strcasecmp(v->name, "notifyringing")) {
12441          global_notifyringing = ast_true(v->value);
12442       } else if (!strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) {
12443          ast_copy_string(global_musicclass, v->value, sizeof(global_musicclass));
12444       } else if (!strcasecmp(v->name, "language")) {
12445          ast_copy_string(default_language, v->value, sizeof(default_language));
12446       } else if (!strcasecmp(v->name, "regcontext")) {
12447          ast_copy_string(regcontext, v->value, sizeof(regcontext));
12448          /* Create context if it doesn't exist already */
12449          if (!ast_context_find(regcontext))
12450             ast_context_create(NULL, regcontext, channeltype);
12451       } else if (!strcasecmp(v->name, "callerid")) {
12452          ast_copy_string(default_callerid, v->value, sizeof(default_callerid));
12453       } else if (!strcasecmp(v->name, "fromdomain")) {
12454          ast_copy_string(default_fromdomain, v->value, sizeof(default_fromdomain));
12455       } else if (!strcasecmp(v->name, "outboundproxy")) {
12456          if (ast_get_ip_or_srv(&outboundproxyip, v->value, "_sip._udp") < 0)
12457             ast_log(LOG_WARNING, "Unable to locate host '%s'\n", v->value);
12458       } else if (!strcasecmp(v->name, "outboundproxyport")) {
12459          /* Port needs to be after IP */
12460          sscanf(v->value, "%d", &format);
12461          outboundproxyip.sin_port = htons(format);
12462       } else if (!strcasecmp(v->name, "autocreatepeer")) {
12463          autocreatepeer = ast_true(v->value);
12464       } else if (!strcasecmp(v->name, "srvlookup")) {
12465          srvlookup = ast_true(v->value);
12466       } else if (!strcasecmp(v->name, "pedantic")) {
12467          pedanticsipchecking = ast_true(v->value);
12468       } else if (!strcasecmp(v->name, "maxexpirey") || !strcasecmp(v->name, "maxexpiry")) {
12469          max_expiry = atoi(v->value);
12470          if (max_expiry < 1)
12471             max_expiry = DEFAULT_MAX_EXPIRY;
12472       } else if (!strcasecmp(v->name, "defaultexpiry") || !strcasecmp(v->name, "defaultexpirey")) {
12473          default_expiry = atoi(v->value);
12474          if (default_expiry < 1)
12475             default_expiry = DEFAULT_DEFAULT_EXPIRY;
12476       } else if (!strcasecmp(v->name, "sipdebug")) {
12477          if (ast_true(v->value))
12478             sipdebug |= SIP_DEBUG_CONFIG;
12479       } else if (!strcasecmp(v->name, "dumphistory")) {
12480          dumphistory = ast_true(v->value);
12481       } else if (!strcasecmp(v->name, "recordhistory")) {
12482          recordhistory = ast_true(v->value);
12483       } else if (!strcasecmp(v->name, "registertimeout")) {
12484          global_reg_timeout = atoi(v->value);
12485          if (global_reg_timeout < 1)
12486             global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT;
12487       } else if (!strcasecmp(v->name, "registerattempts")) {
12488          global_regattempts_max = atoi(v->value);
12489       } else if (!strcasecmp(v->name, "bindaddr")) {
12490          if (!(hp = ast_gethostbyname(v->value, &ahp))) {
12491             ast_log(LOG_WARNING, "Invalid address: %s\n", v->value);
12492          } else {
12493             memcpy(&bindaddr.sin_addr, hp->h_addr, sizeof(bindaddr.sin_addr));
12494          }
12495       } else if (!strcasecmp(v->name, "localnet")) {
12496          struct ast_ha *na;
12497          if (!(na = ast_append_ha("d", v->value, localaddr)))
12498             ast_log(LOG_WARNING, "Invalid localnet value: %s\n", v->value);
12499          else
12500             localaddr = na;
12501       } else if (!strcasecmp(v->name, "localmask")) {
12502          ast_log(LOG_WARNING, "Use of localmask is no long supported -- use localnet with mask syntax\n");
12503       } else if (!strcasecmp(v->name, "externip")) {
12504          if (!(hp = ast_gethostbyname(v->value, &ahp))) 
12505             ast_log(LOG_WARNING, "Invalid address for externip keyword: %s\n", v->value);
12506          else
12507             memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr));
12508          externexpire = 0;
12509       } else if (!strcasecmp(v->name, "externhost")) {
12510          ast_copy_string(externhost, v->value, sizeof(externhost));
12511          if (!(hp = ast_gethostbyname(externhost, &ahp))) 
12512             ast_log(LOG_WARNING, "Invalid address for externhost keyword: %s\n", externhost);
12513          else
12514             memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr));
12515          time(&externexpire);
12516       } else if (!strcasecmp(v->name, "externrefresh")) {
12517          if (sscanf(v->value, "%d", &externrefresh) != 1) {
12518             ast_log(LOG_WARNING, "Invalid externrefresh value '%s', must be an integer >0 at line %d\n", v->value, v->lineno);
12519             externrefresh = 10;
12520          }
12521       } else if (!strcasecmp(v->name, "allow")) {
12522          ast_parse_allow_disallow(&prefs, &global_capability, v->value, 1);
12523       } else if (!strcasecmp(v->name, "disallow")) {
12524          ast_parse_allow_disallow(&prefs, &global_capability, v->value, 0);
12525       } else if (!strcasecmp(v->name, "allowexternaldomains")) {
12526          allow_external_domains = ast_true(v->value);
12527       } else if (!strcasecmp(v->name, "autodomain")) {
12528          auto_sip_domains = ast_true(v->value);
12529       } else if (!strcasecmp(v->name, "domain")) {
12530          char *domain = ast_strdupa(v->value);
12531          char *context = strchr(domain, ',');
12532 
12533          if (context)
12534             *context++ = '\0';
12535 
12536          if (ast_strlen_zero(domain))
12537             ast_log(LOG_WARNING, "Empty domain specified at line %d\n", v->lineno);
12538          else if (ast_strlen_zero(context))
12539             ast_log(LOG_WARNING, "Empty context specified at line %d for domain '%s'\n", v->lineno, domain);
12540          else
12541             add_sip_domain(ast_strip(domain), SIP_DOMAIN_CONFIG, context ? ast_strip(context) : "");
12542       } else if (!strcasecmp(v->name, "register")) {
12543          sip_register(v->value, v->lineno);
12544       } else if (!strcasecmp(v->name, "tos")) {
12545          if (ast_str2tos(v->value, &tos))
12546             ast_log(LOG_WARNING, "Invalid tos value at line %d, should be 'lowdelay', 'throughput', 'reliability', 'mincost', or 'none'\n", v->lineno);
12547       } else if (!strcasecmp(v->name, "bindport")) {
12548          if (sscanf(v->value, "%d", &ourport) == 1) {
12549             bindaddr.sin_port = htons(ourport);
12550          } else {
12551             ast_log(LOG_WARNING, "Invalid port number '%s' at line %d of %s\n", v->value, v->lineno, config);
12552          }
12553       } else if (!strcasecmp(v->name, "qualify")) {
12554          if (!strcasecmp(v->value, "no")) {
12555             default_qualify = 0;
12556          } else if (!strcasecmp(v->value, "yes")) {
12557             default_qualify = DEFAULT_MAXMS;
12558          } else if (sscanf(v->value, "%d", &default_qualify) != 1) {
12559             ast_log(LOG_WARNING, "Qualification default should be 'yes', 'no', or a number of milliseconds at line %d of sip.conf\n", v->lineno);
12560             default_qualify = 0;
12561          }
12562       } else if (!strcasecmp(v->name, "callevents")) {
12563          callevents = ast_true(v->value);
12564       }
12565       /* else if (strcasecmp(v->name,"type"))
12566        * ast_log(LOG_WARNING, "Ignoring %s\n", v->name);
12567        */
12568        v = v->next;
12569    }
12570 
12571    if (!allow_external_domains && AST_LIST_EMPTY(&domain_list)) {
12572       ast_log(LOG_WARNING, "To disallow external domains, you need to configure local SIP domains.\n");
12573       allow_external_domains = 1;
12574    }
12575    
12576    /* Build list of authentication to various SIP realms, i.e. service providers */
12577    v = ast_variable_browse(cfg, "authentication");
12578    while(v) {
12579       /* Format for authentication is auth = username:password@realm */
12580       if (!strcasecmp(v->name, "auth")) {
12581          authl = add_realm_authentication(authl, v->value, v->lineno);
12582       }
12583       v = v->next;
12584    }
12585    
12586    /* Load peers, users and friends */
12587    cat = ast_category_browse(cfg, NULL);
12588    while(cat) {
12589       if (strcasecmp(cat, "general") && strcasecmp(cat, "authentication")) {
12590          utype = ast_variable_retrieve(cfg, cat, "type");
12591          if (utype) {
12592             if (!strcasecmp(utype, "user") || !strcasecmp(utype, "friend")) {
12593                user = build_user(cat, ast_variable_browse(cfg, cat), 0);
12594                if (user) {
12595                   ASTOBJ_CONTAINER_LINK(&userl,user);
12596                   ASTOBJ_UNREF(user, sip_destroy_user);
12597                }
12598             }
12599             if (!strcasecmp(utype, "peer") || !strcasecmp(utype, "friend")) {
12600                peer = build_peer(cat, ast_variable_browse(cfg, cat), 0);
12601                if (peer) {
12602                   ASTOBJ_CONTAINER_LINK(&peerl,peer);
12603                   ASTOBJ_UNREF(peer, sip_destroy_peer);
12604                }
12605             } else if (strcasecmp(utype, "user")) {
12606                ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, "sip.conf");
12607             }
12608          } else
12609             ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat);
12610       }
12611       cat = ast_category_browse(cfg, cat);
12612    }
12613    if (ast_find_ourip(&__ourip, bindaddr)) {
12614       ast_log(LOG_WARNING, "Unable to get own IP address, SIP disabled\n");
12615       return 0;
12616    }
12617    if (!ntohs(bindaddr.sin_port))
12618       bindaddr.sin_port = ntohs(DEFAULT_SIP_PORT);
12619    bindaddr.sin_family = AF_INET;
12620    ast_mutex_lock(&netlock);
12621    if ((sipsock > -1) && (memcmp(&old_bindaddr, &bindaddr, sizeof(struct sockaddr_in)))) {
12622       close(sipsock);
12623       sipsock = -1;
12624    }
12625    if (sipsock < 0) {
12626       sipsock = socket(AF_INET, SOCK_DGRAM, 0);
12627       if (sipsock < 0) {
12628          ast_log(LOG_WARNING, "Unable to create SIP socket: %s\n", strerror(errno));
12629       } else {
12630          /* Allow SIP clients on the same host to access us: */
12631          const int reuseFlag = 1;
12632          setsockopt(sipsock, SOL_SOCKET, SO_REUSEADDR,
12633                (const char*)&reuseFlag,
12634                sizeof reuseFlag);
12635 
12636          if (bind(sipsock, (struct sockaddr *)&bindaddr, sizeof(bindaddr)) < 0) {
12637             ast_log(LOG_WARNING, "Failed to bind to %s:%d: %s\n",
12638             ast_inet_ntoa(iabuf, sizeof(iabuf), bindaddr.sin_addr), ntohs(bindaddr.sin_port),
12639             strerror(errno));
12640             close(sipsock);
12641             sipsock = -1;
12642          } else {
12643             if (option_verbose > 1) { 
12644                ast_verbose(VERBOSE_PREFIX_2 "SIP Listening on %s:%d\n", 
12645                ast_inet_ntoa(iabuf, sizeof(iabuf), bindaddr.sin_addr), ntohs(bindaddr.sin_port));
12646                ast_verbose(VERBOSE_PREFIX_2 "Using TOS bits %d\n", tos);
12647             }
12648             if (setsockopt(sipsock, IPPROTO_IP, IP_TOS, &tos, sizeof(tos))) 
12649                ast_log(LOG_WARNING, "Unable to set TOS to %d\n", tos);
12650          }
12651       }
12652    }
12653    ast_mutex_unlock(&netlock);
12654 
12655    /* Add default domains - host name, IP address and IP:port */
12656    /* Only do this if user added any sip domain with "localdomains" */
12657    /* In order to *not* break backwards compatibility */
12658    /*    Some phones address us at IP only, some with additional port number */
12659    if (auto_sip_domains) {
12660       char temp[MAXHOSTNAMELEN];
12661 
12662       /* First our default IP address */
12663       if (bindaddr.sin_addr.s_addr) {
12664          ast_inet_ntoa(temp, sizeof(temp), bindaddr.sin_addr);
12665          add_sip_domain(temp, SIP_DOMAIN_AUTO, NULL);
12666       } else {
12667          ast_log(LOG_NOTICE, "Can't add wildcard IP address to domain list, please add IP address to domain manually.\n");
12668       }
12669 
12670       /* Our extern IP address, if configured */
12671       if (externip.sin_addr.s_addr) {
12672          ast_inet_ntoa(temp, sizeof(temp), externip.sin_addr);
12673          add_sip_domain(temp, SIP_DOMAIN_AUTO, NULL);
12674       }
12675 
12676       /* Extern host name (NAT traversal support) */
12677       if (!ast_strlen_zero(externhost))
12678          add_sip_domain(externhost, SIP_DOMAIN_AUTO, NULL);
12679       
12680       /* Our host name */
12681       if (!gethostname(temp, sizeof(temp)))
12682          add_sip_domain(temp, SIP_DOMAIN_AUTO, NULL);
12683    }
12684 
12685    /* Release configuration from memory */
12686    ast_config_destroy(cfg);
12687 
12688    /* Load the list of manual NOTIFY types to support */
12689    if (notify_types)
12690       ast_config_destroy(notify_types);
12691    notify_types = ast_config_load(notify_config);
12692 
12693    return 0;
12694 }

static 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 8919 of file chan_sip.c.

References ast_log(), ast_strlen_zero(), sip_pvt::domain, get_header(), key(), keys, LOG_WARNING, sip_pvt::nonce, sip_pvt::opaque, sip_pvt::qop, sip_pvt::realm, and strsep().

Referenced by do_proxy_auth(), and do_register_auth().

08921 {
08922    char tmp[512];
08923    char *c;
08924    char oldnonce[256];
08925 
08926    /* table of recognised keywords, and places where they should be copied */
08927    const struct x {
08928       const char *key;
08929       char *dst;
08930       int dstlen;
08931    } *i, keys[] = {
08932       { "realm=", p->realm, sizeof(p->realm) },
08933       { "nonce=", p->nonce, sizeof(p->nonce) },
08934       { "opaque=", p->opaque, sizeof(p->opaque) },
08935       { "qop=", p->qop, sizeof(p->qop) },
08936       { "domain=", p->domain, sizeof(p->domain) },
08937       { NULL, NULL, 0 },
08938    };
08939 
08940    ast_copy_string(tmp, get_header(req, header), sizeof(tmp));
08941    if (ast_strlen_zero(tmp)) 
08942       return -1;
08943    if (strncasecmp(tmp, "Digest ", strlen("Digest "))) {
08944       ast_log(LOG_WARNING, "missing Digest.\n");
08945       return -1;
08946    }
08947    c = tmp + strlen("Digest ");
08948    for (i = keys; i->key != NULL; i++)
08949       i->dst[0] = '\0'; /* init all to empty strings */
08950    ast_copy_string(oldnonce, p->nonce, sizeof(oldnonce));
08951    while (c && *(c = ast_skip_blanks(c))) {  /* lookup for keys */
08952       for (i = keys; i->key != NULL; i++) {
08953          char *src, *separator;
08954          if (strncasecmp(c, i->key, strlen(i->key)) != 0)
08955             continue;
08956          /* Found. Skip keyword, take text in quotes or up to the separator. */
08957          c += strlen(i->key);
08958          if (*c == '\"') {
08959             src = ++c;
08960             separator = "\"";
08961          } else {
08962             src = c;
08963             separator = ",";
08964          }
08965          strsep(&c, separator); /* clear separator and move ptr */
08966          ast_copy_string(i->dst, src, i->dstlen);
08967          break;
08968       }
08969       if (i->key == NULL) /* not found, try ',' */
08970          strsep(&c, ",");
08971    }
08972    /* Reset nonce count */
08973    if (strcmp(p->nonce, oldnonce)) 
08974       p->noncecount = 0;
08975 
08976    /* Save auth data for following registrations */
08977    if (p->registry) {
08978       struct sip_registry *r = p->registry;
08979 
08980       if (strcmp(r->nonce, p->nonce)) {
08981          ast_copy_string(r->realm, p->realm, sizeof(r->realm));
08982          ast_copy_string(r->nonce, p->nonce, sizeof(r->nonce));
08983          ast_copy_string(r->domain, p->domain, sizeof(r->domain));
08984          ast_copy_string(r->opaque, p->opaque, sizeof(r->opaque));
08985          ast_copy_string(r->qop, p->qop, sizeof(r->qop));
08986          r->noncecount = 0;
08987       }
08988    }
08989    return build_reply_digest(p, sipmethod, digest, digest_len); 
08990 }

static 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 4030 of file chan_sip.c.

References add_header(), add_route(), ast_strlen_zero(), ast_test_flag, sip_pvt::branch, build_via(), copy_header(), DEFAULT_MAX_FORWARDS, default_useragent, get_header(), get_in_brackets(), sip_route::hop, init_req(), sip_pvt::initreq, sip_pvt::lastmsg, n, sip_route::next, sip_pvt::ocseq, sip_pvt::okcontacturi, sip_pvt::our_contact, sip_request::rlPart2, sip_pvt::route, sip_pvt::rpid, set_destination(), SIP_ACK, SIP_CANCEL, sip_methods, SIP_OUTGOING, strcasestr(), text, cfsip_methods::text, thread_safe_rand(), sip_pvt::uri, and sip_pvt::via.

04031 {
04032    struct sip_request *orig = &p->initreq;
04033    char stripped[80];
04034    char tmp[80];
04035    char newto[256];
04036    char *c, *n;
04037    char *ot, *of;
04038    int is_strict = 0;   /* Strict routing flag */
04039 
04040    memset(req, 0, sizeof(struct sip_request));
04041    
04042    snprintf(p->lastmsg, sizeof(p->lastmsg), "Tx: %s", sip_methods[sipmethod].text);
04043    
04044    if (!seqno) {
04045       p->ocseq++;
04046       seqno = p->ocseq;
04047    }
04048    
04049    if (newbranch) {
04050       p->branch ^= thread_safe_rand();
04051       build_via(p, p->via, sizeof(p->via));
04052    }
04053 
04054    /* Check for strict or loose router */
04055    if (p->route && !ast_strlen_zero(p->route->hop) && strstr(p->route->hop,";lr") == NULL)
04056       is_strict = 1;
04057 
04058    if (sipmethod == SIP_CANCEL) {
04059       c = p->initreq.rlPart2; /* Use original URI */
04060    } else if (sipmethod == SIP_ACK) {
04061       /* Use URI from Contact: in 200 OK (if INVITE) 
04062       (we only have the contacturi on INVITEs) */
04063       if (!ast_strlen_zero(p->okcontacturi))
04064          c = is_strict ? p->route->hop : p->okcontacturi;
04065       else
04066          c = p->initreq.rlPart2;
04067    } else if (!ast_strlen_zero(p->okcontacturi)) {
04068          c = is_strict ? p->route->hop : p->okcontacturi; /* Use for BYE or REINVITE */
04069    } else if (!ast_strlen_zero(p->uri)) {
04070       c = p->uri;
04071    } else {
04072       /* We have no URI, use To: or From:  header as URI (depending on direction) */
04073       c = get_header(orig, (ast_test_flag(p, SIP_OUTGOING)) ? "To" : "From");
04074       ast_copy_string(stripped, c, sizeof(stripped));
04075       c = get_in_brackets(stripped);
04076       n = strchr(c, ';');
04077       if (n)
04078          *n = '\0';
04079    }  
04080    init_req(req, sipmethod, c);
04081 
04082    snprintf(tmp, sizeof(tmp), "%d %s", seqno, sip_methods[sipmethod].text);
04083 
04084    add_header(req, "Via", p->via);
04085    if (p->route) {
04086       set_destination(p, p->route->hop);
04087       if (is_strict)
04088          add_route(req, p->route->next);
04089       else
04090          add_route(req, p->route);
04091    }
04092 
04093    ot = get_header(orig, "To");
04094    of = get_header(orig, "From");
04095 
04096    /* Add tag *unless* this is a CANCEL, in which case we need to send it exactly
04097       as our original request, including tag (or presumably lack thereof) */
04098    if (!strcasestr(ot, "tag=") && sipmethod != SIP_CANCEL) {
04099       /* Add the proper tag if we don't have it already.  If they have specified
04100          their tag, use it.  Otherwise, use our own tag */
04101       if (ast_test_flag(p, SIP_OUTGOING) && !ast_strlen_zero(p->theirtag))
04102          snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->theirtag);
04103       else if (!ast_test_flag(p, SIP_OUTGOING))
04104          snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->tag);
04105       else
04106          snprintf(newto, sizeof(newto), "%s", ot);
04107       ot = newto;
04108    }
04109 
04110    if (ast_test_flag(p, SIP_OUTGOING)) {
04111       add_header(req, "From", of);
04112       add_header(req, "To", ot);
04113    } else {
04114       add_header(req, "From", ot);
04115       add_header(req, "To", of);
04116    }
04117    add_header(req, "Contact", p->our_contact);
04118    copy_header(req, orig, "Call-ID");
04119    add_header(req, "CSeq", tmp);
04120 
04121    add_header(req, "User-Agent", default_useragent);
04122    add_header(req, "Max-Forwards", DEFAULT_MAX_FORWARDS);
04123 
04124    if (p->rpid)
04125       add_header(req, "Remote-Party-ID", p->rpid);
04126 
04127    return 0;
04128 }

static 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 3982 of file chan_sip.c.

References add_header(), ALLOWED_METHODS, ast_strlen_zero(), ast_test_flag, copy_all_header(), copy_header(), copy_via_headers(), default_useragent, sip_pvt::expiry, get_header(), init_resp(), sip_pvt::method, sip_pvt::our_contact, SIP_OUTGOING, SIP_REGISTER, SIP_SUBSCRIBE, strcasestr(), sip_pvt::tag, and sip_pvt::theirtag.

03983 {
03984    char newto[256], *ot;
03985 
03986    memset(resp, 0, sizeof(*resp));
03987    init_resp(resp, msg, req);
03988    copy_via_headers(p, resp, req, "Via");
03989    if (msg[0] == '2')
03990       copy_all_header(resp, req, "Record-Route");
03991    copy_header(resp, req, "From");
03992    ot = get_header(req, "To");
03993    if (!strcasestr(ot, "tag=") && strncmp(msg, "100", 3)) {
03994       /* Add the proper tag if we don't have it already.  If they have specified
03995          their tag, use it.  Otherwise, use our own tag */
03996       if (!ast_strlen_zero(p->theirtag) && ast_test_flag(p, SIP_OUTGOING))
03997          snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->theirtag);
03998       else if (p->tag && !ast_test_flag(p, SIP_OUTGOING))
03999          snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->tag);
04000       else {
04001          ast_copy_string(newto, ot, sizeof(newto));
04002          newto[sizeof(newto) - 1] = '\0';
04003       }
04004       ot = newto;
04005    }
04006    add_header(resp, "To", ot);
04007    copy_header(resp, req, "Call-ID");
04008    copy_header(resp, req, "CSeq");
04009    add_header(resp, "User-Agent", default_useragent);
04010    add_header(resp, "Allow", ALLOWED_METHODS);
04011    if (msg[0] == '2' && (p->method == SIP_SUBSCRIBE || p->method == SIP_REGISTER)) {
04012       /* For registration responses, we also need expiry and
04013          contact info */
04014       char tmp[256];
04015 
04016       snprintf(tmp, sizeof(tmp), "%d", p->expiry);
04017       add_header(resp, "Expires", tmp);
04018       if (p->expiry) {  /* Only add contact if we have an expiry time */
04019          char contact[256];
04020          snprintf(contact, sizeof(contact), "%s;expires=%d", p->our_contact, p->expiry);
04021          add_header(resp, "Contact", contact);  /* Not when we unregister */
04022       }
04023    } else if (p->our_contact[0]) {
04024       add_header(resp, "Contact", p->our_contact);
04025    }
04026    return 0;
04027 }

static int restart_monitor void   )  [static]
 

restart_monitor: Start the channel monitor thread ---

Definition at line 11360 of file chan_sip.c.

References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_pthread_create, AST_PTHREADT_NULL, AST_PTHREADT_STOP, do_monitor(), LOG_ERROR, LOG_WARNING, and monitor_thread.

11361 {
11362    /* If we're supposed to be stopped -- stay stopped */
11363    if (monitor_thread == AST_PTHREADT_STOP)
11364       return 0;
11365    if (ast_mutex_lock(&monlock)) {
11366       ast_log(LOG_WARNING, "Unable to lock monitor\n");
11367       return -1;
11368    }
11369    if (monitor_thread == pthread_self()) {
11370       ast_mutex_unlock(&monlock);
11371       ast_log(LOG_WARNING, "Cannot kill myself\n");
11372       return -1;
11373    }
11374    if (monitor_thread != AST_PTHREADT_NULL) {
11375       /* Wake up the thread */
11376       pthread_kill(monitor_thread, SIGURG);
11377    } else {
11378       /* Start a new monitor */
11379       if (ast_pthread_create(&monitor_thread, NULL, do_monitor, NULL) < 0) {
11380          ast_mutex_unlock(&monlock);
11381          ast_log(LOG_ERROR, "Unable to start monitor thread.\n");
11382          return -1;
11383       }
11384    }
11385    ast_mutex_unlock(&monlock);
11386    return 0;
11387 }

static 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, DEFAULT_RETRANS, FLAG_FATAL, FLAG_RESPONSE, free, ast_channel::lock, sip_pvt::lock, LOG_DEBUG, LOG_WARNING, MAX_RETRANS, sip_pkt::method, sip_pkt::next, option_debug, sip_pvt::owner, sip_pkt::owner, sip_pkt::packetlen, sip_pvt::packets, sip_pvt::recv, sip_pkt::retrans, sip_pkt::retransid, sip_pvt::sa, SIP_ALREADYGONE, sip_debug_test_pvt(), SIP_INVITE, sip_methods, SIP_NAT, SIP_NAT_ROUTE, SIP_NEEDDESTROY, SIP_OPTIONS, sip_pkt::timer_a, and sip_pkt::timer_t1.

01158 {
01159    struct sip_pkt *pkt=data, *prev, *cur = NULL;
01160    char iabuf[INET_ADDRSTRLEN];
01161    int reschedule = DEFAULT_RETRANS;
01162 
01163    /* Lock channel */
01164    ast_mutex_lock(&pkt->owner->lock);
01165 
01166    if (pkt->retrans < MAX_RETRANS) {
01167       char buf[80];
01168 
01169       pkt->retrans++;
01170       if (!pkt->timer_t1) {   /* Re-schedule using timer_a and timer_t1 */
01171          if (sipdebug && option_debug > 3)
01172             ast_log(LOG_DEBUG, "SIP TIMER: Not rescheduling id #%d:%s (Method %d) (No timer T1)\n", pkt->retransid, sip_methods[pkt->method].text, pkt->method);
01173       } else {
01174          int siptimer_a;
01175 
01176          if (sipdebug && option_debug > 3)
01177             ast_log(LOG_DEBUG, "SIP TIMER: Rescheduling retransmission #%d (%d) %s - %d\n", pkt->retransid, pkt->retrans, sip_methods[pkt->method].text, pkt->method);
01178          if (!pkt->timer_a)
01179             pkt->timer_a = 2 ;
01180          else
01181             pkt->timer_a = 2 * pkt->timer_a;
01182  
01183          /* For non-invites, a maximum of 4 secs */
01184          siptimer_a = pkt->timer_t1 * pkt->timer_a;   /* Double each time */
01185          if (pkt->method != SIP_INVITE && siptimer_a > 4000)
01186             siptimer_a = 4000;
01187       
01188          /* Reschedule re-transmit */
01189          reschedule = siptimer_a;
01190          if (option_debug > 3)
01191             ast_log(LOG_DEBUG, "** SIP timers: Rescheduling retransmission %d to %d ms (t1 %d ms (Retrans id #%d)) \n", pkt->retrans +1, siptimer_a, pkt->timer_t1, pkt->retransid);
01192       } 
01193 
01194       if (pkt->owner && sip_debug_test_pvt(pkt->owner)) {
01195          if (ast_test_flag(pkt->owner, SIP_NAT) & SIP_NAT_ROUTE)
01196             ast_verbose("Retransmitting #%d (NAT) to %s:%d:\n%s\n---\n", pkt->retrans, ast_inet_ntoa(iabuf, sizeof(iabuf), pkt->owner->recv.sin_addr), ntohs(pkt->owner->recv.sin_port), pkt->data);
01197          else
01198             ast_verbose("Retransmitting #%d (no NAT) to %s:%d:\n%s\n---\n", pkt->retrans, ast_inet_ntoa(iabuf, sizeof(iabuf), pkt->owner->sa.sin_addr), ntohs(pkt->owner->sa.sin_port), pkt->data);
01199       }
01200       snprintf(buf, sizeof(buf), "ReTx %d", reschedule);
01201 
01202       append_history(pkt->owner, buf, pkt->data);
01203       __sip_xmit(pkt->owner, pkt->data, pkt->packetlen);
01204       ast_mutex_unlock(&pkt->owner->lock);
01205       return  reschedule;
01206    } 
01207    /* Too many retries */
01208    if (pkt->owner && pkt->method != SIP_OPTIONS) {
01209       if (ast_test_flag(pkt, FLAG_FATAL) || sipdebug) /* Tell us if it's critical or if we're debugging */
01210          ast_log(LOG_WARNING, "Maximum retries exceeded on transmission %s for seqno %d (%s %s)\n", pkt->owner->callid, pkt->seqno, (ast_test_flag(pkt, FLAG_FATAL)) ? "Critical" : "Non-critical", (ast_test_flag(pkt, FLAG_RESPONSE)) ? "Response" : "Request");
01211    } else {
01212       if (pkt->method == SIP_OPTIONS && sipdebug)
01213          ast_log(LOG_WARNING, "Cancelling retransmit of OPTIONs (call id %s) \n", pkt->owner->callid);
01214    }
01215    append_history(pkt->owner, "MaxRetries", (ast_test_flag(pkt, FLAG_FATAL)) ? "(Critical)" : "(Non-critical)");
01216       
01217    pkt->retransid = -1;
01218 
01219    if (ast_test_flag(pkt, FLAG_FATAL)) {
01220       while(pkt->owner->owner && ast_mutex_trylock(&pkt->owner->owner->lock)) {
01221          ast_mutex_unlock(&pkt->owner->lock);
01222          usleep(1);
01223          ast_mutex_lock(&pkt->owner->lock);
01224       }
01225       if (pkt->owner->owner) {
01226          ast_set_flag(pkt->owner, SIP_ALREADYGONE);
01227          ast_log(LOG_WARNING, "Hanging up call %s - no reply to our critical packet.\n", pkt->owner->callid);
01228          ast_queue_hangup(pkt->owner->owner);
01229          ast_mutex_unlock(&pkt->owner->owner->lock);
01230       } else {
01231          /* If no channel owner, destroy now */
01232          ast_set_flag(pkt->owner, SIP_NEEDDESTROY);   
01233       }
01234    }
01235    /* In any case, go ahead and remove the packet */
01236    prev = NULL;
01237    cur = pkt->owner->packets;
01238    while(cur) {
01239       if (cur == pkt)
01240          break;
01241       prev = cur;
01242       cur = cur->next;
01243    }
01244    if (cur) {
01245       if (prev)
01246          prev->next = cur->next;
01247       else
01248          pkt->owner->packets = cur->next;
01249       ast_mutex_unlock(&pkt->owner->lock);
01250       free(cur);
01251       pkt = NULL;
01252    } else
01253       ast_log(LOG_WARNING, "Weird, couldn't find packet owner!\n");
01254    if (pkt)
01255       ast_mutex_unlock(&pkt->owner->lock);
01256    return 0;
01257 }

static void sdpLineNum_iterator_init int *  iterator  )  [static]
 

Definition at line 2876 of file chan_sip.c.

02877 {
02878    *iterator = 0;
02879 }

static 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_debug_test_pvt(), SIP_NAT, and SIP_NAT_ROUTE.

01500 {
01501    int res;
01502    char iabuf[INET_ADDRSTRLEN];
01503    struct sip_request tmp;
01504    char tmpmsg[80];
01505 
01506    if (sip_debug_test_pvt(p)) {
01507       if (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE)
01508          ast_verbose("%sTransmitting (NAT) to %s:%d:\n%s\n---\n", reliable ? "Reliably " : "", ast_inet_ntoa(iabuf, sizeof(iabuf), p->recv.sin_addr), ntohs(p->recv.sin_port), req->data);
01509       else
01510          ast_verbose("%sTransmitting (no NAT) to %s:%d:\n%s\n---\n", reliable ? "Reliably " : "", ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr), ntohs(p->sa.sin_port), req->data);
01511    }
01512    if (reliable) {
01513       if (recordhistory) {
01514          parse_copy(&tmp, req);
01515          snprintf(tmpmsg, sizeof(tmpmsg), "%s / %s", tmp.data, get_header(&tmp, "CSeq"));
01516          append_history(p, "TxReqRel", tmpmsg);
01517       }
01518       res = __sip_reliable_xmit(p, seqno, 0, req->data, req->len, (reliable > 1), req->method);
01519    } else {
01520       if (recordhistory) {
01521          parse_copy(&tmp, req);
01522          snprintf(tmpmsg, sizeof(tmpmsg), "%s / %s", tmp.data, get_header(&tmp, "CSeq"));
01523          append_history(p, "TxReq", tmpmsg);
01524       }
01525       res = __sip_xmit(p, req->data, req->len);
01526    }
01527    return res;
01528 }

static 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_debug_test_pvt(), SIP_NAT, and SIP_NAT_ROUTE.

01466 {
01467    int res;
01468    char iabuf[INET_ADDRSTRLEN];
01469    struct sip_request tmp;
01470    char tmpmsg[80];
01471 
01472    if (sip_debug_test_pvt(p)) {
01473       if (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE)
01474          ast_verbose("%sTransmitting (NAT) to %s:%d:\n%s\n---\n", reliable ? "Reliably " : "", ast_inet_ntoa(iabuf, sizeof(iabuf), p->recv.sin_addr), ntohs(p->recv.sin_port), req->data);
01475       else
01476          ast_verbose("%sTransmitting (no NAT) to %s:%d:\n%s\n---\n", reliable ? "Reliably " : "", ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr), ntohs(p->sa.sin_port), req->data);
01477    }
01478    if (reliable) {
01479       if (recordhistory) {
01480          parse_copy(&tmp, req);
01481          snprintf(tmpmsg, sizeof(tmpmsg), "%s / %s", tmp.data, get_header(&tmp, "CSeq"));
01482          append_history(p, "TxRespRel", tmpmsg);
01483       }
01484       res = __sip_reliable_xmit(p, seqno, 1, req->data, req->len, (reliable > 1), req->method);
01485    } else {
01486       if (recordhistory) {
01487          parse_copy(&tmp, req);
01488          snprintf(tmpmsg, sizeof(tmpmsg), "%s / %s", tmp.data, get_header(&tmp, "CSeq"));
01489          append_history(p, "TxResp", tmpmsg);
01490       }
01491       res = __sip_xmit(p, req->data, req->len);
01492    }
01493    if (res > 0)
01494       return 0;
01495    return res;
01496 }

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

set_destination: Set destination from SIP URI ---

Definition at line 3886 of file chan_sip.c.

References ahp, ast_gethostbyname(), ast_inet_ntoa(), ast_log(), ast_verbose(), debug, DEFAULT_SIP_PORT, hostname, hp, LOG_WARNING, sip_pvt::sa, and sip_debug_test_pvt().

Referenced by reqprep().

03887 {
03888    char *h, *maddr, hostname[256];
03889    char iabuf[INET_ADDRSTRLEN];
03890    int port, hn;
03891    struct hostent *hp;
03892    struct ast_hostent ahp;
03893    int debug=sip_debug_test_pvt(p);
03894 
03895    /* Parse uri to h (host) and port - uri is already just the part inside the <> */
03896    /* general form we are expecting is sip[s]:username[:password]@host[:port][;...] */
03897 
03898    if (debug)
03899       ast_verbose("set_destination: Parsing <%s> for address/port to send to\n", uri);
03900 
03901    /* Find and parse hostname */
03902    h = strchr(uri, '@');
03903    if (h)
03904       ++h;
03905    else {
03906       h = uri;
03907       if (strncmp(h, "sip:", 4) == 0)
03908          h += 4;
03909       else if (strncmp(h, "sips:", 5) == 0)
03910          h += 5;
03911    }
03912    hn = strcspn(h, ":;>") + 1;
03913    if (hn > sizeof(hostname)) 
03914       hn = sizeof(hostname);
03915    ast_copy_string(hostname, h, hn);
03916    h += hn - 1;
03917 
03918    /* Is "port" present? if not default to DEFAULT_SIP_PORT */
03919    if (*h == ':') {
03920       /* Parse port */
03921       ++h;
03922       port = strtol(h, &h, 10);
03923    }
03924    else
03925       port = DEFAULT_SIP_PORT;
03926 
03927    /* Got the hostname:port - but maybe there's a "maddr=" to override address? */
03928    maddr = strstr(h, "maddr=");
03929    if (maddr) {
03930       maddr += 6;
03931       hn = strspn(maddr, "0123456789.") + 1;
03932       if (hn > sizeof(hostname)) hn = sizeof(hostname);
03933       ast_copy_string(hostname, maddr, hn);
03934    }
03935    
03936    hp = ast_gethostbyname(hostname, &ahp);
03937    if (hp == NULL)  {
03938       ast_log(LOG_WARNING, "Can't find address for host '%s'\n", hostname);
03939       return;
03940    }
03941    p->sa.sin_family = AF_INET;
03942    memcpy(&p->sa.sin_addr, hp->h_addr, sizeof(p->sa.sin_addr));
03943    p->sa.sin_port = htons(port);
03944    if (debug)
03945       ast_verbose("set_destination: set destination to %s, port %d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr), port);
03946 }

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

sip_addheader: Add a SIP header ---

Definition at line 12843 of file chan_sip.c.

References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_strlen_zero(), ast_channel::lock, LOG_DEBUG, LOG_WARNING, pbx_builtin_getvar_helper(), pbx_builtin_setvar_helper(), and sipdebug.

Referenced by load_module().

12844 {
12845    int no = 0;
12846    int ok = 0;
12847    char varbuf[128];
12848    
12849    if (ast_strlen_zero((char *)data)) {
12850       ast_log(LOG_WARNING, "This application requires the argument: Header\n");
12851       return 0;
12852    }
12853    ast_mutex_lock(&chan->lock);
12854 
12855    /* Check for headers */
12856    while (!ok && no <= 50) {
12857       no++;
12858       snprintf(varbuf, sizeof(varbuf), "_SIPADDHEADER%02d", no);
12859       if (ast_strlen_zero(pbx_builtin_getvar_helper(chan, varbuf + 1)))
12860          ok = 1;
12861    }
12862    if (ok) {
12863       pbx_builtin_setvar_helper (chan, varbuf, (char *)data);
12864       if (sipdebug)
12865          ast_log(LOG_DEBUG,"SIP Header added \"%s\" as %s\n", (char *) data, varbuf);
12866    } else {
12867       ast_log(LOG_WARNING, "Too many SIP headers added, max 50\n");
12868    }
12869    ast_mutex_unlock(&chan->lock);
12870    return 0;
12871 }

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

static 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 3034 of file chan_sip.c.

References __ourip, ast_copy_flags, ast_log(), ast_mutex_destroy(), ast_mutex_init(), ast_mutex_lock(), ast_mutex_unlock(), AST_RTP_DTMF, ast_rtp_new_with_bindaddr(), ast_rtp_setnat(), ast_rtp_settos(), ast_sip_ouraddrfor(), ast_test_flag, ast_variables_destroy(), bindaddr, build_callid(), build_via(), calloc, default_context, default_fromdomain, free, global_capability, global_flags, global_musicclass, global_rtpholdtimeout, global_rtpkeepalive, global_rtptimeout, iflist, io, LOG_DEBUG, LOG_WARNING, make_our_tag(), NONE, option_debug, prefs, SIP_DTMF, SIP_DTMF_AUTO, SIP_DTMF_RFC2833, SIP_FLAGS_TO_COPY, sip_methods, SIP_NAT, SIP_NAT_ROUTE, SIP_OPTIONS, SIP_REGISTER, text, thread_safe_rand(), tos, and videosupport.

Referenced by find_call(), sip_notify(), sip_poke_peer(), sip_request_call(), sip_send_mwi_to_peer(), and transmit_register().

03035 {
03036    struct sip_pvt *p;
03037 
03038    if (!(p = calloc(1, sizeof(*p))))
03039       return NULL;
03040 
03041    ast_mutex_init(&p->lock);
03042 
03043    p->method = intended_method;
03044    p->initid = -1;
03045    p->autokillid = -1;
03046    p->subscribed = NONE;
03047    p->stateid = -1;
03048    p->prefs = prefs;
03049    if (intended_method != SIP_OPTIONS) /* Peerpoke has it's own system */
03050       p->timer_t1 = 500;   /* Default SIP retransmission timer T1 (RFC 3261) */
03051 #ifdef OSP_SUPPORT
03052    p->osphandle = -1;
03053    p->osptimelimit = 0;
03054 #endif   
03055    if (sin) {
03056       memcpy(&p->sa, sin, sizeof(p->sa));
03057       if (ast_sip_ouraddrfor(&p->sa.sin_addr,&p->ourip))
03058          memcpy(&p->ourip, &__ourip, sizeof(p->ourip));
03059    } else {
03060       memcpy(&p->ourip, &__ourip, sizeof(p->ourip));
03061    }
03062 
03063    p->branch = thread_safe_rand();  
03064    make_our_tag(p->tag, sizeof(p->tag));
03065    /* Start with 101 instead of 1 */
03066    p->ocseq = 101;
03067 
03068    if (sip_methods[intended_method].need_rtp) {
03069       p->rtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr.sin_addr);
03070       if (videosupport)
03071          p->vrtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr.sin_addr);
03072       if (!p->rtp || (videosupport && !p->vrtp)) {
03073          ast_log(LOG_WARNING, "Unable to create RTP audio %s session: %s\n", videosupport ? "and video" : "", strerror(errno));
03074          ast_mutex_destroy(&p->lock);
03075          if (p->chanvars) {
03076             ast_variables_destroy(p->chanvars);
03077             p->chanvars = NULL;
03078          }
03079          free(p);
03080          return NULL;
03081       }
03082       ast_rtp_settos(p->rtp, tos);
03083       if (p->vrtp)
03084          ast_rtp_settos(p->vrtp, tos);
03085       p->rtptimeout = global_rtptimeout;
03086       p->rtpholdtimeout = global_rtpholdtimeout;
03087       p->rtpkeepalive = global_rtpkeepalive;
03088    }
03089 
03090    if (useglobal_nat && sin) {
03091       /* Setup NAT structure according to global settings if we have an address */
03092       ast_copy_flags(p, &global_flags, SIP_NAT);
03093       memcpy(&p->recv, sin, sizeof(p->recv));
03094       if (p->rtp)
03095          ast_rtp_setnat(p->rtp, (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE));
03096       if (p->vrtp)
03097          ast_rtp_setnat(p->vrtp, (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE));
03098    }
03099 
03100    if (p->method != SIP_REGISTER)
03101       ast_copy_string(p->fromdomain, default_fromdomain, sizeof(p->fromdomain));
03102    build_via(p, p->via, sizeof(p->via));
03103    if (!callid)
03104       build_callid(p->callid, sizeof(p->callid), p->ourip, p->fromdomain);
03105    else
03106       ast_copy_string(p->callid, callid, sizeof(p->callid));
03107    ast_copy_flags(p, &global_flags, SIP_FLAGS_TO_COPY);
03108    /* Assign default music on hold class */
03109    strcpy(p->musicclass, global_musicclass);
03110    p->capability = global_capability;
03111    if ((ast_test_flag(p, SIP_DTMF) == SIP_DTMF_RFC2833) || (ast_test_flag(p, SIP_DTMF) == SIP_DTMF_AUTO))
03112       p->noncodeccapability |= AST_RTP_DTMF;
03113    strcpy(p->context, default_context);
03114 
03115    /* Add to active dialog list */
03116    ast_mutex_lock(&iflock);
03117    p->next = iflist;
03118    iflist = p;
03119    ast_mutex_unlock(&iflock);
03120    if (option_debug)
03121       ast_log(LOG_DEBUG, "Allocating new SIP dialog for %s - %s (%s)\n", callid ? callid : "(No Call-ID)", sip_methods[intended_method].text, p->rtp ? "With RTP" : "No RTP");
03122    return p;
03123 }

static int sip_answer struct ast_channel ast  )  [static]
 

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

Definition at line 2513 of file chan_sip.c.

References ast_channel::_state, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_setstate(), AST_STATE_UP, sip_pvt::initreq, sip_pvt::lock, LOG_DEBUG, ast_channel::name, option_debug, ast_channel::tech_pvt, transmit_response_with_sdp(), and try_suggested_sip_codec().

02514 {
02515    int res = 0;
02516    struct sip_pvt *p = ast->tech_pvt;
02517 
02518    ast_mutex_lock(&p->lock);
02519    if (ast->_state != AST_STATE_UP) {
02520 #ifdef OSP_SUPPORT   
02521       time(&p->ospstart);
02522 #endif
02523       try_suggested_sip_codec(p);   
02524 
02525       ast_setstate(ast, AST_STATE_UP);
02526       if (option_debug)
02527          ast_log(LOG_DEBUG, "sip_answer(%s)\n", ast->name);
02528       res = transmit_response_with_sdp(p, "200 OK", &p->initreq, 1);
02529    }
02530    ast_mutex_unlock(&p->lock);
02531    return res;
02532 }

static 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_STATE_DOWN, AST_STATE_RESERVED, ast_var_name(), ast_var_value(), auto_congest(), sip_pvt::callingpres, sip_pvt::capability, ast_channel::cid, ast_callerid::cid_pres, sip_invite_param::distinctive_ring, INC_CALL_LIMIT, sip_pvt::initid, sip_pvt::jointcapability, LOG_DEBUG, LOG_WARNING, sip_pvt::maxtime, ast_channel::name, sip_pvt::options, sip_invite_param::osptoken, sched, SIP_INVITE, SIP_OUTGOING, ast_channel::tech_pvt, transmit_invite(), update_call_counter(), sip_invite_param::uri_options, sip_pvt::username, ast_channel::varshead, and sip_invite_param::vxml_url.

02005 {
02006    int res;
02007    struct sip_pvt *p;
02008 #ifdef OSP_SUPPORT
02009    char *osphandle = NULL;
02010 #endif   
02011    struct varshead *headp;
02012    struct ast_var_t *current;
02013    
02014 
02015    
02016    p = ast->tech_pvt;
02017    if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) {
02018       ast_log(LOG_WARNING, "sip_call called on %s, neither down nor reserved\n", ast->name);
02019       return -1;
02020    }
02021 
02022 
02023    /* Check whether there is vxml_url, distinctive ring variables */
02024 
02025    headp=&ast->varshead;
02026    AST_LIST_TRAVERSE(headp,current,entries) {
02027       /* Check whether there is a VXML_URL variable */
02028       if (!p->options->vxml_url && !strcasecmp(ast_var_name(current), "VXML_URL")) {
02029          p->options->vxml_url = ast_var_value(current);
02030                } else if (!p->options->uri_options && !strcasecmp(ast_var_name(current), "SIP_URI_OPTIONS")) {
02031                        p->options->uri_options = ast_var_value(current);
02032       } else if (!p->options->distinctive_ring && !strcasecmp(ast_var_name(current), "ALERT_INFO")) {
02033          /* Check whether there is a ALERT_INFO variable */
02034          p->options->distinctive_ring = ast_var_value(current);
02035       } else if (!p->options->addsipheaders && !strncasecmp(ast_var_name(current), "SIPADDHEADER", strlen("SIPADDHEADER"))) {
02036          /* Check whether there is a variable with a name starting with SIPADDHEADER */
02037          p->options->addsipheaders = 1;
02038       }
02039 
02040       
02041 #ifdef OSP_SUPPORT
02042       else if (!p->options->osptoken && !strcasecmp(ast_var_name(current), "OSPTOKEN")) {
02043          p->options->osptoken = ast_var_value(current);
02044       } else if (!osphandle && !strcasecmp(ast_var_name(current), "OSPHANDLE")) {
02045          osphandle = ast_var_value(current);
02046       }
02047 #endif
02048    }
02049    
02050    res = 0;
02051    ast_set_flag(p, SIP_OUTGOING);
02052 #ifdef OSP_SUPPORT
02053    if (!p->options->osptoken || !osphandle || (sscanf(osphandle, "%d", &p->osphandle) != 1)) {
02054       /* Force Disable OSP support */
02055       ast_log(LOG_DEBUG, "Disabling OSP support for this call. osptoken = %s, osphandle = %s\n", p->options->osptoken, osphandle);
02056       p->options->osptoken = NULL;
02057       osphandle = NULL;
02058       p->osphandle = -1;
02059    }
02060 #endif
02061    ast_log(LOG_DEBUG, "Outgoing Call for %s\n", p->username);
02062    res = update_call_counter(p, INC_CALL_LIMIT);
02063    if ( res != -1 ) {
02064       p->callingpres = ast->cid.cid_pres;
02065       p->jointcapability = p->capability;
02066       transmit_invite(p, SIP_INVITE, 1, 2);
02067       if (p->maxtime) {
02068          /* Initialize auto-congest time */
02069          p->initid = ast_sched_add(sched, p->maxtime * 4, auto_congest, p);
02070       }
02071    }
02072    return res;
02073 }

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

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

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 }

static 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, and SIP_NAT_ROUTE.

Referenced by __sip_destroy(), add_sdp(), check_via(), do_register_auth(), get_also_info(), get_destination(), get_rdnis(), get_refer_info(), handle_request(), process_sdp(), receive_message(), retrans_pkt(), send_request(), send_response(), set_destination(), sip_scheddestroy(), sip_sendtext(), transmit_invite(), transmit_notify_with_mwi(), transmit_notify_with_sipfrag(), transmit_register(), transmit_reinvite_with_sdp(), and transmit_sip_request().

01047 {
01048    if (sipdebug == 0)
01049       return 0;
01050    return sip_debug_test_addr(((ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE) ? &p->recv : &p->sa));
01051 }

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

static 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 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(), sched, sip_destroy(), SIP_REALTIME, and SIP_SELFDESTRUCT.

Referenced by _sip_show_peer(), build_peer(), check_user_full(), create_addr(), expire_register(), function_sippeer(), register_verify(), reload_config(), sip_devicestate(), sip_do_debug_peer(), 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 }

static 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(), free, SIP_REALTIME, and user.

Referenced by check_user_full(), reload_config(), sip_show_user(), unload_module(), and update_call_counter().

01768 {
01769    ast_free_ha(user->ha);
01770    if (user->chanvars) {
01771       ast_variables_destroy(user->chanvars);
01772       user->chanvars = NULL;
01773    }
01774    if (ast_test_flag(user, SIP_REALTIME))
01775       ruserobjs--;
01776    else
01777       suserobjs--;
01778    free(user);
01779 }

static int sip_devicestate void *  data  )  [static]
 

sip_devicestate: Part of PBX channel interface ---

Definition at line 11486 of file chan_sip.c.

References sip_peer::addr, ahp, AST_DEVICE_BUSY, AST_DEVICE_INUSE, AST_DEVICE_INVALID, AST_DEVICE_NOT_INUSE, AST_DEVICE_UNAVAILABLE, AST_DEVICE_UNKNOWN, ast_gethostbyname(), ast_log(), ast_strdupa, ASTOBJ_UNREF, sip_peer::call_limit, sip_peer::defaddr, find_peer(), host, hp, sip_peer::inUse, sip_peer::lastms, LOG_DEBUG, sip_peer::maxms, option_debug, and sip_destroy_peer().

11487 {
11488    char *host;
11489    char *tmp;
11490 
11491    struct hostent *hp;
11492    struct ast_hostent ahp;
11493    struct sip_peer *p;
11494 
11495    int res = AST_DEVICE_INVALID;
11496 
11497    host = ast_strdupa(data);
11498    if ((tmp = strchr(host, '@')))
11499       host = tmp + 1;
11500 
11501    if (option_debug > 2) 
11502       ast_log(LOG_DEBUG, "Checking device state for peer %s\n", host);
11503 
11504    if ((p = find_peer(host, NULL, 1))) {
11505       if (p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) {
11506          /* we have an address for the peer */
11507          /* if qualify is turned on, check the status */
11508          if (p->maxms && (p->lastms > p->maxms)) {
11509             res = AST_DEVICE_UNAVAILABLE;
11510          } else {
11511             /* qualify is not on, or the peer is responding properly */
11512             /* check call limit */
11513             if (p->call_limit && (p->inUse == p->call_limit))
11514                res = AST_DEVICE_BUSY;
11515             else if (p->call_limit && p->inUse)
11516                res = AST_DEVICE_INUSE;
11517             else if (p->call_limit)
11518                res = AST_DEVICE_NOT_INUSE;
11519             else
11520                res = AST_DEVICE_UNKNOWN;
11521          }
11522       } else {
11523          /* there is no address, it's unavailable */
11524          res = AST_DEVICE_UNAVAILABLE;
11525       }
11526       ASTOBJ_UNREF(p,sip_destroy_peer);
11527    } else {
11528       hp = ast_gethostbyname(host, &ahp);
11529       if (hp)
11530          res = AST_DEVICE_UNKNOWN;
11531    }
11532 
11533    return res;
11534 }

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

sip_do_debug: Turn on SIP debugging (CLI command)

Definition at line 8751 of file chan_sip.c.

References ast_cli(), debugaddr, RESULT_SHOWUSAGE, RESULT_SUCCESS, SIP_DEBUG_CONSOLE, sip_do_debug_ip(), sip_do_debug_peer(), and sipdebug.

08752 {
08753    int oldsipdebug = sipdebug & SIP_DEBUG_CONSOLE;
08754    if (argc != 2) {
08755       if (argc != 4) 
08756          return RESULT_SHOWUSAGE;
08757       else if (strncmp(argv[2], "ip\0", 3) == 0)
08758          return sip_do_debug_ip(fd, argc, argv);
08759       else if (strncmp(argv[2], "peer\0", 5) == 0)
08760          return sip_do_debug_peer(fd, argc, argv);
08761       else return RESULT_SHOWUSAGE;
08762    }
08763    sipdebug |= SIP_DEBUG_CONSOLE;
08764    memset(&debugaddr, 0, sizeof(debugaddr));
08765    if (oldsipdebug)
08766       ast_cli(fd, "SIP Debugging re-enabled\n");
08767    else
08768       ast_cli(fd, "SIP Debugging enabled\n");
08769    return RESULT_SUCCESS;
08770 }

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

sip_do_debug: Enable SIP Debugging in CLI ---

Definition at line 8695 of file chan_sip.c.

References ahp, ast_cli(), ast_gethostbyname(), ast_inet_ntoa(), debugaddr, hp, RESULT_SHOWUSAGE, RESULT_SUCCESS, SIP_DEBUG_CONSOLE, and sipdebug.

Referenced by sip_do_debug().

08696 {
08697    struct hostent *hp;
08698    struct ast_hostent ahp;
08699    char iabuf[INET_ADDRSTRLEN];
08700    int port = 0;
08701    char *p, *arg;
08702 
08703    if (argc != 4)
08704       return RESULT_SHOWUSAGE;
08705    arg = argv[3];
08706    p = strstr(arg, ":");
08707    if (p) {
08708       *p = '\0';
08709       p++;
08710       port = atoi(p);
08711    }
08712    hp = ast_gethostbyname(arg, &ahp);
08713    if (hp == NULL)  {
08714       return RESULT_SHOWUSAGE;
08715    }
08716    debugaddr.sin_family = AF_INET;
08717    memcpy(&debugaddr.sin_addr, hp->h_addr, sizeof(debugaddr.sin_addr));
08718    debugaddr.sin_port = htons(port);
08719    if (port == 0)
08720       ast_cli(fd, "SIP Debugging Enabled for IP: %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), debugaddr.sin_addr));
08721    else
08722       ast_cli(fd, "SIP Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), debugaddr.sin_addr), port);
08723    sipdebug |= SIP_DEBUG_CONSOLE;
08724    return RESULT_SUCCESS;
08725 }

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

sip_do_debug_peer: Turn on SIP debugging with peer mask

Definition at line 8728 of file chan_sip.c.

References sip_peer::addr, ast_cli(), ast_inet_ntoa(), ASTOBJ_UNREF, debugaddr, find_peer(), RESULT_SHOWUSAGE, RESULT_SUCCESS, SIP_DEBUG_CONSOLE, sip_destroy_peer(), and sipdebug.

Referenced by sip_do_debug().

08729 {
08730    struct sip_peer *peer;
08731    char iabuf[INET_ADDRSTRLEN];
08732    if (argc != 4)
08733       return RESULT_SHOWUSAGE;
08734    peer = find_peer(argv[3], NULL, 1);
08735    if (peer) {
08736       if (peer->addr.sin_addr.s_addr) {
08737          debugaddr.sin_family = AF_INET;
08738          memcpy(&debugaddr.sin_addr, &peer->addr.sin_addr, sizeof(debugaddr.sin_addr));
08739          debugaddr.sin_port = peer->addr.sin_port;
08740          ast_cli(fd, "SIP Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), debugaddr.sin_addr), ntohs(debugaddr.sin_port));
08741          sipdebug |= SIP_DEBUG_CONSOLE;
08742       } else
08743          ast_cli(fd, "Unable to get IP address of peer '%s'\n", argv[3]);
08744       ASTOBJ_UNREF(peer,sip_destroy_peer);
08745    } else
08746       ast_cli(fd, "No such peer '%s'\n", argv[3]);
08747    return RESULT_SUCCESS;
08748 }

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

sip_do_history: Enable SIP History logging (CLI) ---

Definition at line 8830 of file chan_sip.c.

References ast_cli(), recordhistory, RESULT_SHOWUSAGE, and RESULT_SUCCESS.

08831 {
08832    if (argc != 2) {
08833       return RESULT_SHOWUSAGE;
08834    }
08835    recordhistory = 1;
08836    ast_cli(fd, "SIP History Recording Enabled (use 'sip show history')\n");
08837    return RESULT_SUCCESS;
08838 }

static int sip_do_reload void   )  [static]
 

sip_do_reload: Reload module

Definition at line 13038 of file chan_sip.c.

References ast_log(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, authl, clear_realm_authentication(), clear_sip_domains(), LOG_DEBUG, option_debug, regl, and sip_destroy().

Referenced by do_monitor().

13039 {
13040    clear_realm_authentication(authl);
13041    clear_sip_domains();
13042    authl = NULL;
13043 
13044    /* First, destroy all outstanding registry calls */
13045    /* This is needed, since otherwise active registry entries will not be destroyed */
13046    ASTOBJ_CONTAINER_TRAVERSE(&regl, 1, do {
13047       ASTOBJ_RDLOCK(iterator);
13048       if (iterator->call) {
13049          if (option_debug > 2)
13050             ast_log(LOG_DEBUG, "Destroying active SIP dialog for registry %s@%s\n", iterator->username, iterator->hostname);
13051          /* This will also remove references to the registry */
13052          sip_destroy(iterator->call);
13053       }
13054       ASTOBJ_UNLOCK(iterator);
13055    } while(0));
13056 
13057    ASTOBJ_CONTAINER_DESTROYALL(&userl, sip_destroy_user);
13058    ASTOBJ_CONTAINER_DESTROYALL(&regl, sip_registry_destroy);
13059    ASTOBJ_CONTAINER_MARKALL(&peerl);
13060    reload_config();
13061    /* Prune peers who still are supposed to be deleted */
13062    ASTOBJ_CONTAINER_PRUNE_MARKED(&peerl, sip_destroy_peer);
13063 
13064    sip_poke_all_peers();
13065    sip_send_all_registers();
13066 
13067    return 0;
13068 }

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

sip_dtmfmode: change the DTMFmode for a SIP call (application) ---

Definition at line 12793 of file chan_sip.c.

References ast_clear_flag, ast_dsp_free(), ast_dsp_new(), ast_dsp_set_features(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_test_flag, channeltype, DSP_FEATURE_DTMF_DETECT, sip_pvt::lock, ast_channel::lock, LOG_WARNING, SIP_DTMF, SIP_DTMF_INBAND, SIP_DTMF_INFO, SIP_DTMF_RFC2833, ast_channel::tech_pvt, ast_channel::type, and sip_pvt::vad.

Referenced by load_module().

12794 {
12795    struct sip_pvt *p;
12796    char *mode;
12797    if (data)
12798       mode = (char *)data;
12799    else {
12800       ast_log(LOG_WARNING, "This application requires the argument: info, inband, rfc2833\n");
12801       return 0;
12802    }
12803    ast_mutex_lock(&chan->lock);
12804    if (chan->type != channeltype) {
12805       ast_log(LOG_WARNING, "Call this application only on SIP incoming calls\n");
12806       ast_mutex_unlock(&chan->lock);
12807       return 0;
12808    }
12809    p = chan->tech_pvt;
12810    if (!p) {
12811       ast_mutex_unlock(&chan->lock);
12812       return 0;
12813    }
12814    ast_mutex_lock(&p->lock);
12815    if (!strcasecmp(mode,"info")) {
12816       ast_clear_flag(p, SIP_DTMF);
12817       ast_set_flag(p, SIP_DTMF_INFO);
12818    } else if (!strcasecmp(mode,"rfc2833")) {
12819       ast_clear_flag(p, SIP_DTMF);
12820       ast_set_flag(p, SIP_DTMF_RFC2833);
12821    } else if (!strcasecmp(mode,"inband")) { 
12822       ast_clear_flag(p, SIP_DTMF);
12823       ast_set_flag(p, SIP_DTMF_INBAND);
12824    } else
12825       ast_log(LOG_WARNING, "I don't know about this dtmf mode: %s\n",mode);
12826    if (ast_test_flag(p, SIP_DTMF) == SIP_DTMF_INBAND) {
12827       if (!p->vad) {
12828          p->vad = ast_dsp_new();
12829          ast_dsp_set_features(p->vad, DSP_FEATURE_DTMF_DETECT);
12830       }
12831    } else {
12832       if (p->vad) {
12833          ast_dsp_free(p->vad);
12834          p->vad = NULL;
12835       }
12836    }
12837    ast_mutex_unlock(&p->lock);
12838    ast_mutex_unlock(&chan->lock);
12839    return 0;
12840 }

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 8576 of file chan_sip.c.

References ast_log(), sip_pvt::callid, sip_history::event, sip_pvt::history, LOG_DEBUG, sip_history::next, and sip_pvt::subscribed.

Referenced by __sip_destroy().

08577 {
08578    int x;
08579    struct sip_history *hist;
08580 
08581    if (!dialog)
08582       return;
08583 
08584    ast_log(LOG_DEBUG, "\n---------- SIP HISTORY for '%s' \n", dialog->callid);
08585    if (dialog->subscribed)
08586       ast_log(LOG_DEBUG, "  * Subscription\n");
08587    else
08588       ast_log(LOG_DEBUG, "  * SIP Call\n");
08589    x = 0;
08590    hist = dialog->history;
08591    while(hist) {
08592       x++;
08593       ast_log(LOG_DEBUG, "  %d. %s\n", x, hist->event);
08594       hist = hist->next;
08595    }
08596    if (!x)
08597       ast_log(LOG_DEBUG, "Call '%s' has no history\n", dialog->callid);
08598    ast_log(LOG_DEBUG, "\n---------- END SIP HISTORY for '%s' \n", dialog->callid);
08599    
08600 }

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

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

Definition at line 2588 of file chan_sip.c.

References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), sip_pvt::lock, LOG_WARNING, sip_pvt::owner, and ast_channel::tech_pvt.

02589 {
02590    struct sip_pvt *p = newchan->tech_pvt;
02591    ast_mutex_lock(&p->lock);
02592    if (p->owner != oldchan) {
02593       ast_log(LOG_WARNING, "old channel wasn't %p but was %p\n", oldchan, p->owner);
02594       ast_mutex_unlock(&p->lock);
02595       return -1;
02596    }
02597    p->owner = newchan;
02598    ast_mutex_unlock(&p->lock);
02599    return 0;
02600 }

static 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 12989 of file chan_sip.c.

References sip_pvt::peercapability, and ast_channel::tech_pvt.

12990 {
12991    struct sip_pvt *p = chan->tech_pvt;
12992    return p->peercapability;  
12993 }

static 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 12697 of file chan_sip.c.

References ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, sip_pvt::lock, sip_pvt::rtp, SIP_CAN_REINVITE, and ast_channel::tech_pvt.

12698 {
12699    struct sip_pvt *p;
12700    struct ast_rtp *rtp = NULL;
12701    p = chan->tech_pvt;
12702    if (!p)
12703       return NULL;
12704    ast_mutex_lock(&p->lock);
12705    if (p->rtp && ast_test_flag(p, SIP_CAN_REINVITE))
12706       rtp =  p->rtp;
12707    ast_mutex_unlock(&p->lock);
12708    return rtp;
12709 }

static 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 12712 of file chan_sip.c.

References ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, sip_pvt::lock, SIP_CAN_REINVITE, ast_channel::tech_pvt, and sip_pvt::vrtp.

12713 {
12714    struct sip_pvt *p;
12715    struct ast_rtp *rtp = NULL;
12716    p = chan->tech_pvt;
12717    if (!p)
12718       return NULL;
12719 
12720    ast_mutex_lock(&p->lock);
12721    if (p->vrtp && ast_test_flag(p, SIP_CAN_REINVITE))
12722       rtp = p->vrtp;
12723    ast_mutex_unlock(&p->lock);
12724    return rtp;
12725 }

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

sip_getheader: Get a SIP header (dialplan app) ---

Definition at line 12874 of file chan_sip.c.

References ast_goto_if_exists(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_strdupa, ast_strlen_zero(), channeltype, ast_channel::context, dep_warning, ast_channel::exten, get_header(), sip_pvt::initreq, ast_channel::lock, LOG_DEBUG, LOG_WARNING, pbx_builtin_setvar_helper(), ast_channel::priority, strsep(), ast_channel::tech_pvt, and ast_channel::type.

Referenced by load_module().

12875 {
12876    static int dep_warning = 0;
12877    struct sip_pvt *p;
12878    char *argv, *varname = NULL, *header = NULL, *content;
12879    
12880    if (!dep_warning) {
12881       ast_log(LOG_WARNING, "SIPGetHeader is deprecated, use the SIP_HEADER function instead.\n");
12882       dep_warning = 1;
12883    }
12884 
12885    argv = ast_strdupa(data);
12886    if (!argv) {
12887       ast_log(LOG_DEBUG, "Memory allocation failed\n");
12888       return 0;
12889    }
12890 
12891    if (strchr (argv, '=') ) { /* Pick out argumenet */
12892       varname = strsep (&argv, "=");
12893       header = strsep (&argv, "\0");
12894    }
12895 
12896    if (!varname || !header) {
12897       ast_log(LOG_DEBUG, "SipGetHeader: Ignoring command, Syntax error in argument\n");
12898       return 0;
12899    }
12900 
12901    ast_mutex_lock(&chan->lock);
12902    if (chan->type != channeltype) {
12903       ast_log(LOG_WARNING, "Call this application only on incoming SIP calls\n");
12904       ast_mutex_unlock(&chan->lock);
12905       return 0;
12906    }
12907 
12908    p = chan->tech_pvt;
12909    content = get_header(&p->initreq, header);   /* Get the header */
12910    if (!ast_strlen_zero(content)) {
12911       pbx_builtin_setvar_helper(chan, varname, content);
12912    } else {
12913       ast_log(LOG_WARNING,"SIP Header %s not found for channel variable %s\n", header, varname);
12914       ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101);
12915    }
12916    
12917    ast_mutex_unlock(&chan->lock);
12918    return 0;
12919 }

static int sip_hangup struct ast_channel ast  )  [static]
 

sip_hangup: Hangup SIP call Part of PBX interface, called from ast_hangup

Definition at line 2400 of file chan_sip.c.

References __sip_pretend_ack(), ast_channel::_state, AST_CAUSE_NORMAL, ast_clear_flag, ast_copy_flags, ast_dsp_free(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_osp_terminate(), ast_set_flag, AST_STATE_UP, ast_strlen_zero(), ast_test_flag, ast_update_use_count(), sip_pvt::callid, sip_request::data, DEC_CALL_LIMIT, hangup_cause2sip(), ast_channel::hangupcause, INC_CALL_LIMIT, sip_pvt::initreq, sip_pvt::lock, LOG_DEBUG, LOG_WARNING, ast_channel::name, option_debug, sip_pvt::owner, sip_pvt::pendinginvite, SIP_ALREADYGONE, SIP_BYE, SIP_CANCEL, SIP_NEEDDESTROY, SIP_NEEDREINVITE, SIP_OUTGOING, SIP_PENDINGBYE, sip_scheddestroy(), ast_channel::tech_pvt, transmit_request_with_auth(), transmit_response_reliable(), update_call_counter(), usecnt_lock, sip_pvt::username, and sip_pvt::vad.

02401 {
02402    struct sip_pvt *p = ast->tech_pvt;
02403    int needcancel = 0;
02404    struct ast_flags locflags = {0};
02405 
02406    if (!p) {
02407       ast_log(LOG_DEBUG, "Asked to hangup channel not connected\n");
02408       return 0;
02409    }
02410    if (option_debug)
02411       ast_log(LOG_DEBUG, "Hangup call %s, SIP callid %s)\n", ast->name, p->callid);
02412 
02413    ast_mutex_lock(&p->lock);
02414 #ifdef OSP_SUPPORT
02415    if ((p->osphandle > -1) && (ast->_state == AST_STATE_UP)) {
02416       ast_osp_terminate(p->osphandle, AST_CAUSE_NORMAL, p->ospstart, time(NULL) - p->ospstart);
02417    }
02418 #endif   
02419    ast_log(LOG_DEBUG, "update_call_counter(%s) - decrement call limit counter\n", p->username);
02420    update_call_counter(p, DEC_CALL_LIMIT);
02421    /* Determine how to disconnect */
02422    if (p->owner != ast) {
02423       ast_log(LOG_WARNING, "Huh?  We aren't the owner? Can't hangup call.\n");
02424       ast_mutex_unlock(&p->lock);
02425       return 0;
02426    }
02427    /* If the call is not UP, we need to send CANCEL instead of BYE */
02428    if (ast->_state != AST_STATE_UP)
02429       needcancel = 1;
02430 
02431    /* Disconnect */
02432    p = ast->tech_pvt;
02433    if (p->vad) {
02434       ast_dsp_free(p->vad);
02435    }
02436    p->owner = NULL;
02437    ast->tech_pvt = NULL;
02438 
02439    ast_mutex_lock(&usecnt_lock);
02440    usecnt--;
02441    ast_mutex_unlock(&usecnt_lock);
02442    ast_update_use_count();
02443 
02444    ast_set_flag(&locflags, SIP_NEEDDESTROY); 
02445 
02446    /* Start the process if it's not already started */
02447    if (!ast_test_flag(p, SIP_ALREADYGONE) && !ast_strlen_zero(p->initreq.data)) {
02448       if (needcancel) { /* Outgoing call, not up */
02449          if (ast_test_flag(p, SIP_OUTGOING)) {
02450             /* stop retransmitting an INVITE that has not received a response */
02451             __sip_pretend_ack(p);
02452 
02453             /* Send a new request: CANCEL */
02454             transmit_request_with_auth(p, SIP_CANCEL, p->ocseq, 1, 0);
02455             /* Actually don't destroy us yet, wait for the 487 on our original 
02456                INVITE, but do set an autodestruct just in case we never get it. */
02457             ast_clear_flag(&locflags, SIP_NEEDDESTROY);
02458             sip_scheddestroy(p, 32000);
02459             if ( p->initid != -1 ) {
02460                /* channel still up - reverse dec of inUse counter
02461                   only if the channel is not auto-congested */
02462                update_call_counter(p, INC_CALL_LIMIT);
02463             }
02464          } else { /* Incoming call, not up */
02465             char *res;
02466             if (ast->hangupcause && ((res = hangup_cause2sip(ast->hangupcause)))) {
02467                transmit_response_reliable(p, res, &p->initreq, 1);
02468             } else 
02469                transmit_response_reliable(p, "603 Declined", &p->initreq, 1);
02470          }
02471       } else { /* Call is in UP state, send BYE */
02472          if (!p->pendinginvite) {
02473             /* Send a hangup */
02474             transmit_request_with_auth(p, SIP_BYE, 0, 1, 1);
02475          } else {
02476             /* Note we will need a BYE when this all settles out
02477                but we can't send one while we have "INVITE" outstanding. */
02478             ast_set_flag(p, SIP_PENDINGBYE); 
02479             ast_clear_flag(p, SIP_NEEDREINVITE);   
02480          }
02481       }
02482    }
02483    ast_copy_flags(p, (&locflags), SIP_NEEDDESTROY);   
02484    ast_mutex_unlock(&p->lock);
02485    return 0;
02486 }

static 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 2645 of file chan_sip.c.

References ast_channel::_state, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_HOLD, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_RINGING, AST_CONTROL_UNHOLD, AST_CONTROL_VIDUPDATE, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), AST_STATE_RING, AST_STATE_UP, ast_test_flag, sip_pvt::callid, sip_pvt::initreq, sip_pvt::lock, LOG_DEBUG, LOG_WARNING, SIP_ALREADYGONE, SIP_NOVIDEO, SIP_OUTGOING, SIP_PROG_INBAND, SIP_PROG_INBAND_NEVER, SIP_PROG_INBAND_YES, SIP_PROGRESS_SENT, SIP_RINGING, ast_channel::tech_pvt, transmit_info_with_vidupdate(), transmit_response(), transmit_response_with_sdp(), and sip_pvt::vrtp.

02646 {
02647    struct sip_pvt *p = ast->tech_pvt;
02648    int res = 0;
02649 
02650    ast_mutex_lock(&p->lock);
02651    switch(condition) {
02652    case AST_CONTROL_RINGING:
02653       if (ast->_state == AST_STATE_RING) {
02654          if (!ast_test_flag(p, SIP_PROGRESS_SENT) ||
02655              (ast_test_flag(p, SIP_PROG_INBAND) == SIP_PROG_INBAND_NEVER)) {
02656             /* Send 180 ringing if out-of-band seems reasonable */
02657             transmit_response(p, "180 Ringing", &p->initreq);
02658             ast_set_flag(p, SIP_RINGING);
02659             if (ast_test_flag(p, SIP_PROG_INBAND) != SIP_PROG_INBAND_YES)
02660                break;
02661          } else {
02662             /* Well, if it's not reasonable, just send in-band */
02663          }
02664       }
02665       res = -1;
02666       break;
02667    case AST_CONTROL_BUSY:
02668       if (ast->_state != AST_STATE_UP) {
02669          transmit_response(p, "486 Busy Here", &p->initreq);
02670          ast_set_flag(p, SIP_ALREADYGONE);   
02671          ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV);
02672          break;
02673       }
02674       res = -1;
02675       break;
02676    case AST_CONTROL_CONGESTION:
02677       if (ast->_state != AST_STATE_UP) {
02678          transmit_response(p, "503 Service Unavailable", &p->initreq);
02679          ast_set_flag(p, SIP_ALREADYGONE);   
02680          ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV);
02681          break;
02682       }
02683       res = -1;
02684       break;
02685    case AST_CONTROL_PROCEEDING:
02686       if ((ast->_state != AST_STATE_UP) && !ast_test_flag(p, SIP_PROGRESS_SENT) && !ast_test_flag(p, SIP_OUTGOING)) {
02687          transmit_response(p, "100 Trying", &p->initreq);
02688          break;
02689       }
02690       res = -1;
02691       break;
02692    case AST_CONTROL_PROGRESS:
02693       if ((ast->_state != AST_STATE_UP) && !ast_test_flag(p, SIP_PROGRESS_SENT) && !ast_test_flag(p, SIP_OUTGOING)) {
02694          transmit_response_with_sdp(p, "183 Session Progress", &p->initreq, 0);
02695          ast_set_flag(p, SIP_PROGRESS_SENT); 
02696          break;
02697       }
02698       res = -1;
02699       break;
02700    case AST_CONTROL_HOLD:  /* The other part of the bridge are put on hold */
02701       if (sipdebug)
02702          ast_log(LOG_DEBUG, "Bridged channel now on hold%s\n", p->callid);
02703       res = -1;
02704       break;
02705    case AST_CONTROL_UNHOLD:   /* The other part of the bridge are back from hold */
02706       if (sipdebug)
02707          ast_log(LOG_DEBUG, "Bridged channel is back from hold, let's talk! : %s\n", p->callid);
02708       res = -1;
02709       break;
02710    case AST_CONTROL_VIDUPDATE:   /* Request a video frame update */
02711       if (p->vrtp && !ast_test_flag(p, SIP_NOVIDEO)) {
02712          transmit_info_with_vidupdate(p);
02713          res = 0;
02714       } else
02715          res = -1;
02716       break;
02717    case -1:
02718       res = -1;
02719       break;
02720    default:
02721       ast_log(LOG_WARNING, "Don't know how to indicate condition %d\n", condition);
02722       res = -1;
02723       break;
02724    }
02725    ast_mutex_unlock(&p->lock);
02726    return res;
02727 }

static 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 2733 of file chan_sip.c.

References ast_channel::accountcode, ast_channel::adsicpe, ast_channel::amaflags, AST_ADSI_UNAVAILABLE, ast_best_codec(), ast_channel_alloc(), ast_codec_choose(), ast_dsp_digitmode(), ast_dsp_new(), ast_dsp_set_features(), ast_hangup(), ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_pbx_start(), ast_rtcp_fd(), ast_rtp_fd(), ast_setstate(), AST_STATE_DOWN, AST_STATE_RING, ast_strlen_zero(), ast_test_flag, ast_channel::callgroup, sip_pvt::capability, ast_channel::cid, ast_callerid::cid_dnid, ast_callerid::cid_name, ast_callerid::cid_num, ast_callerid::cid_pres, ast_callerid::cid_rdnis, ast_channel::context, DSP_DIGITMODE_DTMF, DSP_DIGITMODE_RELAXDTMF, DSP_FEATURE_DTMF_DETECT, ast_channel::exten, ast_channel::fds, fmt, sip_pvt::fromdomain, sip_pvt::jointcapability, ast_channel::language, sip_pvt::lock, LOG_WARNING, ast_channel::musicclass, ast_variable::name, ast_channel::name, ast_channel::nativeformats, ast_variable::next, pbx_builtin_setvar_helper(), ast_channel::pickupgroup, sip_pvt::prefs, ast_channel::priority, ast_channel::rawreadformat, ast_channel::rawwriteformat, ast_channel::readformat, ast_channel::rings, SIP_DTMF, SIP_DTMF_INBAND, sip_tech, strdup, ast_channel::tech, ast_channel::tech_pvt, thread_safe_rand(), ast_channel::type, usecnt_lock, ast_variable::value, and ast_channel::writeformat.

Referenced by handle_request_invite(), and sip_request_call().

02734 {
02735    struct ast_channel *tmp;
02736    struct ast_variable *v = NULL;
02737    int fmt;
02738 #ifdef OSP_SUPPORT
02739    char iabuf[INET_ADDRSTRLEN];
02740    char peer[MAXHOSTNAMELEN];
02741 #endif   
02742    
02743    ast_mutex_unlock(&i->lock);
02744    /* Don't hold a sip pvt lock while we allocate a channel */
02745    tmp = ast_channel_alloc(1);
02746    ast_mutex_lock(&i->lock);
02747    if (!tmp) {
02748       ast_log(LOG_WARNING, "Unable to allocate SIP channel structure\n");
02749       return NULL;
02750    }
02751    tmp->tech = &sip_tech;
02752    /* Select our native format based on codec preference until we receive
02753       something from another device to the contrary. */
02754    if (i->jointcapability)
02755       tmp->nativeformats = ast_codec_choose(&i->prefs, i->jointcapability, 1);
02756    else if (i->capability)
02757       tmp->nativeformats = ast_codec_choose(&i->prefs, i->capability, 1);
02758    else
02759       tmp->nativeformats = ast_codec_choose(&i->prefs, global_capability, 1);
02760    fmt = ast_best_codec(tmp->nativeformats);
02761 
02762    if (title)
02763       snprintf(tmp->name, sizeof(tmp->name), "SIP/%s-%04x", title, thread_safe_rand() & 0xffff);
02764    else if (strchr(i->fromdomain,':'))
02765       snprintf(tmp->name, sizeof(tmp->name), "SIP/%s-%08x", strchr(i->fromdomain,':')+1, (int)(long)(i));
02766    else
02767       snprintf(tmp->name, sizeof(tmp->name), "SIP/%s-%08x", i->fromdomain, (int)(long)(i));
02768 
02769    tmp->type = channeltype;
02770    if (ast_test_flag(i, SIP_DTMF) ==  SIP_DTMF_INBAND) {
02771       i->vad = ast_dsp_new();
02772       ast_dsp_set_features(i->vad, DSP_FEATURE_DTMF_DETECT);
02773       if (relaxdtmf)
02774          ast_dsp_digitmode(i->vad, DSP_DIGITMODE_DTMF | DSP_DIGITMODE_RELAXDTMF);
02775    }
02776    if (i->rtp) {
02777       tmp->fds[0] = ast_rtp_fd(i->rtp);
02778       tmp->fds[1] = ast_rtcp_fd(i->rtp);
02779    }
02780    if (i->vrtp) {
02781       tmp->fds[2] = ast_rtp_fd(i->vrtp);
02782       tmp->fds[3] = ast_rtcp_fd(i->vrtp);
02783    }
02784    if (state == AST_STATE_RING)
02785       tmp->rings = 1;
02786    tmp->adsicpe = AST_ADSI_UNAVAILABLE;
02787    tmp->writeformat = fmt;
02788    tmp->rawwriteformat = fmt;
02789    tmp->readformat = fmt;
02790    tmp->rawreadformat = fmt;
02791    tmp->tech_pvt = i;
02792 
02793    tmp->callgroup = i->callgroup;
02794    tmp->pickupgroup = i->pickupgroup;
02795    tmp->cid.cid_pres = i->callingpres;
02796    if (!ast_strlen_zero(i->accountcode))
02797       ast_copy_string(tmp->accountcode, i->accountcode, sizeof(tmp->accountcode));
02798    if (i->amaflags)
02799       tmp->amaflags = i->amaflags;
02800    if (!ast_strlen_zero(i->language))
02801       ast_copy_string(tmp->language, i->language, sizeof(tmp->language));
02802    if (!ast_strlen_zero(i->musicclass))
02803       ast_copy_string(tmp->musicclass, i->musicclass, sizeof(tmp->musicclass));
02804    i->owner = tmp;
02805    ast_mutex_lock(&usecnt_lock);
02806    usecnt++;
02807    ast_mutex_unlock(&usecnt_lock);
02808    ast_copy_string(tmp->context, i->context, sizeof(tmp->context));
02809    ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten));
02810    if (!ast_strlen_zero(i->cid_num)) 
02811       tmp->cid.cid_num = strdup(i->cid_num);
02812    if (!ast_strlen_zero(i->cid_name))
02813       tmp->cid.cid_name = strdup(i->cid_name);
02814    if (!ast_strlen_zero(i->rdnis))
02815       tmp->cid.cid_rdnis = strdup(i->rdnis);
02816    if (!ast_strlen_zero(i->exten) && strcmp(i->exten, "s"))
02817       tmp->cid.cid_dnid = strdup(i->exten);
02818    tmp->priority = 1;
02819    if (!ast_strlen_zero(i->uri)) {
02820       pbx_builtin_setvar_helper(tmp, "SIPURI", i->uri);
02821    }
02822    if (!ast_strlen_zero(i->domain)) {
02823       pbx_builtin_setvar_helper(tmp, "SIPDOMAIN", i->domain);
02824    }
02825    if (!ast_strlen_zero(i->useragent)) {
02826       pbx_builtin_setvar_helper(tmp, "SIPUSERAGENT", i->useragent);
02827    }
02828    if (!ast_strlen_zero(i->callid)) {
02829       pbx_builtin_setvar_helper(tmp, "SIPCALLID", i->callid);
02830    }
02831 #ifdef OSP_SUPPORT
02832    snprintf(peer, sizeof(peer), "[%s]:%d", ast_inet_ntoa(iabuf, sizeof(iabuf), i->sa.sin_addr), ntohs(i->sa.sin_port));
02833    pbx_builtin_setvar_helper(tmp, "OSPPEER", peer);
02834 #endif
02835    ast_setstate(tmp, state);
02836    if (state != AST_STATE_DOWN) {
02837       if (ast_pbx_start(tmp)) {
02838          ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
02839          ast_hangup(tmp);
02840          tmp = NULL;
02841       }
02842    }
02843    /* Set channel variables for this call from configuration */
02844    for (v = i->chanvars ; v ; v = v->next)
02845       pbx_builtin_setvar_helper(tmp,v->name,v->value);
02846             
02847    return tmp;
02848 }

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

sip_no_debug: Disable SIP Debugging in CLI ---

Definition at line 8852 of file chan_sip.c.

References ast_cli(), RESULT_SHOWUSAGE, RESULT_SUCCESS, SIP_DEBUG_CONSOLE, and sipdebug.

08854 {
08855    if (argc != 3)
08856       return RESULT_SHOWUSAGE;
08857    sipdebug &= ~SIP_DEBUG_CONSOLE;
08858    ast_cli(fd, "SIP Debugging Disabled\n");
08859    return RESULT_SUCCESS;
08860 }

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

sip_no_history: Disable SIP History logging (CLI) ---

Definition at line 8841 of file chan_sip.c.

References ast_cli(), recordhistory, RESULT_SHOWUSAGE, and RESULT_SUCCESS.

08842 {
08843    if (argc != 3) {
08844       return RESULT_SHOWUSAGE;
08845    }
08846    recordhistory = 0;
08847    ast_cli(fd, "SIP History Recording Disabled\n");
08848    return RESULT_SUCCESS;
08849 }

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

sip_notify: Send SIP notify to peer

Definition at line 8773 of file chan_sip.c.

References __ourip, add_blank_header(), add_header(), ast_cli(), ast_log(), ast_sip_ouraddrfor(), ast_variable_browse(), build_callid(), build_via(), create_addr(), initreqprep(), LOG_WARNING, notify_config, notify_types, sip_pvt::ourip, RESULT_FAILURE, RESULT_SHOWUSAGE, sip_pvt::sa, sip_alloc(), sip_destroy(), SIP_NOTIFY, sip_scheddestroy(), transmit_sip_request(), var, and sip_pvt::via.

08774 {
08775    struct ast_variable *varlist;
08776    int i;
08777 
08778    if (argc < 4)
08779       return RESULT_SHOWUSAGE;
08780 
08781    if (!notify_types) {
08782       ast_cli(fd, "No %s file found, or no types listed there\n", notify_config);
08783       return RESULT_FAILURE;
08784    }
08785 
08786    varlist = ast_variable_browse(notify_types, argv[2]);
08787 
08788    if (!varlist) {
08789       ast_cli(fd, "Unable to find notify type '%s'\n", argv[2]);
08790       return RESULT_FAILURE;
08791    }
08792 
08793    for (i = 3; i < argc; i++) {
08794       struct sip_pvt *p;
08795       struct sip_request req;
08796       struct ast_variable *var;
08797 
08798       p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY);
08799       if (!p) {
08800          ast_log(LOG_WARNING, "Unable to build sip pvt data for notify\n");
08801          return RESULT_FAILURE;
08802       }
08803 
08804       if (create_addr(p, argv[i])) {
08805          /* Maybe they're not registered, etc. */
08806          sip_destroy(p);
08807          ast_cli(fd, "Could not create address for '%s'\n", argv[i]);
08808          continue;
08809       }
08810 
08811       initreqprep(&req, p, SIP_NOTIFY);
08812 
08813       for (var = varlist; var; var = var->next)
08814          add_header(&req, var->name, var->value);
08815 
08816       add_blank_header(&req);
08817       /* Recalculate our side, and recalculate Call ID */
08818       if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
08819          memcpy(&p->ourip, &__ourip, sizeof(p->ourip));
08820       build_via(p, p->via, sizeof(p->via));
08821       build_callid(p->callid, sizeof(p->callid), p->ourip, p->fromdomain);
08822       ast_cli(fd, "Sending NOTIFY of type '%s' to '%s'\n", argv[2], argv[i]);
08823       transmit_sip_request(p, &req);
08824       sip_scheddestroy(p, 15000);
08825    }
08826 
08827    return RESULT_SUCCESS;
08828 }

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

sip_park: Park a call ---

Definition at line 10070 of file chan_sip.c.

References ast_channel_alloc(), ast_channel_masquerade(), ast_do_masquerade(), ast_hangup(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_pthread_create, ast_channel::context, copy_request(), ast_channel::exten, free, ast_channel::lock, LOG_WARNING, malloc, ast_channel::name, ast_channel::priority, ast_channel::readformat, sip_park_thread(), and ast_channel::writeformat.

Referenced by handle_request_refer().

10071 {
10072    struct sip_dual *d;
10073    struct ast_channel *chan1m, *chan2m;
10074    pthread_t th;
10075    chan1m = ast_channel_alloc(0);
10076    chan2m = ast_channel_alloc(0);
10077    if ((!chan2m) || (!chan1m)) {
10078       if (chan1m)
10079          ast_hangup(chan1m);
10080       if (chan2m)
10081          ast_hangup(chan2m);
10082       return -1;
10083    }
10084    snprintf(chan1m->name, sizeof(chan1m->name), "Parking/%s", chan1->name);
10085    /* Make formats okay */
10086    chan1m->readformat = chan1->readformat;
10087    chan1m->writeformat = chan1->writeformat;
10088    ast_channel_masquerade(chan1m, chan1);
10089    /* Setup the extensions and such */
10090    ast_copy_string(chan1m->context, chan1->context, sizeof(chan1m->context));
10091    ast_copy_string(chan1m->exten, chan1->exten, sizeof(chan1m->exten));
10092    chan1m->priority = chan1->priority;
10093       
10094    /* We make a clone of the peer channel too, so we can play
10095       back the announcement */
10096    snprintf(chan2m->name, sizeof (chan2m->name), "SIPPeer/%s",chan2->name);
10097    /* Make formats okay */
10098    chan2m->readformat = chan2->readformat;
10099    chan2m->writeformat = chan2->writeformat;
10100    ast_channel_masquerade(chan2m, chan2);
10101    /* Setup the extensions and such */
10102    ast_copy_string(chan2m->context, chan2->context, sizeof(chan2m->context));
10103    ast_copy_string(chan2m->exten, chan2->exten, sizeof(chan2m->exten));
10104    chan2m->priority = chan2->priority;
10105    ast_mutex_lock(&chan2m->lock);
10106    if (ast_do_masquerade(chan2m)) {
10107       ast_log(LOG_WARNING, "Masquerade failed :(\n");
10108       ast_mutex_unlock(&chan2m->lock);
10109       ast_hangup(chan2m);
10110       return -1;
10111    }
10112    ast_mutex_unlock(&chan2m->lock);
10113    d = malloc(sizeof(struct sip_dual));
10114    if (d) {
10115       memset(d, 0, sizeof(*d));
10116       /* Save original request for followup */
10117       copy_request(&d->req, req);
10118       d->chan1 = chan1m;
10119       d->chan2 = chan2m;
10120       if (!ast_pthread_create(&th, NULL, sip_park_thread, d))
10121          return 0;
10122       free(d);
10123    }
10124    return -1;
10125 }

static void* sip_park_thread void *  stuff  )  [static]
 

sip_park_thread: Park SIP call support function

Definition at line 10047 of file chan_sip.c.

References ast_do_masquerade(), ast_hangup(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_park_call(), sip_dual::chan1, sip_dual::chan2, copy_request(), free, ast_channel::lock, LOG_DEBUG, and sip_dual::req.

Referenced by sip_park().

10048 {
10049    struct ast_channel *chan1, *chan2;
10050    struct sip_dual *d;
10051    struct sip_request req;
10052    int ext;
10053    int res;
10054    d = stuff;
10055    chan1 = d->chan1;
10056    chan2 = d->chan2;
10057    copy_request(&req, &d->req);
10058    free(d);
10059    ast_mutex_lock(&chan1->lock);
10060    ast_do_masquerade(chan1);
10061    ast_mutex_unlock(&chan1->lock);
10062    res = ast_park_call(chan1, chan2, 0, &ext);
10063    /* Then hangup */
10064    ast_hangup(chan2);
10065    ast_log(LOG_DEBUG, "Parked on extension '%d'\n", ext);
10066    return NULL;
10067 }

static void sip_poke_all_peers void   )  [static]
 

sip_poke_all_peers: Send a poke to all known peers

Definition at line 13005 of file chan_sip.c.

References ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_UNLOCK, ASTOBJ_WRLOCK, peerl, and sip_poke_peer().

Referenced by load_module().

13006 {
13007    ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do {
13008       ASTOBJ_WRLOCK(iterator);
13009       sip_poke_peer(iterator);
13010       ASTOBJ_UNLOCK(iterator);
13011    } while (0)
13012    );
13013 }

static int sip_poke_noanswer void *  data  )  [static]
 

sip_poke_noanswer: No answer to Qualify poke ---

Definition at line 11390 of file chan_sip.c.

References ast_device_state_changed(), ast_log(), ast_sched_add(), sip_peer::call, DEFAULT_FREQ_NOTOK, EVENT_FLAG_SYSTEM, sip_peer::lastms, LOG_NOTICE, manager_event(), sip_peer::pokeexpire, sip_destroy(), and sip_poke_peer_s().

Referenced by sip_poke_peer().

11391 {
11392    struct sip_peer *peer = data;
11393    
11394    peer->pokeexpire = -1;
11395    if (peer->lastms > -1) {
11396       ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE!  Last qualify: %d\n", peer->name, peer->lastms);
11397       manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, -1);
11398    }
11399    if (peer->call)
11400       sip_destroy(peer->call);
11401    peer->call = NULL;
11402    peer->lastms = -1;
11403    ast_device_state_changed("SIP/%s", peer->name);
11404    /* Try again quickly */
11405    peer->pokeexpire = ast_sched_add(sched, DEFAULT_FREQ_NOTOK, sip_poke_peer_s, peer);
11406    return 0;
11407 }

static int sip_poke_peer struct sip_peer peer  )  [static]
 

sip_poke_peer: Check availability of peer, also keep NAT open ---

Definition at line 11412 of file chan_sip.c.

References __ourip, sip_peer::addr, ast_copy_flags, ast_inet_ntoa(), ast_log(), ast_sched_add(), ast_sched_del(), ast_set_flag, ast_sip_ouraddrfor(), ast_strlen_zero(), build_callid(), build_via(), sip_peer::call, sip_pvt::callid, DEFAULT_MAXMS, sip_pvt::fromdomain, sip_pvt::fullcontact, sip_peer::fullcontact, sip_peer::lastms, LOG_NOTICE, LOG_WARNING, sip_peer::maxms, sip_pvt::ourip, sip_pvt::peerpoke, sip_peer::pokeexpire, sip_peer::ps, sip_pvt::recv, sip_pvt::sa, sip_alloc(), sip_destroy(), SIP_FLAGS_TO_COPY, SIP_INVITE, SIP_OPTIONS, SIP_OUTGOING, sip_poke_noanswer(), sipdebug, sip_pvt::tohost, sip_peer::tohost, transmit_invite(), sip_pvt::username, and sip_pvt::via.

Referenced by parse_register_contact(), reg_source_db(), sip_poke_all_peers(), and sip_poke_peer_s().

11413 {
11414    struct sip_pvt *p;
11415    if (!peer->maxms || !peer->addr.sin_addr.s_addr) {
11416       /* IF we have no IP, or this isn't to be monitored, return
11417         imeediately after clearing things out */
11418       if (peer->pokeexpire > -1)
11419          ast_sched_del(sched, peer->pokeexpire);
11420       peer->lastms = 0;
11421       peer->pokeexpire = -1;
11422       peer->call = NULL;
11423       return 0;
11424    }
11425    if (peer->call > 0) {
11426       if (sipdebug)
11427          ast_log(LOG_NOTICE, "Still have a QUALIFY dialog active, deleting\n");
11428       sip_destroy(peer->call);
11429    }
11430    p = peer->call = sip_alloc(NULL, NULL, 0, SIP_OPTIONS);
11431    if (!peer->call) {
11432       ast_log(LOG_WARNING, "Unable to allocate dialog for poking peer '%s'\n", peer->name);
11433       return -1;
11434    }
11435    memcpy(&p->sa, &peer->addr, sizeof(p->sa));
11436    memcpy(&p->recv, &peer->addr, sizeof(p->sa));
11437    ast_copy_flags(p, peer, SIP_FLAGS_TO_COPY);
11438 
11439    /* Send OPTIONs to peer's fullcontact */
11440    if (!ast_strlen_zero(peer->fullcontact)) {
11441       ast_copy_string (p->fullcontact, peer->fullcontact, sizeof(p->fullcontact));
11442    }
11443 
11444    if (!ast_strlen_zero(peer->tohost))
11445       ast_copy_string(p->tohost, peer->tohost, sizeof(p->tohost));
11446    else
11447       ast_inet_ntoa(p->tohost, sizeof(p->tohost), peer->addr.sin_addr);
11448 
11449    /* Recalculate our side, and recalculate Call ID */
11450    if (ast_sip_ouraddrfor(&p->sa.sin_addr,&p->ourip))
11451       memcpy(&p->ourip, &__ourip, sizeof(p->ourip));
11452    build_via(p, p->via, sizeof(p->via));
11453    build_callid(p->callid, sizeof(p->callid), p->ourip, p->fromdomain);
11454 
11455    if (peer->pokeexpire > -1)
11456       ast_sched_del(sched, peer->pokeexpire);
11457    p->peerpoke = peer;
11458    ast_set_flag(p, SIP_OUTGOING);
11459 #ifdef VOCAL_DATA_HACK
11460    ast_copy_string(p->username, "__VOCAL_DATA_SHOULD_READ_THE_SIP_SPEC__", sizeof(p->username));
11461    transmit_invite(p, SIP_INVITE, 0, 2);
11462 #else
11463    transmit_invite(p, SIP_OPTIONS, 0, 2);
11464 #endif
11465    gettimeofday(&peer->ps, NULL);
11466    peer->pokeexpire = ast_sched_add(sched, DEFAULT_MAXMS * 2, sip_poke_noanswer, peer);
11467 
11468    return 0;
11469 }

static int sip_poke_peer_s void *  data  )  [static]
 

Definition at line 5659 of file chan_sip.c.

References sip_peer::pokeexpire, and sip_poke_peer().

Referenced by handle_response_peerpoke(), reg_source_db(), and sip_poke_noanswer().

05660 {
05661    struct sip_peer *peer = data;
05662    peer->pokeexpire = -1;
05663    sip_poke_peer(peer);
05664    return 0;
05665 }

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

sip_prune_realtime: Remove temporary realtime objects from memory (CLI) ---

Definition at line 7646 of file chan_sip.c.

References ast_test_flag, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_CONTAINER_WRLOCK, ASTOBJ_MARK, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, name, peerl, RESULT_SHOWUSAGE, SIP_PAGE2_RTCACHEFRIENDS, and user.

07647 {
07648    struct sip_peer *peer;
07649    struct sip_user *user;
07650    int pruneuser = 0;
07651    int prunepeer = 0;
07652    int multi = 0;
07653    char *name = NULL;
07654    regex_t regexbuf;
07655 
07656    switch (argc) {
07657    case 4:
07658       if (!strcasecmp(argv[3], "user"))
07659          return RESULT_SHOWUSAGE;
07660       if (!strcasecmp(argv[3], "peer"))
07661          return RESULT_SHOWUSAGE;
07662       if (!strcasecmp(argv[3], "like"))
07663          return RESULT_SHOWUSAGE;
07664       if (!strcasecmp(argv[3], "all")) {
07665          multi = 1;
07666          pruneuser = prunepeer = 1;
07667       } else {
07668          pruneuser = prunepeer = 1;
07669          name = argv[3];
07670       }
07671       break;
07672    case 5:
07673       if (!strcasecmp(argv[4], "like"))
07674          return RESULT_SHOWUSAGE;
07675       if (!strcasecmp(argv[3], "all"))
07676          return RESULT_SHOWUSAGE;
07677       if (!strcasecmp(argv[3], "like")) {
07678          multi = 1;
07679          name = argv[4];
07680          pruneuser = prunepeer = 1;
07681       } else if (!strcasecmp(argv[3], "user")) {
07682          pruneuser = 1;
07683          if (!strcasecmp(argv[4], "all"))
07684             multi = 1;
07685          else
07686             name = argv[4];
07687       } else if (!strcasecmp(argv[3], "peer")) {
07688          prunepeer = 1;
07689          if (!strcasecmp(argv[4], "all"))
07690             multi = 1;
07691          else
07692             name = argv[4];
07693       } else
07694          return RESULT_SHOWUSAGE;
07695       break;
07696    case 6:
07697       if (strcasecmp(argv[4], "like"))
07698          return RESULT_SHOWUSAGE;
07699       if (!strcasecmp(argv[3], "user")) {
07700          pruneuser = 1;
07701          name = argv[5];
07702       } else if (!strcasecmp(argv[3], "peer")) {
07703          prunepeer = 1;
07704          name = argv[5];
07705       } else
07706          return RESULT_SHOWUSAGE;
07707       break;
07708    default:
07709       return RESULT_SHOWUSAGE;
07710    }
07711 
07712    if (multi && name) {
07713       if (regcomp(&regexbuf, name, REG_EXTENDED | REG_NOSUB))
07714          return RESULT_SHOWUSAGE;
07715    }
07716 
07717    if (multi) {
07718       if (prunepeer) {
07719          int pruned = 0;
07720 
07721          ASTOBJ_CONTAINER_WRLOCK(&peerl);
07722          ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do {
07723             ASTOBJ_RDLOCK(iterator);
07724             if (name && regexec(&regexbuf, iterator->name, 0, NULL, 0)) {
07725                ASTOBJ_UNLOCK(iterator);
07726                continue;
07727             };
07728             if (ast_test_flag((&iterator->flags_page2), SIP_PAGE2_RTCACHEFRIENDS)) {
07729                ASTOBJ_MARK(iterator);
07730                pruned++;
07731             }
07732             ASTOBJ_UNLOCK(iterator);
07733          } while (0) );
07734          if (pruned) {
07735             ASTOBJ_CONTAINER_PRUNE_MARKED(&peerl, sip_destroy_peer);
07736             ast_cli(fd, "%d peers pruned.\n", pruned);
07737          } else
07738             ast_cli(fd, "No peers found to prune.\n");
07739          ASTOBJ_CONTAINER_UNLOCK(&peerl);
07740       }
07741       if (pruneuser) {
07742          int pruned = 0;
07743 
07744          ASTOBJ_CONTAINER_WRLOCK(&userl);
07745          ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do {
07746             ASTOBJ_RDLOCK(iterator);
07747             if (name && regexec(&regexbuf, iterator->name, 0, NULL, 0)) {
07748                ASTOBJ_UNLOCK(iterator);
07749                continue;
07750             };
07751             if (ast_test_flag((&iterator->flags_page2), SIP_PAGE2_RTCACHEFRIENDS)) {
07752                ASTOBJ_MARK(iterator);
07753                pruned++;
07754             }
07755             ASTOBJ_UNLOCK(iterator);
07756          } while (0) );
07757          if (pruned) {
07758             ASTOBJ_CONTAINER_PRUNE_MARKED(&userl, sip_destroy_user);
07759             ast_cli(fd, "%d users pruned.\n", pruned);
07760          } else
07761             ast_cli(fd, "No users found to prune.\n");
07762          ASTOBJ_CONTAINER_UNLOCK(&userl);
07763       }
07764    } else {
07765       if (prunepeer) {
07766          if ((peer = ASTOBJ_CONTAINER_FIND_UNLINK(&peerl, name))) {
07767             if (!ast_test_flag((&peer->flags_page2), SIP_PAGE2_RTCACHEFRIENDS)) {
07768                ast_cli(fd, "Peer '%s' is not a Realtime peer, cannot be pruned.\n", name);
07769                ASTOBJ_CONTAINER_LINK(&peerl, peer);
07770             } else
07771                ast_cli(fd, "Peer '%s' pruned.\n", name);
07772             ASTOBJ_UNREF(peer, sip_destroy_peer);
07773          } else
07774             ast_cli(fd, "Peer '%s' not found.\n", name);
07775       }
07776       if (pruneuser) {
07777          if ((user = ASTOBJ_CONTAINER_FIND_UNLINK(&userl, name))) {
07778             if (!ast_test_flag((&user->flags_page2), SIP_PAGE2_RTCACHEFRIENDS)) {
07779                ast_cli(fd, "User '%s' is not a Realtime user, cannot be pruned.\n", name);
07780                ASTOBJ_CONTAINER_LINK(&userl, user);
07781             } else
07782                ast_cli(fd, "User '%s' pruned.\n", name);
07783             ASTOBJ_UNREF(user, sip_destroy_user);
07784          } else
07785             ast_cli(fd, "User '%s' not found.\n", name);
07786       }
07787    }
07788 
07789    return RESULT_SUCCESS;
07790 }

static struct ast_frame * sip_read struct ast_channel ast  )  [static]
 

sip_read: Read SIP RTP from channel

Definition at line 2997 of file chan_sip.c.

References ast_mutex_lock(), ast_mutex_unlock(), sip_pvt::lastrtprx, sip_pvt::lock, sip_rtp_read(), and ast_channel::tech_pvt.

02998 {
02999    struct ast_frame *fr;
03000    struct sip_pvt *p = ast->tech_pvt;
03001    ast_mutex_lock(&p->lock);
03002    fr = sip_rtp_read(ast, p);
03003    time(&p->lastrtprx);
03004    ast_mutex_unlock(&p->lock);
03005    return fr;
03006 }

static int sip_reg_timeout void *  data  )  [static]
 

sip_reg_timeout: Registration timeout, register again

Definition at line 5277 of file chan_sip.c.

References __sip_pretend_ack(), ast_log(), ast_set_flag, ASTOBJ_REF, ASTOBJ_UNREF, sip_registry::call, EVENT_FLAG_SYSTEM, global_regattempts_max, sip_registry::hostname, LOG_NOTICE, manager_event(), REG_STATE_FAILED, REG_STATE_UNREGISTERED, sip_registry::regattempts, sip_pvt::registry, sip_registry::regstate, regstate2str(), SIP_NEEDDESTROY, SIP_REGISTER, sip_registry_destroy(), sip_registry::timeout, transmit_register(), and sip_registry::username.

Referenced by transmit_register().

05278 {
05279 
05280    /* if we are here, our registration timed out, so we'll just do it over */
05281    struct sip_registry *r = ASTOBJ_REF((struct sip_registry *) data);
05282    struct sip_pvt *p;
05283    int res;
05284 
05285    /* if we couldn't get a reference to the registry object, punt */
05286    if (!r)
05287       return 0;
05288 
05289    ast_log(LOG_NOTICE, "   -- Registration for '%s@%s' timed out, trying again (Attempt #%d)\n", r->username, r->hostname, r->regattempts); 
05290    if (r->call) {
05291       /* Unlink us, destroy old call.  Locking is not relevant here because all this happens
05292          in the single SIP manager thread. */
05293       p = r->call;
05294       if (p->registry)
05295          ASTOBJ_UNREF(p->registry, sip_registry_destroy);
05296       r->call = NULL;
05297       ast_set_flag(p, SIP_NEEDDESTROY);   
05298       /* Pretend to ACK anything just in case */
05299       __sip_pretend_ack(p);
05300    }
05301    /* If we have a limit, stop registration and give up */
05302    if (global_regattempts_max && (r->regattempts > global_regattempts_max)) {
05303       /* Ok, enough is enough. Don't try any more */
05304       /* We could add an external notification here... 
05305          steal it from app_voicemail :-) */
05306       ast_log(LOG_NOTICE, "   -- Giving up forever trying to register '%s@%s'\n", r->username, r->hostname);
05307       r->regstate=REG_STATE_FAILED;
05308    } else {
05309       r->regstate=REG_STATE_UNREGISTERED;
05310       r->timeout = -1;
05311       res=transmit_register(r, SIP_REGISTER, NULL, NULL);
05312    }
05313    manager_event(EVENT_FLAG_SYSTEM, "Registry", "Channel: SIP\r\nUsername: %s\r\nDomain: %s\r\nStatus: %s\r\n", r->username, r->hostname, regstate2str(r->regstate));
05314    ASTOBJ_UNREF(r,sip_registry_destroy);
05315    return 0;
05316 }

static int sip_register char *  value,
int  lineno
[static]
 

sip_register: Parse register=> line in sip.conf and add to registry

Definition at line 3202 of file chan_sip.c.

References ast_log(), ast_strlen_zero(), ASTOBJ_CONTAINER_LINK, ASTOBJ_INIT, ASTOBJ_UNREF, sip_registry::authuser, sip_registry::callid_valid, sip_registry::contact, copy(), default_expiry, sip_registry::expire, sip_registry::hostname, hostname, LOG_ERROR, LOG_WARNING, malloc, sip_registry::ocseq, sip_registry::portno, sip_registry::refresh, regl, regobjs, sip_registry::secret, secret, sip_registry_destroy(), strsep(), sip_registry::timeout, sip_registry::username, and username.

Referenced by reload_config().

03203 {
03204    struct sip_registry *reg;
03205    char copy[256];
03206    char *username=NULL, *hostname=NULL, *secret=NULL, *authuser=NULL;
03207    char *porta=NULL;
03208    char *contact=NULL;
03209    char *stringp=NULL;
03210    
03211    if (!value)
03212       return -1;
03213    ast_copy_string(copy, value, sizeof(copy));
03214    stringp=copy;
03215    username = stringp;
03216    hostname = strrchr(stringp, '@');
03217    if (hostname) {
03218       *hostname = '\0';
03219       hostname++;
03220    }
03221    if (ast_strlen_zero(username) || ast_strlen_zero(hostname)) {
03222       ast_log(LOG_WARNING, "Format for registration is user[:secret[:authuser]]@host[:port][/contact] at line %d\n", lineno);
03223       return -1;
03224    }
03225    stringp=username;
03226    username = strsep(&stringp, ":");
03227    if (username) {
03228       secret = strsep(&stringp, ":");
03229       if (secret) 
03230          authuser = strsep(&stringp, ":");
03231    }
03232    stringp = hostname;
03233    hostname = strsep(&stringp, "/");
03234    if (hostname) 
03235       contact = strsep(&stringp, "/");
03236    if (ast_strlen_zero(contact))
03237       contact = "s";
03238    stringp=hostname;
03239    hostname = strsep(&stringp, ":");
03240    porta = strsep(&stringp, ":");
03241    
03242    if (porta && !atoi(porta)) {
03243       ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno);
03244       return -1;
03245    }
03246    reg = malloc(sizeof(struct sip_registry));
03247    if (!reg) {
03248       ast_log(LOG_ERROR, "Out of memory. Can't allocate SIP registry entry\n");
03249       return -1;
03250    }
03251    memset(reg, 0, sizeof(struct sip_registry));
03252    regobjs++;
03253    ASTOBJ_INIT(reg);
03254    ast_copy_string(reg->contact, contact, sizeof(reg->contact));
03255    if (username)
03256       ast_copy_string(reg->username, username, sizeof(reg->username));
03257    if (hostname)
03258       ast_copy_string(reg->hostname, hostname, sizeof(reg->hostname));
03259    if (authuser)
03260       ast_copy_string(reg->authuser, authuser, sizeof(reg->authuser));
03261    if (secret)
03262       ast_copy_string(reg->secret, secret, sizeof(reg->secret));
03263    reg->expire = -1;
03264    reg->timeout =  -1;
03265    reg->refresh = default_expiry;
03266    reg->portno = porta ? atoi(porta) : 0;
03267    reg->callid_valid = 0;
03268    reg->ocseq = 101;
03269    ASTOBJ_CONTAINER_LINK(&regl, reg);
03270    ASTOBJ_UNREF(reg,sip_registry_destroy);
03271    return 0;
03272 }

static 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, sched, sip_destroy(), and sip_registry::timeout.

Referenced by __sip_destroy(), sip_reg_timeout(), sip_register(), sip_reregister(), and unload_module().

02078 {
02079    /* Really delete */
02080    if (reg->call) {
02081       /* Clear registry before destroying to ensure
02082          we don't get reentered trying to grab the registry lock */
02083       reg->call->registry = NULL;
02084       sip_destroy(reg->call);
02085    }
02086    if (reg->expire > -1)
02087       ast_sched_del(sched, reg->expire);
02088    if (reg->timeout > -1)
02089       ast_sched_del(sched, reg->timeout);
02090    regobjs--;
02091    free(reg);
02092    
02093 }

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

sip_reload: Force reload of module from cli ---

Definition at line 13071 of file chan_sip.c.

References ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), restart_monitor(), and sip_reloading.

Referenced by reload().

13072 {
13073 
13074    ast_mutex_lock(&sip_reload_lock);
13075    if (sip_reloading) {
13076       ast_verbose("Previous SIP reload not yet done\n");
13077    } else
13078       sip_reloading = 1;
13079    ast_mutex_unlock(&sip_reload_lock);
13080    restart_monitor();
13081 
13082    return 0;
13083 }

static 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 11538 of file chan_sip.c.

References __ourip, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_SWITCH_CONGESTION, AST_CAUSE_UNREGISTERED, ast_getformatname(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_sip_ouraddrfor(), AST_STATE_DOWN, ast_strlen_zero(), ast_update_use_count(), build_callid(), build_via(), sip_pvt::callid, calloc, create_addr(), sip_pvt::fromdomain, sip_pvt::fullcontact, global_capability, host, sip_pvt::lock, LOG_ERROR, LOG_NOTICE, sip_pvt::options, sip_pvt::ourip, sip_pvt::peername, sip_pvt::prefcodec, restart_monitor(), sip_pvt::sa, sip_alloc(), sip_destroy(), SIP_INVITE, sip_new(), sip_pvt::username, and sip_pvt::via.

11539 {
11540    int oldformat;
11541    struct sip_pvt *p;
11542    struct ast_channel *tmpc = NULL;
11543    char *ext, *host;
11544    char tmp[256];
11545    char *dest = data;
11546 
11547    oldformat = format;
11548    format &= ((AST_FORMAT_MAX_AUDIO << 1) - 1);
11549    if (!format) {
11550       ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format %s while capability is %s\n", ast_getformatname(oldformat), ast_getformatname(global_capability));
11551       *cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;   /* Can't find codec to connect to host */
11552       return NULL;
11553    }
11554    p = sip_alloc(NULL, NULL, 0, SIP_INVITE);
11555    if (!p) {
11556       ast_log(LOG_ERROR, "Unable to build sip pvt data for '%s' (Out of memory)\n", (char *)data);
11557       *cause = AST_CAUSE_SWITCH_CONGESTION;
11558       return NULL;
11559    }
11560 
11561    p->options = calloc(1, sizeof(*p->options));
11562    if (!p->options) {
11563       sip_destroy(p);
11564       ast_log(LOG_ERROR, "Unable to build option SIP data structure - Out of memory\n");
11565       *cause = AST_CAUSE_SWITCH_CONGESTION;
11566       return NULL;
11567    }
11568 
11569    ast_copy_string(tmp, dest, sizeof(tmp));
11570    host = strchr(tmp, '@');
11571    if (host) {
11572       *host = '\0';
11573       host++;
11574       ext = tmp;
11575    } else {
11576       ext = strchr(tmp, '/');
11577       if (ext) {
11578          *ext++ = '\0';
11579          host = tmp;
11580       }
11581       else {
11582          host = tmp;
11583          ext = NULL;
11584       }
11585    }
11586 
11587    if (create_addr(p, host)) {
11588       *cause = AST_CAUSE_UNREGISTERED;
11589       sip_destroy(p);
11590       return NULL;
11591    }
11592    if (ast_strlen_zero(p->peername) && ext)
11593       ast_copy_string(p->peername, ext, sizeof(p->peername));
11594    /* Recalculate our side, and recalculate Call ID */
11595    if (ast_sip_ouraddrfor(&p->sa.sin_addr,&p->ourip))
11596       memcpy(&p->ourip, &__ourip, sizeof(p->ourip));
11597    build_via(p, p->via, sizeof(p->via));
11598    build_callid(p->callid, sizeof(p->callid), p->ourip, p->fromdomain);
11599    
11600    /* We have an extension to call, don't use the full contact here */
11601    /* This to enable dialling registered peers with extension dialling,
11602       like SIP/peername/extension   
11603       SIP/peername will still use the full contact */
11604    if (ext) {
11605       ast_copy_string(p->username, ext, sizeof(p->username));
11606       p->fullcontact[0] = 0;  
11607    }
11608 #if 0
11609    printf("Setting up to call extension '%s' at '%s'\n", ext ? ext : "<none>", host);
11610 #endif
11611    p->prefcodec = format;
11612    ast_mutex_lock(&p->lock);
11613    tmpc = sip_new(p, AST_STATE_DOWN, host);  /* Place the call */
11614    ast_mutex_unlock(&p->lock);
11615    if (!tmpc)
11616       sip_destroy(p);
11617    ast_update_use_count();
11618    restart_monitor();
11619    return tmpc;
11620 }

static int sip_reregister void *  data  )  [static]
 

sip_reregister: Update registration with SIP Proxy---

Definition at line 5242 of file chan_sip.c.

References __sip_do_register(), append_history(), ast_log(), ASTOBJ_REF, ASTOBJ_UNREF, sip_registry::call, sip_registry::expire, sip_registry::hostname, LOG_NOTICE, recordhistory, sip_registry_destroy(), sipdebug, and sip_registry::username.

Referenced by sip_send_all_registers().

05243 {
05244    /* if we are here, we know that we need to reregister. */
05245    struct sip_registry *r= ASTOBJ_REF((struct sip_registry *) data);
05246 
05247    /* if we couldn't get a reference to the registry object, punt */
05248    if (!r)
05249       return 0;
05250 
05251    if (r->call && recordhistory) {
05252       char tmp[80];
05253       snprintf(tmp, sizeof(tmp), "Account: %s@%s", r->username, r->hostname);
05254       append_history(r->call, "RegistryRenew", tmp);
05255    }
05256    /* Since registry's are only added/removed by the the monitor thread, this
05257       may be overkill to reference/dereference at all here */
05258    if (sipdebug)
05259       ast_log(LOG_NOTICE, "   -- Re-registration for  %s@%s\n", r->username, r->hostname);
05260 
05261    r->expire = -1;
05262    __sip_do_register(r);
05263    ASTOBJ_UNREF(r, sip_registry_destroy);
05264    return 0;
05265 }

static 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 2947 of file chan_sip.c.

References ast_dsp_process(), AST_FRAME_DTMF, AST_FRAME_NULL, AST_FRAME_VOICE, ast_log(), ast_rtcp_read(), ast_rtp_read(), ast_set_read_format(), ast_set_write_format(), ast_test_flag, ast_channel::fdno, ast_frame::frametype, LOG_DEBUG, ast_channel::nativeformats, sip_pvt::owner, ast_channel::readformat, sip_pvt::rtp, SIP_DTMF, SIP_DTMF_INBAND, SIP_DTMF_RFC2833, ast_frame::subclass, sip_pvt::vad, sip_pvt::vrtp, and ast_channel::writeformat.

Referenced by sip_read().

02948 {
02949    /* Retrieve audio/etc from channel.  Assumes p->lock is already held. */
02950    struct ast_frame *f;
02951    static struct ast_frame null_frame = { AST_FRAME_NULL, };
02952    
02953    if (!p->rtp) {
02954       /* We have no RTP allocated for this channel */
02955       return &null_frame;
02956    }
02957 
02958    switch(ast->fdno) {
02959    case 0:
02960       f = ast_rtp_read(p->rtp);  /* RTP Audio */
02961       break;
02962    case 1:
02963       f = ast_rtcp_read(p->rtp); /* RTCP Control Channel */
02964       break;
02965    case 2:
02966       f = ast_rtp_read(p->vrtp); /* RTP Video */
02967       break;
02968    case 3:
02969       f = ast_rtcp_read(p->vrtp);   /* RTCP Control Channel for video */
02970       break;
02971    default:
02972       f = &null_frame;
02973    }
02974    /* Don't forward RFC2833 if we're not supposed to */
02975    if (f && (f->frametype == AST_FRAME_DTMF) && (ast_test_flag(p, SIP_DTMF) != SIP_DTMF_RFC2833))
02976       return &null_frame;
02977    if (p->owner) {
02978       /* We already hold the channel lock */
02979       if (f->frametype == AST_FRAME_VOICE) {
02980          if (f->subclass != p->owner->nativeformats) {
02981             ast_log(LOG_DEBUG, "Oooh, format changed to %d\n", f->subclass);
02982             p->owner->nativeformats = f->subclass;
02983             ast_set_read_format(p->owner, p->owner->readformat);
02984             ast_set_write_format(p->owner, p->owner->writeformat);
02985          }
02986          if ((ast_test_flag(p, SIP_DTMF) == SIP_DTMF_INBAND) && p->vad) {
02987             f = ast_dsp_process(p->owner, p->vad, f);
02988             if (f && (f->frametype == AST_FRAME_DTMF)) 
02989                ast_log(LOG_DEBUG, "* Detected inband DTMF '%c'\n", f->subclass);
02990          }
02991       }
02992    }
02993    return f;
02994 }

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

static void sip_send_all_registers void   )  [static]
 

sip_send_all_registers: Send all known registrations

Definition at line 13016 of file chan_sip.c.

References ast_sched_add(), ast_sched_del(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_UNLOCK, ASTOBJ_WRLOCK, default_expiry, regl, regobjs, and sip_reregister().

Referenced by load_module().

13017 {
13018    int ms;
13019    int regspacing;
13020    if (!regobjs)
13021       return;
13022    regspacing = default_expiry * 1000/regobjs;
13023    if (regspacing > 100)
13024       regspacing = 100;
13025    ms = regspacing;
13026    ASTOBJ_CONTAINER_TRAVERSE(&regl, 1, do {
13027       ASTOBJ_WRLOCK(iterator);
13028       if (iterator->expire > -1)
13029          ast_sched_del(sched, iterator->expire);
13030       ms += regspacing;
13031       iterator->expire = ast_sched_add(sched, ms, sip_reregister, iterator);
13032       ASTOBJ_UNLOCK(iterator);
13033    } while (0)
13034    );
13035 }

static int sip_send_mwi_to_peer struct sip_peer peer  )  [static]
 

sip_send_mwi_to_peer: Send message waiting indication ---

Definition at line 11187 of file chan_sip.c.

References __ourip, ast_app_messagecount(), ast_log(), ast_set_flag, ast_sip_ouraddrfor(), build_callid(), build_via(), create_addr_from_peer(), sip_peer::lastmsgcheck, sip_peer::lastmsgssent, LOG_WARNING, sip_peer::mailbox, sip_alloc(), sip_destroy(), SIP_NOTIFY, SIP_OUTGOING, sip_scheddestroy(), transmit_notify_with_mwi(), and sip_peer::vmexten.

11188 {
11189    /* Called with peerl lock, but releases it */
11190    struct sip_pvt *p;
11191    int newmsgs, oldmsgs;
11192 
11193    /* Check for messages */
11194    ast_app_messagecount(peer->mailbox, &newmsgs, &oldmsgs);
11195    
11196    time(&peer->lastmsgcheck);
11197    
11198    /* Return now if it's the same thing we told them last time */
11199    if (((newmsgs << 8) | (oldmsgs)) == peer->lastmsgssent) {
11200       return 0;
11201    }
11202    
11203    p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY);
11204    if (!p) {
11205       ast_log(LOG_WARNING, "Unable to build sip pvt data for MWI\n");
11206       return -1;
11207    }
11208    peer->lastmsgssent = ((newmsgs << 8) | (oldmsgs));
11209    if (create_addr_from_peer(p, peer)) {
11210       /* Maybe they're not registered, etc. */
11211       sip_destroy(p);
11212       return 0;
11213    }
11214    /* Recalculate our side, and recalculate Call ID */
11215    if (ast_sip_ouraddrfor(&p->sa.sin_addr,&p->ourip))
11216       memcpy(&p->ourip, &__ourip, sizeof(p->ourip));
11217    build_via(p, p->via, sizeof(p->via));
11218    build_callid(p->callid, sizeof(p->callid), p->ourip, p->fromdomain);
11219    /* Send MWI */
11220    ast_set_flag(p, SIP_OUTGOING);
11221    transmit_notify_with_mwi(p, newmsgs, oldmsgs, peer->vmexten);
11222    sip_scheddestroy(p, 15000);
11223    return 0;
11224 }

static int sip_senddigit struct ast_channel ast,
char  digit
[static]
 

sip_senddigit: Send DTMF character on SIP channel

Definition at line 2604 of file chan_sip.c.

References ast_mutex_lock(), ast_mutex_unlock(), ast_rtp_senddigit(), ast_test_flag, sip_pvt::lock, SIP_DTMF, SIP_DTMF_INBAND, SIP_DTMF_INFO, SIP_DTMF_RFC2833, ast_channel::tech_pvt, and transmit_info_with_digit().

02605 {
02606    struct sip_pvt *p = ast->tech_pvt;
02607    int res = 0;
02608    ast_mutex_lock(&p->lock);
02609    switch (ast_test_flag(p, SIP_DTMF)) {
02610    case SIP_DTMF_INFO:
02611       transmit_info_with_digit(p, digit);
02612       break;
02613    case SIP_DTMF_RFC2833:
02614       if (p->rtp)
02615          ast_rtp_senddigit(p->rtp, digit);
02616       break;
02617    case SIP_DTMF_INBAND:
02618       res = -1;
02619       break;
02620    }
02621    ast_mutex_unlock(&p->lock);
02622    return res;
02623 }

static 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(), debug, ast_channel::name, sip_debug_test_pvt(), ast_channel::tech_pvt, and transmit_message_with_text().

01575 {
01576    struct sip_pvt *p = ast->tech_pvt;
01577    int debug=sip_debug_test_pvt(p);
01578 
01579    if (debug)
01580       ast_verbose("Sending text %s on %s\n", text, ast->name);
01581    if (!p)
01582       return -1;
01583    if (ast_strlen_zero(text))
01584       return 0;
01585    if (debug)
01586       ast_verbose("Really sending text %s on %s\n", text, ast->name);
01587    transmit_message_with_text(p, text);
01588    return 0;   
01589 }

static 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 12728 of file chan_sip.c.

References ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_rtp_get_peer(), ast_set_flag, ast_test_flag, sip_pvt::callid, sip_pvt::lastrtprx, sip_pvt::lastrtptx, sip_pvt::lock, LOG_DEBUG, option_debug, sip_pvt::ourip, sip_pvt::pendinginvite, sip_pvt::redircodecs, sip_pvt::redirip, sip_pvt::rtp, SIP_GOTREFER, SIP_NEEDREINVITE, SIP_PENDINGBYE, ast_channel::tech_pvt, transmit_reinvite_with_sdp(), sip_pvt::vredirip, and sip_pvt::vrtp.

12729 {
12730    struct sip_pvt *p;
12731 
12732    p = chan->tech_pvt;
12733    if (!p) 
12734       return -1;
12735    ast_mutex_lock(&p->lock);
12736    if (rtp)
12737       ast_rtp_get_peer(rtp, &p->redirip);
12738    else
12739       memset(&p->redirip, 0, sizeof(p->redirip));
12740    if (vrtp)
12741       ast_rtp_get_peer(vrtp, &p->vredirip);
12742    else
12743       memset(&p->vredirip, 0, sizeof(p->vredirip));
12744    p->redircodecs = codecs;
12745    if (!ast_test_flag(p, SIP_GOTREFER)) {
12746       if (!p->pendinginvite) {
12747          if (option_debug > 2) {
12748             char iabuf[INET_ADDRSTRLEN];
12749             ast_log(LOG_DEBUG, "Sending reinvite on SIP '%s' - It's audio soon redirected to IP %s\n", p->callid, ast_inet_ntoa(iabuf, sizeof(iabuf), rtp ? p->redirip.sin_addr : p->ourip));
12750          }
12751          transmit_reinvite_with_sdp(p);
12752       } else if (!ast_test_flag(p, SIP_PENDINGBYE)) {
12753          if (option_debug > 2) {
12754             char iabuf[INET_ADDRSTRLEN];
12755             ast_log(LOG_DEBUG, "Deferring reinvite on SIP '%s' - It's audio will be redirected to IP %s\n", p->callid, ast_inet_ntoa(iabuf, sizeof(iabuf), rtp ? p->redirip.sin_addr : p->ourip));
12756          }
12757          ast_set_flag(p, SIP_NEEDREINVITE);  
12758       }
12759    }
12760    /* Reset lastrtprx timer */
12761    time(&p->lastrtprx);
12762    time(&p->lastrtptx);
12763    ast_mutex_unlock(&p->lock);
12764    return 0;
12765 }

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

sip_show_channel: Show details of one call ---

Definition at line 8466 of file chan_sip.c.

References ast_cli(), ast_getformatname(), ast_inet_ntoa(), ast_mutex_lock(), ast_strlen_zero(), ast_test_flag, sip_pvt::callid, sip_pvt::capability, sip_pvt::cid_num, dtmfmode2str(), sip_route::hop, iflist, sip_pvt::jointcapability, sip_pvt::lastmsg, nat2str(), ast_channel::nativeformats, sip_pvt::next, sip_pvt::noncodeccapability, NONE, sip_pvt::ourip, sip_pvt::owner, sip_pvt::peercapability, sip_pvt::peername, sip_pvt::recv, sip_pvt::redirip, RESULT_SHOWUSAGE, sip_pvt::route, sip_pvt::sa, SIP_DTMF, SIP_NAT, SIP_NEEDDESTROY, sip_options, SIP_OUTGOING, SIP_PROMISCREDIR, sip_pvt::sipoptions, sip_pvt::subscribed, subscription_type2str(), sip_pvt::tag, text, sip_pvt::theirtag, sip_pvt::uri, sip_pvt::useragent, and sip_pvt::username.

08467 {
08468    struct sip_pvt *cur;
08469    char iabuf[INET_ADDRSTRLEN];
08470    size_t len;
08471    int found = 0;
08472 
08473    if (argc != 4)
08474       return RESULT_SHOWUSAGE;
08475    len = strlen(argv[3]);
08476    ast_mutex_lock(&iflock);
08477    cur = iflist;
08478    while(cur) {
08479       if (!strncasecmp(cur->callid, argv[3],len)) {
08480          ast_cli(fd,"\n");
08481          if (cur->subscribed != NONE)
08482             ast_cli(fd, "  * Subscription (type: %s)\n", subscription_type2str(cur->subscribed));
08483          else
08484             ast_cli(fd, "  * SIP Call\n");
08485          ast_cli(fd, "  Direction:              %s\n", ast_test_flag(cur, SIP_OUTGOING)?"Outgoing":"Incoming");
08486          ast_cli(fd, "  Call-ID:                %s\n", cur->callid);
08487          ast_cli(fd, "  Our Codec Capability:   %d\n", cur->capability);
08488          ast_cli(fd, "  Non-Codec Capability:   %d\n", cur->noncodeccapability);
08489          ast_cli(fd, "  Their Codec Capability:   %d\n", cur->peercapability);
08490          ast_cli(fd, "  Joint Codec Capability:   %d\n", cur->jointcapability);
08491          ast_cli(fd, "  Format                  %s\n", ast_getformatname(cur->owner ? cur->owner->nativeformats : 0) );
08492          ast_cli(fd, "  Theoretical Address:    %s:%d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), cur->sa.sin_addr), ntohs(cur->sa.sin_port));
08493          ast_cli(fd, "  Received Address:       %s:%d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), cur->recv.sin_addr), ntohs(cur->recv.sin_port));
08494          ast_cli(fd, "  NAT Support:            %s\n", nat2str(ast_test_flag(cur, SIP_NAT)));
08495          ast_cli(fd, "  Audio IP:               %s %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), cur->redirip.sin_addr.s_addr ? cur->redirip.sin_addr : cur->ourip), cur->redirip.sin_addr.s_addr ? "(Outside bridge)" : "(local)" );
08496          ast_cli(fd, "  Our Tag:                %s\n", cur->tag);
08497          ast_cli(fd, "  Their Tag:              %s\n", cur->theirtag);
08498          ast_cli(fd, "  SIP User agent:         %s\n", cur->useragent);
08499          if (!ast_strlen_zero(cur->username))
08500             ast_cli(fd, "  Username:               %s\n", cur->username);
08501          if (!ast_strlen_zero(cur->peername))
08502             ast_cli(fd, "  Peername:               %s\n", cur->peername);
08503          if (!ast_strlen_zero(cur->uri))
08504             ast_cli(fd, "  Original uri:           %s\n", cur->uri);
08505          if (!ast_strlen_zero(cur->cid_num))
08506             ast_cli(fd, "  Caller-ID:              %s\n", cur->cid_num);
08507          ast_cli(fd, "  Need Destroy:           %d\n", ast_test_flag(cur, SIP_NEEDDESTROY));
08508          ast_cli(fd, "  Last Message:           %s\n", cur->lastmsg);
08509          ast_cli(fd, "  Promiscuous Redir:      %s\n", ast_test_flag(cur, SIP_PROMISCREDIR) ? "Yes" : "No");
08510          ast_cli(fd, "  Route:                  %s\n", cur->route ? cur->route->hop : "N/A");
08511          ast_cli(fd, "  DTMF Mode:              %s\n", dtmfmode2str(ast_test_flag(cur, SIP_DTMF)));
08512          ast_cli(fd, "  SIP Options:            ");
08513          if (cur->sipoptions) {
08514             int x;
08515             for (x=0 ; (x < (sizeof(sip_options) / sizeof(sip_options[0]))); x++) {
08516                if (cur->sipoptions & sip_options[x].id)
08517                   ast_cli(fd, "%s ", sip_options[x].text);
08518             }
08519          } else
08520             ast_cli(fd, "(none)\n");
08521          ast_cli(fd, "\n\n");
08522          found++;
08523       }
08524       cur = cur->next;
08525    }
08526    ast_mutex_unlock(&iflock);
08527    if (!found) 
08528       ast_cli(fd, "No such SIP Call ID starting with '%s'\n", argv[3]);
08529    return RESULT_SUCCESS;
08530 }

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

sip_show_channels: Show active SIP channels ---

Definition at line 8267 of file chan_sip.c.

References __sip_show_channels().

08268 {
08269         return __sip_show_channels(fd, argc, argv, 0);
08270 }

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

Definition at line 7823 of file chan_sip.c.

References ast_cli(), AST_LIST_EMPTY, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_strlen_zero(), domain::context, domain::domain, domain_mode_to_text(), FORMAT, list, domain::mode, and RESULT_SUCCESS.

07824 {
07825    struct domain *d;
07826 
07827    if (AST_LIST_EMPTY(&domain_list)) {
07828       ast_cli(fd, "SIP Domain support not enabled.\n\n");
07829       return RESULT_SUCCESS;
07830    } else {
07831       ast_cli(fd, FORMAT, "Our local SIP domains:", "Context", "Set by");
07832       AST_LIST_LOCK(&domain_list);
07833       AST_LIST_TRAVERSE(&domain_list, d, list)
07834          ast_cli(fd, FORMAT, d->domain, ast_strlen_zero(d->context) ? "(default)": d->context,
07835             domain_mode_to_text(d->mode));
07836       AST_LIST_UNLOCK(&domain_list);
07837       ast_cli(fd, "\n");
07838       return RESULT_SUCCESS;
07839    }
07840 }

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

sip_show_history: Show history details of one call ---

Definition at line 8533 of file chan_sip.c.

References ast_cli(), ast_mutex_lock(), ast_mutex_unlock(), sip_pvt::callid, sip_history::event, sip_pvt::history, iflist, sip_pvt::next, sip_history::next, NONE, recordhistory, RESULT_SHOWUSAGE, RESULT_SUCCESS, and sip_pvt::subscribed.

08534 {
08535    struct sip_pvt *cur;
08536    struct sip_history *hist;
08537    size_t len;
08538    int x;
08539    int found = 0;
08540 
08541    if (argc != 4)
08542       return RESULT_SHOWUSAGE;
08543    if (!recordhistory)
08544       ast_cli(fd, "\n***Note: History recording is currently DISABLED.  Use 'sip history' to ENABLE.\n");
08545    len = strlen(argv[3]);
08546    ast_mutex_lock(&iflock);
08547    cur = iflist;
08548    while(cur) {
08549       if (!strncasecmp(cur->callid, argv[3], len)) {
08550          ast_cli(fd,"\n");
08551          if (cur->subscribed != NONE)
08552             ast_cli(fd, "  * Subscription\n");
08553          else
08554             ast_cli(fd, "  * SIP Call\n");
08555          x = 0;
08556          hist = cur->history;
08557          while(hist) {
08558             x++;
08559             ast_cli(fd, "%d. %s\n", x, hist->event);
08560             hist = hist->next;
08561          }
08562          if (!x)
08563             ast_cli(fd, "Call '%s' has no history\n", cur->callid);
08564          found++;
08565       }
08566       cur = cur->next;
08567    }
08568    ast_mutex_unlock(&iflock);
08569    if (!found) 
08570       ast_cli(fd, "No such SIP Call ID starting with '%s'\n", argv[3]);
08571    return RESULT_SUCCESS;
08572 }

static 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 7290 of file chan_sip.c.

References ast_cli(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, FORMAT, FORMAT2, RESULT_SHOWUSAGE, and userl.

07290                                                           {
07291 #define FORMAT  "%-25.25s %-15.15s %-15.15s \n"
07292 #define FORMAT2 "%-25.25s %-15.15s %-15.15s \n"
07293    char ilimits[40];
07294    char iused[40];
07295    int showall = 0;
07296 
07297    if (argc < 3) 
07298       return RESULT_SHOWUSAGE;
07299 
07300    if (argc == 4 && !strcmp(argv[3],"all")) 
07301          showall = 1;
07302    
07303    ast_cli(fd, FORMAT, "* User name", "In use", "Limit");
07304    ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do {
07305       ASTOBJ_RDLOCK(iterator);
07306       if (iterator->call_limit)
07307          snprintf(ilimits, sizeof(ilimits), "%d", iterator->call_limit);
07308       else 
07309          ast_copy_string(ilimits, "N/A", sizeof(ilimits));
07310       snprintf(iused, sizeof(iused), "%d", iterator->inUse);
07311       if (showall || iterator->call_limit)
07312          ast_cli(fd, FORMAT2, iterator->name, iused, ilimits);
07313       ASTOBJ_UNLOCK(iterator);
07314    } while (0) );
07315 
07316    ast_cli(fd, FORMAT, "* Peer name", "In use", "Limit");
07317 
07318    ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do {
07319       ASTOBJ_RDLOCK(iterator);
07320       if (iterator->call_limit)
07321          snprintf(ilimits, sizeof(ilimits), "%d", iterator->call_limit);
07322       else 
07323          ast_copy_string(ilimits, "N/A", sizeof(ilimits));
07324       snprintf(iused, sizeof(iused), "%d", iterator->inUse);
07325       if (showall || iterator->call_limit)
07326          ast_cli(fd, FORMAT2, iterator->name, iused, ilimits);
07327       ASTOBJ_UNLOCK(iterator);
07328    } while (0) );
07329 
07330    return RESULT_SUCCESS;
07331 #undef FORMAT
07332 #undef FORMAT2
07333 }

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

sip_show_objects: List all allocated SIP Objects ---

Definition at line 7596 of file chan_sip.c.

References apeerobjs, ast_cli(), ASTOBJ_CONTAINER_DUMP, peerl, regl, regobjs, RESULT_SHOWUSAGE, RESULT_SUCCESS, rpeerobjs, ruserobjs, speerobjs, suserobjs, and userl.

07597 {
07598    char tmp[256];
07599    if (argc != 3)
07600       return RESULT_SHOWUSAGE;
07601    ast_cli(fd, "-= User objects: %d static, %d realtime =-\n\n", suserobjs, ruserobjs);
07602    ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), &userl);
07603    ast_cli(fd, "-= Peer objects: %d static, %d realtime, %d autocreate =-\n\n", speerobjs, rpeerobjs, apeerobjs);
07604    ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), &peerl);
07605    ast_cli(fd, "-= Registry objects: %d =-\n\n", regobjs);
07606    ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), &regl);
07607    return RESULT_SUCCESS;
07608 }

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

sip_show_peer: Show one peer in detail ---

Definition at line 7880 of file chan_sip.c.

References _sip_show_peer().

07881 {
07882    return _sip_show_peer(0, fd, NULL, NULL, argc, argv);
07883 }

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

sip_show_peers: CLI Show Peers command

Definition at line 7457 of file chan_sip.c.

References _sip_show_peers().

07458 {
07459    return _sip_show_peers(fd, NULL, NULL, NULL, argc, argv);
07460 }

static 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 8132 of file chan_sip.c.

References ast_cli(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, DEFAULT_SIP_PORT, FORMAT, FORMAT2, host, regl, regstate2str(), and RESULT_SHOWUSAGE.

08133 {
08134 #define FORMAT2 "%-30.30s  %-12.12s  %8.8s %-20.20s\n"
08135 #define FORMAT  "%-30.30s  %-12.12s  %8d %-20.20s\n"
08136    char host[80];
08137 
08138    if (argc != 3)
08139       return RESULT_SHOWUSAGE;
08140    ast_cli(fd, FORMAT2, "Host", "Username", "Refresh", "State");
08141    ASTOBJ_CONTAINER_TRAVERSE(&regl, 1, do {
08142       ASTOBJ_RDLOCK(iterator);
08143       snprintf(host, sizeof(host), "%s:%d", iterator->hostname, iterator->portno ? iterator->portno : DEFAULT_SIP_PORT);
08144       ast_cli(fd, FORMAT, host, iterator->username, iterator->refresh, regstate2str(iterator->regstate));
08145       ASTOBJ_UNLOCK(iterator);
08146    } while(0));
08147    return RESULT_SUCCESS;
08148 #undef FORMAT
08149 #undef FORMAT2
08150 }

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

sip_show_settings: List global settings for the SIP channel ---

Definition at line 8153 of file chan_sip.c.

References allow_external_domains, ast_check_realtime(), ast_cli(), ast_inet_ntoa(), AST_LIST_EMPTY, ast_strlen_zero(), ast_test_flag, authl, autocreatepeer, bindaddr, callevents, compactheaders, default_callerid, default_context, default_expiry, default_fromdomain, default_language, default_notifymime, default_qualify, default_useragent, dtmfmode2str(), global_allowguest, global_flags, global_flags_page2, global_musicclass, global_mwitime, global_notifyringing, global_realm, global_reg_timeout, global_regattempts_max, global_rtautoclear, global_rtpholdtimeout, global_rtptimeout, global_vmexten, max_expiry, nat2str(), pedanticsipchecking, prefs, print_codec_to_cli(), recordhistory, regcontext, relaxdtmf, RESULT_SHOWUSAGE, RESULT_SUCCESS, SIP_DTMF, SIP_NAT, SIP_PAGE2_IGNOREREGEXPIRE, SIP_PAGE2_RTCACHEFRIENDS, SIP_PAGE2_RTUPDATE, SIP_PROG_INBAND, SIP_PROG_INBAND_NEVER, SIP_PROG_INBAND_NO, SIP_PROMISCREDIR, SIP_USECLIENTCODE, SIP_USEREQPHONE, srvlookup, tos, and videosupport.

08154 {
08155    char tmp[BUFSIZ];
08156    int realtimepeers = 0;
08157    int realtimeusers = 0;
08158 
08159    realtimepeers = ast_check_realtime("sippeers");
08160    realtimeusers = ast_check_realtime("sipusers");
08161 
08162    if (argc != 3)
08163       return RESULT_SHOWUSAGE;
08164    ast_cli(fd, "\n\nGlobal Settings:\n");
08165    ast_cli(fd, "----------------\n");
08166    ast_cli(fd, "  SIP Port:               %d\n", ntohs(bindaddr.sin_port));
08167    ast_cli(fd, "  Bindaddress:            %s\n", ast_inet_ntoa(tmp, sizeof(tmp), bindaddr.sin_addr));
08168    ast_cli(fd, "  Videosupport:           %s\n", videosupport ? "Yes" : "No");
08169    ast_cli(fd, "  AutoCreatePeer:         %s\n", autocreatepeer ? "Yes" : "No");
08170    ast_cli(fd, "  Allow unknown access:   %s\n", global_allowguest ? "Yes" : "No");
08171    ast_cli(fd, "  Promsic. redir:         %s\n", ast_test_flag(&global_flags, SIP_PROMISCREDIR) ? "Yes" : "No");
08172    ast_cli(fd, "  SIP domain support:     %s\n", AST_LIST_EMPTY(&domain_list) ? "No" : "Yes");
08173    ast_cli(fd, "  Call to non-local dom.: %s\n", allow_external_domains ? "Yes" : "No");
08174    ast_cli(fd, "  URI user is phone no:   %s\n", ast_test_flag(&global_flags, SIP_USEREQPHONE) ? "Yes" : "No");
08175    ast_cli(fd, "  Our auth realm          %s\n", global_realm);
08176    ast_cli(fd, "  Realm. auth:            %s\n", authl ? "Yes": "No");
08177    ast_cli(fd, "  User Agent:             %s\n", default_useragent);
08178    ast_cli(fd, "  MWI checking interval:  %d secs\n", global_mwitime);
08179    ast_cli(fd, "  Reg. context:           %s\n", ast_strlen_zero(regcontext) ? "(not set)" : regcontext);
08180    ast_cli(fd, "  Caller ID:              %s\n", default_callerid);
08181    ast_cli(fd, "  From: Domain:           %s\n", default_fromdomain);
08182    ast_cli(fd, "  Record SIP history:     %s\n", recordhistory ? "On" : "Off");
08183    ast_cli(fd, "  Call Events:            %s\n", callevents ? "On" : "Off");
08184    ast_cli(fd, "  IP ToS:                 0x%x\n", tos);
08185 #ifdef OSP_SUPPORT
08186    ast_cli(fd, "  OSP Support:            Yes\n");
08187 #else
08188    ast_cli(fd, "  OSP Support:            No\n");
08189 #endif
08190    if (!realtimepeers && !realtimeusers)
08191       ast_cli(fd, "  SIP realtime:           Disabled\n" );
08192    else
08193       ast_cli(fd, "  SIP realtime:           Enabled\n" );
08194 
08195    ast_cli(fd, "\nGlobal Signalling Settings:\n");
08196    ast_cli(fd, "---------------------------\n");
08197    ast_cli(fd, "  Codecs:                 ");
08198    print_codec_to_cli(fd, &prefs);
08199    ast_cli(fd, "\n");
08200    ast_cli(fd, "  Relax DTMF:             %s\n", relaxdtmf ? "Yes" : "No");
08201    ast_cli(fd, "  Compact SIP headers:    %s\n", compactheaders ? "Yes" : "No");
08202    ast_cli(fd, "  RTP Timeout:            %d %s\n", global_rtptimeout, global_rtptimeout ? "" : "(Disabled)" );
08203    ast_cli(fd, "  RTP Hold Timeout:       %d %s\n", global_rtpholdtimeout, global_rtpholdtimeout ? "" : "(Disabled)");
08204    ast_cli(fd, "  MWI NOTIFY mime type:   %s\n", default_notifymime);
08205    ast_cli(fd, "  DNS SRV lookup:         %s\n", srvlookup ? "Yes" : "No");
08206    ast_cli(fd, "  Pedantic SIP support:   %s\n", pedanticsipchecking ? "Yes" : "No");
08207    ast_cli(fd, "  Reg. max duration:      %d secs\n", max_expiry);
08208    ast_cli(fd, "  Reg. default duration:  %d secs\n", default_expiry);
08209    ast_cli(fd, "  Outbound reg. timeout:  %d secs\n", global_reg_timeout);
08210    ast_cli(fd, "  Outbound reg. attempts: %d\n", global_regattempts_max);
08211    ast_cli(fd, "  Notify ringing state:   %s\n", global_notifyringing ? "Yes" : "No");
08212    ast_cli(fd, "\nDefault Settings:\n");
08213    ast_cli(fd, "-----------------\n");
08214    ast_cli(fd, "  Context:                %s\n", default_context);
08215    ast_cli(fd, "  Nat:                    %s\n", nat2str(ast_test_flag(&global_flags, SIP_NAT)));
08216    ast_cli(fd, "  DTMF:                   %s\n", dtmfmode2str(ast_test_flag(&global_flags, SIP_DTMF)));
08217    ast_cli(fd, "  Qualify:                %d\n", default_qualify);
08218    ast_cli(fd, "  Use ClientCode:         %s\n", ast_test_flag(&global_flags, SIP_USECLIENTCODE) ? "Yes" : "No");
08219    ast_cli(fd, "  Progress inband:        %s\n", (ast_test_flag(&global_flags, SIP_PROG_INBAND) == SIP_PROG_INBAND_NEVER) ? "Never" : (ast_test_flag(&global_flags, SIP_PROG_INBAND) == SIP_PROG_INBAND_NO) ? "No" : "Yes" );
08220    ast_cli(fd, "  Language:               %s\n", ast_strlen_zero(default_language) ? "(Defaults to English)" : default_language);
08221    ast_cli(fd, "  Musicclass:             %s\n", global_musicclass);
08222    ast_cli(fd, "  Voice Mail Extension:   %s\n", global_vmexten);
08223 
08224    
08225    if (realtimepeers || realtimeusers) {
08226       ast_cli(fd, "\nRealtime SIP Settings:\n");
08227       ast_cli(fd, "----------------------\n");
08228       ast_cli(fd, "  Realtime Peers:         %s\n", realtimepeers ? "Yes" : "No");
08229       ast_cli(fd, "  Realtime Users:         %s\n", realtimeusers ? "Yes" : "No");
08230       ast_cli(fd, "  Cache Friends:          %s\n", ast_test_flag(&global_flags_page2, SIP_PAGE2_RTCACHEFRIENDS) ? "Yes" : "No");
08231       ast_cli(fd, "  Update:                 %s\n", ast_test_flag(&global_flags_page2, SIP_PAGE2_RTUPDATE) ? "Yes" : "No");
08232       ast_cli(fd, "  Ignore Reg. Expire:     %s\n", ast_test_flag(&global_flags_page2, SIP_PAGE2_IGNOREREGEXPIRE) ? "Yes" : "No");
08233       ast_cli(fd, "  Auto Clear:             %d\n", global_rtautoclear);
08234    }
08235    ast_cli(fd, "\n----\n");
08236    return RESULT_SUCCESS;
08237 }

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

sip_show_subscriptions: Show active SIP subscriptions ---

Definition at line 8273 of file chan_sip.c.

References __sip_show_channels().

08274 {
08275         return __sip_show_channels(fd, argc, argv, 1);
08276 }

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

sip_show_user: Show one user in detail ---

Definition at line 8068 of file chan_sip.c.

References ast_callerid_merge(), ast_cdr_flags2str(), ast_cli(), ast_codec_pref_index(), ast_describe_caller_presentation(), ast_getformatname(), ast_strlen_zero(), ASTOBJ_UNREF, find_user(), ast_variable::name, ast_variable::next, print_group(), RESULT_SHOWUSAGE, sip_destroy_user(), user, and ast_variable::value.

08069 {
08070    char cbuf[256];
08071    struct sip_user *user;
08072    struct ast_codec_pref *pref;
08073    struct ast_variable *v;
08074    int x = 0, codec = 0, load_realtime = 0;
08075 
08076    if (argc < 4)
08077       return RESULT_SHOWUSAGE;
08078 
08079    /* Load from realtime storage? */
08080    load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? 1 : 0;
08081 
08082    user = find_user(argv[3], load_realtime);
08083    if (user) {
08084       ast_cli(fd,"\n\n");
08085       ast_cli(fd, "  * Name       : %s\n", user->name);
08086       ast_cli(fd, "  Secret       : %s\n", ast_strlen_zero(user->secret)?"<Not set>":"<Set>");
08087       ast_cli(fd, "  MD5Secret    : %s\n", ast_strlen_zero(user->md5secret)?"<Not set>":"<Set>");
08088       ast_cli(fd, "  Context      : %s\n", user->context);
08089       ast_cli(fd, "  Language     : %s\n", user->language);
08090       if (!ast_strlen_zero(user->accountcode))
08091          ast_cli(fd, "  Accountcode  : %s\n", user->accountcode);
08092       ast_cli(fd, "  AMA flags    : %s\n", ast_cdr_flags2str(user->amaflags));
08093       ast_cli(fd, "  CallingPres  : %s\n", ast_describe_caller_presentation(user->callingpres));
08094       ast_cli(fd, "  Call limit   : %d\n", user->call_limit);
08095       ast_cli(fd, "  Callgroup    : ");
08096       print_group(fd, user->callgroup, 0);
08097       ast_cli(fd, "  Pickupgroup  : ");
08098       print_group(fd, user->pickupgroup, 0);
08099       ast_cli(fd, "  Callerid     : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), user->cid_name, user->cid_num, "<unspecified>"));
08100       ast_cli(fd, "  ACL          : %s\n", (user->ha?"Yes":"No"));
08101       ast_cli(fd, "  Codec Order  : (");
08102       pref = &user->prefs;
08103       for(x = 0; x < 32 ; x++) {
08104          codec = ast_codec_pref_index(pref,x);
08105          if (!codec)
08106             break;
08107          ast_cli(fd, "%s", ast_getformatname(codec));
08108          if (x < 31 && ast_codec_pref_index(pref,x+1))
08109             ast_cli(fd, "|");
08110       }
08111 
08112       if (!x)
08113          ast_cli(fd, "none");
08114       ast_cli(fd, ")\n");
08115 
08116       if (user->chanvars) {
08117          ast_cli(fd, "  Variables    :\n");
08118          for (v = user->chanvars ; v ; v = v->next)
08119             ast_cli(fd, "                 %s = %s\n", v->name, v->value);
08120       }
08121       ast_cli(fd,"\n");
08122       ASTOBJ_UNREF(user,sip_destroy_user);
08123    } else {
08124       ast_cli(fd,"User %s not found.\n", argv[3]);
08125       ast_cli(fd,"\n");
08126    }
08127 
08128    return RESULT_SUCCESS;
08129 }

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

sip_show_users: CLI Command 'SIP Show Users' ---

Definition at line 7378 of file chan_sip.c.

References ast_cli(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, FORMAT, RESULT_SHOWUSAGE, and userl.

07379 {
07380    regex_t regexbuf;
07381    int havepattern = 0;
07382 
07383 #define FORMAT  "%-25.25s  %-15.15s  %-15.15s  %-15.15s  %-5.5s%-10.10s\n"
07384 
07385    switch (argc) {
07386    case 5:
07387       if (!strcasecmp(argv[3], "like")) {
07388          if (regcomp(&regexbuf, argv[4], REG_EXTENDED | REG_NOSUB))
07389             return RESULT_SHOWUSAGE;
07390          havepattern = 1;
07391       } else
07392          return RESULT_SHOWUSAGE;
07393    case 3:
07394       break;
07395    default:
07396       return RESULT_SHOWUSAGE;
07397    }
07398 
07399    ast_cli(fd, FORMAT, "Username", "Secret", "Accountcode", "Def.Context", "ACL", "NAT");
07400    ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do {
07401       ASTOBJ_RDLOCK(iterator);
07402 
07403       if (havepattern && regexec(&regexbuf, iterator->name, 0, NULL, 0)) {
07404          ASTOBJ_UNLOCK(iterator);
07405          continue;
07406       }
07407 
07408       ast_cli(fd, FORMAT, iterator->name, 
07409          iterator->secret, 
07410          iterator->accountcode,
07411          iterator->context,
07412          iterator->ha ? "Yes" : "No",
07413          nat2str(ast_test_flag(iterator, SIP_NAT)));
07414       ASTOBJ_UNLOCK(iterator);
07415    } while (0)
07416    );
07417 
07418    if (havepattern)
07419       regfree(&regexbuf);
07420 
07421    return RESULT_SUCCESS;
07422 #undef FORMAT
07423 }

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

sip_sipredirect: Transfer call before connect with a 302 redirect ---

Definition at line 12925 of file chan_sip.c.

References ast_log(), ast_set_flag, ast_strdupa, ast_strlen_zero(), get_header(), host, sip_pvt::initreq, LOG_ERROR, sip_pvt::our_contact, SIP_ALREADYGONE, strsep(), and transmit_response_reliable().

Referenced by sip_transfer().

12926 {
12927    char *cdest;
12928    char *extension, *host, *port;
12929    char tmp[80];
12930    
12931    cdest = ast_strdupa(dest);
12932    if (!cdest) {
12933       ast_log(LOG_ERROR, "Problem allocating the memory\n");
12934       return 0;
12935    }
12936    extension = strsep(&cdest, "@");
12937    host = strsep(&cdest, ":");
12938    port = strsep(&cdest, ":");
12939    if (!extension) {
12940       ast_log(LOG_ERROR, "Missing mandatory argument: extension\n");
12941       return 0;
12942    }
12943 
12944    /* we'll issue the redirect message here */
12945    if (!host) {
12946       char *localtmp;
12947       ast_copy_string(tmp, get_header(&p->initreq, "To"), sizeof(tmp));
12948       if (!strlen(tmp)) {
12949          ast_log(LOG_ERROR, "Cannot retrieve the 'To' header from the original SIP request!\n");
12950          return 0;
12951       }
12952       if ((localtmp = strstr(tmp, "sip:")) && (localtmp = strchr(localtmp, '@'))) {
12953          char lhost[80], lport[80];
12954          memset(lhost, 0, sizeof(lhost));
12955          memset(lport, 0, sizeof(lport));
12956          localtmp++;
12957          /* This is okey because lhost and lport are as big as tmp */
12958          sscanf(localtmp, "%[^<>:; ]:%[^<>:; ]", lhost, lport);
12959          if (!strlen(lhost)) {
12960             ast_log(LOG_ERROR, "Can't find the host address\n");
12961             return 0;
12962          }
12963          host = ast_strdupa(lhost);
12964          if (!host) {
12965             ast_log(LOG_ERROR, "Problem allocating the memory\n");
12966             return 0;
12967          }
12968          if (!ast_strlen_zero(lport)) {
12969             port = ast_strdupa(lport);
12970             if (!port) {
12971                ast_log(LOG_ERROR, "Problem allocating the memory\n");
12972                return 0;
12973             }
12974          }
12975       }
12976    }
12977 
12978    snprintf(p->our_contact, sizeof(p->our_contact), "Transfer <sip:%s@%s%s%s>", extension, host, port ? ":" : "", port ? port : "");
12979    transmit_response_reliable(p, "302 Moved Temporarily", &p->initreq, 1);
12980 
12981    /* this is all that we want to send to that SIP device */
12982    ast_set_flag(p, SIP_ALREADYGONE);
12983 
12984    /* hangup here */
12985    return -1;
12986 }

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

sip_transfer: Transfer SIP call

Definition at line 2628 of file chan_sip.c.

References ast_channel::_state, ast_mutex_lock(), ast_mutex_unlock(), AST_STATE_RING, sip_pvt::lock, sip_sipredirect(), ast_channel::tech_pvt, and transmit_refer().

02629 {
02630    struct sip_pvt *p = ast->tech_pvt;
02631    int res;
02632 
02633    ast_mutex_lock(&p->lock);
02634    if (ast->_state == AST_STATE_RING)
02635       res = sip_sipredirect(p, dest);
02636    else
02637       res = transmit_refer(p, dest);
02638    ast_mutex_unlock(&p->lock);
02639    return res;
02640 }

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

sip_write: Send frame to media channel (rtp) ---

Definition at line 2535 of file chan_sip.c.

References ast_channel::_state, AST_FRAME_IMAGE, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_rtp_write(), ast_set_flag, AST_STATE_UP, ast_test_flag, ast_frame::frametype, sip_pvt::initreq, sip_pvt::lastrtptx, sip_pvt::lock, LOG_WARNING, ast_channel::nativeformats, ast_channel::readformat, sip_pvt::rtp, SIP_OUTGOING, SIP_PROGRESS_SENT, ast_frame::subclass, ast_channel::tech_pvt, transmit_response_with_sdp(), sip_pvt::vrtp, and ast_channel::writeformat.

02536 {
02537    struct sip_pvt *p = ast->tech_pvt;
02538    int res = 0;
02539    switch (frame->frametype) {
02540    case AST_FRAME_VOICE:
02541       if (!(frame->subclass & ast->nativeformats)) {
02542          ast_log(LOG_WARNING, "Asked to transmit frame type %d, while native formats is %d (read/write = %d/%d)\n",
02543             frame->subclass, ast->nativeformats, ast->readformat, ast->writeformat);
02544          return 0;
02545       }
02546       if (p) {
02547          ast_mutex_lock(&p->lock);
02548          if (p->rtp) {
02549             /* If channel is not up, activate early media session */
02550             if ((ast->_state != AST_STATE_UP) && !ast_test_flag(p, SIP_PROGRESS_SENT) && !ast_test_flag(p, SIP_OUTGOING)) {
02551                transmit_response_with_sdp(p, "183 Session Progress", &p->initreq, 0);
02552                ast_set_flag(p, SIP_PROGRESS_SENT); 
02553             }
02554             time(&p->lastrtptx);
02555             res =  ast_rtp_write(p->rtp, frame);
02556          }
02557          ast_mutex_unlock(&p->lock);
02558       }
02559       break;
02560    case AST_FRAME_VIDEO:
02561       if (p) {
02562          ast_mutex_lock(&p->lock);
02563          if (p->vrtp) {
02564             /* Activate video early media */
02565             if ((ast->_state != AST_STATE_UP) && !ast_test_flag(p, SIP_PROGRESS_SENT) && !ast_test_flag(p, SIP_OUTGOING)) {
02566                transmit_response_with_sdp(p, "183 Session Progress", &p->initreq, 0);
02567                ast_set_flag(p, SIP_PROGRESS_SENT); 
02568             }
02569             time(&p->lastrtptx);
02570             res =  ast_rtp_write(p->vrtp, frame);
02571          }
02572          ast_mutex_unlock(&p->lock);
02573       }
02574       break;
02575    case AST_FRAME_IMAGE:
02576       return 0;
02577       break;
02578    default: 
02579       ast_log(LOG_WARNING, "Can't send %d type frames with SIP write\n", frame->frametype);
02580       return 0;
02581    }
02582 
02583    return res;
02584 }

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

sipsock_read: Read data from SIP socket ---

Definition at line 11097 of file chan_sip.c.

References append_history(), ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_set_flag, ast_test_flag, ast_update_use_count(), ast_verbose(), sip_pvt::callid, find_call(), find_sip_method(), get_header(), handle_request(), sip_pvt::lock, ast_channel::lock, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, lws2sws(), sip_pvt::owner, parse_request(), pedanticsipchecking, recordhistory, sip_pvt::recv, sip_debug_test_addr(), SIP_PKT_DEBUG, and sipsock.

Referenced by do_monitor().

11098 {
11099    struct sip_request req;
11100    struct sockaddr_in sin = { 0, };
11101    struct sip_pvt *p;
11102    int res;
11103    socklen_t len;
11104    int nounlock;
11105    int recount = 0;
11106    char iabuf[INET_ADDRSTRLEN];
11107 
11108    len = sizeof(sin);
11109    memset(&req, 0, sizeof(req));
11110    res = recvfrom(sipsock, req.data, sizeof(req.data) - 1, 0, (struct sockaddr *)&sin, &len);
11111    if (res < 0) {
11112 #if !defined(__FreeBSD__)
11113       if (errno == EAGAIN)
11114          ast_log(LOG_NOTICE, "SIP: Received packet with bad UDP checksum\n");
11115       else 
11116 #endif
11117       if (errno != ECONNREFUSED)
11118          ast_log(LOG_WARNING, "Recv error: %s\n", strerror(errno));
11119       return 1;
11120    }
11121    if (res == sizeof(req.data)) {
11122       ast_log(LOG_DEBUG, "Received packet exceeds buffer. Data is possibly lost\n");
11123    }
11124    req.data[res] = '\0';
11125    req.len = res;
11126    if(sip_debug_test_addr(&sin))
11127       ast_set_flag(&req, SIP_PKT_DEBUG);
11128    if (pedanticsipchecking)
11129       req.len = lws2sws(req.data, req.len);  /* Fix multiline headers */
11130    if (ast_test_flag(&req, SIP_PKT_DEBUG)) {
11131       ast_verbose("\n<-- SIP read from %s:%d: \n%s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), ntohs(sin.sin_port), req.data);
11132    }
11133    parse_request(&req);
11134    req.method = find_sip_method(req.rlPart1);
11135    if (ast_test_flag(&req, SIP_PKT_DEBUG)) {
11136       ast_verbose("--- (%d headers %d lines)", req.headers, req.lines);
11137       if (req.headers + req.lines == 0) 
11138          ast_verbose(" Nat keepalive ");
11139       ast_verbose("---\n");
11140    }
11141 
11142    if (req.headers < 2) {
11143       /* Must have at least two headers */
11144       return 1;
11145    }
11146 
11147 
11148    /* Process request, with netlock held */
11149 retrylock:
11150    ast_mutex_lock(&netlock);
11151    p = find_call(&req, &sin, req.method);
11152    if (p) {
11153       /* Go ahead and lock the owner if it has one -- we may need it */
11154       if (p->owner && ast_mutex_trylock(&p->owner->lock)) {
11155          ast_log(LOG_DEBUG, "Failed to grab lock, trying again...\n");
11156          ast_mutex_unlock(&p->lock);
11157          ast_mutex_unlock(&netlock);
11158          /* Sleep infintismly short amount of time */
11159          usleep(1);
11160          goto retrylock;
11161       }
11162       memcpy(&p->recv, &sin, sizeof(p->recv));
11163       if (recordhistory) {
11164          char tmp[80];
11165          /* This is a response, note what it was for */
11166          snprintf(tmp, sizeof(tmp), "%s / %s", req.data, get_header(&req, "CSeq"));
11167          append_history(p, "Rx", tmp);
11168       }
11169       nounlock = 0;
11170       if (handle_request(p, &req, &sin, &recount, &nounlock) == -1) {
11171          /* Request failed */
11172          ast_log(LOG_DEBUG, "SIP message could not be handled, bad request: %-70.70s\n", p->callid[0] ? p->callid : "<no callid>");
11173       }
11174       
11175       if (p->owner && !nounlock)
11176          ast_mutex_unlock(&p->owner->lock);
11177       ast_mutex_unlock(&p->lock);
11178    }
11179    ast_mutex_unlock(&netlock);
11180    if (recount)
11181       ast_update_use_count();
11182 
11183    return 1;
11184 }

static const char* subscription_type2str enum subscriptiontype  subtype  )  [static]
 

subscription_type2str: Show subscription type in string format

Definition at line 8240 of file chan_sip.c.

References subscription_types, and type.

Referenced by __sip_show_channels(), and sip_show_channel().

08240                                                                         {
08241    int i;
08242 
08243    for (i = 1; (i < (sizeof(subscription_types) / sizeof(subscription_types[0]))); i++) {
08244       if (subscription_types[i].type == subtype) {
08245          return subscription_types[i].text;
08246       }
08247    }
08248    return subscription_types[0].text;
08249 }

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

temp_peer: Create temporary peer (used in autocreatepeer mode) ---

Definition at line 11994 of file chan_sip.c.

References apeerobjs, ast_copy_flags, ast_set_flag, ASTOBJ_INIT, default_context, default_language, DEFAULT_SIP_PORT, default_subscribecontext, global_capability, global_flags, global_musicclass, global_rtpholdtimeout, global_rtpkeepalive, global_rtptimeout, malloc, prefs, reg_source_db(), SIP_DYNAMIC, SIP_FLAGS_TO_COPY, and SIP_SELFDESTRUCT.

Referenced by register_verify().

11995 {
11996    struct sip_peer *peer;
11997 
11998    peer = malloc(sizeof(*peer));
11999    if (!peer)
12000       return NULL;
12001 
12002    memset(peer, 0, sizeof(*peer));
12003    apeerobjs++;
12004    ASTOBJ_INIT(peer);
12005 
12006    peer->expire = -1;
12007    peer->pokeexpire = -1;
12008    ast_copy_string(peer->name, name, sizeof(peer->name));
12009    ast_copy_flags(peer, &global_flags, SIP_FLAGS_TO_COPY);
12010    strcpy(peer->context, default_context);
12011    strcpy(peer->subscribecontext, default_subscribecontext);
12012    strcpy(peer->language, default_language);
12013    strcpy(peer->musicclass, global_musicclass);
12014    peer->addr.sin_port = htons(DEFAULT_SIP_PORT);
12015    peer->addr.sin_family = AF_INET;
12016    peer->capability = global_capability;
12017    peer->rtptimeout = global_rtptimeout;
12018    peer->rtpholdtimeout = global_rtpholdtimeout;
12019    peer->rtpkeepalive = global_rtpkeepalive;
12020    ast_set_flag(peer, SIP_SELFDESTRUCT);
12021    ast_set_flag(peer, SIP_DYNAMIC);
12022    peer->prefs = prefs;
12023    reg_source_db(peer);
12024 
12025    return peer;
12026 }

static 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(), and ast_mutex_unlock().

Referenced by build_callid(), build_reply_digest(), check_auth(), make_our_tag(), reg_source_db(), reqprep(), sip_alloc(), sip_new(), transmit_invite(), and transmit_register().

00957 {
00958    int val;
00959 
00960    ast_mutex_lock(&rand_lock);
00961    val = rand();
00962    ast_mutex_unlock(&rand_lock);
00963    
00964    return val;
00965 }

static 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 5565 of file chan_sip.c.

References add_digit(), sip_pvt::ocseq, reqprep(), send_request(), and SIP_INFO.

Referenced by sip_senddigit().

05566 {
05567    struct sip_request req;
05568    reqprep(&req, p, SIP_INFO, 0, 1);
05569    add_digit(&req, digit);
05570    return send_request(p, &req, 1, p->ocseq);
05571 }

static int transmit_info_with_vidupdate struct sip_pvt p  )  [static]
 

transmit_info_with_vidupdate: Send SIP INFO with video update request ---

Definition at line 5574 of file chan_sip.c.

References add_vidupdate(), sip_pvt::ocseq, reqprep(), send_request(), and SIP_INFO.

Referenced by sip_indicate().

05575 {
05576    struct sip_request req;
05577    reqprep(&req, p, SIP_INFO, 0, 1);
05578    add_vidupdate(&req);
05579    return send_request(p, &req, 1, p->ocseq);
05580 }

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

transmit_invite: Build REFER/INVITE/OPTIONS message and transmit it ---

Definition at line 4865 of file chan_sip.c.

References add_blank_header(), add_header(), add_header_contentLength(), add_sdp(), sip_invite_param::addsipheaders, ALLOWED_METHODS, append_date(), AST_LIST_TRAVERSE, ast_log(), ast_rtp_offered_from_local(), ast_strdupa, ast_strlen_zero(), ast_var_name(), ast_var_value(), ast_verbose(), sip_invite_param::auth, sip_invite_param::authheader, sip_pvt::branch, build_via(), copy_request(), sip_invite_param::distinctive_ring, sip_request::headers, sip_pvt::initreq, initreqprep(), sip_pvt::lastinvite, sip_request::lines, LOG_DEBUG, LOG_WARNING, sip_request::method, sip_pvt::ocseq, sip_pvt::options, sip_invite_param::osptoken, sip_pvt::owner, parse_request(), sip_pvt::refer_to, sip_pvt::referred_by, reqprep(), sip_pvt::rtp, send_request(), sip_debug_test_pvt(), SIP_OPTIONS, SIP_REFER, sipdebug, thread_safe_rand(), ast_channel::varshead, and sip_pvt::via.

Referenced by do_proxy_auth(), sip_call(), and sip_poke_peer().

04866 {
04867    struct sip_request req;
04868    
04869    req.method = sipmethod;
04870    if (init) {
04871       /* Bump branch even on initial requests */
04872       p->branch ^= thread_safe_rand();
04873       build_via(p, p->via, sizeof(p->via));
04874       if (init > 1)
04875          initreqprep(&req, p, sipmethod);
04876       else
04877          reqprep(&req, p, sipmethod, 0, 1);
04878    } else
04879       reqprep(&req, p, sipmethod, 0, 1);
04880       
04881    if (p->options && p->options->auth)
04882       add_header(&req, p->options->authheader, p->options->auth);
04883    append_date(&req);
04884    if (sipmethod == SIP_REFER) { /* Call transfer */
04885       if (!ast_strlen_zero(p->refer_to))
04886          add_header(&req, "Refer-To", p->refer_to);
04887       if (!ast_strlen_zero(p->referred_by))
04888          add_header(&req, "Referred-By", p->referred_by);
04889    }
04890 #ifdef OSP_SUPPORT
04891    if ((req.method != SIP_OPTIONS) && p->options && !ast_strlen_zero(p->options->osptoken)) {
04892       ast_log(LOG_DEBUG,"Adding OSP Token: %s\n", p->options->osptoken);
04893       add_header(&req, "P-OSP-Auth-Token", p->options->osptoken);
04894    }
04895 #endif
04896    if (p->options && !ast_strlen_zero(p->options->distinctive_ring))
04897    {
04898       add_header(&req, "Alert-Info", p->options->distinctive_ring);
04899    }
04900    add_header(&req, "Allow", ALLOWED_METHODS);
04901    if (p->options && p->options->addsipheaders ) {
04902       struct ast_channel *ast;
04903       char *header = (char *) NULL;
04904       char *content = (char *) NULL;
04905       char *end = (char *) NULL;
04906       struct varshead *headp = (struct varshead *) NULL;
04907       struct ast_var_t *current;
04908 
04909       ast = p->owner;   /* The owner channel */
04910       if (ast) {
04911          char *headdup;
04912          headp = &ast->varshead;
04913          if (!headp)
04914             ast_log(LOG_WARNING,"No Headp for the channel...ooops!\n");
04915          else {
04916             AST_LIST_TRAVERSE(headp, current, entries) {  
04917                /* SIPADDHEADER: Add SIP header to outgoing call        */
04918                if (!strncasecmp(ast_var_name(current), "SIPADDHEADER", strlen("SIPADDHEADER"))) {
04919                   header = ast_var_value(current);
04920                   headdup = ast_strdupa(header);
04921                   /* Strip of the starting " (if it's there) */
04922                   if (*headdup == '"')
04923                      headdup++;
04924                   if ((content = strchr(headdup, ':'))) {
04925                      *content = '\0';
04926                      content++;  /* Move pointer ahead */
04927                      /* Skip white space */
04928                      while (*content == ' ')
04929                         content++;
04930                      /* Strip the ending " (if it's there) */
04931                      end = content + strlen(content) -1; 
04932                      if (*end == '"')
04933                         *end = '\0';
04934                   
04935                      add_header(&req, headdup, content);
04936                      if (sipdebug)
04937                         ast_log(LOG_DEBUG, "Adding SIP Header \"%s\" with content :%s: \n", headdup, content);
04938                   }
04939                }
04940             }
04941          }
04942       }
04943    }
04944    if (sdp && p->rtp) {
04945       ast_rtp_offered_from_local(p->rtp, 1);
04946       add_sdp(&req, p);
04947    } else {
04948       add_header_contentLength(&req, 0);
04949       add_blank_header(&req);
04950    }
04951 
04952    if (!p->initreq.headers) {
04953       /* Use this as the basis */
04954       copy_request(&p->initreq, &req);
04955       parse_request(&p->initreq);
04956       if (sip_debug_test_pvt(p))
04957          ast_verbose("%d headers, %d lines\n", p->initreq.headers, p->initreq.lines);
04958    }
04959    p->lastinvite = p->ocseq;
04960    return send_request(p, &req, init ? 2 : 1, p->ocseq);
04961 }

static 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 5511 of file chan_sip.c.

References add_text(), sip_pvt::ocseq, reqprep(), send_request(), and SIP_MESSAGE.

Referenced by sip_sendtext().

05512 {
05513    struct sip_request req;
05514    reqprep(&req, p, SIP_MESSAGE, 0, 1);
05515    add_text(&req, text);
05516    return send_request(p, &req, 1, p->ocseq);
05517 }

static 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 5136 of file chan_sip.c.

References add_header(), add_header_contentLength(), add_line(), ast_build_string(), ast_inet_ntoa(), ast_log(), ast_strlen_zero(), ast_verbose(), copy_request(), default_notifymime, determine_firstline_parts(), sip_pvt::fromdomain, global_vmexten, sip_request::headers, sip_pvt::initreq, initreqprep(), sip_request::lines, LOG_WARNING, sip_pvt::ocseq, sip_pvt::ourip, parse_request(), send_request(), sip_debug_test_pvt(), SIP_NOTIFY, and t.

Referenced by sip_send_mwi_to_peer().

05137 {
05138    struct sip_request req;
05139    char tmp[500];
05140    char *t = tmp;
05141    size_t maxbytes = sizeof(tmp);
05142    char iabuf[INET_ADDRSTRLEN];
05143 
05144    initreqprep(&req, p, SIP_NOTIFY);
05145    add_header(&req, "Event", "message-summary");
05146    add_header(&req, "Content-Type", default_notifymime);
05147 
05148    ast_build_string(&t, &maxbytes, "Messages-Waiting: %s\r\n", newmsgs ? "yes" : "no");
05149    ast_build_string(&t, &maxbytes, "Message-Account: sip:%s@%s\r\n", !ast_strlen_zero(vmexten) ? vmexten : global_vmexten, ast_strlen_zero(p->fromdomain) ? ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip) : p->fromdomain);
05150    ast_build_string(&t, &maxbytes, "Voice-Message: %d/%d (0/0)\r\n", newmsgs, oldmsgs);
05151 
05152    if (t > tmp + sizeof(tmp))
05153       ast_log(LOG_WARNING, "Buffer overflow detected!!  (Please file a bug report)\n");
05154 
05155    add_header_contentLength(&req, strlen(tmp));
05156    add_line(&req, tmp);
05157 
05158    if (!p->initreq.headers) { /* Use this as the basis */
05159       copy_request(&p->initreq, &req);
05160       parse_request(&p->initreq);
05161       if (sip_debug_test_pvt(p))
05162          ast_verbose("%d headers, %d lines\n", p->initreq.headers, p->initreq.lines);
05163       determine_firstline_parts(&p->initreq);
05164    }
05165 
05166    return send_request(p, &req, 1, p->ocseq);
05167 }

static 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 5189 of file chan_sip.c.

References add_header(), add_header_contentLength(), add_line(), ast_verbose(), copy_request(), determine_firstline_parts(), sip_request::headers, sip_pvt::initreq, sip_request::lines, sip_pvt::ocseq, parse_request(), reqprep(), send_request(), sip_debug_test_pvt(), and SIP_NOTIFY.

Referenced by handle_request_refer().

05190 {
05191    struct sip_request req;
05192    char tmp[20];
05193    reqprep(&req, p, SIP_NOTIFY, 0, 1);
05194    snprintf(tmp, sizeof(tmp), "refer;id=%d", cseq);
05195    add_header(&req, "Event", tmp);
05196    add_header(&req, "Subscription-state", "terminated;reason=noresource");
05197    add_header(&req, "Content-Type", "message/sipfrag;version=2.0");
05198 
05199    strcpy(tmp, "SIP/2.0 200 OK");
05200    add_header_contentLength(&req, strlen(tmp));
05201    add_line(&req, tmp);
05202 
05203    if (!p->initreq.headers) {
05204       /* Use this as the basis */
05205       copy_request(&p->initreq, &req);
05206       parse_request(&p->initreq);
05207       if (sip_debug_test_pvt(p))
05208          ast_verbose("%d headers, %d lines\n", p->initreq.headers, p->initreq.lines);
05209       determine_firstline_parts(&p->initreq);
05210    }
05211 
05212    return send_request(p, &req, 1, p->ocseq);
05213 }

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

transmit_refer: Transmit SIP REFER message ---

Definition at line 5520 of file chan_sip.c.

References add_blank_header(), add_header(), ast_log(), ast_strlen_zero(), ast_test_flag, sip_pvt::from, get_header(), get_in_brackets(), sip_pvt::initreq, LOG_NOTICE, sip_pvt::ocseq, sip_pvt::our_contact, sip_pvt::refer_to, sip_pvt::referred_by, reqprep(), send_request(), SIP_OUTGOING, and SIP_REFER.

Referenced by sip_transfer().

05521 {
05522    struct sip_request req;
05523    char from[256];
05524    char *of, *c;
05525    char referto[256];
05526 
05527    if (ast_test_flag(p, SIP_OUTGOING)) 
05528       of = get_header(&p->initreq, "To");
05529    else
05530       of = get_header(&p->initreq, "From");
05531    ast_copy_string(from, of, sizeof(from));
05532    of = get_in_brackets(from);
05533    ast_copy_string(p->from,of,sizeof(p->from));
05534    if (strncmp(of, "sip:", 4)) {
05535       ast_log(LOG_NOTICE, "From address missing 'sip:', using it anyway\n");
05536    } else
05537       of += 4;
05538    /* Get just the username part */
05539    if ((c = strchr(dest, '@'))) {
05540       c = NULL;
05541    } else if ((c = strchr(of, '@'))) {
05542       *c = '\0';
05543       c++;
05544    }
05545    if (c) {
05546       snprintf(referto, sizeof(referto), "<sip:%s@%s>", dest, c);
05547    } else {
05548       snprintf(referto, sizeof(referto), "<sip:%s>", dest);
05549    }
05550 
05551    /* save in case we get 407 challenge */
05552    ast_copy_string(p->refer_to, referto, sizeof(p->refer_to));
05553    ast_copy_string(p->referred_by, p->our_contact, sizeof(p->referred_by));
05554 
05555    reqprep(&req, p, SIP_REFER, 0, 1);
05556    add_header(&req, "Refer-To", referto);
05557    if (!ast_strlen_zero(p->our_contact))
05558       add_header(&req, "Referred-By", p->our_contact);
05559    add_blank_header(&req);
05560    return send_request(p, &req, 1, p->ocseq);
05561 }

static 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 5319 of file chan_sip.c.

References __ourip, add_blank_header(), add_header(), add_header_contentLength(), append_history(), ast_log(), ast_sched_add(), ast_sched_del(), ast_set_flag, ast_sip_ouraddrfor(), ast_strlen_zero(), ast_verbose(), ASTOBJ_REF, sip_pvt::authname, sip_registry::authuser, bindaddr, sip_pvt::branch, build_callid(), build_contact(), build_reply_digest(), build_via(), sip_registry::call, sip_pvt::callid, sip_registry::callid, sip_registry::callid_valid, sip_registry::contact, copy_request(), create_addr(), default_expiry, default_fromdomain, DEFAULT_MAX_FORWARDS, default_useragent, determine_firstline_parts(), sip_registry::domain, sip_pvt::domain, sip_pvt::exten, sip_pvt::fromdomain, sip_pvt::fromuser, global_reg_timeout, sip_request::headers, sip_registry::hostname, init_req(), sip_pvt::initreq, sip_request::lines, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, make_our_tag(), sip_registry::md5secret, sip_pvt::nonce, sip_registry::nonce, sip_registry::noncecount, sip_pvt::noncecount, sip_pvt::ocseq, sip_registry::ocseq, sip_registry::opaque, sip_pvt::opaque, option_debug, sip_pvt::our_contact, sip_pvt::ourip, parse_request(), sip_pvt::peermd5secret, sip_pvt::peername, sip_pvt::peersecret, sip_registry::portno, sip_registry::qop, sip_pvt::qop, sip_registry::realm, sip_pvt::realm, recordhistory, REG_STATE_AUTHSENT, REG_STATE_REGSENT, sip_registry::regattempts, sip_pvt::registry, sip_registry::regstate, sip_pvt::sa, sip_registry::secret, send_request(), sip_alloc(), sip_debug_test_pvt(), sip_destroy(), sip_methods, SIP_OUTGOING, sip_reg_timeout(), SIP_REGISTER, sipdebug, sip_pvt::tag, cfsip_methods::text, sip_pvt::theirtag, thread_safe_rand(), sip_registry::timeout, sip_pvt::tohost, sip_pvt::uri, sip_pvt::username, and sip_registry::username.

Referenced by __sip_do_register(), do_register_auth(), and sip_reg_timeout().

05320 {
05321    struct sip_request req;
05322    char from[256];
05323    char to[256];
05324    char tmp[80];
05325    char via[80];
05326    char addr[80];
05327    struct sip_pvt *p;
05328 
05329    /* exit if we are already in process with this registrar ?*/
05330    if ( r == NULL || ((auth==NULL) && (r->regstate==REG_STATE_REGSENT || r->regstate==REG_STATE_AUTHSENT))) {
05331       ast_log(LOG_NOTICE, "Strange, trying to register %s@%s when registration already pending\n", r->username, r->hostname);
05332       return 0;
05333    }
05334 
05335    if (r->call) { /* We have a registration */
05336       if (!auth) {
05337          ast_log(LOG_WARNING, "Already have a REGISTER going on to %s@%s?? \n", r->username, r->hostname);
05338          return 0;
05339       } else {
05340          p = r->call;
05341          make_our_tag(p->tag, sizeof(p->tag));  /* create a new local tag for every register attempt */
05342          p->theirtag[0]='\0'; /* forget their old tag, so we don't match tags when getting response */
05343       }
05344    } else {
05345       /* Build callid for registration if we haven't registered before */
05346       if (!r->callid_valid) {
05347          build_callid(r->callid, sizeof(r->callid), __ourip, default_fromdomain);
05348          r->callid_valid = 1;
05349       }
05350       /* Allocate SIP packet for registration */
05351       p=sip_alloc( r->callid, NULL, 0, SIP_REGISTER);
05352       if (!p) {
05353          ast_log(LOG_WARNING, "Unable to allocate registration call\n");
05354          return 0;
05355       }
05356       if (recordhistory) {
05357          char tmp[80];
05358          snprintf(tmp, sizeof(tmp), "Account: %s@%s", r->username, r->hostname);
05359          append_history(p, "RegistryInit", tmp);
05360       }
05361       /* Find address to hostname */
05362       if (create_addr(p, r->hostname)) {
05363          /* we have what we hope is a temporary network error,
05364           * probably DNS.  We need to reschedule a registration try */
05365          sip_destroy(p);
05366          if (r->timeout > -1) {
05367             ast_sched_del(sched, r->timeout);
05368             r->timeout = ast_sched_add(sched, global_reg_timeout*1000, sip_reg_timeout, r);
05369             ast_log(LOG_WARNING, "Still have a registration timeout for %s@%s (create_addr() error), %d\n", r->username, r->hostname, r->timeout);
05370          } else {
05371             r->timeout = ast_sched_add(sched, global_reg_timeout*1000, sip_reg_timeout, r);
05372             ast_log(LOG_WARNING, "Probably a DNS error for registration to %s@%s, trying REGISTER again (after %d seconds)\n", r->username, r->hostname, global_reg_timeout);
05373          }
05374          r->regattempts++;
05375          return 0;
05376       }
05377       /* Copy back Call-ID in case create_addr changed it */
05378       ast_copy_string(r->callid, p->callid, sizeof(r->callid));
05379       if (r->portno)
05380          p->sa.sin_port = htons(r->portno);
05381       else  /* Set registry port to the port set from the peer definition/srv or default */
05382          r->portno = ntohs(p->sa.sin_port);
05383       ast_set_flag(p, SIP_OUTGOING);   /* Registration is outgoing call */
05384       r->call=p;        /* Save pointer to SIP packet */
05385       p->registry=ASTOBJ_REF(r); /* Add pointer to registry in packet */
05386       if (!ast_strlen_zero(r->secret)) /* Secret (password) */
05387          ast_copy_string(p->peersecret, r->secret, sizeof(p->peersecret));
05388       if (!ast_strlen_zero(r->md5secret))
05389          ast_copy_string(p->peermd5secret, r->md5secret, sizeof(p->peermd5secret));
05390       /* User name in this realm  
05391       - if authuser is set, use that, otherwise use username */
05392       if (!ast_strlen_zero(r->authuser)) {   
05393          ast_copy_string(p->peername, r->authuser, sizeof(p->peername));
05394          ast_copy_string(p->authname, r->authuser, sizeof(p->authname));
05395       } else {
05396          if (!ast_strlen_zero(r->username)) {
05397             ast_copy_string(p->peername, r->username, sizeof(p->peername));
05398             ast_copy_string(p->authname, r->username, sizeof(p->authname));
05399             ast_copy_string(p->fromuser, r->username, sizeof(p->fromuser));
05400          }
05401       }
05402       if (!ast_strlen_zero(r->username))
05403          ast_copy_string(p->username, r->username, sizeof(p->username));
05404       /* Save extension in packet */
05405       ast_copy_string(p->exten, r->contact, sizeof(p->exten));
05406 
05407       /*
05408         check which address we should use in our contact header 
05409         based on whether the remote host is on the external or
05410         internal network so we can register through nat
05411        */
05412       if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
05413          memcpy(&p->ourip, &bindaddr.sin_addr, sizeof(p->ourip));
05414       build_contact(p);
05415    }
05416 
05417    /* set up a timeout */
05418    if (auth == NULL)  {
05419       if (r->timeout > -1) {
05420          ast_log(LOG_WARNING, "Still have a registration timeout, #%d - deleting it\n", r->timeout);
05421          ast_sched_del(sched, r->timeout);
05422       }
05423       r->timeout = ast_sched_add(sched, global_reg_timeout * 1000, sip_reg_timeout, r);
05424       ast_log(LOG_DEBUG, "Scheduled a registration timeout for %s id  #%d \n", r->hostname, r->timeout);
05425    }
05426 
05427    if (strchr(r->username, '@')) {
05428       snprintf(from, sizeof(from), "<sip:%s>;tag=%s", r->username, p->tag);
05429       if (!ast_strlen_zero(p->theirtag))
05430          snprintf(to, sizeof(to), "<sip:%s>;tag=%s", r->username, p->theirtag);
05431       else
05432          snprintf(to, sizeof(to), "<sip:%s>", r->username);
05433    } else {
05434       snprintf(from, sizeof(from), "<sip:%s@%s>;tag=%s", r->username, p->tohost, p->tag);
05435       if (!ast_strlen_zero(p->theirtag))
05436          snprintf(to, sizeof(to), "<sip:%s@%s>;tag=%s", r->username, p->tohost, p->theirtag);
05437       else
05438          snprintf(to, sizeof(to), "<sip:%s@%s>", r->username, p->tohost);
05439    }
05440    
05441    /* Fromdomain is what we are registering to, regardless of actual
05442       host name from SRV */
05443    if (!ast_strlen_zero(p->fromdomain))
05444       snprintf(addr, sizeof(addr), "sip:%s", p->fromdomain);
05445    else
05446       snprintf(addr, sizeof(addr), "sip:%s", r->hostname);
05447    ast_copy_string(p->uri, addr, sizeof(p->uri));
05448 
05449    p->branch ^= thread_safe_rand();
05450 
05451    memset(&req, 0, sizeof(req));
05452    init_req(&req, sipmethod, addr);
05453 
05454    /* Add to CSEQ */
05455    snprintf(tmp, sizeof(tmp), "%u %s", ++r->ocseq, sip_methods[sipmethod].text);
05456    p->ocseq = r->ocseq;
05457 
05458    build_via(p, via, sizeof(via));
05459    add_header(&req, "Via", via);
05460    add_header(&req, "From", from);
05461    add_header(&req, "To", to);
05462    add_header(&req, "Call-ID", p->callid);
05463    add_header(&req, "CSeq", tmp);
05464    add_header(&req, "User-Agent", default_useragent);
05465    add_header(&req, "Max-Forwards", DEFAULT_MAX_FORWARDS);
05466 
05467    
05468    if (auth)   /* Add auth header */
05469       add_header(&req, authheader, auth);
05470    else if (!ast_strlen_zero(r->nonce)) {
05471       char digest[1024];
05472 
05473       /* We have auth data to reuse, build a digest header! */
05474       if (sipdebug)
05475          ast_log(LOG_DEBUG, "   >>> Re-using Auth data for %s@%s\n", r->username, r->hostname);
05476       ast_copy_string(p->realm, r->realm, sizeof(p->realm));
05477       ast_copy_string(p->nonce, r->nonce, sizeof(p->nonce));
05478       ast_copy_string(p->domain, r->domain, sizeof(p->domain));
05479       ast_copy_string(p->opaque, r->opaque, sizeof(p->opaque));
05480       ast_copy_string(p->qop, r->qop, sizeof(p->qop));
05481       p->noncecount = r->noncecount++;
05482 
05483       memset(digest,0,sizeof(digest));
05484       if(!build_reply_digest(p, sipmethod, digest, sizeof(digest)))
05485          add_header(&req, "Authorization", digest);
05486       else
05487          ast_log(LOG_NOTICE, "No authorization available for authentication of registration to %s@%s\n", r->username, r->hostname);
05488    
05489    }
05490 
05491    snprintf(tmp, sizeof(tmp), "%d", default_expiry);
05492    add_header(&req, "Expires", tmp);
05493    add_header(&req, "Contact", p->our_contact);
05494    add_header(&req, "Event", "registration");
05495    add_header_contentLength(&req, 0);
05496    add_blank_header(&req);
05497    copy_request(&p->initreq, &req);
05498    parse_request(&p->initreq);
05499    if (sip_debug_test_pvt(p)) {
05500       ast_verbose("REGISTER %d headers, %d lines\n", p->initreq.headers, p->initreq.lines);
05501    }
05502    determine_firstline_parts(&p->initreq);
05503    r->regstate=auth?REG_STATE_AUTHSENT:REG_STATE_REGSENT;
05504    r->regattempts++; /* Another attempt */
05505    if (option_debug > 3)
05506       ast_verbose("REGISTER attempt %d to %s@%s\n", r->regattempts, r->username, r->hostname);
05507    return send_request(p, &req, 2, p->ocseq);
05508 }

static int transmit_reinvite_with_sdp struct sip_pvt p  )  [static]
 

transmit_reinvite_with_sdp: Transmit reinvite with SDP :-) ---

Definition at line 4592 of file chan_sip.c.

References add_header(), add_sdp(), ALLOWED_METHODS, ast_rtp_offered_from_local(), ast_set_flag, ast_test_flag, ast_verbose(), copy_request(), sip_request::headers, sip_pvt::initreq, sip_pvt::lastinvite, sip_request::lines, sip_pvt::ocseq, parse_request(), reqprep(), sip_pvt::rtp, send_request(), sip_debug_test_pvt(), SIP_INVITE, SIP_OUTGOING, SIP_REINVITE_UPDATE, SIP_UPDATE, and sipdebug.

Referenced by check_pendings(), and sip_set_rtp_peer().

04593 {
04594    struct sip_request req;
04595    if (ast_test_flag(p, SIP_REINVITE_UPDATE))
04596       reqprep(&req, p, SIP_UPDATE, 0, 1);
04597    else 
04598       reqprep(&req, p, SIP_INVITE, 0, 1);
04599    
04600    add_header(&req, "Allow", ALLOWED_METHODS);
04601    if (sipdebug)
04602       add_header(&req, "X-asterisk-info", "SIP re-invite (RTP bridge)");
04603    ast_rtp_offered_from_local(p->rtp, 1);
04604    add_sdp(&req, p);
04605    /* Use this as the basis */
04606    copy_request(&p->initreq, &req);
04607    parse_request(&p->initreq);
04608    if (sip_debug_test_pvt(p))
04609       ast_verbose("%d headers, %d lines\n", p->initreq.headers, p->initreq.lines);
04610    p->lastinvite = p->ocseq;
04611    ast_set_flag(p, SIP_OUTGOING);
04612    return send_request(p, &req, 1, p->ocseq);
04613 }

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

transmit_request: transmit generic SIP request ---

Definition at line 5583 of file chan_sip.c.

References add_blank_header(), add_header_contentLength(), sip_pvt::ocseq, reqprep(), and send_request().

Referenced by handle_response(), handle_response_invite(), and handle_response_peerpoke().

05584 {
05585    struct sip_request resp;
05586    reqprep(&resp, p, sipmethod, seqno, newbranch);
05587    add_header_contentLength(&resp, 0);
05588    add_blank_header(&resp);
05589    return send_request(p, &resp, reliable, seqno ? seqno : p->ocseq);
05590 }

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

transmit_request_with_auth: Transmit SIP request, auth added ---

Definition at line 5593 of file chan_sip.c.

References add_blank_header(), add_header(), add_header_contentLength(), ast_cause2str(), ast_log(), sip_invite_param::auth_type, build_reply_digest(), sip_pvt::callid, ast_channel::hangupcause, LOG_WARNING, sip_pvt::ocseq, sip_pvt::options, sip_pvt::owner, PROXY_AUTH, sip_pvt::realm, reqprep(), send_request(), SIP_BYE, and WWW_AUTH.

Referenced by check_pendings(), handle_request_refer(), and sip_hangup().

05594 {
05595    struct sip_request resp;
05596 
05597    reqprep(&resp, p, sipmethod, seqno, newbranch);
05598    if (*p->realm) {
05599       char digest[1024];
05600 
05601       memset(digest, 0, sizeof(digest));
05602       if(!build_reply_digest(p, sipmethod, digest, sizeof(digest))) {
05603          if (p->options && p->options->auth_type == PROXY_AUTH)
05604             add_header(&resp, "Proxy-Authorization", digest);
05605          else if (p->options && p->options->auth_type == WWW_AUTH)
05606             add_header(&resp, "Authorization", digest);
05607          else  /* Default, to be backwards compatible (maybe being too careful, but leaving it for now) */
05608             add_header(&resp, "Proxy-Authorization", digest);
05609       } else
05610          ast_log(LOG_WARNING, "No authentication available for call %s\n", p->callid);
05611    }
05612    /* If we are hanging up and know a cause for that, send it in clear text to make
05613       debugging easier. */
05614    if (sipmethod == SIP_BYE) {
05615       if (p->owner && p->owner->hangupcause) {
05616          add_header(&resp, "X-Asterisk-HangupCause", ast_cause2str(p->owner->hangupcause));
05617       }
05618    }
05619 
05620    add_header_contentLength(&resp, 0);
05621    add_blank_header(&resp);
05622    return send_request(p, &resp, reliable, seqno ? seqno : p->ocseq);   
05623 }

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

transmit_response: Transmit response, no retransmits

Definition at line 4152 of file chan_sip.c.

References __transmit_response().

04153 {
04154    return __transmit_response(p, msg, req, 0);
04155 }

static 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 4168 of file chan_sip.c.

References __transmit_response().

Referenced by handle_request(), handle_request_bye(), handle_request_cancel(), handle_request_invite(), sip_hangup(), and sip_sipredirect().

04169 {
04170    return __transmit_response(p, msg, req, fatal ? 2 : 1);
04171 }

static 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 4198 of file chan_sip.c.

References add_blank_header(), add_header(), add_header_contentLength(), respprep(), and send_response().

Referenced by handle_request(), handle_request_options(), and handle_request_refer().

04199 {
04200    struct sip_request resp;
04201    respprep(&resp, p, msg, req);
04202    add_header(&resp, "Accept", "application/sdp");
04203    add_header_contentLength(&resp, 0);
04204    add_blank_header(&resp);
04205    return send_response(p, &resp, reliable, 0);
04206 }

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

Definition at line 4209 of file chan_sip.c.

References add_blank_header(), add_header(), add_header_contentLength(), ast_log(), get_header(), global_realm, LOG_WARNING, respprep(), and send_response().

Referenced by check_auth().

04210 {
04211    struct sip_request resp;
04212    char tmp[256];
04213    int seqno = 0;
04214 
04215    if (reliable && (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1)) {
04216       ast_log(LOG_WARNING, "Unable to determine sequence number from '%s'\n", get_header(req, "CSeq"));
04217       return -1;
04218    }
04219    /* Stale means that they sent us correct authentication, but 
04220       based it on an old challenge (nonce) */
04221    snprintf(tmp, sizeof(tmp), "Digest realm=\"%s\", nonce=\"%s\"%s", global_realm, randdata, stale ? ", stale=true" : "");
04222    respprep(&resp, p, msg, req);
04223    add_header(&resp, header, tmp);
04224    add_header_contentLength(&resp, 0);
04225    add_blank_header(&resp);
04226    return send_response(p, &resp, reliable, seqno);
04227 }

static 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 4187 of file chan_sip.c.

References add_blank_header(), add_header_contentLength(), append_date(), respprep(), and send_response().

Referenced by register_verify().

04188 {
04189    struct sip_request resp;
04190    respprep(&resp, p, msg, req);
04191    append_date(&resp);
04192    add_header_contentLength(&resp, 0);
04193    add_blank_header(&resp);
04194    return send_response(p, &resp, 0, 0);
04195 }

static 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 4518 of file chan_sip.c.

References add_sdp(), ast_log(), ast_rtp_offered_from_local(), sip_pvt::callid, get_header(), LOG_ERROR, LOG_WARNING, respprep(), sip_pvt::rtp, send_response(), and try_suggested_sip_codec().

Referenced by handle_request_invite(), sip_answer(), sip_indicate(), and sip_write().

04519 {
04520    struct sip_request resp;
04521    int seqno;
04522    if (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1) {
04523       ast_log(LOG_WARNING, "Unable to get seqno from '%s'\n", get_header(req, "CSeq"));
04524       return -1;
04525    }
04526    respprep(&resp, p, msg, req);
04527    if (p->rtp) {
04528       ast_rtp_offered_from_local(p->rtp, 0);
04529       try_suggested_sip_codec(p);   
04530       add_sdp(&resp, p);
04531    } else {
04532       ast_log(LOG_ERROR, "Can't add SDP to response, since we have no RTP session allocated. Call-ID %s\n", p->callid);
04533    }
04534    return send_response(p, &resp, retrans, seqno);
04535 }

static 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 4158 of file chan_sip.c.

References add_header(), append_date(), respprep(), and send_response().

Referenced by handle_request_invite().

04159 {
04160    struct sip_request resp;
04161    respprep(&resp, p, msg, req);
04162    append_date(&resp);
04163    add_header(&resp, "Unsupported", unsupported);
04164    return send_response(p, &resp, 0, 0);
04165 }

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

transmit_sip_request: Transmit SIP request

Definition at line 5170 of file chan_sip.c.

References ast_verbose(), copy_request(), determine_firstline_parts(), sip_request::headers, sip_pvt::initreq, sip_request::lines, sip_pvt::ocseq, parse_request(), send_request(), and sip_debug_test_pvt().

Referenced by sip_notify().

05171 {
05172    if (!p->initreq.headers) {
05173       /* Use this as the basis */
05174       copy_request(&p->initreq, req);
05175       parse_request(&p->initreq);
05176       if (sip_debug_test_pvt(p))
05177          ast_verbose("%d headers, %d lines\n", p->initreq.headers, p->initreq.lines);
05178       determine_firstline_parts(&p->initreq);
05179    }
05180 
05181    return send_request(p, req, 0, p->ocseq);
05182 }

static 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 4964 of file chan_sip.c.

References add_header(), add_header_contentLength(), add_line(), ast_build_string(), ast_device_state(), AST_DEVICE_UNAVAILABLE, AST_EXTENSION_BUSY, AST_EXTENSION_DEACTIVATED, AST_EXTENSION_INUSE, AST_EXTENSION_NOT_INUSE, AST_EXTENSION_REMOVED, AST_EXTENSION_RINGING, AST_EXTENSION_UNAVAILABLE, ast_get_hint(), ast_log(), AST_MAX_EXTENSION, sip_pvt::context, CPIM_PIDF_XML, DIALOG_INFO_XML, sip_pvt::dialogver, sip_pvt::expiry, sip_pvt::exten, find_subscription_type(), get_header(), get_in_brackets(), global_notifyringing, sip_pvt::initreq, LOG_WARNING, NONE, sip_pvt::ocseq, PIDF_XML, reqprep(), send_request(), SIP_NOTIFY, sip_pvt::subscribed, t, TIMEOUT, and XPIDF_XML.

Referenced by __sip_autodestruct(), cb_extensionstate(), and handle_request_subscribe().

04965 {
04966    char tmp[4000], from[256], to[256];
04967    char *t = tmp, *c, *a, *mfrom, *mto;
04968    size_t maxbytes = sizeof(tmp);
04969    struct sip_request req;
04970    char hint[AST_MAX_EXTENSION];
04971    char *statestring = "terminated";
04972    const struct cfsubscription_types *subscriptiontype;
04973    enum state { NOTIFY_OPEN, NOTIFY_INUSE, NOTIFY_CLOSED } local_state = NOTIFY_OPEN;
04974    char *pidfstate = "--";
04975    char *pidfnote= "Ready";
04976 
04977    memset(from, 0, sizeof(from));
04978    memset(to, 0, sizeof(to));
04979    memset(tmp, 0, sizeof(tmp));
04980 
04981    switch (state) {
04982    case (AST_EXTENSION_RINGING | AST_EXTENSION_INUSE):
04983       if (global_notifyringing)
04984          statestring = "early";
04985       else
04986          statestring = "confirmed";
04987       local_state = NOTIFY_INUSE;
04988       pidfstate = "busy";
04989       pidfnote = "Ringing";
04990       break;
04991    case AST_EXTENSION_RINGING:
04992       statestring = "early";
04993       local_state = NOTIFY_INUSE;
04994       pidfstate = "busy";
04995       pidfnote = "Ringing";
04996       break;
04997    case AST_EXTENSION_INUSE:
04998       statestring = "confirmed";
04999       local_state = NOTIFY_INUSE;
05000       pidfstate = "busy";
05001       pidfnote = "On the phone";
05002       break;
05003    case AST_EXTENSION_BUSY:
05004       statestring = "confirmed";
05005       local_state = NOTIFY_CLOSED;
05006       pidfstate = "busy";
05007       pidfnote = "On the phone";
05008       break;
05009    case AST_EXTENSION_UNAVAILABLE:
05010       statestring = "confirmed";
05011       local_state = NOTIFY_CLOSED;
05012       pidfstate = "away";
05013       pidfnote = "Unavailable";
05014       break;
05015    case AST_EXTENSION_NOT_INUSE:
05016    default:
05017       /* Default setting */
05018       break;
05019    }
05020 
05021    subscriptiontype = find_subscription_type(p->subscribed);
05022    
05023    /* Check which device/devices we are watching  and if they are registered */
05024    if (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, p->context, p->exten)) {
05025       /* If they are not registered, we will override notification and show no availability */
05026       if (ast_device_state(hint) == AST_DEVICE_UNAVAILABLE) {
05027          local_state = NOTIFY_CLOSED;
05028          pidfstate = "away";
05029          pidfnote = "Not online";
05030       }
05031    }
05032 
05033    ast_copy_string(from, get_header(&p->initreq, "From"), sizeof(from));
05034    c = get_in_brackets(from);
05035    if (strncmp(c, "sip:", 4)) {
05036       ast_log(LOG_WARNING, "Huh?  Not a SIP header (%s)?\n", c);
05037       return -1;
05038    }
05039    if ((a = strchr(c, ';')))
05040       *a = '\0';
05041    mfrom = c;
05042 
05043    ast_copy_string(to, get_header(&p->initreq, "To"), sizeof(to));
05044    c = get_in_brackets(to);
05045    if (strncmp(c, "sip:", 4)) {
05046       ast_log(LOG_WARNING, "Huh?  Not a SIP header (%s)?\n", c);
05047       return -1;
05048    }
05049    if ((a = strchr(c, ';')))
05050       *a = '\0';
05051    mto = c;
05052 
05053    reqprep(&req, p, SIP_NOTIFY, 0, 1);
05054 
05055    
05056    add_header(&req, "Event", subscriptiontype->event);
05057    add_header(&req, "Content-Type", subscriptiontype->mediatype);
05058    switch(state) {
05059    case AST_EXTENSION_DEACTIVATED:
05060       if (p->subscribed == TIMEOUT)
05061          add_header(&req, "Subscription-State", "terminated;reason=timeout");
05062       else {
05063          add_header(&req, "Subscription-State", "terminated;reason=probation");
05064          add_header(&req, "Retry-After", "60");
05065       }
05066       break;
05067    case AST_EXTENSION_REMOVED:
05068       add_header(&req, "Subscription-State", "terminated;reason=noresource");
05069       break;
05070       break;
05071    default:
05072       if (p->expiry)
05073          add_header(&req, "Subscription-State", "active");
05074       else  /* Expired */
05075          add_header(&req, "Subscription-State", "terminated;reason=timeout");
05076    }
05077    switch (p->subscribed) {
05078    case XPIDF_XML:
05079    case CPIM_PIDF_XML:
05080       ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\"?>\n");
05081       ast_build_string(&t, &maxbytes, "<!DOCTYPE presence PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n");
05082       ast_build_string(&t, &maxbytes, "<presence>\n");
05083       ast_build_string(&t, &maxbytes, "<presentity uri=\"%s;method=SUBSCRIBE\" />\n", mfrom);
05084       ast_build_string(&t, &maxbytes, "<atom id=\"%s\">\n", p->exten);
05085       ast_build_string(&t, &maxbytes, "<address uri=\"%s;user=ip\" priority=\"0.800000\">\n", mto);
05086       ast_build_string(&t, &maxbytes, "<status status=\"%s\" />\n", (local_state ==  NOTIFY_OPEN) ? "open" : (local_state == NOTIFY_INUSE) ? "inuse" : "closed");
05087       ast_build_string(&t, &maxbytes, "<msnsubstatus substatus=\"%s\" />\n", (local_state == NOTIFY_OPEN) ? "online" : (local_state == NOTIFY_INUSE) ? "onthephone" : "offline");
05088       ast_build_string(&t, &maxbytes, "</address>\n</atom>\n</presence>\n");
05089       break;
05090    case PIDF_XML: /* Eyebeam supports this format */
05091       ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n");
05092       ast_build_string(&t, &maxbytes, "<presence xmlns=\"urn:ietf:params:xml:ns:pidf\" \nxmlns:pp=\"urn:ietf:params:xml:ns:pidf:person\"\nxmlns:es=\"urn:ietf:params:xml:ns:pidf:rpid:status:rpid-status\"\nxmlns:ep=\"urn:ietf:params:xml:ns:pidf:rpid:rpid-person\"\nentity=\"%s\">\n", mfrom);
05093       ast_build_string(&t, &maxbytes, "<pp:person><status>\n");
05094       if (pidfstate[0] != '-')
05095          ast_build_string(&t, &maxbytes, "<ep:activities><ep:%s/></ep:activities>\n", pidfstate);
05096       ast_build_string(&t, &maxbytes, "</status></pp:person>\n");
05097       ast_build_string(&t, &maxbytes, "<note>%s</note>\n", pidfnote); /* Note */
05098       ast_build_string(&t, &maxbytes, "<tuple id=\"%s\">\n", p->exten); /* Tuple start */
05099       ast_build_string(&t, &maxbytes, "<contact priority=\"1\">%s</contact>\n", mto);
05100       if (pidfstate[0] == 'b') /* Busy? Still open ... */
05101          ast_build_string(&t, &maxbytes, "<status><basic>open</basic></status>\n");
05102       else
05103          ast_build_string(&t, &maxbytes, "<status><basic>%s</basic></status>\n", (local_state != NOTIFY_CLOSED) ? "open" : "closed");
05104       ast_build_string(&t, &maxbytes, "</tuple>\n</presence>\n");
05105       break;
05106    case DIALOG_INFO_XML: /* SNOM subscribes in this format */
05107       ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\"?>\n");
05108       ast_build_string(&t, &maxbytes, "<dialog-info xmlns=\"urn:ietf:params:xml:ns:dialog-info\" version=\"%d\" state=\"%s\" entity=\"%s\">\n", p->dialogver++, full ? "full":"partial", mto);
05109       if ((state & AST_EXTENSION_RINGING) && global_notifyringing)
05110          ast_build_string(&t, &maxbytes, "<dialog id=\"%s\" direction=\"recipient\">\n", p->exten);
05111       else
05112          ast_build_string(&t, &maxbytes, "<dialog id=\"%s\">\n", p->exten);
05113       ast_build_string(&t, &maxbytes, "<state>%s</state>\n", statestring);
05114       ast_build_string(&t, &maxbytes, "</dialog>\n</dialog-info>\n");
05115       break;
05116    case NONE:
05117    default:
05118       break;
05119    }
05120 
05121    if (t > tmp + sizeof(tmp))
05122       ast_log(LOG_WARNING, "Buffer overflow detected!!  (Please file a bug report)\n");
05123 
05124    add_header_contentLength(&req, strlen(tmp));
05125    add_line(&req, tmp);
05126 
05127    return send_request(p, &req, 1, p->ocseq);
05128 }

static void try_suggested_sip_codec struct sip_pvt p  )  [static]
 

Try setting codec suggested by the SIP_CODEC channel variable.

Definition at line 2489 of file chan_sip.c.

References ast_getformatbyname(), ast_log(), sip_pvt::capability, fmt, sip_pvt::jointcapability, LOG_NOTICE, sip_pvt::owner, and pbx_builtin_getvar_helper().

Referenced by sip_answer(), and transmit_response_with_sdp().

02490 {
02491    int fmt;
02492    char *codec;
02493 
02494    codec = pbx_builtin_getvar_helper(p->owner, "SIP_CODEC");
02495    if (!codec) 
02496       return;
02497 
02498    fmt = ast_getformatbyname(codec);
02499    if (fmt) {
02500       ast_log(LOG_NOTICE, "Changing codec to '%s' for this call because of ${SIP_CODEC) variable\n",codec);
02501       if (p->jointcapability & fmt) {
02502          p->jointcapability &= fmt;
02503          p->capability &= fmt;
02504       } else
02505          ast_log(LOG_NOTICE, "Ignoring ${SIP_CODEC} variable because it is not shared by both ends.\n");
02506    } else
02507       ast_log(LOG_NOTICE, "Ignoring ${SIP_CODEC} variable because of unrecognized/not configured codec (check allow/disallow in sip.conf): %s\n",codec);
02508    return;  
02509 }

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 13180 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_PTHREADT_STOP, 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_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.

13181 {
13182    struct sip_pvt *p, *pl;
13183    
13184    /* First, take us out of the channel type list */
13185    ast_channel_unregister(&sip_tech);
13186 
13187    ast_custom_function_unregister(&sipchaninfo_function);
13188    ast_custom_function_unregister(&sippeer_function);
13189    ast_custom_function_unregister(&sip_header_function);
13190    ast_custom_function_unregister(&checksipdomain_function);
13191 
13192    ast_unregister_application(app_dtmfmode);
13193    ast_unregister_application(app_sipaddheader);
13194    ast_unregister_application(app_sipgetheader);
13195 
13196    ast_cli_unregister_multiple(my_clis, sizeof(my_clis) / sizeof(my_clis[0]));
13197 
13198    ast_rtp_proto_unregister(&sip_rtp);
13199 
13200    ast_manager_unregister("SIPpeers");
13201    ast_manager_unregister("SIPshowpeer");
13202 
13203    if (!ast_mutex_lock(&iflock)) {
13204       /* Hangup all interfaces if they have an owner */
13205       p = iflist;
13206       while (p) {
13207          if (p->owner)
13208             ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD);
13209          p = p->next;
13210       }
13211       ast_mutex_unlock(&iflock);
13212    } else {
13213       ast_log(LOG_WARNING, "Unable to lock the interface list\n");
13214       return -1;
13215    }
13216 
13217    if (!ast_mutex_lock(&monlock)) {
13218       if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP)) {
13219          pthread_cancel(monitor_thread);
13220          pthread_kill(monitor_thread, SIGURG);
13221          pthread_join(monitor_thread, NULL);
13222       }
13223       monitor_thread = AST_PTHREADT_STOP;
13224       ast_mutex_unlock(&monlock);
13225    } else {
13226       ast_log(LOG_WARNING, "Unable to lock the monitor\n");
13227       return -1;
13228    }
13229 
13230    if (!ast_mutex_lock(&iflock)) {
13231       /* Destroy all the interfaces and free their memory */
13232       p = iflist;
13233       while (p) {
13234          pl = p;
13235          p = p->next;
13236          /* Free associated memory */
13237          ast_mutex_destroy(&pl->lock);
13238          if (pl->chanvars) {
13239             ast_variables_destroy(pl->chanvars);
13240             pl->chanvars = NULL;
13241          }
13242          free(pl);
13243       }
13244       iflist = NULL;
13245       ast_mutex_unlock(&iflock);
13246    } else {
13247       ast_log(LOG_WARNING, "Unable to lock the interface list\n");
13248       return -1;
13249    }
13250 
13251    /* Free memory for local network address mask */
13252    ast_free_ha(localaddr);
13253 
13254    ASTOBJ_CONTAINER_DESTROYALL(&userl, sip_destroy_user);
13255    ASTOBJ_CONTAINER_DESTROY(&userl);
13256    ASTOBJ_CONTAINER_DESTROYALL(&peerl, sip_destroy_peer);
13257    ASTOBJ_CONTAINER_DESTROY(&peerl);
13258    ASTOBJ_CONTAINER_DESTROYALL(&regl, sip_registry_destroy);
13259    ASTOBJ_CONTAINER_DESTROY(&regl);
13260 
13261    clear_realm_authentication(authl);
13262    clear_sip_domains();
13263    close(sipsock);
13264    sched_context_destroy(sched);
13265       
13266    return 0;
13267 }

static 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, 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 }

static 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, 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 13269 of file chan_sip.c.

References usecnt.

13270 {
13271    return usecnt;
13272 }


Variable Documentation

struct in_addr __ourip [static]
 

Definition at line 409 of file chan_sip.c.

const struct cfalias aliases[] [static]
 

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

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_show_objects(), and temp_peer().

char* app_dtmfmode = "SIPDtmfMode" [static]
 

Definition at line 12769 of file chan_sip.c.

Referenced by load_module(), and unload_module().

char* app_sipaddheader = "SIPAddHeader" [static]
 

Definition at line 12771 of file chan_sip.c.

Referenced by load_module(), and unload_module().

char* app_sipgetheader = "SIPGetHeader" [static]
 

Definition at line 12783 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 register_verify(), reload_config(), and sip_show_settings().

struct sockaddr_in bindaddr = { 0, } [static]
 

Definition at line 867 of file chan_sip.c.

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.

struct ast_custom_function checksipdomain_function [static]
 

Definition at line 9219 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 add_header(), reload_config(), and sip_show_settings().

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

Definition at line 144 of file chan_sip.c.

char debug_usage[] [static]
 

Definition at line 9118 of file chan_sip.c.

struct sockaddr_in debugaddr [static]
 

Definition at line 416 of file chan_sip.c.

Referenced by 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 build_rpid(), reload_config(), and sip_show_settings().

char default_context[AST_MAX_CONTEXT] = DEFAULT_CONTEXT [static]
 

Definition at line 332 of file chan_sip.c.

int default_expiry = DEFAULT_DEFAULT_EXPIRY [static]
 

Definition at line 119 of file chan_sip.c.

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

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 build_peer(), 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 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 12768 of file chan_sip.c.

Referenced by load_module().

char* descrip_sipaddheader [static]
 

Definition at line 12775 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 12786 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 complete_dpreply(), parse_register_contact(), reg_source_db(), and reload_config().

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 ast_sip_ouraddrfor(), and 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 build_peer(), build_user(), reload_config(), sip_alloc(), sip_request_call(), and temp_peer().

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(), sip_show_settings(), and transmit_state_notify().

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

Definition at line 582 of file chan_sip.c.

int global_rtpholdtimeout = 0 [static]
 

Definition at line 365 of file chan_sip.c.

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

int global_rtpkeepalive = 0 [static]
 

Definition at line 367 of file chan_sip.c.

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

int global_rtptimeout = 0 [static]
 

Definition at line 363 of file chan_sip.c.

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

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

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 7843 of file chan_sip.c.

char mandescr_show_peers[] [static]
 

Initial value:

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

Definition at line 7425 of file chan_sip.c.

int max_expiry = DEFAULT_MAX_EXPIRY [static]
 

Definition at line 118 of file chan_sip.c.

Referenced by handle_request_subscribe(), parse_register_contact(), 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.

struct ast_cli_entry my_clis[] [static]
 

Definition at line 13091 of file chan_sip.c.

char no_debug_usage[] [static]
 

Initial value:

 
"Usage: sip no debug\n"
"       Disables dumping of SIP packets for debugging purposes\n"

Definition at line 9127 of file chan_sip.c.

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 9131 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 9067 of file chan_sip.c.

int ourport [static]
 

Definition at line 411 of file chan_sip.c.

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 __get_header(), check_user_full(), find_call(), get_destination(), get_refer_info(), handle_request(), process_sdp(), register_verify(), reload_config(), sip_show_settings(), and sipsock_read().

struct ast_peer_list peerl [static]
 

The peer list: Peers and Friends ---.

struct ast_codec_pref prefs [static]
 

Definition at line 444 of file chan_sip.c.

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 9109 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 do_register_auth(), reload_config(), sip_do_history(), sip_no_history(), sip_reregister(), sip_show_history(), sip_show_settings(), sipsock_read(), and transmit_register().

char regcontext[AST_MAX_CONTEXT] = "" [static]
 

Context for auto-extensions

Definition at line 430 of file chan_sip.c.

struct ast_register_list regl [static]
 

The register list: Other SIP proxys we register with and call ---.

Referenced by delete_users(), load_module(), sip_do_reload(), sip_register(), sip_send_all_registers(), sip_show_objects(), sip_show_registry(), and unload_module().

int regobjs = 0 [static]
 

Definition at line 378 of file chan_sip.c.

Referenced by sip_register(), sip_send_all_registers(), 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(), and sip_show_objects().

int ruserobjs = 0 [static]
 

Definition at line 374 of file chan_sip.c.

Referenced by sip_show_objects().

struct sched_context* sched [static]
 

Definition at line 435 of file chan_sip.c.

char show_channel_usage[] [static]
 

Initial value:

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

Definition at line 9091 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 9087 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 9062 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 9095 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 9082 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 9148 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 9104 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 9099 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 9114 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 9152 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 9144 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 9077 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 9072 of file chan_sip.c.

struct ast_custom_function sip_header_function [static]
 

Definition at line 9198 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(), 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 9140 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 12996 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(), sip_new(), and unload_module().

struct ast_custom_function sipchaninfo_function [static]
 

Definition at line 9383 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 add_sip_domain(), build_reply_digest(), check_auth(), handle_request_info(), handle_request_invite(), handle_request_subscribe(), parse_request(), reload_config(), sip_addheader(), sip_do_debug(), sip_do_debug_ip(), sip_do_debug_peer(), sip_no_debug(), sip_poke_peer(), sip_reregister(), transmit_invite(), transmit_register(), and transmit_reinvite_with_sdp().

struct ast_custom_function sippeer_function
 

Definition at line 9306 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(), 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(), and sip_show_objects().

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

Definition at line 12767 of file chan_sip.c.

Referenced by load_module().

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

Definition at line 12772 of file chan_sip.c.

Referenced by load_module().

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

Definition at line 12784 of file chan_sip.c.

Referenced by load_module().

int tos = 0 [static]
 

Definition at line 418 of file chan_sip.c.

int usecnt = 0 [static]
 

Definition at line 385 of file chan_sip.c.

struct ast_user_list userl [static]
 

The user list: Users and friends ---.

int videosupport = 0 [static]
 

Definition at line 420 of file chan_sip.c.

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


Generated on Fri May 26 01:47:03 2006 for Asterisk - the Open Source PBX by  doxygen 1.4.6