Sat Apr 12 07:12:38 2008

Asterisk developer's documentation


chan_sip.c File Reference

Implementation of Session Initiation Protocol. More...

#include "asterisk.h"
#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/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/udptl.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/devicestate.h"
#include "asterisk/linkedlists.h"
#include "asterisk/stringfields.h"
#include "asterisk/monitor.h"
#include "asterisk/localtime.h"
#include "asterisk/abstract_jb.h"
#include "asterisk/compiler.h"
#include "asterisk/threadstorage.h"
#include "asterisk/translate.h"
#include "asterisk/dnsmgr.h"

Go to the source code of this file.

Data Structures

struct  ast_peer_list
 The peer list: Peers and Friends. More...
struct  ast_register_list
 The register list: Other SIP proxys we register with and place calls to. More...
struct  ast_user_list
 The user list: Users and friends. More...
struct  c_referstatusstring
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
 Domain data structure. More...
struct  sip_auth
 sip_auth: Credentials for authentication to other SIP services More...
struct  sip_dual
 structure used in transfers More...
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
 Structure for SIP peer data, we place calls to peers if registered or fixed IP address (host). More...
struct  sip_pkt
 sip packet - raw format for outbound packets that are sent or scheduled for transmission More...
struct  sip_pvt
 sip_pvt: PVT structures are used for each SIP dialog, ie. a call, a registration, a subscribe More...
struct  sip_refer
 Structure to handle SIP transfers. Dynamically allocated when needed. More...
struct  sip_registry
 Registrations with other SIP proxies. More...
struct  sip_request
 sip_request: The data grabbed from the UDP socket More...
struct  sip_route
 Structure to save routing information for a SIP session. More...
struct  sip_user
 Structure for SIP user data. User's place calls to us. More...
struct  t38properties
 T.38 channel settings (at some point we need to make this alloc'ed. More...

Defines

#define ALLOWED_METHODS   "INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY"
 SIP Methods we support.
#define append_history(p, event, fmt, args...)   append_history_full(p, "%-15s " fmt, event, ## args)
 Append to SIP dialog history.
#define CALLERID_UNKNOWN   "Unknown"
#define CAN_CREATE_DIALOG   1
#define CAN_CREATE_DIALOG_UNSUPPORTED_METHOD   2
#define CAN_NOT_CREATE_DIALOG   0
#define DEC_CALL_LIMIT   0
#define DEC_CALL_RINGING   2
#define DEFAULT_ALLOW_EXT_DOM   TRUE
#define DEFAULT_ALLOWGUEST   TRUE
#define DEFAULT_AUTOCREATEPEER   FALSE
#define DEFAULT_CALLERID   "asterisk"
#define DEFAULT_COMPACTHEADERS   FALSE
#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_CALL_BITRATE   (384)
#define DEFAULT_MAX_EXPIRY   3600
#define DEFAULT_MAX_FORWARDS   "70"
#define DEFAULT_MAXMS   2000
#define DEFAULT_MIN_EXPIRY   60
#define DEFAULT_MOHINTERPRET   "default"
#define DEFAULT_MOHSUGGEST   ""
#define DEFAULT_MWITIME   10
#define DEFAULT_NOTIFYMIME   "application/simple-message-summary"
#define DEFAULT_NOTIFYRINGING   TRUE
#define DEFAULT_PEDANTIC   FALSE
#define DEFAULT_QUALIFY   FALSE
#define DEFAULT_REALM   "asterisk"
#define DEFAULT_REGISTRATION_TIMEOUT   20
#define DEFAULT_RETRANS   1000
#define DEFAULT_SRVLOOKUP   TRUE
#define DEFAULT_T1MIN   100
#define DEFAULT_TOS_AUDIO   0
#define DEFAULT_TOS_SIP   0
#define DEFAULT_TOS_VIDEO   0
#define DEFAULT_TRANS_TIMEOUT   -1
#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 FALSE   0
#define FLAG_FATAL   (1 << 1)
#define FLAG_RESPONSE   (1 << 0)
#define FORMAT   "%-15.15s %-10.10s %-11.11s %5.5d/%5.5d %-15.15s %-3.3s %-3.3s %-15.15s %-10.10s\n"
#define FORMAT   "%-30.30s %-12.12s %8d %-20.20s %-25.25s\n"
#define FORMAT   "%-40.40s %-20.20s %-16.16s\n"
#define FORMAT   "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8d %-10s %-10s\n"
#define FORMAT   "%-25.25s %-15.15s %-15.15s %-15.15s %-5.5s%-10.10s\n"
#define FORMAT   "%-25.25s %-15.15s %-15.15s \n"
#define FORMAT2   "%-15.15s %-10.10s %-11.11s %-11.11s %-15.15s %-7.7s %-15.15s\n"
#define FORMAT2   "%-30.30s %-12.12s %8.8s %-20.20s %-25.25s\n"
#define FORMAT2   "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8s %-10s %-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 %-10.10s\n"
#define INC_CALL_LIMIT   1
#define INC_CALL_RINGING   3
#define INITIAL_CSEQ   101
#define IPTOS_MINCOST   0x02
#define MAX(a, b)   ((a) > (b) ? (a) : (b))
#define MAX_AUTHTRIES   3
#define MAX_HISTORY_ENTRIES   50
#define MAX_RETRANS   6
#define NO_RTP   0
#define NOT_SUPPORTED   0
#define RTP   1
#define SDP_MAX_RTPMAP_CODECS   32
#define SDP_SAMPLE_RATE(x)   (x == AST_FORMAT_G722) ? 16000 : 8000
#define SIP_ALREADYGONE   (1 << 0)
#define SIP_CALL_LIMIT   (1 << 28)
#define SIP_CAN_REINVITE   (1 << 20)
#define SIP_CAN_REINVITE_NAT   (2 << 20)
#define SIP_DEFER_BYE_ON_TRANSFER   (1 << 15)
#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_FLAGS_TO_COPY
#define SIP_FREE_BIT   (1 << 14)
#define SIP_G726_NONSTANDARD   (1 << 31)
#define SIP_GOTREFER   (1 << 7)
#define SIP_INC_COUNT   (1 << 30)
#define SIP_INSECURE_INVITE   (1 << 24)
#define SIP_INSECURE_PORT   (1 << 23)
#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_NO_HISTORY   (1 << 27)
#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_HISTINFO   (1 << 15)
#define SIP_OPT_JOIN   (1 << 4)
#define SIP_OPT_NOREFERSUB   (1 << 14)
#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_RESPRIORITY   (1 << 16)
#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_OUTGOING   (1 << 13)
#define SIP_PAGE2_ALLOWOVERLAP   (1 << 17)
#define SIP_PAGE2_ALLOWSUBSCRIBE   (1 << 16)
#define SIP_PAGE2_BUGGY_MWI   (1 << 26)
#define SIP_PAGE2_CALL_ONHOLD   (3 << 23)
#define SIP_PAGE2_CALL_ONHOLD_ACTIVE   (1 << 23)
#define SIP_PAGE2_CALL_ONHOLD_INACTIVE   (3 << 23)
#define SIP_PAGE2_CALL_ONHOLD_ONEDIR   (2 << 23)
#define SIP_PAGE2_DEBUG   (3 << 11)
#define SIP_PAGE2_DEBUG_CONFIG   (1 << 11)
#define SIP_PAGE2_DEBUG_CONSOLE   (1 << 12)
#define SIP_PAGE2_DYNAMIC   (1 << 13)
#define SIP_PAGE2_FLAGS_TO_COPY
#define SIP_PAGE2_IGNOREREGEXPIRE   (1 << 10)
#define SIP_PAGE2_INC_RINGING   (1 << 19)
#define SIP_PAGE2_OUTGOING_CALL   (1 << 27)
#define SIP_PAGE2_RFC2833_COMPENSATE   (1 << 25)
#define SIP_PAGE2_RT_FROMCONTACT   (1 << 4)
#define SIP_PAGE2_RTAUTOCLEAR   (1 << 2)
#define SIP_PAGE2_RTCACHEFRIENDS   (1 << 0)
#define SIP_PAGE2_RTSAVE_SYSNAME   (1 << 5)
#define SIP_PAGE2_RTUPDATE   (1 << 1)
#define SIP_PAGE2_SELFDESTRUCT   (1 << 14)
#define SIP_PAGE2_SUBSCRIBEMWIONLY   (1 << 18)
#define SIP_PAGE2_T38SUPPORT   (7 << 20)
#define SIP_PAGE2_T38SUPPORT_RTP   (2 << 20)
#define SIP_PAGE2_T38SUPPORT_TCP   (4 << 20)
#define SIP_PAGE2_T38SUPPORT_UDPTL   (1 << 20)
#define SIP_PAGE2_VIDEOSUPPORT   (1 << 15)
#define SIP_PENDINGBYE   (1 << 6)
#define SIP_PKT_DEBUG   (1 << 0)
#define SIP_PKT_IGNORE   (1 << 2)
#define SIP_PKT_IGNORE_REQ   (1 << 4)
#define SIP_PKT_IGNORE_RESP   (1 << 3)
#define SIP_PKT_WITH_TOTAG   (1 << 1)
#define SIP_PROG_INBAND   (3 << 25)
#define SIP_PROG_INBAND_NEVER   (0 << 25)
#define SIP_PROG_INBAND_NO   (1 << 25)
#define SIP_PROG_INBAND_YES   (2 << 25)
#define SIP_PROGRESS_SENT   (1 << 4)
#define SIP_PROMISCREDIR   (1 << 8)
#define SIP_REALTIME   (1 << 11)
#define SIP_REINVITE   (7 << 20)
#define SIP_REINVITE_UPDATE   (4 << 20)
#define SIP_RINGING   (1 << 3)
#define SIP_SENDRPID   (1 << 29)
#define SIP_TRANS_TIMEOUT   32000
#define SIP_TRUSTRPID   (1 << 9)
#define SIP_USECLIENTCODE   (1 << 12)
#define SIP_USEREQPHONE   (1 << 10)
#define sipdebug   ast_test_flag(&global_flags[1], SIP_PAGE2_DEBUG)
#define sipdebug_config   ast_test_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONFIG)
#define sipdebug_console   ast_test_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE)
#define STANDARD_SIP_PORT   5060
 Standard SIP port from RFC 3261. DO NOT CHANGE THIS.
#define SUPPORTED   1
#define SUPPORTED_EXTENSIONS   "replaces"
 SIP Extensions we support.
#define T38FAX_FILL_BIT_REMOVAL   (1 << 0)
#define T38FAX_RATE_12000   (1 << 12)
#define T38FAX_RATE_14400   (1 << 13)
#define T38FAX_RATE_2400   (1 << 8)
#define T38FAX_RATE_4800   (1 << 9)
#define T38FAX_RATE_7200   (1 << 10)
#define T38FAX_RATE_9600   (1 << 11)
#define T38FAX_RATE_MANAGEMENT_LOCAL_TCF   (1 << 3)
#define T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF   (0 << 3)
#define T38FAX_TRANSCODING_JBIG   (1 << 2)
#define T38FAX_TRANSCODING_MMR   (1 << 1)
#define T38FAX_UDP_EC_FEC   (1 << 4)
#define T38FAX_UDP_EC_NONE   (0 << 4)
#define T38FAX_UDP_EC_REDUNDANCY   (2 << 4)
#define T38FAX_VERSION   (3 << 6)
#define T38FAX_VERSION_0   (0 << 6)
#define T38FAX_VERSION_1   (1 << 6)
#define TRUE   1
#define UNLINK(element, head, prev)
#define VIDEO_CODEC_MASK   0x1fc0000
#define XMIT_ERROR   -2

Enumerations

enum  check_auth_result {
  AUTH_SUCCESSFUL = 0, AUTH_CHALLENGE_SENT = 1, AUTH_SECRET_FAILED = -1, AUTH_USERNAME_MISMATCH = -2,
  AUTH_NOT_FOUND = -3, AUTH_FAKE_AUTH = -4, AUTH_UNKNOWN_DOMAIN = -5, AUTH_PEER_NOT_DYNAMIC = -6,
  AUTH_ACL_FAILED = -7
}
 Authentication result from check_auth* functions. More...
enum  domain_mode { SIP_DOMAIN_AUTO, SIP_DOMAIN_CONFIG }
 Modes for SIP domain handling in the PBX. More...
enum  invitestates {
  INV_NONE = 0, INV_CALLING = 1, INV_PROCEEDING = 2, INV_EARLY_MEDIA = 3,
  INV_COMPLETED = 4, INV_CONFIRMED = 5, INV_TERMINATED = 6, INV_CANCELLED = 7
}
 States for the INVITE transaction, not the dialog. More...
enum  parse_register_result { PARSE_REGISTER_FAILED, PARSE_REGISTER_UPDATE, PARSE_REGISTER_QUERY }
enum  referstatus {
  REFER_IDLE, REFER_SENT, REFER_RECEIVED, REFER_CONFIRMED,
  REFER_ACCEPTED, REFER_RINGING, REFER_200OK, REFER_FAILED,
  REFER_NOAUTH
}
 Parameters to know status of transfer. More...
enum  sip_auth_type { PROXY_AUTH, WWW_AUTH }
 Authentication types - proxy or www authentication. More...
enum  sip_result { AST_SUCCESS = 0, AST_FAILURE = -1 }
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,
  SIP_PING
}
 SIP Request methods known by Asterisk. More...
enum  sipregistrystate {
  REG_STATE_UNREGISTERED = 0, REG_STATE_REGSENT, REG_STATE_AUTHSENT, REG_STATE_REGISTERED,
  REG_STATE_REJECTED, REG_STATE_TIMEOUT, REG_STATE_NOAUTH, REG_STATE_FAILED
}
 States for outbound registrations (with register= lines in sip.conf. More...
enum  subscriptiontype {
  NONE = 0, XPIDF_XML, DIALOG_INFO_XML, CPIM_PIDF_XML,
  PIDF_XML, MWI_NOTIFICATION
}
enum  t38state {
  T38_DISABLED = 0, T38_LOCAL_DIRECT, T38_LOCAL_REINVITE, T38_PEER_DIRECT,
  T38_PEER_REINVITE, T38_ENABLED
}
 T38 States for a call. More...
enum  transfermodes { TRANSFER_OPENFORALL, TRANSFER_CLOSED }
 Authorization scheme for call transfers. More...
enum  xmittype { XMIT_CRITICAL = 2, XMIT_RELIABLE = 1, XMIT_UNRELIABLE = 0 }

Functions

static const char * __get_header (const struct sip_request *req, const char *name, int *start)
static void __sip_ack (struct sip_pvt *p, int seqno, int resp, int sipmethod)
 Acknowledges receipt of a packet and stops retransmission.
static int __sip_autodestruct (const void *data)
 Kill a SIP dialog (called by scheduler).
static void __sip_destroy (struct sip_pvt *p, int lockowner)
 Execute destruction of SIP dialog structure, release memory.
static int __sip_do_register (struct sip_registry *r)
 Register with SIP proxy.
static void __sip_pretend_ack (struct sip_pvt *p)
 Pretend to ack all packets maybe the lock on p is not strictly necessary but there might be a race.
static int __sip_reliable_xmit (struct sip_pvt *p, int seqno, int resp, char *data, int len, int fatal, int sipmethod)
 Transmit packet with retransmits.
static int __sip_semi_ack (struct sip_pvt *p, int seqno, int resp, int sipmethod)
 Acks receipt of packet, keep it around (used for provisional responses).
static int __sip_show_channels (int fd, int argc, char *argv[], int subscriptions)
 SIP show channels CLI (main function).
static int __sip_xmit (struct sip_pvt *p, char *data, int len)
 Transmit SIP message.
static int __transmit_response (struct sip_pvt *p, const char *msg, const struct sip_request *req, enum xmittype reliable)
 Base transmit response function.
static int _sip_show_peer (int type, int fd, struct mansession *s, const struct message *m, int argc, const char *argv[])
 Show one peer in detail (main function).
static int _sip_show_peers (int fd, int *total, struct mansession *s, const struct message *m, int argc, const char *argv[])
 _sip_show_peers: Execute sip show peers command
static int acf_channel_read (struct ast_channel *chan, char *funcname, char *preparse, char *buf, size_t buflen)
static void add_blank (struct sip_request *req)
 add a blank line if no body
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, int *min_packet_size)
 Add codec offer to SDP offer/answer body in INVITE or 200 OK.
static int add_digit (struct sip_request *req, char digit, unsigned int duration)
 Add DTMF INFO tone to sip message.
static int add_header (struct sip_request *req, const char *var, const char *value)
 Add header to SIP message.
static int add_header_contentLength (struct sip_request *req, int len)
 Add 'Content-Length' header to SIP message.
static int add_line (struct sip_request *req, const char *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)
 Add RFC 2833 DTMF offer to SDP.
static struct sip_authadd_realm_authentication (struct sip_auth *authlist, char *configuration, int lineno)
 Add realm authentication in list.
static void add_route (struct sip_request *req, struct sip_route *route)
 Add route header into request per learned route.
static enum sip_result add_sdp (struct sip_request *resp, struct sip_pvt *p)
 Add Session Description Protocol message.
static int add_sip_domain (const char *domain, const enum domain_mode mode, const char *context)
 Add SIP domain to list of domains we are responsible for.
static int add_t38_sdp (struct sip_request *resp, struct sip_pvt *p)
 Add T.38 Session Description Protocol message.
static int add_text (struct sip_request *req, const char *text)
 Add text body to SIP message.
static int add_vidupdate (struct sip_request *req)
 add XML encoded media control with update
static void append_date (struct sip_request *req)
 Append date to SIP message.
static void append_history_full (struct sip_pvt *p, const char *fmt,...)
 Append to SIP dialog history with arg list.
static void static void append_history_va (struct sip_pvt *p, const char *fmt, va_list ap)
 Append to SIP dialog history with arg list.
 AST_LIST_HEAD_NOLOCK (sip_history_head, sip_history)
static AST_LIST_HEAD_STATIC (domain_list, domain)
 AST_MODULE_INFO (ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT,"Session Initiation Protocol (SIP)",.load=load_module,.unload=unload_module,.reload=reload,)
 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 SIP dialog list (of sip_pvt's).
static void ast_quiet_chan (struct ast_channel *chan)
 Turn off generator data XXX Does this function belong in the SIP channel?
static int ast_sip_ouraddrfor (struct in_addr *them, struct in_addr *us)
 NAT fix - decide which IP address to use for ASterisk server?
 AST_THREADSTORAGE_CUSTOM (ts_temp_pvt, temp_pvt_init, temp_pvt_cleanup)
 A per-thread temporary pvt structure.
static int attempt_transfer (struct sip_dual *transferer, struct sip_dual *target)
 Attempt transfer of SIP call This fix for attended transfers on a local PBX.
static int auto_congest (const void *nothing)
 Scheduled congestion on a call.
static void build_callid_pvt (struct sip_pvt *pvt)
 Build SIP Call-ID value for a non-REGISTER transaction.
static void build_callid_registry (struct sip_registry *reg, struct in_addr ourip, const char *fromdomain)
 Build SIP Call-ID value for a REGISTER transaction.
static void build_contact (struct sip_pvt *p)
 Build contact header - the contact header we send out.
static struct sip_peerbuild_peer (const char *name, struct ast_variable *v, struct ast_variable *alt, int realtime)
 Build peer from configuration (file or realtime static/dynamic).
static int build_reply_digest (struct sip_pvt *p, int method, char *digest, int digest_len)
 Build reply digest.
static void build_route (struct sip_pvt *p, struct sip_request *req, int backwards)
 Build route list from Record-Route header.
static void build_rpid (struct sip_pvt *p)
 Build the Remote Party-ID & From using callingpres options.
static struct sip_userbuild_user (const char *name, struct ast_variable *v, int realtime)
 Initiate a SIP user structure from configuration (configuration or realtime).
static void build_via (struct sip_pvt *p)
 Build a Via header for a request.
static int cb_extensionstate (char *context, char *exten, int state, void *data, char *cid_num, char *cid_name)
 Callback for the devicestate notification (SUBSCRIBE) support subsystem.
static void change_hold_state (struct sip_pvt *dialog, struct sip_request *req, int holdstate, int sendonly)
 Change hold state for a call.
static enum check_auth_result check_auth (struct sip_pvt *p, struct sip_request *req, const char *username, const char *secret, const char *md5secret, int sipmethod, char *uri, enum xmittype reliable, int ignore)
 Check user authorization from peer definition Some actions, like REGISTER and INVITEs from peers require authentication (if peer have secret set).
static void check_pendings (struct sip_pvt *p)
 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, enum xmittype reliable, struct sockaddr_in *sin)
 Find user If we get a match, this will add a reference pointer to the user object in ASTOBJ, that needs to be unreferenced.
static enum check_auth_result check_user_full (struct sip_pvt *p, struct sip_request *req, int sipmethod, char *uri, enum xmittype reliable, struct sockaddr_in *sin, struct sip_peer **authpeer)
 Check if matching user or peer is defined Match user on From: user name and peer on IP/port This is used on first invite (not re-invites) and subscribe requests.
static void check_via (struct sip_pvt *p, struct sip_request *req)
 check Via: header for hostname, port and rport request/answer
static void cleanup_stale_contexts (char *new, char *old)
 Destroy disused contexts between reloads Only used in reload_config so the code for regcontext doesn't get ugly.
static int clear_realm_authentication (struct sip_auth *authlist)
 Clear realm authentication list (at reload).
static void clear_sip_domains (void)
 Clear our domain list (at reload).
static char * complete_sip_debug_peer (const char *line, const char *word, int pos, int state)
 Support routine for 'sip debug peer' CLI.
static char * complete_sip_peer (const char *word, int state, int flags2)
 Do completion on peer name.
static char * complete_sip_prune_realtime_peer (const char *line, const char *word, int pos, int state)
 Support routine for 'sip prune realtime peer' CLI.
static char * complete_sip_prune_realtime_user (const char *line, const char *word, int pos, int state)
 Support routine for 'sip prune realtime user' CLI.
static char * complete_sip_show_peer (const char *line, const char *word, int pos, int state)
 Support routine for 'sip show peer' CLI.
static char * complete_sip_show_user (const char *line, const char *word, int pos, int state)
 Support routine for 'sip show user' CLI.
static char * complete_sip_user (const char *word, int state, int flags2)
 Do completion on user name.
static char * complete_sipch (const char *line, const char *word, int pos, int state)
 Support routine for 'sip show channel' CLI.
static char * complete_sipnotify (const char *line, const char *word, int pos, int state)
 Support routine for 'sip notify' CLI.
static int copy_all_header (struct sip_request *req, const struct sip_request *orig, const char *field)
 Copy all headers from one request to another.
static int copy_header (struct sip_request *req, const struct sip_request *orig, const char *field)
 Copy one header field from one request to another.
static void copy_request (struct sip_request *dst, const struct sip_request *src)
 copy SIP request (mostly used to save request for responses)
static int copy_via_headers (struct sip_pvt *p, struct sip_request *req, const struct sip_request *orig, const char *field)
 Copy SIP VIA Headers from the request to the response.
static int create_addr (struct sip_pvt *dialog, const char *opeer)
 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 *dialog, struct sip_peer *peer)
 Create address structure from peer reference. return -1 on error, 0 on success.
static void destroy_association (struct sip_peer *peer)
 Remove registration data from realtime database or AST/DB when registration expires.
static int determine_firstline_parts (struct sip_request *req)
 Parse first line of incoming SIP request.
static void * do_monitor (void *data)
 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)
 Add authentication on outbound SIP packet.
static int do_register_auth (struct sip_pvt *p, struct sip_request *req, char *header, char *respheader)
 Authenticate for outbound registration.
static void do_setnat (struct sip_pvt *p, int natflags)
 Set nat mode on the various data sockets.
static int does_peer_need_mwi (struct sip_peer *peer)
 Check whether peer needs a new MWI notification check.
static const char * domain_mode_to_text (const enum domain_mode mode)
 Print domain mode to cli.
static const char * dtmfmode2str (int mode)
 Convert DTMF mode to printable string.
static int expire_register (const void *data)
 Expire registration of SIP peer.
static void extract_uri (struct sip_pvt *p, struct sip_request *req)
 Check Contact: URI of SIP message.
static const char * find_alias (const char *name, const char *_default)
 Find compressed SIP alias.
static struct sip_pvtfind_call (struct sip_request *req, struct sockaddr_in *sin, const int intended_method)
 Connect incoming SIP message to current dialog or create new dialog structure Called by handle_request, sipsock_read.
static const char * find_closing_quote (const char *start, const char *lim)
 Locate closing quote in a string, skipping escaped quotes. optionally with a limit on the search. start must be past the first quote.
static struct sip_peerfind_peer (const char *peer, struct sockaddr_in *sin, int realtime)
 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, const char *realm)
 Find authentication for a specific realm.
static int find_sdp (struct sip_request *req)
 Determine whether a SIP message contains an SDP in its body.
static int find_sip_method (const char *msg)
 find_sip_method: Find SIP method from header
static struct
cfsubscription_types
find_subscription_type (enum subscriptiontype subtype)
 Find subscription type in array.
static struct sip_userfind_user (const char *name, int realtime)
 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)
 Remove route from route list.
static int func_check_sipdomain (struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
 Dial plan function to check if domain is local.
static int func_header_read (struct ast_channel *chan, char *function, char *data, char *buf, size_t len)
 Read SIP header (dialplan function).
static int function_sipchaninfo_read (struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
 ${SIPCHANINFO()} Dialplan function - reads sip channel data
static int function_sippeer (struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
 ${SIPPEER()} Dialplan function - reads peer data
static char * generate_random_string (char *buf, size_t size)
 Generate 32 byte random string for callid's etc.
static int get_also_info (struct sip_pvt *p, struct sip_request *oreq)
 Call transfer support (old way, deprecated by the IETF)--.
static char * get_body (struct sip_request *req, char *name)
 Get a specific line from the message body.
static char * get_body_by_line (const char *line, const char *name, int nameLen)
 Reads one line of SIP message body.
static char * get_calleridname (const char *input, char *output, size_t outputsize)
 Get caller id name from SIP headers.
static int get_destination (struct sip_pvt *p, struct sip_request *oreq)
 Find out who the call is for We use the INVITE uri to find out.
static const char * get_header (const struct sip_request *req, const char *name)
 Get header from SIP request.
static char * get_in_brackets (char *tmp)
 Pick out text in brackets from character string.
static int get_msg_text (char *buf, int len, struct sip_request *req)
 Get text out of a SIP MESSAGE packet.
static int get_rdnis (struct sip_pvt *p, struct sip_request *oreq)
 Get referring dnis.
static int get_refer_info (struct sip_pvt *transferer, struct sip_request *outgoing_req)
 Call transfer support (the REFER method) Extracts Refer headers into pvt dialog structure.
static int get_rpid_num (const char *input, char *output, int maxlen)
 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 const char * get_sdp (struct sip_request *req, const char *name)
 Get a line from an SDP message body.
static const char * get_sdp_iterate (int *start, struct sip_request *req, const char *name)
 Lookup 'name' in the SDP starting at the 'start' line. Returns the matching line, and 'start' is updated with the next line number.
static struct sip_pvtget_sip_pvt_byid_locked (const char *callid, const char *totag, const char *fromtag)
 Lock interface lock and find matching pvt lock
  • Their tag is fromtag, our tag is to-tag
  • This means that in some transactions, totag needs to be their tag :-) depending upon the direction.

static const char * gettag (const struct sip_request *req, const char *header, char *tagbuf, int tagbufsize)
 Get tag from packet.
static int handle_common_options (struct ast_flags *flags, struct ast_flags *mask, struct ast_variable *v)
 Handle flag-type options common to configuration of devices - users and peers.
static int handle_invite_replaces (struct sip_pvt *p, struct sip_request *req, int debug, int ignore, int seqno, struct sockaddr_in *sin)
 Handle the transfer part of INVITE with a replaces: header, meaning a target pickup or an attended transfer.
static int handle_request (struct sip_pvt *p, struct sip_request *req, struct sockaddr_in *sin, int *recount, int *nounlock)
 Handle incoming SIP requests (methods).
static int handle_request_bye (struct sip_pvt *p, struct sip_request *req)
 Handle incoming BYE request.
static int handle_request_cancel (struct sip_pvt *p, struct sip_request *req)
 Handle incoming CANCEL request.
static void handle_request_info (struct sip_pvt *p, struct sip_request *req)
 Receive SIP INFO Message.
static int handle_request_invite (struct sip_pvt *p, struct sip_request *req, int debug, int seqno, struct sockaddr_in *sin, int *recount, char *e, int *nounlock)
 Handle incoming INVITE request.
static int handle_request_message (struct sip_pvt *p, struct sip_request *req)
 Handle incoming MESSAGE request.
static int handle_request_notify (struct sip_pvt *p, struct sip_request *req, struct sockaddr_in *sin, int seqno, char *e)
 Handle incoming notifications.
static int handle_request_options (struct sip_pvt *p, struct sip_request *req)
 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)
static int handle_request_register (struct sip_pvt *p, struct sip_request *req, struct sockaddr_in *sin, char *e)
 Handle incoming REGISTER request.
static int handle_request_subscribe (struct sip_pvt *p, struct sip_request *req, struct sockaddr_in *sin, int seqno, char *e)
 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 SIP response in dialogue.
static void handle_response_invite (struct sip_pvt *p, int resp, char *rest, struct sip_request *req, int seqno)
 Handle SIP response to INVITE dialogue.
static void handle_response_peerpoke (struct sip_pvt *p, int resp, struct sip_request *req)
 Handle qualification responses (OPTIONS).
static void handle_response_refer (struct sip_pvt *p, int resp, char *rest, struct sip_request *req, int seqno)
static int handle_response_register (struct sip_pvt *p, int resp, char *rest, struct sip_request *req, int ignore, int seqno)
 Handle responses on REGISTER to services.
static const char * hangup_cause2sip (int cause)
 Convert Asterisk hangup causes to SIP codes.
static int hangup_sip2cause (int cause)
 Convert SIP hangup causes to Asterisk hangup causes.
static int init_req (struct sip_request *req, int sipmethod, const char *recip)
 Initialize SIP request.
static int init_resp (struct sip_request *resp, const char *msg)
 Initialize SIP response, based on SIP request.
static void initialize_initreq (struct sip_pvt *p, struct sip_request *req)
 Initialize the initital request packet in the pvt structure. This packet is used for creating replies and future requests in a dialog.
static void initreqprep (struct sip_request *req, struct sip_pvt *p, int sipmethod)
 Initiate new SIP request to peer/user.
static const char * insecure2str (int port, int invite)
 Convert Insecure setting to printable string.
static void list_route (struct sip_route *route)
 List all routes - mostly for debugging.
static int load_module (void)
 PBX load module - initialization.
static int local_attended_transfer (struct sip_pvt *transferer, struct sip_dual *current, struct sip_request *req, int seqno)
 Find all call legs and bridge transferee with target called from handle_request_refer.
static int lws2sws (char *msgbuf, int len)
 Parse multiline SIP headers into one header This is enabled if pedanticsipchecking is enabled.
static void make_our_tag (char *tagbuf, size_t len)
 Make our SIP dialog tag.
static int manager_sip_show_peer (struct mansession *s, const struct message *m)
 Show SIP peers in the manager API.
static int manager_sip_show_peers (struct mansession *s, const struct message *m)
 Show SIP peers in the manager API.
static int method_match (enum sipmethod id, const char *name)
 returns true if 'name' (with optional trailing whitespace) matches the sip method 'id'. Strictly speaking, SIP methods are case SENSITIVE, but we do a case-insensitive comparison to be more tolerant. following Jon Postel's rule: Be gentle in what you accept, strict with what you send
static char * nat2str (int nat)
 Convert NAT setting to text string.
static void parse_copy (struct sip_request *dst, const struct sip_request *src)
 Copy SIP request, parse it.
static void parse_moved_contact (struct sip_pvt *p, struct sip_request *req)
 Parse 302 Moved temporalily response.
static int parse_ok_contact (struct sip_pvt *pvt, struct sip_request *req)
 Save contact header for 200 OK on INVITE.
static enum parse_register_result parse_register_contact (struct sip_pvt *pvt, struct sip_peer *peer, struct sip_request *req)
 Parse contact header and save registration (peer registration).
static void parse_request (struct sip_request *req)
 Parse a SIP message.
static unsigned int parse_sip_options (struct sip_pvt *pvt, const char *supported)
 Parse supported header in incoming packet.
static int peer_status (struct sip_peer *peer, char *status, int statuslen)
 Report Peer status in character string.
static void print_codec_to_cli (int fd, struct ast_codec_pref *pref)
 Print codec list from preference to CLI/manager.
static void print_group (int fd, ast_group_t group, int crlf)
 Print call group and pickup group.
static int process_sdp (struct sip_pvt *p, struct sip_request *req)
 Process SIP SDP offer, select formats and activate RTP channels If offer is rejected, we will not change any properties of the call Return 0 on success, a negative value on errors. Must be called after find_sdp().
static struct sip_peerrealtime_peer (const char *newpeername, 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)
 Update peer object in realtime storage If the Asterisk system name is set in asterisk.conf, we will use that name and store that in the "regserver" field in the sippeers table to facilitate multi-server setups.
static struct sip_userrealtime_user (const char *username)
 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 SIP MESSAGE method messages.
static char * referstatus2str (enum referstatus rstatus)
 Convert transfer status to string.
static void reg_source_db (struct sip_peer *peer)
 Get registration details from Asterisk DB.
static void register_peer_exten (struct sip_peer *peer, int onoff)
 Automatically add peer extension to dial plan.
static enum check_auth_result register_verify (struct sip_pvt *p, struct sockaddr_in *sin, struct sip_request *req, char *uri)
 Verify registration of user
  • Registration is done in several steps, first a REGISTER without auth to get a challenge (nonce) then a second one with auth
  • Registration requests are only matched with peers that are marked as "dynamic".

static char * regstate2str (enum sipregistrystate regstate)
 Convert registration state status to string.
static int reload (void)
 Part of Asterisk module interface.
static int reload_config (enum channelreloadreason reason)
 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 to authentication for outbound registrations
static int reqprep (struct sip_request *req, struct sip_pvt *p, int sipmethod, int seqno, int newbranch)
 Initialize a SIP request message (not the initial one in a dialog).
static int respprep (struct sip_request *resp, struct sip_pvt *p, const char *msg, const struct sip_request *req)
 Prepare SIP response packet.
static int restart_monitor (void)
 Start the channel monitor thread.
static int retrans_pkt (const void *data)
 Retransmit SIP message if no answer (Called from scheduler).
static int send_request (struct sip_pvt *p, struct sip_request *req, enum xmittype reliable, int seqno)
 Send SIP Request to the other part of the dialogue.
static int send_response (struct sip_pvt *p, struct sip_request *req, enum xmittype reliable, int seqno)
 Transmit response on SIP request.
static int set_address_from_contact (struct sip_pvt *pvt)
 Change the other partys IP address based on given contact.
static void set_destination (struct sip_pvt *p, char *uri)
 Set destination from SIP URI.
static void set_insecure_flags (struct ast_flags *flags, const char *value, int lineno)
 Parse the "insecure" setting from sip.conf or from realtime.
static void set_peer_defaults (struct sip_peer *peer)
 Set peer defaults before configuring specific configurations.
static int sip_addheader (struct ast_channel *chan, void *data)
 Add a SIP header to an outbound INVITE.
static int sip_addrcmp (char *name, struct sockaddr_in *sin)
 Support routine for find_peer.
static struct sip_pvtsip_alloc (ast_string_field callid, struct sockaddr_in *sin, int useglobal_nat, const int intended_method)
 Allocate SIP_PVT structure and set defaults.
static void sip_alreadygone (struct sip_pvt *dialog)
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)
 Initiate SIP call from PBX used from the dial() application.
static void sip_cancel_destroy (struct sip_pvt *p)
 Cancel destruction of SIP dialog.
static int sip_debug_test_addr (const struct sockaddr_in *addr)
 See if we pass debug IP filter.
static int sip_debug_test_pvt (struct sip_pvt *p)
 Test PVT for debugging output.
static void sip_destroy (struct sip_pvt *p)
 Destroy SIP call structure.
static void sip_destroy_peer (struct sip_peer *peer)
 Destroy peer object from memory.
static void sip_destroy_user (struct sip_user *user)
 Remove user object from in-memory storage.
static int sip_devicestate (void *data)
 Part of PBX channel interface.
static int sip_do_debug (int fd, int argc, char *argv[])
 Turn on SIP debugging (CLI command).
static int sip_do_debug_deprecated (int fd, int argc, char *argv[])
static int sip_do_debug_ip (int fd, int argc, char *argv[])
 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[])
 Enable SIP History logging (CLI).
static int sip_do_reload (enum channelreloadreason reason)
 Reload module.
static int sip_dtmfmode (struct ast_channel *chan, void *data)
 Set the DTMFmode for an outbound SIP call (application).
static void sip_dump_history (struct sip_pvt *dialog)
 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)
 Return SIP UA's codec (part of the RTP interface).
static enum ast_rtp_get_result sip_get_rtp_peer (struct ast_channel *chan, struct ast_rtp **rtp)
 Returns null if we can't reinvite audio (part of RTP interface).
static struct ast_udptlsip_get_udptl_peer (struct ast_channel *chan)
static enum ast_rtp_get_result sip_get_vrtp_peer (struct ast_channel *chan, struct ast_rtp **rtp)
 Returns null if we can't reinvite video (part of RTP interface).
static int sip_handle_t38_reinvite (struct ast_channel *chan, struct sip_pvt *pvt, int reinvite)
 Handle T38 reinvite.
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, const void *data, size_t datalen)
 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 const char * sip_nat_mode (const struct sip_pvt *p)
 Display SIP nat mode.
static struct ast_channelsip_new (struct sip_pvt *i, int state, const char *title)
 Initiate a call in the SIP channel called from sip_request_call (calls from the pbx ) for outbound channels and from handle_request_invite for inbound channels.
static int sip_no_debug (int fd, int argc, char *argv[])
 Disable SIP Debugging in CLI.
static int sip_no_debug_deprecated (int fd, int argc, char *argv[])
static int sip_no_history (int fd, int argc, char *argv[])
 Disable SIP History logging (CLI).
static int sip_notify (int fd, int argc, char *argv[])
 Cli command to send SIP notify to peer.
static int sip_park (struct ast_channel *chan1, struct ast_channel *chan2, struct sip_request *req, int seqno)
 Park a call using the subsystem in res_features.c This is executed in a separate thread.
static void * sip_park_thread (void *stuff)
 Park SIP call support function Starts in a new thread, then parks the call XXX Should we add a wait period after streaming audio and before hangup?? Sometimes the audio can't be heard before hangup.
static void sip_peer_hold (struct sip_pvt *p, int hold)
 Change onhold state of a peer using a pvt structure.
static void sip_poke_all_peers (void)
 Send a poke to all known peers Space them out 100 ms apart XXX We might have a cool algorithm for this or use random - any suggestions?
static int sip_poke_noanswer (const void *data)
 React to lack of answer to Qualify poke.
static int sip_poke_peer (struct sip_peer *peer)
 Check availability of peer, also keep NAT open.
static int sip_poke_peer_s (const void *data)
 Poke peer (send qualify to check if peer is alive and well).
static int sip_prune_realtime (int fd, int argc, char *argv[])
 Remove temporary realtime objects from memory (CLI).
static struct ast_framesip_read (struct ast_channel *ast)
 Read SIP RTP from channel.
static struct sockaddr_in * sip_real_dst (const struct sip_pvt *p)
 The real destination address for a write.
static int sip_refer_allocate (struct sip_pvt *p)
 Allocate SIP refer structure.
static int sip_reg_timeout (const void *data)
 Registration timeout, register again.
static int sip_register (char *value, int lineno)
 Parse register=> line in sip.conf and add to registry.
static void sip_registry_destroy (struct sip_registry *reg)
 Destroy registry object Objects created with the register= statement in static configuration.
static int sip_reinvite_retry (const void *data)
 Reset the NEEDREINVITE flag after waiting when we get 491 on a Re-invite to avoid race conditions between asterisk servers. Called from the scheduler.
static int sip_reload (int fd, int argc, char *argv[])
 Force reload of module from cli.
static struct ast_channelsip_request_call (const char *type, int format, void *data, int *cause)
 PBX interface function -build SIP pvt structure SIP calls initiated by the PBX arrive here.
static int sip_reregister (const void *data)
 Update registration with SIP Proxy.
static struct ast_framesip_rtp_read (struct ast_channel *ast, struct sip_pvt *p, int *faxdetect)
 Read RTP from network.
static void sip_scheddestroy (struct sip_pvt *p, int ms)
 Schedule destruction of SIP dialog.
static void sip_send_all_registers (void)
 Send all known registrations.
static int sip_send_mwi_to_peer (struct sip_peer *peer)
 Send message waiting indication to alert peer that they've got voicemail.
static int sip_senddigit_begin (struct ast_channel *ast, char digit)
static int sip_senddigit_end (struct ast_channel *ast, char digit, unsigned int duration)
 Send DTMF character on SIP channel within one call, we're able to transmit in many methods simultaneously.
static int sip_sendtext (struct ast_channel *ast, const char *dest, const char *text, int ispdu)
 Send SIP MESSAGE text within a call Called from PBX core sendtext() application.
static int sip_set_rtp_peer (struct ast_channel *chan, struct ast_rtp *rtp, struct ast_rtp *vrtp, int codecs, int nat_active)
 Set the RTP peer for this call.
static int sip_set_udptl_peer (struct ast_channel *chan, struct ast_udptl *udptl)
static int sip_show_channel (int fd, int argc, char *argv[])
 Show details of one active dialog.
static int sip_show_channels (int fd, int argc, char *argv[])
 Show active SIP channels.
static int sip_show_domains (int fd, int argc, char *argv[])
 CLI command to list local domains.
static int sip_show_history (int fd, int argc, char *argv[])
 Show history details of one dialog.
static int sip_show_inuse (int fd, int argc, char *argv[])
 CLI Command to show calls within limits set by call_limit.
static int sip_show_objects (int fd, int argc, char *argv[])
 List all allocated SIP Objects (realtime or static).
static int sip_show_peer (int fd, int argc, char *argv[])
 Show one peer in detail.
static int sip_show_peers (int fd, int argc, char *argv[])
 CLI Show Peers command.
static int sip_show_registry (int fd, int argc, char *argv[])
 Show SIP Registry (registrations with other SIP proxies.
static int sip_show_settings (int fd, int argc, char *argv[])
 List global settings for the SIP channel.
static int sip_show_subscriptions (int fd, int argc, char *argv[])
 Show active SIP subscriptions.
static int sip_show_user (int fd, int argc, char *argv[])
 Show one user in detail.
static int sip_show_users (int fd, int argc, char *argv[])
 CLI Command 'SIP Show Users'.
static int sip_sipredirect (struct sip_pvt *p, const char *dest)
 Transfer call before connect with a 302 redirect.
static int sip_transfer (struct ast_channel *ast, const char *dest)
 Transfer SIP call.
static int sip_write (struct ast_channel *ast, struct ast_frame *frame)
 Send frame to media channel (rtp).
static int sipsock_read (int *id, int fd, short events, void *ignore)
 Read data from SIP socket.
static void stop_media_flows (struct sip_pvt *p)
 Immediately stop RTP, VRTP and UDPTL as applicable.
static const char * subscription_type2str (enum subscriptiontype subtype)
 Show subscription type in string format.
static int t38_get_rate (int t38cap)
 Get Max T.38 Transmission rate from T38 capabilities.
static struct sip_peertemp_peer (const char *name)
 Create temporary peer (used in autocreatepeer mode).
static void temp_pvt_cleanup (void *)
static char * transfermode2str (enum transfermodes mode)
 Convert transfer mode to text string.
static void transmit_fake_auth_response (struct sip_pvt *p, struct sip_request *req, int reliable)
 Send a fake 401 Unauthorized response when the administrator wants to hide the names of local users/peers from fishers.
static int transmit_info_with_digit (struct sip_pvt *p, const char digit, unsigned int duration)
 Send SIP INFO dtmf message, see Cisco documentation on cisco.com.
static int transmit_info_with_vidupdate (struct sip_pvt *p)
 Send SIP INFO with video update request.
static int transmit_invite (struct sip_pvt *p, int sipmethod, int sdp, int init)
 Build REFER/INVITE/OPTIONS message and transmit it.
static int transmit_message_with_text (struct sip_pvt *p, const char *text)
 Transmit text with SIP MESSAGE method.
static int transmit_notify_with_mwi (struct sip_pvt *p, int newmsgs, int oldmsgs, char *vmexten)
 Notify user of messages waiting in voicemail.
static int transmit_notify_with_sipfrag (struct sip_pvt *p, int cseq, char *message, int terminate)
 Notify a transferring party of the status of transfer.
static int transmit_refer (struct sip_pvt *p, const char *dest)
 Transmit SIP REFER message (initiated by the transfer() dialplan application.
static int transmit_register (struct sip_registry *r, int sipmethod, const char *auth, const char *authheader)
 Transmit register to SIP proxy or UA.
static int transmit_reinvite_with_sdp (struct sip_pvt *p)
 Transmit reinvite with SDP.
static int transmit_reinvite_with_t38_sdp (struct sip_pvt *p)
 Transmit reinvite with T38 SDP We reinvite so that the T38 processing can take place. SIP Signalling stays with * in the path.
static int transmit_request (struct sip_pvt *p, int sipmethod, int seqno, enum xmittype reliable, int newbranch)
 Transmit generic SIP request returns XMIT_ERROR if transmit failed with a critical error (don't retry).
static int transmit_request_with_auth (struct sip_pvt *p, int sipmethod, int seqno, enum xmittype reliable, int newbranch)
 Transmit SIP request, auth added.
static int transmit_response (struct sip_pvt *p, const char *msg, const struct sip_request *req)
 Transmit response, no retransmits.
static int transmit_response_reliable (struct sip_pvt *p, const char *msg, const struct sip_request *req)
 Transmit response, Make sure you get an ACK This is only used for responses to INVITEs, where we need to make sure we get an ACK.
static int transmit_response_using_temp (ast_string_field callid, struct sockaddr_in *sin, int useglobal_nat, const int intended_method, const struct sip_request *req, const char *msg)
 Transmit response, no retransmits, using a temporary pvt structure.
static int transmit_response_with_allow (struct sip_pvt *p, const char *msg, const struct sip_request *req, enum xmittype reliable)
 Append Accept header, content length before transmitting response.
static int transmit_response_with_auth (struct sip_pvt *p, const char *msg, const struct sip_request *req, const char *randdata, enum xmittype reliable, const char *header, int stale)
 Respond with authorization request.
static int transmit_response_with_date (struct sip_pvt *p, const char *msg, const struct sip_request *req)
 Append date and content length before transmitting response.
static int transmit_response_with_sdp (struct sip_pvt *p, const char *msg, const struct sip_request *req, enum xmittype reliable)
 Used for 200 OK and 183 early media.
static int transmit_response_with_t38_sdp (struct sip_pvt *p, char *msg, struct sip_request *req, int retrans)
 Used for 200 OK and 183 early media.
static int transmit_response_with_unsupported (struct sip_pvt *p, const char *msg, const struct sip_request *req, const char *unsupported)
 Transmit response, no retransmits.
static int transmit_sip_request (struct sip_pvt *p, struct sip_request *req)
 Transmit SIP request unreliably (only used in sip_notify subsystem).
static int transmit_state_notify (struct sip_pvt *p, int state, int full, int timeout)
 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.
static int unload_module (void)
 PBX unload module API.
static int update_call_counter (struct sip_pvt *fup, int event)
 update_call_counter: Handle call_limit for SIP users Setting a call-limit will cause calls above the limit not to be accepted.
static void update_peer (struct sip_peer *p, int expiry)
 Update peer data in database (if used).

Variables

static struct in_addr __ourip
static int allow_external_domains
static int apeerobjs = 0
static char * app_dtmfmode = "SIPDtmfMode"
static char * app_sipaddheader = "SIPAddHeader"
static struct sip_authauthl = NULL
static int autocreatepeer
static struct sockaddr_in bindaddr = { 0, }
static struct ast_custom_function checksipdomain_function
static struct ast_cli_entry cli_sip []
static struct ast_cli_entry cli_sip_debug_deprecated
static struct ast_cli_entry cli_sip_no_debug_deprecated
static int compactheaders
static const char config [] = "sip.conf"
static char debug_usage []
static struct sockaddr_in debugaddr
static char default_callerid [AST_MAX_EXTENSION]
static char default_context [AST_MAX_CONTEXT]
static int default_expiry = DEFAULT_DEFAULT_EXPIRY
static char default_fromdomain [AST_MAX_EXTENSION]
static struct ast_jb_conf default_jbconf
 Global jitterbuffer configuration - by default, jb is disabled.
static char default_language [MAX_LANGUAGE]
static int default_maxcallbitrate
static char default_mohinterpret [MAX_MUSICCLASS]
static char default_mohsuggest [MAX_MUSICCLASS]
static char default_notifymime [AST_MAX_EXTENSION]
static struct ast_codec_pref default_prefs
static int default_qualify
static char default_subscribecontext [AST_MAX_CONTEXT]
static char default_vmexten [AST_MAX_EXTENSION]
static char * descrip_dtmfmode = "SIPDtmfMode(inband|info|rfc2833): Changes the dtmfmode for a SIP call\n"
static char * descrip_sipaddheader
static int dumphistory
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
static int global_allowsubscribe
static enum transfermodes global_allowtransfer
static int global_alwaysauthreject
static int global_autoframing
static int global_callevents
static int global_capability = AST_FORMAT_ULAW | AST_FORMAT_ALAW | AST_FORMAT_GSM | AST_FORMAT_H263
 Codecs that we support by default:.
static int global_directrtpsetup
static struct ast_flags global_flags [2] = {{0}}
static struct ast_jb_conf global_jbconf
static int global_limitonpeers
static int global_matchexterniplocally
static int global_mwitime
static int global_notifyhold
static int global_notifyringing
static char global_realm [MAXHOSTNAMELEN]
static int global_reg_timeout
static int global_regattempts_max
static char global_regcontext [AST_MAX_CONTEXT]
static int global_relaxdtmf
static int global_rtautoclear
static int global_rtpholdtimeout
static int global_rtpkeepalive
static int global_rtptimeout
static int global_t1min
static int global_t38_capability = T38FAX_VERSION_0 | T38FAX_RATE_2400 | T38FAX_RATE_4800 | T38FAX_RATE_7200 | T38FAX_RATE_9600
static unsigned int global_tos_audio
static unsigned int global_tos_sip
static unsigned int global_tos_video
static char global_useragent [AST_MAX_EXTENSION]
static char history_usage []
static struct sip_pvtiflist
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 int min_expiry = DEFAULT_MIN_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 char no_debug_usage []
static char no_history_usage []
static const char notify_config [] = "sip_notify.conf"
static struct ast_confignotify_types
static char notify_usage []
static int ourport
static struct sockaddr_in outboundproxyip
static int pedanticsipchecking
static struct ast_peer_list peerl
static char prune_realtime_usage []
static int recordhistory
static struct c_referstatusstring referstatusstrings []
static struct ast_register_list regl
static int regobjs = 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
static struct cfsip_methods sip_methods []
static struct cfsip_options sip_options []
static char sip_reload_usage []
static int sip_reloading = FALSE
static enum channelreloadreason sip_reloadreason
static struct ast_rtp_protocol sip_rtp
 Interface structure with callbacks used to connect to RTP module.
static struct ast_channel_tech sip_tech
 Definition of this channel for PBX channel registration.
static struct ast_channel_tech sip_tech_info
 This version of the sip channel tech has no send_digit_begin callback. This is for use with channels using SIP INFO DTMF so that the core knows that the channel doesn't want DTMF BEGIN frames.
static struct ast_udptl_protocol sip_udptl
 Interface structure with callbacks used to connect to UDPTL module.
static struct ast_custom_function sipchaninfo_function
 Structure to declare a dialplan function: SIPCHANINFO.
struct ast_custom_function sippeer_function
 Structure to declare a dialplan function: SIPPEER.
static int sipsock = -1
static int * sipsock_read_id
static int speerobjs = 0
static int srvlookup
static 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 struct ast_user_list userl


Detailed Description

Implementation of Session Initiation Protocol.

Author:
Mark Spencer <markster@digium.com>
See Also: Implementation of RFC 3261 - without S/MIME, TCP and TLS support Configuration file sip.conf

Todo:
SIP over TCP
Todo:
SIP over TLS
Todo:
Better support of forking
Todo:
VIA branch tag transaction checking
Todo:
Transaction support

Overview of the handling of SIP sessions
The SIP channel handles several types of SIP sessions, or dialogs, not all of them being "telephone calls".
  • Incoming calls that will be sent to the PBX core
  • Outgoing calls, generated by the PBX
  • SIP subscriptions and notifications of states and voicemail messages
  • SIP registrations, both inbound and outbound
  • SIP peer management (peerpoke, OPTIONS)
  • SIP text messages
In the SIP channel, there's a list of active SIP dialogs, which includes all of these when they are active. "sip show channels" in the CLI will show most of these, excluding subscriptions which are shown by "sip show subscriptions"

incoming packets
Incoming packets are received in the monitoring thread, then handled by sipsock_read(). This function parses the packet and matches an existing dialog or starts a new SIP dialog.
sipsock_read sends the packet to handle_request(), that parses a bit more. if it's a response to an outbound request, it's sent to handle_response(). If it is a request, handle_request sends it to one of a list of functions depending on the request type - INVITE, OPTIONS, REFER, BYE, CANCEL etc sipsock_read locks the ast_channel if it exists (an active call) and unlocks it after we have processed the SIP message.

A new INVITE is sent to handle_request_invite(), that will end up starting a new channel in the PBX, the new channel after that executing in a separate channel thread. This is an incoming "call". When the call is answered, either by a bridged channel or the PBX itself the sip_answer() function is called.

The actual media - Video or Audio - is mostly handled by the RTP subsystem in rtp.c

Outbound calls
Outbound calls are set up by the PBX through the sip_request_call() function. After that, they are activated by sip_call().
Hanging up
The PBX issues a hangup on both incoming and outgoing calls through the sip_hangup() function
Deprecated stuff
This is deprecated and will be removed after the 1.4 release
  • the SIPUSERAGENT dialplan variable
  • the ALERT_INFO dialplan variable

Definition in file chan_sip.c.


Define Documentation

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

#define append_history ( p,
event,
fmt,
args...   )     append_history_full(p, "%-15s " fmt, event, ## args)

#define CALLERID_UNKNOWN   "Unknown"

Definition at line 199 of file chan_sip.c.

Referenced by initreqprep().

#define CAN_CREATE_DIALOG   1

Definition at line 368 of file chan_sip.c.

Referenced by find_call().

#define CAN_CREATE_DIALOG_UNSUPPORTED_METHOD   2

Definition at line 369 of file chan_sip.c.

Referenced by find_call().

#define CAN_NOT_CREATE_DIALOG   0

Definition at line 367 of file chan_sip.c.

#define DEC_CALL_LIMIT   0

#define DEC_CALL_RINGING   2

Definition at line 610 of file chan_sip.c.

Referenced by handle_response_invite(), and update_call_counter().

#define DEFAULT_ALLOW_EXT_DOM   TRUE

Definition at line 507 of file chan_sip.c.

Referenced by reload_config().

#define DEFAULT_ALLOWGUEST   TRUE

Definition at line 501 of file chan_sip.c.

Referenced by reload_config().

#define DEFAULT_AUTOCREATEPEER   FALSE

Definition at line 511 of file chan_sip.c.

Referenced by reload_config().

#define DEFAULT_CALLERID   "asterisk"

Definition at line 498 of file chan_sip.c.

Referenced by reload_config().

#define DEFAULT_COMPACTHEADERS   FALSE

Definition at line 503 of file chan_sip.c.

Referenced by reload_config().

#define DEFAULT_CONTEXT   "default"

Definition at line 494 of file chan_sip.c.

Referenced by reload_config().

#define DEFAULT_DEFAULT_EXPIRY   120

Definition at line 171 of file chan_sip.c.

Referenced by reload_config().

#define DEFAULT_EXPIRY   900

Expire slowly

Definition at line 188 of file chan_sip.c.

#define DEFAULT_FREQ_NOTOK   10 * 1000

Qualification: How often to check, if the host is down...

Definition at line 203 of file chan_sip.c.

#define DEFAULT_FREQ_OK   60 * 1000

Qualification: How often to check for the host to be up

Definition at line 202 of file chan_sip.c.

#define DEFAULT_MAX_CALL_BITRATE   (384)

Max bitrate for video

Definition at line 514 of file chan_sip.c.

Referenced by reload_config().

#define DEFAULT_MAX_EXPIRY   3600

Definition at line 173 of file chan_sip.c.

Referenced by reload_config().

#define DEFAULT_MAX_FORWARDS   "70"

Definition at line 175 of file chan_sip.c.

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

#define DEFAULT_MAXMS   2000

Qualification: Must be faster than 2 seconds by default

Definition at line 201 of file chan_sip.c.

#define DEFAULT_MIN_EXPIRY   60

Definition at line 172 of file chan_sip.c.

Referenced by reload_config().

#define DEFAULT_MOHINTERPRET   "default"

Definition at line 495 of file chan_sip.c.

Referenced by reload_config().

#define DEFAULT_MOHSUGGEST   ""

Definition at line 496 of file chan_sip.c.

Referenced by reload_config().

#define DEFAULT_MWITIME   10

Definition at line 500 of file chan_sip.c.

Referenced by reload_config().

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

Definition at line 499 of file chan_sip.c.

Referenced by reload_config().

#define DEFAULT_NOTIFYRINGING   TRUE

Definition at line 509 of file chan_sip.c.

Referenced by reload_config().

#define DEFAULT_PEDANTIC   FALSE

Definition at line 510 of file chan_sip.c.

Referenced by reload_config().

#define DEFAULT_QUALIFY   FALSE

Definition at line 512 of file chan_sip.c.

Referenced by reload_config().

#define DEFAULT_REALM   "asterisk"

Definition at line 508 of file chan_sip.c.

Referenced by reload_config().

#define DEFAULT_REGISTRATION_TIMEOUT   20

Definition at line 174 of file chan_sip.c.

Referenced by reload_config().

#define DEFAULT_RETRANS   1000

How frequently to retransmit Default: 2 * 500 ms in RFC 3261

Definition at line 205 of file chan_sip.c.

#define DEFAULT_SRVLOOKUP   TRUE

Recommended setting is ON

Definition at line 502 of file chan_sip.c.

Referenced by reload_config().

#define DEFAULT_T1MIN   100

100 MS for minimal roundtrip time

Definition at line 513 of file chan_sip.c.

Referenced by reload_config().

#define DEFAULT_TOS_AUDIO   0

Audio packets should be marked as DSCP EF (Expedited Forwarding), but the default is 0 to be compatible with previous versions.

Definition at line 505 of file chan_sip.c.

Referenced by reload_config().

#define DEFAULT_TOS_SIP   0

Call signalling packets should be marked as DSCP CS3, but the default is 0 to be compatible with previous versions.

Definition at line 504 of file chan_sip.c.

Referenced by reload_config().

#define DEFAULT_TOS_VIDEO   0

Video packets should be marked as DSCP AF41, but the default is 0 to be compatible with previous versions.

Definition at line 506 of file chan_sip.c.

Referenced by reload_config().

#define DEFAULT_TRANS_TIMEOUT   -1

#define DEFAULT_USERAGENT   "Asterisk PBX"

Default Useragent: header unless re-defined in sip.conf

Definition at line 516 of file chan_sip.c.

Referenced by reload_config().

#define DEFAULT_VMEXTEN   "asterisk"

Definition at line 497 of file chan_sip.c.

Referenced by reload_config().

#define EXPIRY_GUARD_LIMIT   30

Below here, we use EXPIRY_GUARD_PCT instead of EXPIRY_GUARD_SECS

Definition at line 180 of file chan_sip.c.

Referenced by handle_response_register().

#define EXPIRY_GUARD_MIN   500

This is the minimum guard time applied. If GUARD_PCT turns out to be lower than this, it will use this time instead. This is in milliseconds.

Definition at line 182 of file chan_sip.c.

Referenced by handle_response_register().

#define EXPIRY_GUARD_PCT   0.20

Percentage of expires timeout to use when below EXPIRY_GUARD_LIMIT

Definition at line 186 of file chan_sip.c.

Referenced by handle_response_register().

#define EXPIRY_GUARD_SECS   15

How long before expiry do we reregister

Definition at line 179 of file chan_sip.c.

Referenced by handle_response_register().

#define FALSE   0

Definition at line 155 of file chan_sip.c.

#define FLAG_FATAL   (1 << 1)

Definition at line 1025 of file chan_sip.c.

Referenced by __sip_reliable_xmit(), and retrans_pkt().

#define FLAG_RESPONSE   (1 << 0)

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

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

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

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

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

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

#define FORMAT2   "%-15.15s %-10.10s %-11.11s %-11.11s %-15.15s %-7.7s %-15.15s\n"

#define FORMAT2   "%-30.30s %-12.12s %8.8s %-20.20s %-25.25s\n"

#define FORMAT2   "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8s %-10s %-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 %-10.10s\n"

Referenced by __sip_show_channels().

#define INC_CALL_LIMIT   1

Definition at line 609 of file chan_sip.c.

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

#define INC_CALL_RINGING   3

Definition at line 611 of file chan_sip.c.

Referenced by sip_call(), and update_call_counter().

#define INITIAL_CSEQ   101

our initial sip sequence number

Definition at line 219 of file chan_sip.c.

Referenced by sip_alloc(), sip_register(), and transmit_response_using_temp().

#define IPTOS_MINCOST   0x02

Definition at line 166 of file chan_sip.c.

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

Definition at line 196 of file chan_sip.c.

#define MAX_AUTHTRIES   3

Try authentication three times, then fail

Definition at line 211 of file chan_sip.c.

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

#define MAX_HISTORY_ENTRIES   50

Max entires in the history list for a sip_pvt

Definition at line 1022 of file chan_sip.c.

Referenced by append_history_va().

#define MAX_RETRANS   6

Try only 6 times for retransmissions, a total of 7 transmissions

Definition at line 206 of file chan_sip.c.

#define NO_RTP   0

Definition at line 235 of file chan_sip.c.

#define NOT_SUPPORTED   0

Definition at line 408 of file chan_sip.c.

#define RTP   1

Definition at line 234 of file chan_sip.c.

#define SDP_MAX_RTPMAP_CODECS   32

Maximum number of codecs allowed in received SDP

Definition at line 217 of file chan_sip.c.

Referenced by process_sdp().

#define SDP_SAMPLE_RATE (  )     (x == AST_FORMAT_G722) ? 16000 : 8000

Definition at line 6355 of file chan_sip.c.

Referenced by add_sdp().

#define SIP_ALREADYGONE   (1 << 0)

Whether or not we've already been destroyed by our peer

Definition at line 715 of file chan_sip.c.

Referenced by handle_request(), handle_response_invite(), sip_alreadygone(), sip_hangup(), and sip_set_rtp_peer().

#define SIP_CALL_LIMIT   (1 << 28)

Call limit enforced for this call

Definition at line 756 of file chan_sip.c.

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

#define SIP_CAN_REINVITE   (1 << 20)

allow peers to be reinvited to send media directly p2p

Definition at line 744 of file chan_sip.c.

Referenced by _sip_show_peer(), handle_common_options(), reload_config(), sip_get_rtp_peer(), sip_get_udptl_peer(), sip_get_vrtp_peer(), and sip_handle_t38_reinvite().

#define SIP_CAN_REINVITE_NAT   (2 << 20)

allow media reinvite when new peer is behind NAT

Definition at line 745 of file chan_sip.c.

Referenced by handle_common_options(), sip_get_rtp_peer(), and sip_set_rtp_peer().

#define SIP_DEFER_BYE_ON_TRANSFER   (1 << 15)

Do not hangup at first ast_hangup

Definition at line 730 of file chan_sip.c.

Referenced by handle_invite_replaces(), handle_request_refer(), local_attended_transfer(), sip_hangup(), and sip_set_rtp_peer().

#define SIP_DTMF   (3 << 16)

#define SIP_DTMF_AUTO   (3 << 16)

DTMF Support: AUTO switch between rfc2833 and in-band DTMF

Definition at line 735 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)

DTMF Support: Inband audio, only for ULAW/ALAW - "inband"

Definition at line 733 of file chan_sip.c.

Referenced by dtmfmode2str(), handle_common_options(), process_sdp(), sip_dtmfmode(), sip_new(), sip_rtp_read(), sip_senddigit_begin(), and sip_senddigit_end().

#define SIP_DTMF_INFO   (2 << 16)

DTMF Support: SIP Info messages - "info"

Definition at line 734 of file chan_sip.c.

Referenced by dtmfmode2str(), handle_common_options(), sip_dtmfmode(), sip_new(), and sip_senddigit_end().

#define SIP_DTMF_RFC2833   (0 << 16)

#define SIP_FLAGS_TO_COPY

#define SIP_FREE_BIT   (1 << 14)

----

Definition at line 729 of file chan_sip.c.

#define SIP_G726_NONSTANDARD   (1 << 31)

Use non-standard packing for G726-32 data

Definition at line 759 of file chan_sip.c.

Referenced by add_codec_to_sdp(), handle_common_options(), and process_sdp().

#define SIP_GOTREFER   (1 << 7)

#define SIP_INC_COUNT   (1 << 30)

Did this connection increment the counter of in-use calls?

Definition at line 758 of file chan_sip.c.

Referenced by __sip_destroy(), handle_request_cancel(), sip_hangup(), and update_call_counter().

#define SIP_INSECURE_INVITE   (1 << 24)

don't require authentication for incoming INVITEs

Definition at line 749 of file chan_sip.c.

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

#define SIP_INSECURE_PORT   (1 << 23)

don't require matching port for incoming requests

Definition at line 748 of file chan_sip.c.

Referenced by _sip_show_peer(), handle_common_options(), realtime_peer(), set_insecure_flags(), and sip_addrcmp().

#define SIP_MAX_HEADERS   64

Max amount of SIP headers to read

Definition at line 213 of file chan_sip.c.

Referenced by add_header(), and parse_request().

#define SIP_MAX_LINES   64

Max amount of lines in SIP attachment (like SDP)

Definition at line 214 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 215 of file chan_sip.c.

#define SIP_NAT   (3 << 18)

#define SIP_NAT_ALWAYS   (3 << 18)

NAT Both ROUTE and RFC3581

Definition at line 741 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 738 of file chan_sip.c.

Referenced by handle_common_options(), and nat2str().

#define SIP_NAT_RFC3581   (1 << 18)

NAT RFC3581

Definition at line 739 of file chan_sip.c.

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

#define SIP_NAT_ROUTE   (2 << 18)

#define SIP_NEEDDESTROY   (1 << 1)

#define SIP_NEEDREINVITE   (1 << 5)

Do we need to send another reinvite?

Definition at line 720 of file chan_sip.c.

Referenced by check_pendings(), sip_handle_t38_reinvite(), sip_hangup(), sip_read(), sip_reinvite_retry(), sip_set_rtp_peer(), and sip_set_udptl_peer().

#define SIP_NO_HISTORY   (1 << 27)

#define SIP_NOVIDEO   (1 << 2)

Didn't get video in invite, don't offer

Definition at line 717 of file chan_sip.c.

Referenced by add_sdp(), process_sdp(), and sip_indicate().

#define SIP_OPT_100REL   (1 << 1)

Definition at line 411 of file chan_sip.c.

#define SIP_OPT_EARLY_SESSION   (1 << 3)

Definition at line 413 of file chan_sip.c.

#define SIP_OPT_EVENTLIST   (1 << 11)

Definition at line 421 of file chan_sip.c.

#define SIP_OPT_GRUU   (1 << 12)

Definition at line 422 of file chan_sip.c.

#define SIP_OPT_HISTINFO   (1 << 15)

Definition at line 425 of file chan_sip.c.

#define SIP_OPT_JOIN   (1 << 4)

Definition at line 414 of file chan_sip.c.

#define SIP_OPT_NOREFERSUB   (1 << 14)

Definition at line 424 of file chan_sip.c.

#define SIP_OPT_PATH   (1 << 5)

Definition at line 415 of file chan_sip.c.

#define SIP_OPT_PRECONDITION   (1 << 7)

Definition at line 417 of file chan_sip.c.

#define SIP_OPT_PREF   (1 << 6)

Definition at line 416 of file chan_sip.c.

#define SIP_OPT_PRIVACY   (1 << 8)

Definition at line 418 of file chan_sip.c.

#define SIP_OPT_REPLACES   (1 << 0)

Definition at line 410 of file chan_sip.c.

Referenced by handle_request_invite().

#define SIP_OPT_RESPRIORITY   (1 << 16)

Definition at line 426 of file chan_sip.c.

#define SIP_OPT_SDP_ANAT   (1 << 9)

Definition at line 419 of file chan_sip.c.

#define SIP_OPT_SEC_AGREE   (1 << 10)

Definition at line 420 of file chan_sip.c.

#define SIP_OPT_TARGET_DIALOG   (1 << 13)

Definition at line 423 of file chan_sip.c.

#define SIP_OPT_TIMER   (1 << 2)

Definition at line 412 of file chan_sip.c.

#define SIP_OUTGOING   (1 << 13)

#define SIP_PAGE2_ALLOWOVERLAP   (1 << 17)

Allow overlap dialing ?

Definition at line 782 of file chan_sip.c.

Referenced by _sip_show_peer(), get_destination(), handle_common_options(), handle_request_invite(), reload_config(), and sip_show_settings().

#define SIP_PAGE2_ALLOWSUBSCRIBE   (1 << 16)

Allow subscriptions from this peer?

Definition at line 781 of file chan_sip.c.

Referenced by _sip_show_peer(), build_peer(), build_user(), handle_common_options(), handle_request_subscribe(), reload_config(), and sip_show_settings().

#define SIP_PAGE2_BUGGY_MWI   (1 << 26)

26: Buggy CISCO MWI fix

Definition at line 794 of file chan_sip.c.

Referenced by handle_common_options(), and transmit_notify_with_mwi().

#define SIP_PAGE2_CALL_ONHOLD   (3 << 23)

#define SIP_PAGE2_CALL_ONHOLD_ACTIVE   (1 << 23)

23: Active hold

Definition at line 790 of file chan_sip.c.

Referenced by change_hold_state().

#define SIP_PAGE2_CALL_ONHOLD_INACTIVE   (3 << 23)

23: Inactive hold

Definition at line 792 of file chan_sip.c.

Referenced by add_sdp(), and change_hold_state().

#define SIP_PAGE2_CALL_ONHOLD_ONEDIR   (2 << 23)

23: One directional hold

Definition at line 791 of file chan_sip.c.

Referenced by add_sdp(), and change_hold_state().

#define SIP_PAGE2_DEBUG   (3 << 11)

Definition at line 775 of file chan_sip.c.

#define SIP_PAGE2_DEBUG_CONFIG   (1 << 11)

Definition at line 776 of file chan_sip.c.

Referenced by reload_config().

#define SIP_PAGE2_DEBUG_CONSOLE   (1 << 12)

#define SIP_PAGE2_DYNAMIC   (1 << 13)

Dynamic Peers register with Asterisk

Definition at line 778 of file chan_sip.c.

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

#define SIP_PAGE2_FLAGS_TO_COPY

#define SIP_PAGE2_IGNOREREGEXPIRE   (1 << 10)

Definition at line 774 of file chan_sip.c.

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

#define SIP_PAGE2_INC_RINGING   (1 << 19)

Did this connection increment the counter of in-use calls?

Definition at line 784 of file chan_sip.c.

Referenced by update_call_counter().

#define SIP_PAGE2_OUTGOING_CALL   (1 << 27)

27: Is this an outgoing call?

Definition at line 795 of file chan_sip.c.

Referenced by sip_request_call(), and update_call_counter().

#define SIP_PAGE2_RFC2833_COMPENSATE   (1 << 25)

#define SIP_PAGE2_RT_FROMCONTACT   (1 << 4)

Definition at line 771 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 770 of file chan_sip.c.

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

#define SIP_PAGE2_RTCACHEFRIENDS   (1 << 0)

#define SIP_PAGE2_RTSAVE_SYSNAME   (1 << 5)

Definition at line 772 of file chan_sip.c.

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

#define SIP_PAGE2_RTUPDATE   (1 << 1)

Definition at line 769 of file chan_sip.c.

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

#define SIP_PAGE2_SELFDESTRUCT   (1 << 14)

Automatic peers need to destruct themselves

Definition at line 779 of file chan_sip.c.

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

#define SIP_PAGE2_SUBSCRIBEMWIONLY   (1 << 18)

Only issue MWI notification if subscribed to

Definition at line 783 of file chan_sip.c.

Referenced by build_peer(), does_peer_need_mwi(), and register_verify().

#define SIP_PAGE2_T38SUPPORT   (7 << 20)

T38 Fax Passthrough Support

Definition at line 785 of file chan_sip.c.

Referenced by create_addr_from_peer(), and sip_alloc().

#define SIP_PAGE2_T38SUPPORT_RTP   (2 << 20)

21: T38 Fax Passthrough Support (not implemented)

Definition at line 787 of file chan_sip.c.

Referenced by _sip_show_peer(), add_sdp(), handle_common_options(), and sip_show_settings().

#define SIP_PAGE2_T38SUPPORT_TCP   (4 << 20)

22: T38 Fax Passthrough Support (not implemented)

Definition at line 788 of file chan_sip.c.

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

#define SIP_PAGE2_T38SUPPORT_UDPTL   (1 << 20)

20: T38 Fax Passthrough Support

Definition at line 786 of file chan_sip.c.

Referenced by _sip_show_peer(), handle_common_options(), sip_read(), sip_rtp_read(), and sip_show_settings().

#define SIP_PAGE2_VIDEOSUPPORT   (1 << 15)

#define SIP_PENDINGBYE   (1 << 6)

Need to send bye after we ack?

Definition at line 721 of file chan_sip.c.

Referenced by check_pendings(), handle_response_invite(), sip_handle_t38_reinvite(), sip_hangup(), sip_read(), sip_set_rtp_peer(), and sip_set_udptl_peer().

#define SIP_PKT_DEBUG   (1 << 0)

#define SIP_PKT_IGNORE   (1 << 2)

#define SIP_PKT_IGNORE_REQ   (1 << 4)

Req ignore - ???

Definition at line 806 of file chan_sip.c.

Referenced by handle_request().

#define SIP_PKT_IGNORE_RESP   (1 << 3)

Resp ignore - ???

Definition at line 805 of file chan_sip.c.

Referenced by handle_request().

#define SIP_PKT_WITH_TOTAG   (1 << 1)

This packet has a to-tag

Definition at line 803 of file chan_sip.c.

Referenced by find_call(), and handle_request().

#define SIP_PROG_INBAND   (3 << 25)

three settings, uses two bits

Definition at line 751 of file chan_sip.c.

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

#define SIP_PROG_INBAND_NEVER   (0 << 25)

Definition at line 752 of file chan_sip.c.

Referenced by sip_indicate(), and sip_show_settings().

#define SIP_PROG_INBAND_NO   (1 << 25)

Definition at line 753 of file chan_sip.c.

Referenced by handle_common_options(), and sip_show_settings().

#define SIP_PROG_INBAND_YES   (2 << 25)

Definition at line 754 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 719 of file chan_sip.c.

Referenced by sip_indicate(), and sip_write().

#define SIP_PROMISCREDIR   (1 << 8)

Promiscuous redirection

Definition at line 723 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)

#define SIP_REINVITE   (7 << 20)

three bits used

Definition at line 743 of file chan_sip.c.

Referenced by handle_common_options().

#define SIP_REINVITE_UPDATE   (4 << 20)

use UPDATE (RFC3311) when reinviting this peer

Definition at line 746 of file chan_sip.c.

Referenced by handle_common_options(), transmit_reinvite_with_sdp(), and transmit_reinvite_with_t38_sdp().

#define SIP_RINGING   (1 << 3)

Have sent 180 ringing

Definition at line 718 of file chan_sip.c.

Referenced by sip_indicate().

#define SIP_SENDRPID   (1 << 29)

Remote Party-ID Support

Definition at line 757 of file chan_sip.c.

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

#define SIP_TRANS_TIMEOUT   32000

SIP request timeout (rfc 3261) 64*T1

Todo:
Use known T1 for timeout (peerpoke)

Definition at line 207 of file chan_sip.c.

Referenced by sip_call(), and sip_sipredirect().

#define SIP_TRUSTRPID   (1 << 9)

Trust RPID headers?

Definition at line 724 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 727 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 725 of file chan_sip.c.

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

#define sipdebug   ast_test_flag(&global_flags[1], SIP_PAGE2_DEBUG)

#define sipdebug_config   ast_test_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONFIG)

Definition at line 835 of file chan_sip.c.

#define sipdebug_console   ast_test_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE)

Definition at line 836 of file chan_sip.c.

Referenced by sip_do_debug(), and sip_do_debug_deprecated().

#define STANDARD_SIP_PORT   5060

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

#define SUPPORTED_EXTENSIONS   "replaces"

#define T38FAX_FILL_BIT_REMOVAL   (1 << 0)

Default: 0 (unset)

Definition at line 809 of file chan_sip.c.

Referenced by add_t38_sdp(), and process_sdp().

#define T38FAX_RATE_12000   (1 << 12)

12000 bps t38FaxRate

Definition at line 828 of file chan_sip.c.

Referenced by process_sdp(), and t38_get_rate().

#define T38FAX_RATE_14400   (1 << 13)

14400 bps t38FaxRate This is default: NO MMR and JBIG trancoding, NO fill bit removal, transferredTCF TCF, UDP FEC, Version 0 and 9600 max fax rate

Definition at line 829 of file chan_sip.c.

Referenced by process_sdp(), and t38_get_rate().

#define T38FAX_RATE_2400   (1 << 8)

2400 bps t38FaxRate

Definition at line 824 of file chan_sip.c.

Referenced by process_sdp(), and t38_get_rate().

#define T38FAX_RATE_4800   (1 << 9)

4800 bps t38FaxRate

Definition at line 825 of file chan_sip.c.

Referenced by process_sdp(), and t38_get_rate().

#define T38FAX_RATE_7200   (1 << 10)

7200 bps t38FaxRate

Definition at line 826 of file chan_sip.c.

Referenced by process_sdp(), and t38_get_rate().

#define T38FAX_RATE_9600   (1 << 11)

9600 bps t38FaxRate

Definition at line 827 of file chan_sip.c.

Referenced by process_sdp(), and t38_get_rate().

#define T38FAX_RATE_MANAGEMENT_LOCAL_TCF   (1 << 3)

Unset for transferredTCF (UDPTL), set for localTCF (TPKT)

Definition at line 814 of file chan_sip.c.

Referenced by add_t38_sdp(), and process_sdp().

#define T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF   (0 << 3)

Definition at line 813 of file chan_sip.c.

Referenced by create_addr_from_peer(), process_sdp(), and sip_alloc().

#define T38FAX_TRANSCODING_JBIG   (1 << 2)

Default: 0 (unset)

Definition at line 811 of file chan_sip.c.

Referenced by add_t38_sdp(), and process_sdp().

#define T38FAX_TRANSCODING_MMR   (1 << 1)

Default: 0 (unset)

Definition at line 810 of file chan_sip.c.

Referenced by add_t38_sdp(), and process_sdp().

#define T38FAX_UDP_EC_FEC   (1 << 4)

Set for t38UDPFEC

Definition at line 817 of file chan_sip.c.

Referenced by create_addr_from_peer(), process_sdp(), and sip_alloc().

#define T38FAX_UDP_EC_NONE   (0 << 4)

two bits, if unset NO t38UDPEC field in T38 SDP

Definition at line 816 of file chan_sip.c.

Referenced by add_t38_sdp(), create_addr_from_peer(), process_sdp(), and sip_alloc().

#define T38FAX_UDP_EC_REDUNDANCY   (2 << 4)

Set for t38UDPRedundancy

Definition at line 818 of file chan_sip.c.

Referenced by add_t38_sdp(), create_addr_from_peer(), process_sdp(), and sip_alloc().

#define T38FAX_VERSION   (3 << 6)

two bits, 2 values so far, up to 4 values max

Definition at line 820 of file chan_sip.c.

Referenced by add_t38_sdp().

#define T38FAX_VERSION_0   (0 << 6)

Version 0

Definition at line 821 of file chan_sip.c.

Referenced by add_t38_sdp(), and process_sdp().

#define T38FAX_VERSION_1   (1 << 6)

Version 1

Definition at line 822 of file chan_sip.c.

Referenced by add_t38_sdp(), and process_sdp().

#define TRUE   1

Definition at line 159 of file chan_sip.c.

#define UNLINK ( element,
head,
prev   ) 

--- some list management macros.

Definition at line 1600 of file chan_sip.c.

Referenced by __sip_ack(), and __sip_destroy().

#define VIDEO_CODEC_MASK   0x1fc0000

Video codecs from H.261 thru AST_FORMAT_MAX_VIDEO

Definition at line 164 of file chan_sip.c.

#define XMIT_ERROR   -2


Enumeration Type Documentation

Authentication result from check_auth* functions.

Enumerator:
AUTH_SUCCESSFUL 
AUTH_CHALLENGE_SENT 
AUTH_SECRET_FAILED 
AUTH_USERNAME_MISMATCH 
AUTH_NOT_FOUND 
AUTH_FAKE_AUTH 
AUTH_UNKNOWN_DOMAIN 
AUTH_PEER_NOT_DYNAMIC 
AUTH_ACL_FAILED 

Definition at line 343 of file chan_sip.c.

00343                        {
00344    AUTH_SUCCESSFUL = 0,
00345    AUTH_CHALLENGE_SENT = 1,
00346    AUTH_SECRET_FAILED = -1,
00347    AUTH_USERNAME_MISMATCH = -2,
00348    AUTH_NOT_FOUND = -3,
00349    AUTH_FAKE_AUTH = -4,
00350    AUTH_UNKNOWN_DOMAIN = -5,
00351    AUTH_PEER_NOT_DYNAMIC = -6,
00352    AUTH_ACL_FAILED = -7,
00353 };

Modes for SIP domain handling in the PBX.

Enumerator:
SIP_DOMAIN_AUTO  This domain is auto-configured
SIP_DOMAIN_CONFIG  This domain is from configuration

Definition at line 678 of file chan_sip.c.

00678                  {
00679    SIP_DOMAIN_AUTO,     /*!< This domain is auto-configured */
00680    SIP_DOMAIN_CONFIG,      /*!< This domain is from configuration */
00681 };

States for the INVITE transaction, not the dialog.

Note:
this is for the INVITE that sets up the dialog
Enumerator:
INV_NONE  No state at all, maybe not an INVITE dialog
INV_CALLING  Invite sent, no answer
INV_PROCEEDING  We got/sent 1xx message
INV_EARLY_MEDIA  We got 18x message with to-tag back
INV_COMPLETED  Got final response with error. Wait for ACK, then CONFIRMED
INV_CONFIRMED  Confirmed response - we've got an ack (Incoming calls only)
INV_TERMINATED  Transaction done - either successful (AST_STATE_UP) or failed, but done The only way out of this is a BYE from one side
INV_CANCELLED  Transaction cancelled by client or server in non-terminated state

Definition at line 254 of file chan_sip.c.

00254                   {
00255    INV_NONE = 0,          /*!< No state at all, maybe not an INVITE dialog */
00256    INV_CALLING = 1,  /*!< Invite sent, no answer */
00257    INV_PROCEEDING = 2,  /*!< We got/sent 1xx message */
00258    INV_EARLY_MEDIA = 3,    /*!< We got 18x message with to-tag back */
00259    INV_COMPLETED = 4,   /*!< Got final response with error. Wait for ACK, then CONFIRMED */
00260    INV_CONFIRMED = 5,   /*!< Confirmed response - we've got an ack (Incoming calls only) */
00261    INV_TERMINATED = 6,  /*!< Transaction done - either successful (AST_STATE_UP) or failed, but done 
00262                     The only way out of this is a BYE from one side */
00263    INV_CANCELLED = 7,   /*!< Transaction cancelled by client or server in non-terminated state */
00264 };

Enumerator:
PARSE_REGISTER_FAILED 
PARSE_REGISTER_UPDATE 
PARSE_REGISTER_QUERY 

Definition at line 281 of file chan_sip.c.

Parameters to know status of transfer.

Enumerator:
REFER_IDLE  No REFER is in progress
REFER_SENT  Sent REFER to transferee
REFER_RECEIVED  Received REFER from transferer
REFER_CONFIRMED  Refer confirmed with a 100 TRYING
REFER_ACCEPTED  Accepted by transferee
REFER_RINGING  Target Ringing
REFER_200OK  Answered by transfer target
REFER_FAILED  REFER declined - go on
REFER_NOAUTH  We had no auth for REFER

Definition at line 858 of file chan_sip.c.

00858                  {
00859         REFER_IDLE,                    /*!< No REFER is in progress */
00860         REFER_SENT,                    /*!< Sent REFER to transferee */
00861         REFER_RECEIVED,                /*!< Received REFER from transferer */
00862         REFER_CONFIRMED,               /*!< Refer confirmed with a 100 TRYING */
00863         REFER_ACCEPTED,                /*!< Accepted by transferee */
00864         REFER_RINGING,                 /*!< Target Ringing */
00865         REFER_200OK,                   /*!< Answered by transfer target */
00866         REFER_FAILED,                  /*!< REFER declined - go on */
00867         REFER_NOAUTH                   /*!< We had no auth for REFER */
00868 };

Authentication types - proxy or www authentication.

Note:
Endpoints, like Asterisk, should always use WWW authentication to allow multiple authentications in the same call - to the proxy and to the end point.
Enumerator:
PROXY_AUTH 
WWW_AUTH 

Definition at line 337 of file chan_sip.c.

00337                    {
00338    PROXY_AUTH,
00339    WWW_AUTH,
00340 };

enum sip_result

Enumerator:
AST_SUCCESS 
AST_FAILURE 

Definition at line 246 of file chan_sip.c.

00246                 {
00247    AST_SUCCESS = 0,
00248    AST_FAILURE = -1,
00249 };

enum sipmethod

SIP Request methods known by Asterisk.

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 
SIP_PING 

Definition at line 312 of file chan_sip.c.

00312                {
00313    SIP_UNKNOWN,      /* Unknown response */
00314    SIP_RESPONSE,     /* Not request, response to outbound request */
00315    SIP_REGISTER,
00316    SIP_OPTIONS,
00317    SIP_NOTIFY,
00318    SIP_INVITE,
00319    SIP_ACK,
00320    SIP_PRACK,     /* Not supported at all */
00321    SIP_BYE,
00322    SIP_REFER,
00323    SIP_SUBSCRIBE,
00324    SIP_MESSAGE,
00325    SIP_UPDATE,    /* We can send UPDATE; but not accept it */
00326    SIP_INFO,
00327    SIP_CANCEL,
00328    SIP_PUBLISH,      /* Not supported at all */
00329    SIP_PING,      /* Not supported at all, no standard but still implemented out there */
00330 };

States for outbound registrations (with register= lines in sip.conf.

Enumerator:
REG_STATE_UNREGISTERED  We are not registred
REG_STATE_REGSENT  Registration request sent
REG_STATE_AUTHSENT  We have tried to authenticate
REG_STATE_REGISTERED  Registred and done
REG_STATE_REJECTED  Registration rejected
REG_STATE_TIMEOUT  Registration timed out
REG_STATE_NOAUTH  We have no accepted credentials
REG_STATE_FAILED  Registration failed after several tries

Definition at line 356 of file chan_sip.c.

00356                       {
00357    REG_STATE_UNREGISTERED = 0,   /*!< We are not registred */
00358    REG_STATE_REGSENT,   /*!< Registration request sent */
00359    REG_STATE_AUTHSENT,  /*!< We have tried to authenticate */
00360    REG_STATE_REGISTERED,   /*!< Registred and done */
00361    REG_STATE_REJECTED,  /*!< Registration rejected */
00362    REG_STATE_TIMEOUT,   /*!< Registration timed out */
00363    REG_STATE_NOAUTH, /*!< We have no accepted credentials */
00364    REG_STATE_FAILED, /*!< Registration failed after several tries */
00365 };

Enumerator:
NONE 
XPIDF_XML 
DIALOG_INFO_XML 
CPIM_PIDF_XML 
PIDF_XML 
MWI_NOTIFICATION 

Definition at line 287 of file chan_sip.c.

00287                       { 
00288    NONE = 0,
00289    XPIDF_XML,
00290    DIALOG_INFO_XML,
00291    CPIM_PIDF_XML,
00292    PIDF_XML,
00293    MWI_NOTIFICATION
00294 };

enum t38state

T38 States for a call.

Enumerator:
T38_DISABLED  Not enabled
T38_LOCAL_DIRECT  Offered from local
T38_LOCAL_REINVITE  Offered from local - REINVITE
T38_PEER_DIRECT  Offered from peer
T38_PEER_REINVITE  Offered from peer - REINVITE
T38_ENABLED  Negotiated (enabled)

Definition at line 839 of file chan_sip.c.

00839               {
00840         T38_DISABLED = 0,                /*!< Not enabled */
00841         T38_LOCAL_DIRECT,                /*!< Offered from local */
00842         T38_LOCAL_REINVITE,              /*!< Offered from local - REINVITE */
00843         T38_PEER_DIRECT,                 /*!< Offered from peer */
00844         T38_PEER_REINVITE,               /*!< Offered from peer - REINVITE */
00845         T38_ENABLED                      /*!< Negotiated (enabled) */
00846 };

Authorization scheme for call transfers.

Note:
Not a bitfield flag, since there are plans for other modes, like "only allow transfers for authenticated devices"
Enumerator:
TRANSFER_OPENFORALL  Allow all SIP transfers
TRANSFER_CLOSED  Allow no SIP transfers

Definition at line 240 of file chan_sip.c.

00240                    {
00241    TRANSFER_OPENFORALL,            /*!< Allow all SIP transfers */
00242    TRANSFER_CLOSED,                /*!< Allow no SIP transfers */
00243 };

enum xmittype

Enumerator:
XMIT_CRITICAL  Transmit critical SIP message reliably, with re-transmits. If it fails, it's critical and will cause a teardown of the session
XMIT_RELIABLE  Transmit SIP message reliably, with re-transmits
XMIT_UNRELIABLE  Transmit SIP message without bothering with re-transmits

Definition at line 274 of file chan_sip.c.

00274               {
00275    XMIT_CRITICAL = 2,              /*!< Transmit critical SIP message reliably, with re-transmits.
00276                                               If it fails, it's critical and will cause a teardown of the session */
00277    XMIT_RELIABLE = 1,              /*!< Transmit SIP message reliably, with re-transmits */
00278    XMIT_UNRELIABLE = 0,            /*!< Transmit SIP message without bothering with re-transmits */
00279 };


Function Documentation

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

Definition at line 4202 of file chan_sip.c.

References find_alias(), sip_request::header, sip_request::headers, and len.

04203 {
04204    int pass;
04205 
04206    /*
04207     * Technically you can place arbitrary whitespace both before and after the ':' in
04208     * a header, although RFC3261 clearly says you shouldn't before, and place just
04209     * one afterwards.  If you shouldn't do it, what absolute idiot decided it was 
04210     * a good idea to say you can do it, and if you can do it, why in the hell would.
04211     * you say you shouldn't.
04212     * Anyways, pedanticsipchecking controls whether we allow spaces before ':',
04213     * and we always allow spaces after that for compatibility.
04214     */
04215    for (pass = 0; name && pass < 2;pass++) {
04216       int x, len = strlen(name);
04217       for (x=*start; x<req->headers; x++) {
04218          if (!strncasecmp(req->header[x], name, len)) {
04219             char *r = req->header[x] + len;  /* skip name */
04220             if (pedanticsipchecking)
04221                r = ast_skip_blanks(r);
04222 
04223             if (*r == ':') {
04224                *start = x+1;
04225                return ast_skip_blanks(r+1);
04226             }
04227          }
04228       }
04229       if (pass == 0) /* Try aliases */
04230          name = find_alias(name, NULL);
04231    }
04232 
04233    /* Don't return NULL, so get_header is always a valid pointer */
04234    return "";
04235 }

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

Acknowledges receipt of a packet and stops retransmission.

Definition at line 2137 of file chan_sip.c.

References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_del(), ast_test_flag, sip_pkt::data, FALSE, FLAG_RESPONSE, free, sip_pvt::lock, LOG_DEBUG, sip_pkt::next, option_debug, sip_pvt::packets, sip_pvt::pendinginvite, sip_pkt::retransid, sip_pkt::seqno, sip_methods, sipdebug, cfsip_methods::text, TRUE, and UNLINK.

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

02138 {
02139    struct sip_pkt *cur, *prev = NULL;
02140 
02141    /* Just in case... */
02142    char *msg;
02143    int res = FALSE;
02144 
02145    msg = sip_methods[sipmethod].text;
02146 
02147    ast_mutex_lock(&p->lock);
02148    for (cur = p->packets; cur; prev = cur, cur = cur->next) {
02149       if ((cur->seqno == seqno) && ((ast_test_flag(cur, FLAG_RESPONSE)) == resp) &&
02150          ((ast_test_flag(cur, FLAG_RESPONSE)) || 
02151           (!strncasecmp(msg, cur->data, strlen(msg)) && (cur->data[strlen(msg)] < 33)))) {
02152          if (!resp && (seqno == p->pendinginvite)) {
02153             if (option_debug)
02154                ast_log(LOG_DEBUG, "Acked pending invite %d\n", p->pendinginvite);
02155             p->pendinginvite = 0;
02156          }
02157          /* this is our baby */
02158          res = TRUE;
02159          UNLINK(cur, p->packets, prev);
02160          if (cur->retransid > -1) {
02161             if (sipdebug && option_debug > 3)
02162                ast_log(LOG_DEBUG, "** SIP TIMER: Cancelling retransmit of packet (reply received) Retransid #%d\n", cur->retransid);
02163             ast_sched_del(sched, cur->retransid);
02164             cur->retransid = -1;
02165          }
02166          free(cur);
02167          break;
02168       }
02169    }
02170    ast_mutex_unlock(&p->lock);
02171    if (option_debug)
02172       ast_log(LOG_DEBUG, "Stopping retransmission on '%s' of %s %d: Match %s\n", p->callid, resp ? "Response" : "Request", seqno, res ? "Not Found" : "Found");
02173 }

static int __sip_autodestruct ( const void *  data  )  [static]

Kill a SIP dialog (called by scheduler).

Definition at line 2063 of file chan_sip.c.

References append_history, AST_EXTENSION_DEACTIVATED, ast_log(), ast_queue_hangup(), ASTOBJ_UNREF, sip_pvt::autokillid, DEFAULT_TRANS_TIMEOUT, LOG_DEBUG, LOG_WARNING, sip_pvt::method, MWI_NOTIFICATION, NONE, option_debug, sip_pvt::owner, sip_pvt::packets, sip_pvt::refer, sip_pvt::relatedpeer, SIP_BYE, sip_destroy(), sip_destroy_peer(), sip_methods, sip_scheddestroy(), sip_pvt::subscribed, cfsip_methods::text, transmit_request_with_auth(), transmit_state_notify(), TRUE, and XMIT_RELIABLE.

Referenced by sip_scheddestroy().

02064 {
02065    struct sip_pvt *p = (struct sip_pvt *)data;
02066 
02067    /* If this is a subscription, tell the phone that we got a timeout */
02068    if (p->subscribed) {
02069       transmit_state_notify(p, AST_EXTENSION_DEACTIVATED, 1, TRUE);  /* Send last notification */
02070       p->subscribed = NONE;
02071       append_history(p, "Subscribestatus", "timeout");
02072       if (option_debug > 2)
02073          ast_log(LOG_DEBUG, "Re-scheduled destruction of SIP subsription %s\n", p->callid ? p->callid : "<unknown>");
02074       return 10000;  /* Reschedule this destruction so that we know that it's gone */
02075    }
02076 
02077    /* If there are packets still waiting for delivery, delay the destruction */
02078    if (p->packets) {
02079       if (option_debug > 2)
02080          ast_log(LOG_DEBUG, "Re-scheduled destruction of SIP call %s\n", p->callid ? p->callid : "<unknown>");
02081       append_history(p, "ReliableXmit", "timeout");
02082       return 10000;
02083    }
02084 
02085    /* If we're destroying a subscription, dereference peer object too */
02086    if (p->subscribed == MWI_NOTIFICATION && p->relatedpeer)
02087       ASTOBJ_UNREF(p->relatedpeer,sip_destroy_peer);
02088 
02089    /* Reset schedule ID */
02090    p->autokillid = -1;
02091 
02092    if (option_debug)
02093       ast_log(LOG_DEBUG, "Auto destroying SIP dialog '%s'\n", p->callid);
02094    append_history(p, "AutoDestroy", "%s", p->callid);
02095    if (p->owner) {
02096       ast_log(LOG_WARNING, "Autodestruct on dialog '%s' with owner in place (Method: %s)\n", p->callid, sip_methods[p->method].text);
02097       ast_queue_hangup(p->owner);
02098    } else if (p->refer) {
02099       if (option_debug > 2)
02100          ast_log(LOG_DEBUG, "Finally hanging up channel after transfer: %s\n", p->callid);
02101       transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, 1);
02102       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
02103    } else
02104       sip_destroy(p);
02105    return 0;
02106 }

static void __sip_destroy ( struct sip_pvt p,
int  lockowner 
) [static]

Execute destruction of SIP dialog structure, release memory.

Definition at line 3051 of file chan_sip.c.

References ast_channel_lock, ast_channel_unlock, ast_extension_state_del(), AST_LIST_REMOVE_HEAD, ast_log(), ast_mutex_destroy(), ast_rtp_destroy(), ast_sched_del(), ast_string_field_free_memory, ast_test_flag, ast_udptl_destroy(), ast_variables_destroy(), ast_verbose(), ASTOBJ_UNREF, sip_pvt::autokillid, sip_registry::call, sip_pvt::chanvars, DEC_CALL_LIMIT, sip_pvt::flags, free, free_old_route(), sip_pvt::history, sip_pvt::history_entries, iflist, sip_pvt::initid, sip_pvt::lock, LOG_DEBUG, LOG_WARNING, sip_pvt::method, sip_peer::mwipvt, sip_pkt::next, sip_pvt::next, option_debug, sip_pvt::options, sip_pvt::owner, sip_pvt::packets, sip_pvt::refer, sip_pvt::registry, sip_pvt::relatedpeer, sip_pkt::retransid, sip_pvt::route, sip_pvt::rtp, sip_debug_test_pvt(), sip_dump_history(), SIP_INC_COUNT, sip_methods, SIP_PAGE2_CALL_ONHOLD, sip_registry_destroy(), sip_pvt::stateid, ast_channel::tech_pvt, cfsip_methods::text, sip_pvt::udptl, UNLINK, update_call_counter(), sip_pvt::vrtp, and sip_pvt::waitid.

Referenced by do_monitor(), sip_destroy(), and unload_module().

03052 {
03053    struct sip_pvt *cur, *prev = NULL;
03054    struct sip_pkt *cp;
03055 
03056    if (sip_debug_test_pvt(p) || option_debug > 2)
03057       ast_verbose("Really destroying SIP dialog '%s' Method: %s\n", p->callid, sip_methods[p->method].text);
03058 
03059    if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) {
03060       update_call_counter(p, DEC_CALL_LIMIT);
03061       if (option_debug > 1)
03062          ast_log(LOG_DEBUG, "This call did not properly clean up call limits. Call ID %s\n", p->callid);
03063    }
03064 
03065    /* Remove link from peer to subscription of MWI */
03066    if (p->relatedpeer && p->relatedpeer->mwipvt)
03067       p->relatedpeer->mwipvt = NULL;
03068 
03069    if (dumphistory)
03070       sip_dump_history(p);
03071 
03072    if (p->options)
03073       free(p->options);
03074 
03075    if (p->stateid > -1)
03076       ast_extension_state_del(p->stateid, NULL);
03077    if (p->initid > -1)
03078       ast_sched_del(sched, p->initid);
03079    if (p->waitid > -1)
03080       ast_sched_del(sched, p->waitid);
03081    if (p->autokillid > -1)
03082       ast_sched_del(sched, p->autokillid);
03083 
03084    if (p->rtp)
03085       ast_rtp_destroy(p->rtp);
03086    if (p->vrtp)
03087       ast_rtp_destroy(p->vrtp);
03088    if (p->udptl)
03089       ast_udptl_destroy(p->udptl);
03090    if (p->refer)
03091       free(p->refer);
03092    if (p->route) {
03093       free_old_route(p->route);
03094       p->route = NULL;
03095    }
03096    if (p->registry) {
03097       if (p->registry->call == p)
03098          p->registry->call = NULL;
03099       ASTOBJ_UNREF(p->registry, sip_registry_destroy);
03100    }
03101 
03102    /* Unlink us from the owner if we have one */
03103    if (p->owner) {
03104       if (lockowner)
03105          ast_channel_lock(p->owner);
03106       if (option_debug)
03107          ast_log(LOG_DEBUG, "Detaching from %s\n", p->owner->name);
03108       p->owner->tech_pvt = NULL;
03109       if (lockowner)
03110          ast_channel_unlock(p->owner);
03111    }
03112    /* Clear history */
03113    if (p->history) {
03114       struct sip_history *hist;
03115       while ( (hist = AST_LIST_REMOVE_HEAD(p->history, list)) ) {
03116          free(hist);
03117          p->history_entries--;
03118       }
03119       free(p->history);
03120       p->history = NULL;
03121    }
03122 
03123    for (prev = NULL, cur = iflist; cur; prev = cur, cur = cur->next) {
03124       if (cur == p) {
03125          UNLINK(cur, iflist, prev);
03126          break;
03127       }
03128    }
03129    if (!cur) {
03130       ast_log(LOG_WARNING, "Trying to destroy \"%s\", not found in dialog list?!?! \n", p->callid);
03131       return;
03132    } 
03133 
03134    /* remove all current packets in this dialog */
03135    while((cp = p->packets)) {
03136       p->packets = p->packets->next;
03137       if (cp->retransid > -1)
03138          ast_sched_del(sched, cp->retransid);
03139       free(cp);
03140    }
03141    if (p->chanvars) {
03142       ast_variables_destroy(p->chanvars);
03143       p->chanvars = NULL;
03144    }
03145    ast_mutex_destroy(&p->lock);
03146 
03147    ast_string_field_free_memory(p);
03148 
03149    free(p);
03150 }

static int __sip_do_register ( struct sip_registry r  )  [static]

Register with SIP proxy.

Definition at line 7409 of file chan_sip.c.

References SIP_REGISTER, and transmit_register().

Referenced by sip_reregister().

07410 {
07411    int res;
07412 
07413    res = transmit_register(r, SIP_REGISTER, NULL, NULL);
07414    return res;
07415 }

static void __sip_pretend_ack ( struct sip_pvt p  )  [static]

Pretend to ack all packets maybe the lock on p is not strictly necessary but there might be a race.

Definition at line 2177 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, sip_methods, and cfsip_methods::text.

Referenced by handle_request_cancel(), sip_hangup(), and sip_reg_timeout().

02178 {
02179    struct sip_pkt *cur = NULL;
02180 
02181    while (p->packets) {
02182       int method;
02183       if (cur == p->packets) {
02184          ast_log(LOG_WARNING, "Have a packet that doesn't want to give up! %s\n", sip_methods[cur->method].text);
02185          return;
02186       }
02187       cur = p->packets;
02188       method = (cur->method) ? cur->method : find_sip_method(cur->data);
02189       __sip_ack(p, cur->seqno, ast_test_flag(cur, FLAG_RESPONSE), method);
02190    }
02191 }

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

Transmit packet with retransmits.

Returns:
0 on success, -1 on failure to allocate packet

Definition at line 2017 of file chan_sip.c.

References __sip_xmit(), append_history, ast_calloc, AST_FAILURE, ast_log(), ast_sched_add_variable(), ast_sched_del(), ast_set_flag, AST_SUCCESS, ast_test_flag, sip_pkt::data, DEFAULT_RETRANS, FLAG_FATAL, FLAG_RESPONSE, LOG_DEBUG, sip_pkt::method, sip_pkt::next, option_debug, sip_pkt::owner, sip_pkt::packetlen, sip_pvt::packets, sip_pvt::pendinginvite, retrans_pkt(), sip_pkt::retransid, sip_pkt::seqno, SIP_INVITE, sipdebug, sip_pvt::timer_t1, sip_pkt::timer_t1, and XMIT_ERROR.

Referenced by send_request(), and send_response().

02018 {
02019    struct sip_pkt *pkt;
02020    int siptimer_a = DEFAULT_RETRANS;
02021    int xmitres = 0;
02022 
02023    if (!(pkt = ast_calloc(1, sizeof(*pkt) + len + 1)))
02024       return AST_FAILURE;
02025    memcpy(pkt->data, data, len);
02026    pkt->method = sipmethod;
02027    pkt->packetlen = len;
02028    pkt->next = p->packets;
02029    pkt->owner = p;
02030    pkt->seqno = seqno;
02031    if (resp)
02032       ast_set_flag(pkt, FLAG_RESPONSE);
02033    pkt->data[len] = '\0';
02034    pkt->timer_t1 = p->timer_t1;  /* Set SIP timer T1 */
02035    if (fatal)
02036       ast_set_flag(pkt, FLAG_FATAL);
02037    if (pkt->timer_t1)
02038       siptimer_a = pkt->timer_t1 * 2;
02039 
02040    /* Schedule retransmission */
02041    pkt->retransid = ast_sched_add_variable(sched, siptimer_a, retrans_pkt, pkt, 1);
02042    if (option_debug > 3 && sipdebug)
02043       ast_log(LOG_DEBUG, "*** SIP TIMER: Initializing retransmit timer on packet: Id  #%d\n", pkt->retransid);
02044    pkt->next = p->packets;
02045    p->packets = pkt;
02046    if (sipmethod == SIP_INVITE) {
02047       /* Note this is a pending invite */
02048       p->pendinginvite = seqno;
02049    }
02050 
02051    xmitres = __sip_xmit(pkt->owner, pkt->data, pkt->packetlen);   /* Send packet */
02052 
02053    if (xmitres == XMIT_ERROR) {  /* Serious network trouble, no need to try again */
02054       append_history(pkt->owner, "XmitErr", "%s", (ast_test_flag(pkt, FLAG_FATAL)) ? "(Critical)" : "(Non-critical)");
02055       ast_sched_del(sched, pkt->retransid);  /* No more retransmission */
02056       pkt->retransid = -1;
02057       return AST_FAILURE;
02058    } else
02059       return AST_SUCCESS;
02060 }

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

Acks receipt of packet, keep it around (used for provisional responses).

Definition at line 2194 of file chan_sip.c.

References ast_log(), ast_sched_del(), ast_test_flag, sip_pkt::data, FLAG_RESPONSE, LOG_DEBUG, method_match(), sip_pkt::next, option_debug, sip_pvt::packets, sip_pkt::retransid, sip_pkt::seqno, sip_methods, sipdebug, and cfsip_methods::text.

Referenced by handle_response().

02195 {
02196    struct sip_pkt *cur;
02197    int res = -1;
02198 
02199    for (cur = p->packets; cur; cur = cur->next) {
02200       if (cur->seqno == seqno && ast_test_flag(cur, FLAG_RESPONSE) == resp &&
02201          (ast_test_flag(cur, FLAG_RESPONSE) || method_match(sipmethod, cur->data))) {
02202          /* this is our baby */
02203          if (cur->retransid > -1) {
02204             if (option_debug > 3 && sipdebug)
02205                ast_log(LOG_DEBUG, "*** SIP TIMER: Cancelling retransmission #%d - %s (got response)\n", cur->retransid, sip_methods[sipmethod].text);
02206             ast_sched_del(sched, cur->retransid);
02207             cur->retransid = -1;
02208          }
02209          res = 0;
02210          break;
02211       }
02212    }
02213    if (option_debug)
02214       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");
02215    return res;
02216 }

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

SIP show channels CLI (main function).

Definition at line 10712 of file chan_sip.c.

References ast_cli(), ast_extension_state2str(), ast_getformatname_multiple(), ast_inet_ntoa(), ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, sip_pvt::flags, FORMAT, FORMAT2, FORMAT3, sip_pvt::icseq, iflist, sip_pvt::lastmsg, sip_pvt::laststate, sip_peer::mailbox, MWI_NOTIFICATION, ast_channel::nativeformats, sip_pvt::next, NONE, sip_pvt::ocseq, sip_pvt::owner, sip_pvt::refer, referstatus2str(), sip_pvt::relatedpeer, RESULT_SHOWUSAGE, RESULT_SUCCESS, S_OR, sip_pvt::sa, SIP_NEEDDESTROY, SIP_PAGE2_CALL_ONHOLD, sip_refer::status, sip_pvt::subscribed, and subscription_type2str().

Referenced by sip_show_channels(), and sip_show_subscriptions().

10713 {
10714 #define FORMAT3 "%-15.15s  %-10.10s  %-11.11s  %-15.15s  %-13.13s  %-15.15s %-10.10s\n"
10715 #define FORMAT2 "%-15.15s  %-10.10s  %-11.11s  %-11.11s  %-15.15s  %-7.7s  %-15.15s\n"
10716 #define FORMAT  "%-15.15s  %-10.10s  %-11.11s  %5.5d/%5.5d  %-15.15s  %-3.3s %-3.3s  %-15.15s %-10.10s\n"
10717    struct sip_pvt *cur;
10718    int numchans = 0;
10719    char *referstatus = NULL;
10720 
10721    if (argc != 3)
10722       return RESULT_SHOWUSAGE;
10723    ast_mutex_lock(&iflock);
10724    cur = iflist;
10725    if (!subscriptions)
10726       ast_cli(fd, FORMAT2, "Peer", "User/ANR", "Call ID", "Seq (Tx/Rx)", "Format", "Hold", "Last Message");
10727    else 
10728       ast_cli(fd, FORMAT3, "Peer", "User", "Call ID", "Extension", "Last state", "Type", "Mailbox");
10729    for (; cur; cur = cur->next) {
10730       referstatus = "";
10731       if (cur->refer) { /* SIP transfer in progress */
10732          referstatus = referstatus2str(cur->refer->status);
10733       }
10734       if (cur->subscribed == NONE && !subscriptions) {
10735          char formatbuf[BUFSIZ/2];
10736          ast_cli(fd, FORMAT, ast_inet_ntoa(cur->sa.sin_addr), 
10737             S_OR(cur->username, S_OR(cur->cid_num, "(None)")),
10738             cur->callid, 
10739             cur->ocseq, cur->icseq,
10740             ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->owner ? cur->owner->nativeformats : 0),
10741             ast_test_flag(&cur->flags[1], SIP_PAGE2_CALL_ONHOLD) ? "Yes" : "No",
10742             ast_test_flag(&cur->flags[0], SIP_NEEDDESTROY) ? "(d)" : "",
10743             cur->lastmsg ,
10744             referstatus
10745          );
10746          numchans++;
10747       }
10748       if (cur->subscribed != NONE && subscriptions) {
10749          ast_cli(fd, FORMAT3, ast_inet_ntoa(cur->sa.sin_addr),
10750             S_OR(cur->username, S_OR(cur->cid_num, "(None)")), 
10751                cur->callid,
10752             /* the 'complete' exten/context is hidden in the refer_to field for subscriptions */
10753             cur->subscribed == MWI_NOTIFICATION ? "--" : cur->subscribeuri,
10754             cur->subscribed == MWI_NOTIFICATION ? "<none>" : ast_extension_state2str(cur->laststate), 
10755             subscription_type2str(cur->subscribed),
10756             cur->subscribed == MWI_NOTIFICATION ? (cur->relatedpeer ? cur->relatedpeer->mailbox : "<none>") : "<none>"
10757 );
10758          numchans++;
10759       }
10760    }
10761    ast_mutex_unlock(&iflock);
10762    if (!subscriptions)
10763       ast_cli(fd, "%d active SIP channel%s\n", numchans, (numchans != 1) ? "s" : "");
10764    else
10765       ast_cli(fd, "%d active SIP subscription%s\n", numchans, (numchans != 1) ? "s" : "");
10766    return RESULT_SUCCESS;
10767 #undef FORMAT
10768 #undef FORMAT2
10769 #undef FORMAT3
10770 }

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

Transmit SIP message.

Definition at line 1767 of file chan_sip.c.

References ast_inet_ntoa(), ast_log(), errno, LOG_WARNING, sip_real_dst(), sipsock, and XMIT_ERROR.

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

01768 {
01769    int res;
01770    const struct sockaddr_in *dst = sip_real_dst(p);
01771    res = sendto(sipsock, data, len, 0, (const struct sockaddr *)dst, sizeof(struct sockaddr_in));
01772 
01773    if (res == -1) {
01774       switch (errno) {
01775          case EBADF:       /* Bad file descriptor - seems like this is generated when the host exist, but doesn't accept the UDP packet */
01776          case EHOSTUNREACH:   /* Host can't be reached */
01777          case ENETDOWN:       /* Inteface down */
01778          case ENETUNREACH: /* Network failure */
01779             res = XMIT_ERROR; /* Don't bother with trying to transmit again */
01780       }
01781    }
01782    if (res != len)
01783       ast_log(LOG_WARNING, "sip_xmit of %p (len %d) to %s:%d returned %d: %s\n", data, len, ast_inet_ntoa(dst->sin_addr), ntohs(dst->sin_port), res, strerror(errno));
01784    return res;
01785 }

static int __transmit_response ( struct sip_pvt p,
const char *  msg,
const struct sip_request req,
enum xmittype  reliable 
) [static]

Base transmit response function.

Definition at line 5955 of file chan_sip.c.

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

Referenced by transmit_response(), transmit_response_reliable(), and transmit_response_using_temp().

05956 {
05957    struct sip_request resp;
05958    int seqno = 0;
05959 
05960    if (reliable && (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1)) {
05961       ast_log(LOG_WARNING, "Unable to determine sequence number from '%s'\n", get_header(req, "CSeq"));
05962       return -1;
05963    }
05964    respprep(&resp, p, msg, req);
05965    add_header_contentLength(&resp, 0);
05966    /* If we are cancelling an incoming invite for some reason, add information
05967       about the reason why we are doing this in clear text */
05968    if (p->method == SIP_INVITE && msg[0] != '1' && p->owner && p->owner->hangupcause) {
05969       char buf[10];
05970 
05971       add_header(&resp, "X-Asterisk-HangupCause", ast_cause2str(p->owner->hangupcause));
05972       snprintf(buf, sizeof(buf), "%d", p->owner->hangupcause);
05973       add_header(&resp, "X-Asterisk-HangupCauseCode", buf);
05974    }
05975    return send_response(p, &resp, reliable, seqno);
05976 }

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

Show one peer in detail (main function).

Definition at line 10270 of file chan_sip.c.

References sip_peer::accountcode, sip_peer::addr, sip_peer::allowtransfer, sip_peer::amaflags, ast_callerid_merge(), ast_cdr_flags2str(), ast_check_realtime(), ast_cli(), ast_codec_pref_index(), ast_describe_caller_presentation(), ast_getformatname(), ast_getformatname_multiple(), ast_inet_ntoa(), ast_print_group(), ast_sched_when(), ast_strlen_zero(), ast_test_flag, astman_append(), astman_get_header(), astman_send_error(), ASTOBJ_UNREF, sip_peer::auth, sip_peer::autoframing, 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, FALSE, find_peer(), sip_peer::flags, sip_peer::fromdomain, sip_peer::fromuser, sip_peer::fullcontact, sip_peer::ha, cfsip_options::id, insecure2str(), sip_peer::language, sip_peer::lastmsg, sip_peer::lastmsgssent, sip_peer::mailbox, sip_peer::maxcallbitrate, 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, sip_peer::regexten, RESULT_SHOWUSAGE, RESULT_SUCCESS, S_OR, sip_auth::secret, sip_peer::secret, SIP_CAN_REINVITE, sip_destroy_peer(), SIP_DTMF, SIP_INSECURE_INVITE, SIP_INSECURE_PORT, SIP_NAT, sip_options, SIP_PAGE2_ALLOWOVERLAP, SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PAGE2_DYNAMIC, SIP_PAGE2_T38SUPPORT_RTP, SIP_PAGE2_T38SUPPORT_TCP, SIP_PAGE2_T38SUPPORT_UDPTL, SIP_PAGE2_VIDEOSUPPORT, SIP_PROMISCREDIR, SIP_REALTIME, SIP_SENDRPID, SIP_TRUSTRPID, SIP_USEREQPHONE, sip_peer::sipoptions, sip_peer::subscribecontext, text, sip_peer::tohost, transfermode2str(), TRUE, 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().

10271 {
10272    char status[30] = "";
10273    char cbuf[256];
10274    struct sip_peer *peer;
10275    char codec_buf[512];
10276    struct ast_codec_pref *pref;
10277    struct ast_variable *v;
10278    struct sip_auth *auth;
10279    int x = 0, codec = 0, load_realtime;
10280    int realtimepeers;
10281 
10282    realtimepeers = ast_check_realtime("sippeers");
10283 
10284    if (argc < 4)
10285       return RESULT_SHOWUSAGE;
10286 
10287    load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? TRUE : FALSE;
10288    peer = find_peer(argv[3], NULL, load_realtime);
10289    if (s) {    /* Manager */
10290       if (peer) {
10291          const char *id = astman_get_header(m,"ActionID");
10292 
10293          astman_append(s, "Response: Success\r\n");
10294          if (!ast_strlen_zero(id))
10295             astman_append(s, "ActionID: %s\r\n",id);
10296       } else {
10297          snprintf (cbuf, sizeof(cbuf), "Peer %s not found.\n", argv[3]);
10298          astman_send_error(s, m, cbuf);
10299          return 0;
10300       }
10301    }
10302    if (peer && type==0 ) { /* Normal listing */
10303       ast_cli(fd,"\n\n");
10304       ast_cli(fd, "  * Name       : %s\n", peer->name);
10305       if (realtimepeers) { /* Realtime is enabled */
10306          ast_cli(fd, "  Realtime peer: %s\n", ast_test_flag(&peer->flags[0], SIP_REALTIME) ? "Yes, cached" : "No");
10307       }
10308       ast_cli(fd, "  Secret       : %s\n", ast_strlen_zero(peer->secret)?"<Not set>":"<Set>");
10309       ast_cli(fd, "  MD5Secret    : %s\n", ast_strlen_zero(peer->md5secret)?"<Not set>":"<Set>");
10310       for (auth = peer->auth; auth; auth = auth->next) {
10311          ast_cli(fd, "  Realm-auth   : Realm %-15.15s User %-10.20s ", auth->realm, auth->username);
10312          ast_cli(fd, "%s\n", !ast_strlen_zero(auth->secret)?"<Secret set>":(!ast_strlen_zero(auth->md5secret)?"<MD5secret set>" : "<Not set>"));
10313       }
10314       ast_cli(fd, "  Context      : %s\n", peer->context);
10315       ast_cli(fd, "  Subscr.Cont. : %s\n", S_OR(peer->subscribecontext, "<Not set>") );
10316       ast_cli(fd, "  Language     : %s\n", peer->language);
10317       if (!ast_strlen_zero(peer->accountcode))
10318          ast_cli(fd, "  Accountcode  : %s\n", peer->accountcode);
10319       ast_cli(fd, "  AMA flags    : %s\n", ast_cdr_flags2str(peer->amaflags));
10320       ast_cli(fd, "  Transfer mode: %s\n", transfermode2str(peer->allowtransfer));
10321       ast_cli(fd, "  CallingPres  : %s\n", ast_describe_caller_presentation(peer->callingpres));
10322       if (!ast_strlen_zero(peer->fromuser))
10323          ast_cli(fd, "  FromUser     : %s\n", peer->fromuser);
10324       if (!ast_strlen_zero(peer->fromdomain))
10325          ast_cli(fd, "  FromDomain   : %s\n", peer->fromdomain);
10326       ast_cli(fd, "  Callgroup    : ");
10327       print_group(fd, peer->callgroup, 0);
10328       ast_cli(fd, "  Pickupgroup  : ");
10329       print_group(fd, peer->pickupgroup, 0);
10330       ast_cli(fd, "  Mailbox      : %s\n", peer->mailbox);
10331       ast_cli(fd, "  VM Extension : %s\n", peer->vmexten);
10332       ast_cli(fd, "  LastMsgsSent : %d/%d\n", (peer->lastmsgssent & 0x7fff0000) >> 16, peer->lastmsgssent & 0xffff);
10333       ast_cli(fd, "  Call limit   : %d\n", peer->call_limit);
10334       ast_cli(fd, "  Dynamic      : %s\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)?"Yes":"No"));
10335       ast_cli(fd, "  Callerid     : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>"));
10336       ast_cli(fd, "  MaxCallBR    : %d kbps\n", peer->maxcallbitrate);
10337       ast_cli(fd, "  Expire       : %ld\n", ast_sched_when(sched, peer->expire));
10338       ast_cli(fd, "  Insecure     : %s\n", insecure2str(ast_test_flag(&peer->flags[0], SIP_INSECURE_PORT), ast_test_flag(&peer->flags[0], SIP_INSECURE_INVITE)));
10339       ast_cli(fd, "  Nat          : %s\n", nat2str(ast_test_flag(&peer->flags[0], SIP_NAT)));
10340       ast_cli(fd, "  ACL          : %s\n", (peer->ha?"Yes":"No"));
10341       ast_cli(fd, "  T38 pt UDPTL : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT_UDPTL)?"Yes":"No");
10342 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS
10343       ast_cli(fd, "  T38 pt RTP   : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT_RTP)?"Yes":"No");
10344       ast_cli(fd, "  T38 pt TCP   : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT_TCP)?"Yes":"No");
10345 #endif
10346       ast_cli(fd, "  CanReinvite  : %s\n", ast_test_flag(&peer->flags[0], SIP_CAN_REINVITE)?"Yes":"No");
10347       ast_cli(fd, "  PromiscRedir : %s\n", ast_test_flag(&peer->flags[0], SIP_PROMISCREDIR)?"Yes":"No");
10348       ast_cli(fd, "  User=Phone   : %s\n", ast_test_flag(&peer->flags[0], SIP_USEREQPHONE)?"Yes":"No");
10349       ast_cli(fd, "  Video Support: %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_VIDEOSUPPORT)?"Yes":"No");
10350       ast_cli(fd, "  Trust RPID   : %s\n", ast_test_flag(&peer->flags[0], SIP_TRUSTRPID) ? "Yes" : "No");
10351       ast_cli(fd, "  Send RPID    : %s\n", ast_test_flag(&peer->flags[0], SIP_SENDRPID) ? "Yes" : "No");
10352       ast_cli(fd, "  Subscriptions: %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE) ? "Yes" : "No");
10353       ast_cli(fd, "  Overlap dial : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWOVERLAP) ? "Yes" : "No");
10354 
10355       /* - is enumerated */
10356       ast_cli(fd, "  DTMFmode     : %s\n", dtmfmode2str(ast_test_flag(&peer->flags[0], SIP_DTMF)));
10357       ast_cli(fd, "  LastMsg      : %d\n", peer->lastmsg);
10358       ast_cli(fd, "  ToHost       : %s\n", peer->tohost);
10359       ast_cli(fd, "  Addr->IP     : %s Port %d\n",  peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)", ntohs(peer->addr.sin_port));
10360       ast_cli(fd, "  Defaddr->IP  : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port));
10361       if (!ast_strlen_zero(global_regcontext))
10362          ast_cli(fd, "  Reg. exten   : %s\n", peer->regexten);
10363       ast_cli(fd, "  Def. Username: %s\n", peer->username);
10364       ast_cli(fd, "  SIP Options  : ");
10365       if (peer->sipoptions) {
10366          int lastoption = -1;
10367          for (x=0 ; (x < (sizeof(sip_options) / sizeof(sip_options[0]))); x++) {
10368             if (sip_options[x].id != lastoption) {
10369                if (peer->sipoptions & sip_options[x].id)
10370                   ast_cli(fd, "%s ", sip_options[x].text);
10371                lastoption = x;
10372             }
10373          }
10374       } else
10375          ast_cli(fd, "(none)");
10376 
10377       ast_cli(fd, "\n");
10378       ast_cli(fd, "  Codecs       : ");
10379       ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability);
10380       ast_cli(fd, "%s\n", codec_buf);
10381       ast_cli(fd, "  Codec Order  : (");
10382       print_codec_to_cli(fd, &peer->prefs);
10383       ast_cli(fd, ")\n");
10384 
10385       ast_cli(fd, "  Auto-Framing:  %s \n", peer->autoframing ? "Yes" : "No");
10386       ast_cli(fd, "  Status       : ");
10387       peer_status(peer, status, sizeof(status));
10388       ast_cli(fd, "%s\n",status);
10389       ast_cli(fd, "  Useragent    : %s\n", peer->useragent);
10390       ast_cli(fd, "  Reg. Contact : %s\n", peer->fullcontact);
10391       if (peer->chanvars) {
10392          ast_cli(fd, "  Variables    :\n");
10393          for (v = peer->chanvars ; v ; v = v->next)
10394             ast_cli(fd, "                 %s = %s\n", v->name, v->value);
10395       }
10396       ast_cli(fd,"\n");
10397       ASTOBJ_UNREF(peer,sip_destroy_peer);
10398    } else  if (peer && type == 1) { /* manager listing */
10399       char buf[256];
10400       astman_append(s, "Channeltype: SIP\r\n");
10401       astman_append(s, "ObjectName: %s\r\n", peer->name);
10402       astman_append(s, "ChanObjectType: peer\r\n");
10403       astman_append(s, "SecretExist: %s\r\n", ast_strlen_zero(peer->secret)?"N":"Y");
10404       astman_append(s, "MD5SecretExist: %s\r\n", ast_strlen_zero(peer->md5secret)?"N":"Y");
10405       astman_append(s, "Context: %s\r\n", peer->context);
10406       astman_append(s, "Language: %s\r\n", peer->language);
10407       if (!ast_strlen_zero(peer->accountcode))
10408          astman_append(s, "Accountcode: %s\r\n", peer->accountcode);
10409       astman_append(s, "AMAflags: %s\r\n", ast_cdr_flags2str(peer->amaflags));
10410       astman_append(s, "CID-CallingPres: %s\r\n", ast_describe_caller_presentation(peer->callingpres));
10411       if (!ast_strlen_zero(peer->fromuser))
10412          astman_append(s, "SIP-FromUser: %s\r\n", peer->fromuser);
10413       if (!ast_strlen_zero(peer->fromdomain))
10414          astman_append(s, "SIP-FromDomain: %s\r\n", peer->fromdomain);
10415       astman_append(s, "Callgroup: ");
10416       astman_append(s, "%s\r\n", ast_print_group(buf, sizeof(buf), peer->callgroup));
10417       astman_append(s, "Pickupgroup: ");
10418       astman_append(s, "%s\r\n", ast_print_group(buf, sizeof(buf), peer->pickupgroup));
10419       astman_append(s, "VoiceMailbox: %s\r\n", peer->mailbox);
10420       astman_append(s, "TransferMode: %s\r\n", transfermode2str(peer->allowtransfer));
10421       astman_append(s, "LastMsgsSent: %d\r\n", peer->lastmsgssent);
10422       astman_append(s, "Call-limit: %d\r\n", peer->call_limit);
10423       astman_append(s, "MaxCallBR: %d kbps\r\n", peer->maxcallbitrate);
10424       astman_append(s, "Dynamic: %s\r\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)?"Y":"N"));
10425       astman_append(s, "Callerid: %s\r\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, ""));
10426       astman_append(s, "RegExpire: %ld seconds\r\n", ast_sched_when(sched,peer->expire));
10427       astman_append(s, "SIP-AuthInsecure: %s\r\n", insecure2str(ast_test_flag(&peer->flags[0], SIP_INSECURE_PORT), ast_test_flag(&peer->flags[0], SIP_INSECURE_INVITE)));
10428       astman_append(s, "SIP-NatSupport: %s\r\n", nat2str(ast_test_flag(&peer->flags[0], SIP_NAT)));
10429       astman_append(s, "ACL: %s\r\n", (peer->ha?"Y":"N"));
10430       astman_append(s, "SIP-CanReinvite: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_CAN_REINVITE)?"Y":"N"));
10431       astman_append(s, "SIP-PromiscRedir: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_PROMISCREDIR)?"Y":"N"));
10432       astman_append(s, "SIP-UserPhone: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_USEREQPHONE)?"Y":"N"));
10433       astman_append(s, "SIP-VideoSupport: %s\r\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_VIDEOSUPPORT)?"Y":"N"));
10434 
10435       /* - is enumerated */
10436       astman_append(s, "SIP-DTMFmode: %s\r\n", dtmfmode2str(ast_test_flag(&peer->flags[0], SIP_DTMF)));
10437       astman_append(s, "SIPLastMsg: %d\r\n", peer->lastmsg);
10438       astman_append(s, "ToHost: %s\r\n", peer->tohost);
10439       astman_append(s, "Address-IP: %s\r\nAddress-Port: %d\r\n",  peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "", ntohs(peer->addr.sin_port));
10440       astman_append(s, "Default-addr-IP: %s\r\nDefault-addr-port: %d\r\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port));
10441       astman_append(s, "Default-Username: %s\r\n", peer->username);
10442       if (!ast_strlen_zero(global_regcontext))
10443          astman_append(s, "RegExtension: %s\r\n", peer->regexten);
10444       astman_append(s, "Codecs: ");
10445       ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability);
10446       astman_append(s, "%s\r\n", codec_buf);
10447       astman_append(s, "CodecOrder: ");
10448       pref = &peer->prefs;
10449       for(x = 0; x < 32 ; x++) {
10450          codec = ast_codec_pref_index(pref,x);
10451          if (!codec)
10452             break;
10453          astman_append(s, "%s", ast_getformatname(codec));
10454          if (x < 31 && ast_codec_pref_index(pref,x+1))
10455             astman_append(s, ",");
10456       }
10457 
10458       astman_append(s, "\r\n");
10459       astman_append(s, "Status: ");
10460       peer_status(peer, status, sizeof(status));
10461       astman_append(s, "%s\r\n", status);
10462       astman_append(s, "SIP-Useragent: %s\r\n", peer->useragent);
10463       astman_append(s, "Reg-Contact : %s\r\n", peer->fullcontact);
10464       if (peer->chanvars) {
10465          for (v = peer->chanvars ; v ; v = v->next) {
10466             astman_append(s, "ChanVariable:\n");
10467             astman_append(s, " %s,%s\r\n", v->name, v->value);
10468          }
10469       }
10470 
10471       ASTOBJ_UNREF(peer,sip_destroy_peer);
10472 
10473    } else {
10474       ast_cli(fd,"Peer %s not found.\n", argv[3]);
10475       ast_cli(fd,"\n");
10476    }
10477 
10478    return RESULT_SUCCESS;
10479 }

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

_sip_show_peers: Execute sip show peers command

Definition at line 9820 of file chan_sip.c.

References ast_check_realtime(), ast_cli(), ast_inet_ntoa(), ast_strlen_zero(), ast_test_flag, astman_append(), astman_get_header(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, FALSE, FORMAT, FORMAT2, id, name, peer_status(), peerl, RESULT_SHOWUSAGE, RESULT_SUCCESS, SIP_NAT_ROUTE, SIP_PAGE2_DYNAMIC, SIP_PAGE2_VIDEOSUPPORT, SIP_REALTIME, and TRUE.

Referenced by manager_sip_show_peers(), and sip_show_peers().

09821 {
09822    regex_t regexbuf;
09823    int havepattern = FALSE;
09824 
09825 #define FORMAT2 "%-25.25s  %-15.15s %-3.3s %-3.3s %-3.3s %-8s %-10s %-10s\n"
09826 #define FORMAT  "%-25.25s  %-15.15s %-3.3s %-3.3s %-3.3s %-8d %-10s %-10s\n"
09827 
09828    char name[256];
09829    int total_peers = 0;
09830    int peers_mon_online = 0;
09831    int peers_mon_offline = 0;
09832    int peers_unmon_offline = 0;
09833    int peers_unmon_online = 0;
09834    const char *id;
09835    char idtext[256] = "";
09836    int realtimepeers;
09837 
09838    realtimepeers = ast_check_realtime("sippeers");
09839 
09840    if (s) { /* Manager - get ActionID */
09841       id = astman_get_header(m,"ActionID");
09842       if (!ast_strlen_zero(id))
09843          snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
09844    }
09845 
09846    switch (argc) {
09847    case 5:
09848       if (!strcasecmp(argv[3], "like")) {
09849          if (regcomp(&regexbuf, argv[4], REG_EXTENDED | REG_NOSUB))
09850             return RESULT_SHOWUSAGE;
09851          havepattern = TRUE;
09852       } else
09853          return RESULT_SHOWUSAGE;
09854    case 3:
09855       break;
09856    default:
09857       return RESULT_SHOWUSAGE;
09858    }
09859 
09860    if (!s) /* Normal list */
09861       ast_cli(fd, FORMAT2, "Name/username", "Host", "Dyn", "Nat", "ACL", "Port", "Status", (realtimepeers ? "Realtime" : ""));
09862    
09863    ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do {
09864       char status[20] = "";
09865       char srch[2000];
09866       char pstatus;
09867       
09868       ASTOBJ_RDLOCK(iterator);
09869 
09870       if (havepattern && regexec(&regexbuf, iterator->name, 0, NULL, 0)) {
09871          ASTOBJ_UNLOCK(iterator);
09872          continue;
09873       }
09874 
09875       if (!ast_strlen_zero(iterator->username) && !s)
09876          snprintf(name, sizeof(name), "%s/%s", iterator->name, iterator->username);
09877       else
09878          ast_copy_string(name, iterator->name, sizeof(name));
09879       
09880       pstatus = peer_status(iterator, status, sizeof(status));
09881       if (pstatus == 1)
09882          peers_mon_online++;
09883       else if (pstatus == 0)
09884          peers_mon_offline++;
09885       else {
09886          if (iterator->addr.sin_port == 0)
09887             peers_unmon_offline++;
09888          else
09889             peers_unmon_online++;
09890       }
09891 
09892       snprintf(srch, sizeof(srch), FORMAT, name,
09893          iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iterator->addr.sin_addr) : "(Unspecified)",
09894          ast_test_flag(&iterator->flags[1], SIP_PAGE2_DYNAMIC) ? " D " : "   ",  /* Dynamic or not? */
09895          ast_test_flag(&iterator->flags[0], SIP_NAT_ROUTE) ? " N " : "   ",   /* NAT=yes? */
09896          iterator->ha ? " A " : "   ",    /* permit/deny */
09897          ntohs(iterator->addr.sin_port), status,
09898          realtimepeers ? (ast_test_flag(&iterator->flags[0], SIP_REALTIME) ? "Cached RT":"") : "");
09899 
09900       if (!s)  {/* Normal CLI list */
09901          ast_cli(fd, FORMAT, name, 
09902          iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iterator->addr.sin_addr) : "(Unspecified)",
09903          ast_test_flag(&iterator->flags[1], SIP_PAGE2_DYNAMIC) ? " D " : "   ",  /* Dynamic or not? */
09904          ast_test_flag(&iterator->flags[0], SIP_NAT_ROUTE) ? " N " : "   ",   /* NAT=yes? */
09905          iterator->ha ? " A " : "   ",       /* permit/deny */
09906          
09907          ntohs(iterator->addr.sin_port), status,
09908          realtimepeers ? (ast_test_flag(&iterator->flags[0], SIP_REALTIME) ? "Cached RT":"") : "");
09909       } else { /* Manager format */
09910          /* The names here need to be the same as other channels */
09911          astman_append(s, 
09912          "Event: PeerEntry\r\n%s"
09913          "Channeltype: SIP\r\n"
09914          "ObjectName: %s\r\n"
09915          "ChanObjectType: peer\r\n" /* "peer" or "user" */
09916          "IPaddress: %s\r\n"
09917          "IPport: %d\r\n"
09918          "Dynamic: %s\r\n"
09919          "Natsupport: %s\r\n"
09920          "VideoSupport: %s\r\n"
09921          "ACL: %s\r\n"
09922          "Status: %s\r\n"
09923          "RealtimeDevice: %s\r\n\r\n", 
09924          idtext,
09925          iterator->name, 
09926          iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iterator->addr.sin_addr) : "-none-",
09927          ntohs(iterator->addr.sin_port), 
09928          ast_test_flag(&iterator->flags[1], SIP_PAGE2_DYNAMIC) ? "yes" : "no",   /* Dynamic or not? */
09929          ast_test_flag(&iterator->flags[0], SIP_NAT_ROUTE) ? "yes" : "no", /* NAT=yes? */
09930          ast_test_flag(&iterator->flags[1], SIP_PAGE2_VIDEOSUPPORT) ? "yes" : "no", /* VIDEOSUPPORT=yes? */
09931          iterator->ha ? "yes" : "no",       /* permit/deny */
09932          status,
09933          realtimepeers ? (ast_test_flag(&iterator->flags[0], SIP_REALTIME) ? "yes":"no") : "no");
09934       }
09935 
09936       ASTOBJ_UNLOCK(iterator);
09937 
09938       total_peers++;
09939    } while(0) );
09940    
09941    if (!s)
09942       ast_cli(fd, "%d sip peers [Monitored: %d online, %d offline Unmonitored: %d online, %d offline]\n",
09943               total_peers, peers_mon_online, peers_mon_offline, peers_unmon_online, peers_unmon_offline);
09944 
09945    if (havepattern)
09946       regfree(&regexbuf);
09947 
09948    if (total)
09949       *total = total_peers;
09950    
09951 
09952    return RESULT_SUCCESS;
09953 #undef FORMAT
09954 #undef FORMAT2
09955 }

static int acf_channel_read ( struct ast_channel chan,
char *  funcname,
char *  preparse,
char *  buf,
size_t  buflen 
) [static]

Definition at line 14586 of file chan_sip.c.

References AST_APP_ARG, AST_DECLARE_APP_ARGS, ast_log(), ast_rtp_get_quality(), AST_STANDARD_APP_ARGS, ast_strdupa, ast_strlen_zero(), ast_rtp_quality::local_count, ast_rtp_quality::local_jitter, ast_rtp_quality::local_lostpackets, ast_rtp_quality::local_ssrc, LOG_ERROR, LOG_WARNING, parse(), ast_rtp_quality::remote_count, ast_rtp_quality::remote_jitter, ast_rtp_quality::remote_lostpackets, ast_rtp_quality::remote_ssrc, sip_pvt::rtp, ast_rtp_quality::rtt, sip_tech, sip_tech_info, ast_channel::tech, ast_channel::tech_pvt, type, and sip_pvt::vrtp.

14587 {
14588    struct ast_rtp_quality qos;
14589    struct sip_pvt *p = chan->tech_pvt;
14590    char *all = "", *parse = ast_strdupa(preparse);
14591    AST_DECLARE_APP_ARGS(args,
14592       AST_APP_ARG(param);
14593       AST_APP_ARG(type);
14594       AST_APP_ARG(field);
14595    );
14596    AST_STANDARD_APP_ARGS(args, parse);
14597 
14598    /* Sanity check */
14599    if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) {
14600       ast_log(LOG_ERROR, "Cannot call %s on a non-SIP channel\n", funcname);
14601       return 0;
14602    }
14603 
14604    if (strcasecmp(args.param, "rtpqos"))
14605       return 0;
14606 
14607    /* Default arguments of audio,all */
14608    if (ast_strlen_zero(args.type))
14609       args.type = "audio";
14610    if (ast_strlen_zero(args.field))
14611       args.field = "all";
14612 
14613    memset(buf, 0, buflen);
14614    memset(&qos, 0, sizeof(qos));
14615 
14616    if (strcasecmp(args.type, "AUDIO") == 0) {
14617       all = ast_rtp_get_quality(p->rtp, &qos);
14618    } else if (strcasecmp(args.type, "VIDEO") == 0) {
14619       all = ast_rtp_get_quality(p->vrtp, &qos);
14620    }
14621 
14622    if (strcasecmp(args.field, "local_ssrc") == 0)
14623       snprintf(buf, buflen, "%u", qos.local_ssrc);
14624    else if (strcasecmp(args.field, "local_lostpackets") == 0)
14625       snprintf(buf, buflen, "%u", qos.local_lostpackets);
14626    else if (strcasecmp(args.field, "local_jitter") == 0)
14627       snprintf(buf, buflen, "%.0lf", qos.local_jitter * 1000.0);
14628    else if (strcasecmp(args.field, "local_count") == 0)
14629       snprintf(buf, buflen, "%u", qos.local_count);
14630    else if (strcasecmp(args.field, "remote_ssrc") == 0)
14631       snprintf(buf, buflen, "%u", qos.remote_ssrc);
14632    else if (strcasecmp(args.field, "remote_lostpackets") == 0)
14633       snprintf(buf, buflen, "%u", qos.remote_lostpackets);
14634    else if (strcasecmp(args.field, "remote_jitter") == 0)
14635       snprintf(buf, buflen, "%.0lf", qos.remote_jitter * 1000.0);
14636    else if (strcasecmp(args.field, "remote_count") == 0)
14637       snprintf(buf, buflen, "%u", qos.remote_count);
14638    else if (strcasecmp(args.field, "rtt") == 0)
14639       snprintf(buf, buflen, "%.0lf", qos.rtt * 1000.0);
14640    else if (strcasecmp(args.field, "all") == 0)
14641       ast_copy_string(buf, all, buflen);
14642    else {
14643       ast_log(LOG_WARNING, "Unrecognized argument '%s' to %s\n", preparse, funcname);
14644       return -1;
14645    }
14646    return 0;
14647 }

static void add_blank ( struct sip_request req  )  [static]

add a blank line if no body

Definition at line 2229 of file chan_sip.c.

References sip_request::data, sip_request::len, and sip_request::lines.

Referenced by send_request(), and send_response().

02230 {
02231    if (!req->lines) {
02232       /* Add extra empty return. add_header() reserves 4 bytes so cannot be truncated */
02233       snprintf(req->data + req->len, sizeof(req->data) - req->len, "\r\n");
02234       req->len += strlen(req->data + req->len);
02235    }
02236 }

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,
int *  min_packet_size 
) [static]

Add codec offer to SDP offer/answer body in INVITE or 200 OK.

Definition at line 6159 of file chan_sip.c.

References ast_build_string(), ast_codec_pref_getsize(), AST_FORMAT_G723_1, AST_FORMAT_G729A, AST_FORMAT_ILBC, ast_getformatname(), ast_rtp_codec_getpref(), ast_rtp_lookup_code(), ast_rtp_lookup_mime_subtype(), AST_RTP_OPT_G726_NONSTANDARD, ast_test_flag, ast_verbose(), ast_format_list::cur_ms, sip_pvt::flags, sip_pvt::rtp, and SIP_G726_NONSTANDARD.

Referenced by add_sdp().

06162 {
06163    int rtp_code;
06164    struct ast_format_list fmt;
06165 
06166 
06167    if (debug)
06168       ast_verbose("Adding codec 0x%x (%s) to SDP\n", codec, ast_getformatname(codec));
06169    if ((rtp_code = ast_rtp_lookup_code(p->rtp, 1, codec)) == -1)
06170       return;
06171 
06172    if (p->rtp) {
06173       struct ast_codec_pref *pref = ast_rtp_codec_getpref(p->rtp);
06174       fmt = ast_codec_pref_getsize(pref, codec);
06175    } else /* I dont see how you couldn't have p->rtp, but good to check for and error out if not there like earlier code */
06176       return;
06177    ast_build_string(m_buf, m_size, " %d", rtp_code);
06178    ast_build_string(a_buf, a_size, "a=rtpmap:%d %s/%d\r\n", rtp_code,
06179           ast_rtp_lookup_mime_subtype(1, codec,
06180                        ast_test_flag(&p->flags[0], SIP_G726_NONSTANDARD) ? AST_RTP_OPT_G726_NONSTANDARD : 0),
06181           sample_rate);
06182    if (codec == AST_FORMAT_G729A) {
06183       /* Indicate that we don't support VAD (G.729 annex B) */
06184       ast_build_string(a_buf, a_size, "a=fmtp:%d annexb=no\r\n", rtp_code);
06185    } else if (codec == AST_FORMAT_G723_1) {
06186       /* Indicate that we don't support VAD (G.723.1 annex A) */
06187       ast_build_string(a_buf, a_size, "a=fmtp:%d annexa=no\r\n", rtp_code);
06188    } else if (codec == AST_FORMAT_ILBC) {
06189       /* Add information about us using only 20/30 ms packetization */
06190       ast_build_string(a_buf, a_size, "a=fmtp:%d mode=%d\r\n", rtp_code, fmt.cur_ms);
06191    }
06192 
06193    if (fmt.cur_ms && (fmt.cur_ms < *min_packet_size))
06194       *min_packet_size = fmt.cur_ms;
06195 
06196    /* Our first codec packetization processed cannot be less than zero */
06197    if ((*min_packet_size) == 0  && fmt.cur_ms)
06198       *min_packet_size = fmt.cur_ms;
06199 }

static int add_digit ( struct sip_request req,
char  digit,
unsigned int  duration 
) [static]

Add DTMF INFO tone to sip message.

Definition at line 6127 of file chan_sip.c.

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

Referenced by transmit_info_with_digit().

06128 {
06129    char tmp[256];
06130 
06131    snprintf(tmp, sizeof(tmp), "Signal=%c\r\nDuration=%u\r\n", digit, duration);
06132    add_header(req, "Content-Type", "application/dtmf-relay");
06133    add_header_contentLength(req, strlen(tmp));
06134    add_line(req, tmp);
06135    return 0;
06136 }

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

Add header to SIP message.

Definition at line 5522 of file chan_sip.c.

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

05523 {
05524    int maxlen = sizeof(req->data) - 4 - req->len; /* 4 bytes are for two \r\n ? */
05525 
05526    if (req->headers == SIP_MAX_HEADERS) {
05527       ast_log(LOG_WARNING, "Out of SIP header space\n");
05528       return -1;
05529    }
05530 
05531    if (req->lines) {
05532       ast_log(LOG_WARNING, "Can't add more headers when lines have been added\n");
05533       return -1;
05534    }
05535 
05536    if (maxlen <= 0) {
05537       ast_log(LOG_WARNING, "Out of space, can't add anymore (%s:%s)\n", var, value);
05538       return -1;
05539    }
05540 
05541    req->header[req->headers] = req->data + req->len;
05542 
05543    if (compactheaders)
05544       var = find_alias(var, var);
05545 
05546    snprintf(req->header[req->headers], maxlen, "%s: %s\r\n", var, value);
05547    req->len += strlen(req->header[req->headers]);
05548    req->headers++;
05549 
05550    return 0;   
05551 }

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

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

Add content (not header) to SIP message.

Definition at line 5563 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.

05564 {
05565    if (req->lines == SIP_MAX_LINES)  {
05566       ast_log(LOG_WARNING, "Out of SIP line space\n");
05567       return -1;
05568    }
05569    if (!req->lines) {
05570       /* Add extra empty return */
05571       snprintf(req->data + req->len, sizeof(req->data) - req->len, "\r\n");
05572       req->len += strlen(req->data + req->len);
05573    }
05574    if (req->len >= sizeof(req->data) - 4) {
05575       ast_log(LOG_WARNING, "Out of space, can't add anymore\n");
05576       return -1;
05577    }
05578    req->line[req->lines] = req->data + req->len;
05579    snprintf(req->line[req->lines], sizeof(req->data) - req->len, "%s", line);
05580    req->len += strlen(req->line[req->lines]);
05581    req->lines++;
05582    return 0;   
05583 }

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]

Add RFC 2833 DTMF offer to SDP.

Definition at line 6335 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.

Referenced by add_sdp().

06338 {
06339    int rtp_code;
06340 
06341    if (debug)
06342       ast_verbose("Adding non-codec 0x%x (%s) to SDP\n", format, ast_rtp_lookup_mime_subtype(0, format, 0));
06343    if ((rtp_code = ast_rtp_lookup_code(p->rtp, 0, format)) == -1)
06344       return;
06345 
06346    ast_build_string(m_buf, m_size, " %d", rtp_code);
06347    ast_build_string(a_buf, a_size, "a=rtpmap:%d %s/%d\r\n", rtp_code,
06348           ast_rtp_lookup_mime_subtype(0, format, 0),
06349           sample_rate);
06350    if (format == AST_RTP_DTMF)
06351       /* Indicate we support DTMF and FLASH... */
06352       ast_build_string(a_buf, a_size, "a=fmtp:%d 0-16\r\n", rtp_code);
06353 }

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

Add realm authentication in list.

Definition at line 16160 of file chan_sip.c.

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

Referenced by build_peer(), and reload_config().

16161 {
16162    char authcopy[256];
16163    char *username=NULL, *realm=NULL, *secret=NULL, *md5secret=NULL;
16164    char *stringp;
16165    struct sip_auth *a, *b, *auth;
16166 
16167    if (ast_strlen_zero(configuration))
16168       return authlist;
16169 
16170    if (option_debug)
16171       ast_log(LOG_DEBUG, "Auth config ::  %s\n", configuration);
16172 
16173    ast_copy_string(authcopy, configuration, sizeof(authcopy));
16174    stringp = authcopy;
16175 
16176    username = stringp;
16177    realm = strrchr(stringp, '@');
16178    if (realm)
16179       *realm++ = '\0';
16180    if (ast_strlen_zero(username) || ast_strlen_zero(realm)) {
16181       ast_log(LOG_WARNING, "Format for authentication entry is user[:secret]@realm at line %d\n", lineno);
16182       return authlist;
16183    }
16184    stringp = username;
16185    username = strsep(&stringp, ":");
16186    if (username) {
16187       secret = strsep(&stringp, ":");
16188       if (!secret) {
16189          stringp = username;
16190          md5secret = strsep(&stringp,"#");
16191       }
16192    }
16193    if (!(auth = ast_calloc(1, sizeof(*auth))))
16194       return authlist;
16195 
16196    ast_copy_string(auth->realm, realm, sizeof(auth->realm));
16197    ast_copy_string(auth->username, username, sizeof(auth->username));
16198    if (secret)
16199       ast_copy_string(auth->secret, secret, sizeof(auth->secret));
16200    if (md5secret)
16201       ast_copy_string(auth->md5secret, md5secret, sizeof(auth->md5secret));
16202 
16203    /* find the end of the list */
16204    for (b = NULL, a = authlist; a ; b = a, a = a->next)
16205       ;
16206    if (b)
16207       b->next = auth;   /* Add structure add end of list */
16208    else
16209       authlist = auth;
16210 
16211    if (option_verbose > 2)
16212       ast_verbose("Added authentication for realm %s\n", realm);
16213 
16214    return authlist;
16215 
16216 }

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

Add route header into request per learned route.

Definition at line 5684 of file chan_sip.c.

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

Referenced by reqprep().

05685 {
05686    char r[BUFSIZ*2], *p;
05687    int n, rem = sizeof(r);
05688 
05689    if (!route)
05690       return;
05691 
05692    p = r;
05693    for (;route ; route = route->next) {
05694       n = strlen(route->hop);
05695       if (rem < n+3) /* we need room for ",<route>" */
05696          break;
05697       if (p != r) {  /* add a separator after fist route */
05698          *p++ = ',';
05699          --rem;
05700       }
05701       *p++ = '<';
05702       ast_copy_string(p, route->hop, rem); /* cannot fail */
05703       p += n;
05704       *p++ = '>';
05705       rem -= (n+2);
05706    }
05707    *p = '\0';
05708    add_header(req, "Route", r);
05709 }

static enum sip_result add_sdp ( struct sip_request resp,
struct sip_pvt p 
) [static]

Add Session Description Protocol message.

Definition at line 6358 of file chan_sip.c.

References add_codec_to_sdp(), add_header(), add_header_contentLength(), add_line(), add_noncodec_to_sdp(), ast_build_string(), ast_codec_pref_index(), AST_FAILURE, AST_FORMAT_AUDIO_MASK, AST_FORMAT_MAX_AUDIO, AST_FORMAT_MAX_VIDEO, AST_FORMAT_VIDEO_MASK, ast_getformatname_multiple(), ast_inet_ntoa(), ast_internal_timing_enabled(), ast_log(), ast_rtp_get_us(), AST_RTP_MAX, AST_SUCCESS, ast_test_flag, ast_verbose(), capability, debug, FALSE, sip_pvt::flags, sip_pvt::jointcapability, sip_pvt::jointnoncodeccapability, sip_pvt::lastrtprx, sip_pvt::lastrtptx, len, LOG_DEBUG, LOG_WARNING, sip_pvt::maxcallbitrate, option_debug, sip_pvt::ourip, sip_pvt::owner, sip_pvt::prefcodec, sip_pvt::prefs, sip_pvt::redirip, sip_pvt::rtp, SDP_SAMPLE_RATE, sip_pvt::sessionid, sip_pvt::sessionversion, sip_debug_test_pvt(), SIP_NOVIDEO, SIP_PAGE2_CALL_ONHOLD, SIP_PAGE2_CALL_ONHOLD_INACTIVE, SIP_PAGE2_CALL_ONHOLD_ONEDIR, SIP_PAGE2_T38SUPPORT_RTP, sip_pvt::t38, t38properties::t38support, TRUE, sip_pvt::vredirip, and sip_pvt::vrtp.

06359 {
06360    int len = 0;
06361    int alreadysent = 0;
06362 
06363    struct sockaddr_in sin;
06364    struct sockaddr_in vsin;
06365    struct sockaddr_in dest;
06366    struct sockaddr_in vdest = { 0, };
06367 
06368    /* SDP fields */
06369    char *version =   "v=0\r\n";     /* Protocol version */
06370    char *subject =   "s=session\r\n";  /* Subject of the session */
06371    char owner[256];           /* Session owner/creator */
06372    char connection[256];            /* Connection data */
06373    char *stime = "t=0 0\r\n";          /* Time the session is active */
06374    char bandwidth[256] = "";        /* Max bitrate */
06375    char *hold;
06376    char m_audio[256];            /* Media declaration line for audio */
06377    char m_video[256];            /* Media declaration line for video */
06378    char a_audio[1024];           /* Attributes for audio */
06379    char a_video[1024];           /* Attributes for video */
06380    char *m_audio_next = m_audio;
06381    char *m_video_next = m_video;
06382    size_t m_audio_left = sizeof(m_audio);
06383    size_t m_video_left = sizeof(m_video);
06384    char *a_audio_next = a_audio;
06385    char *a_video_next = a_video;
06386    size_t a_audio_left = sizeof(a_audio);
06387    size_t a_video_left = sizeof(a_video);
06388 
06389    int x;
06390    int capability;
06391    int needvideo = FALSE;
06392    int debug = sip_debug_test_pvt(p);
06393    int min_audio_packet_size = 0;
06394    int min_video_packet_size = 0;
06395 
06396    m_video[0] = '\0';   /* Reset the video media string if it's not needed */
06397 
06398    if (!p->rtp) {
06399       ast_log(LOG_WARNING, "No way to add SDP without an RTP structure\n");
06400       return AST_FAILURE;
06401    }
06402 
06403    /* Set RTP Session ID and version */
06404    if (!p->sessionid) {
06405       p->sessionid = getpid();
06406       p->sessionversion = p->sessionid;
06407    } else
06408       p->sessionversion++;
06409 
06410    /* Get our addresses */
06411    ast_rtp_get_us(p->rtp, &sin);
06412    if (p->vrtp)
06413       ast_rtp_get_us(p->vrtp, &vsin);
06414 
06415    /* Is this a re-invite to move the media out, then use the original offer from caller  */
06416    if (p->redirip.sin_addr.s_addr) {
06417       dest.sin_port = p->redirip.sin_port;
06418       dest.sin_addr = p->redirip.sin_addr;
06419    } else {
06420       dest.sin_addr = p->ourip;
06421       dest.sin_port = sin.sin_port;
06422    }
06423 
06424    capability = p->jointcapability;
06425 
06426 
06427    if (option_debug > 1) {
06428       char codecbuf[BUFSIZ];
06429       ast_log(LOG_DEBUG, "** Our capability: %s Video flag: %s\n", ast_getformatname_multiple(codecbuf, sizeof(codecbuf), capability), ast_test_flag(&p->flags[0], SIP_NOVIDEO) ? "True" : "False");
06430       ast_log(LOG_DEBUG, "** Our prefcodec: %s \n", ast_getformatname_multiple(codecbuf, sizeof(codecbuf), p->prefcodec));
06431    }
06432    
06433 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS
06434    if (ast_test_flag(&p->t38.t38support, SIP_PAGE2_T38SUPPORT_RTP)) {
06435       ast_build_string(&m_audio_next, &m_audio_left, " %d", 191);
06436       ast_build_string(&a_audio_next, &a_audio_left, "a=rtpmap:%d %s/%d\r\n", 191, "t38", 8000);
06437    }
06438 #endif
06439 
06440    /* Check if we need video in this call */
06441    if ((capability & AST_FORMAT_VIDEO_MASK) && !ast_test_flag(&p->flags[0], SIP_NOVIDEO)) {
06442       if (p->vrtp) {
06443          needvideo = TRUE;
06444          if (option_debug > 1)
06445             ast_log(LOG_DEBUG, "This call needs video offers!\n");
06446       } else if (option_debug > 1)
06447          ast_log(LOG_DEBUG, "This call needs video offers, but there's no video support enabled!\n");
06448    }
06449       
06450 
06451    /* Ok, we need video. Let's add what we need for video and set codecs.
06452       Video is handled differently than audio since we can not transcode. */
06453    if (needvideo) {
06454       /* Determine video destination */
06455       if (p->vredirip.sin_addr.s_addr) {
06456          vdest.sin_addr = p->vredirip.sin_addr;
06457          vdest.sin_port = p->vredirip.sin_port;
06458       } else {
06459          vdest.sin_addr = p->ourip;
06460          vdest.sin_port = vsin.sin_port;
06461       }
06462       ast_build_string(&m_video_next, &m_video_left, "m=video %d RTP/AVP", ntohs(vdest.sin_port));
06463 
06464       /* Build max bitrate string */
06465       if (p->maxcallbitrate)
06466          snprintf(bandwidth, sizeof(bandwidth), "b=CT:%d\r\n", p->maxcallbitrate);
06467       if (debug) 
06468          ast_verbose("Video is at %s port %d\n", ast_inet_ntoa(p->ourip), ntohs(vsin.sin_port));   
06469    }
06470 
06471    if (debug) 
06472       ast_verbose("Audio is at %s port %d\n", ast_inet_ntoa(p->ourip), ntohs(sin.sin_port)); 
06473 
06474    /* Start building generic SDP headers */
06475 
06476    /* We break with the "recommendation" and send our IP, in order that our
06477       peer doesn't have to ast_gethostbyname() us */
06478 
06479    snprintf(owner, sizeof(owner), "o=root %d %d IN IP4 %s\r\n", p->sessionid, p->sessionversion, ast_inet_ntoa(dest.sin_addr));
06480    snprintf(connection, sizeof(connection), "c=IN IP4 %s\r\n", ast_inet_ntoa(dest.sin_addr));
06481    ast_build_string(&m_audio_next, &m_audio_left, "m=audio %d RTP/AVP", ntohs(dest.sin_port));
06482 
06483    if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) == SIP_PAGE2_CALL_ONHOLD_ONEDIR)
06484       hold = "a=recvonly\r\n";
06485    else if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) == SIP_PAGE2_CALL_ONHOLD_INACTIVE)
06486       hold = "a=inactive\r\n";
06487    else
06488       hold = "a=sendrecv\r\n";
06489 
06490    /* Now, start adding audio codecs. These are added in this order:
06491       - First what was requested by the calling channel
06492       - Then preferences in order from sip.conf device config for this peer/user
06493       - Then other codecs in capabilities, including video
06494    */
06495 
06496    /* Prefer the audio codec we were requested to use, first, no matter what 
06497       Note that p->prefcodec can include video codecs, so mask them out
06498     */
06499    if (capability & p->prefcodec) {
06500       int codec = p->prefcodec & AST_FORMAT_AUDIO_MASK;
06501 
06502       add_codec_to_sdp(p, codec, SDP_SAMPLE_RATE(codec),
06503              &m_audio_next, &m_audio_left,
06504              &a_audio_next, &a_audio_left,
06505              debug, &min_audio_packet_size);
06506       alreadysent |= codec;
06507    }
06508 
06509    /* Start by sending our preferred audio codecs */
06510    for (x = 0; x < 32; x++) {
06511       int codec;
06512 
06513       if (!(codec = ast_codec_pref_index(&p->prefs, x)))
06514          break; 
06515 
06516       if (!(capability & codec))
06517          continue;
06518 
06519       if (alreadysent & codec)
06520          continue;
06521 
06522       add_codec_to_sdp(p, codec, SDP_SAMPLE_RATE(codec),
06523              &m_audio_next, &m_audio_left,
06524              &a_audio_next, &a_audio_left,
06525              debug, &min_audio_packet_size);
06526       alreadysent |= codec;
06527    }
06528 
06529    /* Now send any other common audio and video codecs, and non-codec formats: */
06530    for (x = 1; x <= (needvideo ? AST_FORMAT_MAX_VIDEO : AST_FORMAT_MAX_AUDIO); x <<= 1) {
06531       if (!(capability & x))  /* Codec not requested */
06532          continue;
06533 
06534       if (alreadysent & x) /* Already added to SDP */
06535          continue;
06536 
06537       if (x <= AST_FORMAT_MAX_AUDIO)
06538          add_codec_to_sdp(p, x, SDP_SAMPLE_RATE(x),
06539                 &m_audio_next, &m_audio_left,
06540                 &a_audio_next, &a_audio_left,
06541                 debug, &min_audio_packet_size);
06542       else 
06543          add_codec_to_sdp(p, x, 90000,
06544                 &m_video_next, &m_video_left,
06545                 &a_video_next, &a_video_left,
06546                 debug, &min_video_packet_size);
06547    }
06548 
06549    /* Now add DTMF RFC2833 telephony-event as a codec */
06550    for (x = 1; x <= AST_RTP_MAX; x <<= 1) {
06551       if (!(p->jointnoncodeccapability & x))
06552          continue;
06553 
06554       add_noncodec_to_sdp(p, x, 8000,
06555                 &m_audio_next, &m_audio_left,
06556                 &a_audio_next, &a_audio_left,
06557                 debug);
06558    }
06559 
06560    if (option_debug > 2)
06561       ast_log(LOG_DEBUG, "-- Done with adding codecs to SDP\n");
06562 
06563    if (!p->owner || !ast_internal_timing_enabled(p->owner))
06564       ast_build_string(&a_audio_next, &a_audio_left, "a=silenceSupp:off - - - -\r\n");
06565 
06566    if (min_audio_packet_size)
06567       ast_build_string(&a_audio_next, &a_audio_left, "a=ptime:%d\r\n", min_audio_packet_size);
06568 
06569    if (min_video_packet_size)
06570       ast_build_string(&a_video_next, &a_video_left, "a=ptime:%d\r\n", min_video_packet_size);
06571 
06572    if ((m_audio_left < 2) || (m_video_left < 2) || (a_audio_left == 0) || (a_video_left == 0))
06573       ast_log(LOG_WARNING, "SIP SDP may be truncated due to undersized buffer!!\n");
06574 
06575    ast_build_string(&m_audio_next, &m_audio_left, "\r\n");
06576    if (needvideo)
06577       ast_build_string(&m_video_next, &m_video_left, "\r\n");
06578 
06579    len = strlen(version) + strlen(subject) + strlen(owner) + strlen(connection) + strlen(stime) + strlen(m_audio) + strlen(a_audio) + strlen(hold);
06580    if (needvideo) /* only if video response is appropriate */
06581       len += strlen(m_video) + strlen(a_video) + strlen(bandwidth) + strlen(hold);
06582 
06583    add_header(resp, "Content-Type", "application/sdp");
06584    add_header_contentLength(resp, len);
06585    add_line(resp, version);
06586    add_line(resp, owner);
06587    add_line(resp, subject);
06588    add_line(resp, connection);
06589    if (needvideo)    /* only if video response is appropriate */
06590       add_line(resp, bandwidth);
06591    add_line(resp, stime);
06592    add_line(resp, m_audio);
06593    add_line(resp, a_audio);
06594    add_line(resp, hold);
06595    if (needvideo) { /* only if video response is appropriate */
06596       add_line(resp, m_video);
06597       add_line(resp, a_video);
06598       add_line(resp, hold);   /* Repeat hold for the video stream */
06599    }
06600 
06601    /* Update lastrtprx when we send our SDP */
06602    p->lastrtprx = p->lastrtptx = time(NULL); /* XXX why both ? */
06603 
06604    if (option_debug > 2) {
06605       char buf[BUFSIZ];
06606       ast_log(LOG_DEBUG, "Done building SDP. Settling with this capability: %s\n", ast_getformatname_multiple(buf, BUFSIZ, capability));
06607    }
06608 
06609    return AST_SUCCESS;
06610 }

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

Add SIP domain to list of domains we are responsible for.

Definition at line 16096 of file chan_sip.c.

References ast_calloc, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), ast_strlen_zero(), domain::context, domain::domain, LOG_DEBUG, LOG_WARNING, domain::mode, and sipdebug.

Referenced by reload_config().

16097 {
16098    struct domain *d;
16099 
16100    if (ast_strlen_zero(domain)) {
16101       ast_log(LOG_WARNING, "Zero length domain.\n");
16102       return 1;
16103    }
16104 
16105    if (!(d = ast_calloc(1, sizeof(*d))))
16106       return 0;
16107 
16108    ast_copy_string(d->domain, domain, sizeof(d->domain));
16109 
16110    if (!ast_strlen_zero(context))
16111       ast_copy_string(d->context, context, sizeof(d->context));
16112 
16113    d->mode = mode;
16114 
16115    AST_LIST_LOCK(&domain_list);
16116    AST_LIST_INSERT_TAIL(&domain_list, d, list);
16117    AST_LIST_UNLOCK(&domain_list);
16118 
16119    if (sipdebug)  
16120       ast_log(LOG_DEBUG, "Added local SIP domain '%s'\n", domain);
16121 
16122    return 1;
16123 }

static int add_t38_sdp ( struct sip_request resp,
struct sip_pvt p 
) [static]

Add T.38 Session Description Protocol message.

Definition at line 6238 of file chan_sip.c.

References add_header(), add_header_contentLength(), add_line(), ast_build_string(), ast_inet_ntoa(), ast_log(), ast_udptl_get_local_max_datagram(), ast_udptl_get_us(), t38properties::capability, debug, t38properties::jointcapability, sip_pvt::lastrtprx, sip_pvt::lastrtptx, len, LOG_DEBUG, LOG_WARNING, sip_pvt::ourip, t38properties::peercapability, s, sip_pvt::sessionid, sip_pvt::sessionversion, sip_debug_test_pvt(), t, sip_pvt::t38, t38_get_rate(), T38FAX_FILL_BIT_REMOVAL, T38FAX_RATE_MANAGEMENT_LOCAL_TCF, T38FAX_TRANSCODING_JBIG, T38FAX_TRANSCODING_MMR, T38FAX_UDP_EC_NONE, T38FAX_UDP_EC_REDUNDANCY, T38FAX_VERSION, T38FAX_VERSION_0, T38FAX_VERSION_1, sip_pvt::udptl, and sip_pvt::udptlredirip.

Referenced by transmit_invite(), transmit_reinvite_with_t38_sdp(), and transmit_response_with_t38_sdp().

06239 {
06240    int len = 0;
06241    int x = 0;
06242    struct sockaddr_in udptlsin;
06243    char v[256] = "";
06244    char s[256] = "";
06245    char o[256] = "";
06246    char c[256] = "";
06247    char t[256] = "";
06248    char m_modem[256];
06249    char a_modem[1024];
06250    char *m_modem_next = m_modem;
06251    size_t m_modem_left = sizeof(m_modem);
06252    char *a_modem_next = a_modem;
06253    size_t a_modem_left = sizeof(a_modem);
06254    struct sockaddr_in udptldest = { 0, };
06255    int debug;
06256    
06257    debug = sip_debug_test_pvt(p);
06258    len = 0;
06259    if (!p->udptl) {
06260       ast_log(LOG_WARNING, "No way to add SDP without an UDPTL structure\n");
06261       return -1;
06262    }
06263    
06264    if (!p->sessionid) {
06265       p->sessionid = getpid();
06266       p->sessionversion = p->sessionid;
06267    } else
06268       p->sessionversion++;
06269    
06270    /* Our T.38 end is */
06271    ast_udptl_get_us(p->udptl, &udptlsin);
06272    
06273    /* Determine T.38 UDPTL destination */
06274    if (p->udptlredirip.sin_addr.s_addr) {
06275       udptldest.sin_port = p->udptlredirip.sin_port;
06276       udptldest.sin_addr = p->udptlredirip.sin_addr;
06277    } else {
06278       udptldest.sin_addr = p->ourip;
06279       udptldest.sin_port = udptlsin.sin_port;
06280    }
06281    
06282    if (debug) 
06283       ast_log(LOG_DEBUG, "T.38 UDPTL is at %s port %d\n", ast_inet_ntoa(p->ourip), ntohs(udptlsin.sin_port));
06284    
06285    /* We break with the "recommendation" and send our IP, in order that our
06286       peer doesn't have to ast_gethostbyname() us */
06287    
06288    if (debug) {
06289       ast_log(LOG_DEBUG, "Our T38 capability (%d), peer T38 capability (%d), joint capability (%d)\n",
06290          p->t38.capability,
06291          p->t38.peercapability,
06292          p->t38.jointcapability);
06293    }
06294    snprintf(v, sizeof(v), "v=0\r\n");
06295    snprintf(o, sizeof(o), "o=root %d %d IN IP4 %s\r\n", p->sessionid, p->sessionversion, ast_inet_ntoa(udptldest.sin_addr));
06296    snprintf(s, sizeof(s), "s=session\r\n");
06297    snprintf(c, sizeof(c), "c=IN IP4 %s\r\n", ast_inet_ntoa(udptldest.sin_addr));
06298    snprintf(t, sizeof(t), "t=0 0\r\n");
06299    ast_build_string(&m_modem_next, &m_modem_left, "m=image %d udptl t38\r\n", ntohs(udptldest.sin_port));
06300    
06301    if ((p->t38.jointcapability & T38FAX_VERSION) == T38FAX_VERSION_0)
06302       ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxVersion:0\r\n");
06303    if ((p->t38.jointcapability & T38FAX_VERSION) == T38FAX_VERSION_1)
06304       ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxVersion:1\r\n");
06305    if ((x = t38_get_rate(p->t38.jointcapability)))
06306       ast_build_string(&a_modem_next, &a_modem_left, "a=T38MaxBitRate:%d\r\n",x);
06307    ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxFillBitRemoval:%d\r\n", (p->t38.jointcapability & T38FAX_FILL_BIT_REMOVAL) ? 1 : 0);
06308    ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxTranscodingMMR:%d\r\n", (p->t38.jointcapability & T38FAX_TRANSCODING_MMR) ? 1 : 0);
06309    ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxTranscodingJBIG:%d\r\n", (p->t38.jointcapability & T38FAX_TRANSCODING_JBIG) ? 1 : 0);
06310    ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxRateManagement:%s\r\n", (p->t38.jointcapability & T38FAX_RATE_MANAGEMENT_LOCAL_TCF) ? "localTCF" : "transferredTCF");
06311    x = ast_udptl_get_local_max_datagram(p->udptl);
06312    ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxMaxBuffer:%d\r\n",x);
06313    ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxMaxDatagram:%d\r\n",x);
06314    if (p->t38.jointcapability != T38FAX_UDP_EC_NONE)
06315       ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxUdpEC:%s\r\n", (p->t38.jointcapability & T38FAX_UDP_EC_REDUNDANCY) ? "t38UDPRedundancy" : "t38UDPFEC");
06316    len = strlen(v) + strlen(s) + strlen(o) + strlen(c) + strlen(t) + strlen(m_modem) + strlen(a_modem);
06317    add_header(resp, "Content-Type", "application/sdp");
06318    add_header_contentLength(resp, len);
06319    add_line(resp, v);
06320    add_line(resp, o);
06321    add_line(resp, s);
06322    add_line(resp, c);
06323    add_line(resp, t);
06324    add_line(resp, m_modem);
06325    add_line(resp, a_modem);
06326    
06327    /* Update lastrtprx when we send our SDP */
06328    p->lastrtprx = p->lastrtptx = time(NULL);
06329    
06330    return 0;
06331 }

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

Add text body to SIP message.

Definition at line 6116 of file chan_sip.c.

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

Referenced by transmit_message_with_text().

06117 {
06118    /* XXX Convert \n's to \r\n's XXX */
06119    add_header(req, "Content-Type", "text/plain");
06120    add_header_contentLength(req, strlen(text));
06121    add_line(req, text);
06122    return 0;
06123 }

static int add_vidupdate ( struct sip_request req  )  [static]

add XML encoded media control with update

Note:
XML: The only way to turn 0 bits of information into a few hundred. (markster)

Definition at line 6140 of file chan_sip.c.

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

Referenced by transmit_info_with_vidupdate().

06141 {
06142    const char *xml_is_a_huge_waste_of_space =
06143       "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\r\n"
06144       " <media_control>\r\n"
06145       "  <vc_primitive>\r\n"
06146       "   <to_encoder>\r\n"
06147       "    <picture_fast_update>\r\n"
06148       "    </picture_fast_update>\r\n"
06149       "   </to_encoder>\r\n"
06150       "  </vc_primitive>\r\n"
06151       " </media_control>\r\n";
06152    add_header(req, "Content-Type", "application/media_control+xml");
06153    add_header_contentLength(req, strlen(xml_is_a_huge_waste_of_space));
06154    add_line(req, xml_is_a_huge_waste_of_space);
06155    return 0;
06156 }

static void append_date ( struct sip_request req  )  [static]

Append date to SIP message.

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

06064 {
06065    char tmpdat[256];
06066    struct tm tm;
06067    time_t t = time(NULL);
06068 
06069    gmtime_r(&t, &tm);
06070    strftime(tmpdat, sizeof(tmpdat), "%a, %d %b %Y %T GMT", &tm);
06071    add_header(req, "Date", tmpdat);
06072 }

static void append_history_full ( struct sip_pvt p,
const char *  fmt,
  ... 
) [static]

Append to SIP dialog history with arg list.

Definition at line 1872 of file chan_sip.c.

References append_history_va(), ast_test_flag, sip_pvt::flags, and SIP_NO_HISTORY.

01873 {
01874    va_list ap;
01875 
01876    if (!p)
01877       return;
01878 
01879    if (ast_test_flag(&p->flags[0], SIP_NO_HISTORY) 
01880       && !recordhistory && !dumphistory) {
01881       return;
01882    }
01883 
01884    va_start(ap, fmt);
01885    append_history_va(p, fmt, ap);
01886    va_end(ap);
01887 
01888    return;
01889 }

static void static void append_history_va ( struct sip_pvt p,
const char *  fmt,
va_list  ap 
) [static]

Append to SIP dialog history with arg list.

Definition at line 1845 of file chan_sip.c.

References ast_calloc, AST_LIST_INSERT_TAIL, AST_LIST_REMOVE_HEAD, free, MAX_HISTORY_ENTRIES, and strsep().

Referenced by append_history_full().

01846 {
01847    char buf[80], *c = buf; /* max history length */
01848    struct sip_history *hist;
01849    int l;
01850 
01851    vsnprintf(buf, sizeof(buf), fmt, ap);
01852    strsep(&c, "\r\n"); /* Trim up everything after \r or \n */
01853    l = strlen(buf) + 1;
01854    if (!(hist = ast_calloc(1, sizeof(*hist) + l)))
01855       return;
01856    if (!p->history && !(p->history = ast_calloc(1, sizeof(*p->history)))) {
01857       free(hist);
01858       return;
01859    }
01860    memcpy(hist->event, buf, l);
01861    if (p->history_entries == MAX_HISTORY_ENTRIES) {
01862       struct sip_history *oldest;
01863       oldest = AST_LIST_REMOVE_HEAD(p->history, list);
01864       p->history_entries--;
01865       free(oldest);
01866    }
01867    AST_LIST_INSERT_TAIL(p->history, hist, list);
01868    p->history_entries++;
01869 }

AST_LIST_HEAD_NOLOCK ( sip_history_head  ,
sip_history   
)

history list, entry in sip_pvt

static AST_LIST_HEAD_STATIC ( domain_list  ,
domain   
) [static]

The SIP domain list

AST_MODULE_INFO ( ASTERISK_GPL_KEY  ,
AST_MODFLAG_DEFAULT  ,
"Session Initiation Protocol (SIP)"  ,
load = load_module,
unload = unload_module,
reload = reload 
)

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 SIP dialog list (of sip_pvt's).

static void ast_quiet_chan ( struct ast_channel chan  )  [static]

Turn off generator data XXX Does this function belong in the SIP channel?

Definition at line 13135 of file chan_sip.c.

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

Referenced by attempt_transfer(), and handle_invite_replaces().

13136 {
13137    if (chan && chan->_state == AST_STATE_UP) {
13138       if (chan->generatordata)
13139          ast_deactivate_generator(chan);
13140    }
13141 }

static enum sip_result ast_sip_ouraddrfor ( struct in_addr *  them,
struct in_addr *  us 
) [static]

NAT fix - decide which IP address to use for ASterisk server?

Using the localaddr structure built up with localnet statements in sip.conf apply it to their address to see if we need to substitute our externip or can get away with our internal bindaddr

Definition at line 1805 of file chan_sip.c.

References ast_apply_ha(), ast_gethostbyname(), ast_inet_ntoa(), ast_log(), ast_ouraddrfor(), AST_SUCCESS, bindaddr, externexpire, externhost, externip, externrefresh, hp, localaddr, LOG_DEBUG, LOG_NOTICE, and option_debug.

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

01806 {
01807    struct sockaddr_in theirs, ours;
01808 
01809    /* Get our local information */
01810    ast_ouraddrfor(them, us);
01811    theirs.sin_addr = *them;
01812    ours.sin_addr = *us;
01813 
01814    if (localaddr && externip.sin_addr.s_addr &&
01815        (ast_apply_ha(localaddr, &theirs)) &&
01816        (!global_matchexterniplocally || !ast_apply_ha(localaddr, &ours))) {
01817       if (externexpire && time(NULL) >= externexpire) {
01818          struct ast_hostent ahp;
01819          struct hostent *hp;
01820 
01821          externexpire = time(NULL) + externrefresh;
01822          if ((hp = ast_gethostbyname(externhost, &ahp))) {
01823             memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr));
01824          } else
01825             ast_log(LOG_NOTICE, "Warning: Re-lookup of '%s' failed!\n", externhost);
01826       }
01827       *us = externip.sin_addr;
01828       if (option_debug) {
01829          ast_log(LOG_DEBUG, "Target address %s is not local, substituting externip\n", 
01830             ast_inet_ntoa(*(struct in_addr *)&them->s_addr));
01831       }
01832    } else if (bindaddr.sin_addr.s_addr)
01833       *us = bindaddr.sin_addr;
01834    return AST_SUCCESS;
01835 }

AST_THREADSTORAGE_CUSTOM ( ts_temp_pvt  ,
temp_pvt_init  ,
temp_pvt_cleanup   
)

A per-thread temporary pvt structure.

static int attempt_transfer ( struct sip_dual transferer,
struct sip_dual target 
) [static]

Attempt transfer of SIP call This fix for attended transfers on a local PBX.

Definition at line 13145 of file chan_sip.c.

References ast_channel::_state, ast_cdr_append(), ast_channel_masquerade(), ast_log(), ast_quiet_chan(), AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), ast_state2str(), ast_channel::cdr, sip_dual::chan1, sip_dual::chan2, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, and option_debug.

13146 {
13147    int res = 0;
13148    struct ast_channel *peera = NULL,   
13149       *peerb = NULL,
13150       *peerc = NULL,
13151       *peerd = NULL;
13152 
13153 
13154    /* We will try to connect the transferee with the target and hangup
13155       all channels to the transferer */   
13156    if (option_debug > 3) {
13157       ast_log(LOG_DEBUG, "Sip transfer:--------------------\n");
13158       if (transferer->chan1)
13159          ast_log(LOG_DEBUG, "-- Transferer to PBX channel: %s State %s\n", transferer->chan1->name, ast_state2str(transferer->chan1->_state));
13160       else
13161          ast_log(LOG_DEBUG, "-- No transferer first channel - odd??? \n");
13162       if (target->chan1)
13163          ast_log(LOG_DEBUG, "-- Transferer to PBX second channel (target): %s State %s\n", target->chan1->name, ast_state2str(target->chan1->_state));
13164       else
13165          ast_log(LOG_DEBUG, "-- No target first channel ---\n");
13166       if (transferer->chan2)
13167          ast_log(LOG_DEBUG, "-- Bridged call to transferee: %s State %s\n", transferer->chan2->name, ast_state2str(transferer->chan2->_state));
13168       else
13169          ast_log(LOG_DEBUG, "-- No bridged call to transferee\n");
13170       if (target->chan2)
13171          ast_log(LOG_DEBUG, "-- Bridged call to transfer target: %s State %s\n", target->chan2 ? target->chan2->name : "<none>", target->chan2 ? ast_state2str(target->chan2->_state) : "(none)");
13172       else
13173          ast_log(LOG_DEBUG, "-- No target second channel ---\n");
13174       ast_log(LOG_DEBUG, "-- END Sip transfer:--------------------\n");
13175    }
13176    if (transferer->chan2) { /* We have a bridge on the transferer's channel */
13177       peera = transferer->chan1; /* Transferer - PBX -> transferee channel * the one we hangup */
13178       peerb = target->chan1;     /* Transferer - PBX -> target channel - This will get lost in masq */
13179       peerc = transferer->chan2; /* Asterisk to Transferee */
13180       peerd = target->chan2;     /* Asterisk to Target */
13181       if (option_debug > 2)
13182          ast_log(LOG_DEBUG, "SIP transfer: Four channels to handle\n");
13183    } else if (target->chan2) {   /* Transferer has no bridge (IVR), but transferee */
13184       peera = target->chan1;     /* Transferer to PBX -> target channel */
13185       peerb = transferer->chan1; /* Transferer to IVR*/
13186       peerc = target->chan2;     /* Asterisk to Target */
13187       peerd = transferer->chan2; /* Nothing */
13188       if (option_debug > 2)
13189          ast_log(LOG_DEBUG, "SIP transfer: Three channels to handle\n");
13190    }
13191 
13192    if (peera && peerb && peerc && (peerb != peerc)) {
13193       ast_quiet_chan(peera);     /* Stop generators */
13194       ast_quiet_chan(peerb);  
13195       ast_quiet_chan(peerc);
13196       if (peerd)
13197          ast_quiet_chan(peerd);
13198 
13199       /* Fix CDRs so they're attached to the remaining channel */
13200       if (peera->cdr && peerb->cdr)
13201          peerb->cdr = ast_cdr_append(peerb->cdr, peera->cdr);
13202       else if (peera->cdr) 
13203          peerb->cdr = peera->cdr;
13204       peera->cdr = NULL;
13205 
13206       if (peerb->cdr && peerc->cdr) 
13207          peerb->cdr = ast_cdr_append(peerb->cdr, peerc->cdr);
13208       else if (peerc->cdr)
13209          peerb->cdr = peerc->cdr;
13210       peerc->cdr = NULL;
13211    
13212       if (option_debug > 3)
13213          ast_log(LOG_DEBUG, "SIP transfer: trying to masquerade %s into %s\n", peerc->name, peerb->name);
13214       if (ast_channel_masquerade(peerb, peerc)) {
13215          ast_log(LOG_WARNING, "Failed to masquerade %s into %s\n", peerb->name, peerc->name);
13216          res = -1;
13217       } else
13218          ast_log(LOG_DEBUG, "SIP transfer: Succeeded to masquerade channels.\n");
13219       return res;
13220    } else {
13221       ast_log(LOG_NOTICE, "SIP Transfer attempted with no appropriate bridged calls to transfer\n");
13222       if (transferer->chan1)
13223          ast_softhangup_nolock(transferer->chan1, AST_SOFTHANGUP_DEV);
13224       if (target->chan1)
13225          ast_softhangup_nolock(target->chan1, AST_SOFTHANGUP_DEV);
13226       return -2;
13227    }
13228    return 0;
13229 }

static int auto_congest ( const void *  nothing  )  [static]

Scheduled congestion on a call.

Definition at line 2911 of file chan_sip.c.

References append_history, ast_channel_trylock, ast_channel_unlock, AST_CONTROL_CONGESTION, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_queue_control(), sip_pvt::initid, sip_pvt::lock, LOG_NOTICE, and sip_pvt::owner.

02912 {
02913    struct sip_pvt *p = (struct sip_pvt *)nothing;
02914 
02915    ast_mutex_lock(&p->lock);
02916    p->initid = -1;
02917    if (p->owner) {
02918       /* XXX fails on possible deadlock */
02919       if (!ast_channel_trylock(p->owner)) {
02920          ast_log(LOG_NOTICE, "Auto-congesting %s\n", p->owner->name);
02921          append_history(p, "Cong", "Auto-congesting (timer)");
02922          ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
02923          ast_channel_unlock(p->owner);
02924       }
02925    }
02926    ast_mutex_unlock(&p->lock);
02927    return 0;
02928 }

static void build_callid_pvt ( struct sip_pvt pvt  )  [static]

Build SIP Call-ID value for a non-REGISTER transaction.

Definition at line 4363 of file chan_sip.c.

References ast_inet_ntoa(), ast_string_field_build, generate_random_string(), sip_pvt::ourip, and S_OR.

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

04364 {
04365    char buf[33];
04366 
04367    const char *host = S_OR(pvt->fromdomain, ast_inet_ntoa(pvt->ourip));
04368    
04369    ast_string_field_build(pvt, callid, "%s@%s", generate_random_string(buf, sizeof(buf)), host);
04370 
04371 }

static void build_callid_registry ( struct sip_registry reg,
struct in_addr  ourip,
const char *  fromdomain 
) [static]

Build SIP Call-ID value for a REGISTER transaction.

Definition at line 4374 of file chan_sip.c.

References ast_inet_ntoa(), ast_string_field_build, generate_random_string(), and S_OR.

Referenced by transmit_register().

04375 {
04376    char buf[33];
04377 
04378    const char *host = S_OR(fromdomain, ast_inet_ntoa(ourip));
04379 
04380    ast_string_field_build(reg, callid, "%s@%s", generate_random_string(buf, sizeof(buf)), host);
04381 }

static void build_contact ( struct sip_pvt p  )  [static]

Build contact header - the contact header we send out.

Definition at line 6781 of file chan_sip.c.

References ast_inet_ntoa(), ast_string_field_build, ast_strlen_zero(), sip_pvt::ourip, ourport, and STANDARD_SIP_PORT.

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

06782 {
06783    /* Construct Contact: header */
06784    if (ourport != STANDARD_SIP_PORT)
06785       ast_string_field_build(p, our_contact, "<sip:%s%s%s:%d>", p->exten, ast_strlen_zero(p->exten) ? "" : "@", ast_inet_ntoa(p->ourip), ourport);
06786    else
06787       ast_string_field_build(p, our_contact, "<sip:%s%s%s>", p->exten, ast_strlen_zero(p->exten) ? "" : "@", ast_inet_ntoa(p->ourip));
06788 }

static struct sip_peer * build_peer ( const char *  name,
struct ast_variable v,
struct ast_variable alt,
int  realtime 
) [static, read]

Build peer from configuration (file or realtime static/dynamic).

Definition at line 16426 of file chan_sip.c.

References sip_peer::accountcode, add_realm_authentication(), sip_peer::addr, sip_peer::allowtransfer, sip_peer::amaflags, ast_append_ha(), ast_callerid_split(), ast_calloc, ast_cdr_amaflags2int(), ast_clear_flag, ast_copy_flags, ast_free_ha(), ast_get_group(), ast_get_ip(), ast_get_ip_or_srv(), ast_get_time_t(), 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_FLAG_MARKED, ASTOBJ_INIT, ASTOBJ_UNMARK, ASTOBJ_UNREF, sip_peer::auth, sip_peer::autoframing, sip_peer::call_limit, sip_peer::callgroup, sip_peer::callingpres, sip_peer::capability, sip_peer::chanvars, sip_peer::cid_name, sip_peer::cid_num, clear_realm_authentication(), sip_peer::context, sip_peer::defaddr, DEFAULT_MAXMS, destroy_association(), sip_peer::expire, ast_flags::flags, sip_peer::flags, sip_peer::fromdomain, sip_peer::fromuser, sip_peer::fullcontact, sip_peer::ha, handle_common_options(), sip_peer::language, sip_peer::lastmsgssent, ast_variable::lineno, LOG_DEBUG, LOG_WARNING, sip_peer::mailbox, sip_peer::maxcallbitrate, sip_peer::maxms, sip_peer::md5secret, sip_peer::mohinterpret, sip_peer::mohsuggest, ast_variable::name, ast_variable::next, option_debug, peerl, sip_peer::pickupgroup, sip_peer::prefs, reg_source_db(), sip_peer::regexten, sip_peer::rtpholdtimeout, sip_peer::rtpkeepalive, sip_peer::rtptimeout, sip_peer::secret, set_peer_defaults(), sip_destroy_peer(), SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PAGE2_DYNAMIC, SIP_PAGE2_IGNOREREGEXPIRE, SIP_PAGE2_RT_FROMCONTACT, SIP_PAGE2_SUBSCRIBEMWIONLY, SIP_REALTIME, SIP_USEREQPHONE, STANDARD_SIP_PORT, sip_peer::subscribecontext, sip_peer::tohost, TRANSFER_CLOSED, TRANSFER_OPENFORALL, TRUE, sip_peer::username, ast_variable::value, and sip_peer::vmexten.

16427 {
16428    struct sip_peer *peer = NULL;
16429    struct ast_ha *oldha = NULL;
16430    int obproxyfound=0;
16431    int found=0;
16432    int firstpass=1;
16433    int format=0;     /* Ama flags */
16434    time_t regseconds = 0;
16435    char *varname = NULL, *varval = NULL;
16436    struct ast_variable *tmpvar = NULL;
16437    struct ast_flags peerflags[2] = {{(0)}};
16438    struct ast_flags mask[2] = {{(0)}};
16439 
16440 
16441    if (!realtime)
16442       /* Note we do NOT use find_peer here, to avoid realtime recursion */
16443       /* We also use a case-sensitive comparison (unlike find_peer) so
16444          that case changes made to the peer name will be properly handled
16445          during reload
16446       */
16447       peer = ASTOBJ_CONTAINER_FIND_UNLINK_FULL(&peerl, name, name, 0, 0, strcmp);
16448 
16449    if (peer) {
16450       /* Already in the list, remove it and it will be added back (or FREE'd)  */
16451       found = 1;
16452       if (!(peer->objflags & ASTOBJ_FLAG_MARKED))
16453          firstpass = 0;
16454    } else {
16455       if (!(peer = ast_calloc(1, sizeof(*peer))))
16456          return NULL;
16457 
16458       if (realtime)
16459          rpeerobjs++;
16460       else
16461          speerobjs++;
16462       ASTOBJ_INIT(peer);
16463    }
16464    /* Note that our peer HAS had its reference count incrased */
16465    if (firstpass) {
16466       peer->lastmsgssent = -1;
16467       oldha = peer->ha;
16468       peer->ha = NULL;
16469       set_peer_defaults(peer);   /* Set peer defaults */
16470    }
16471    if (!found && name)
16472          ast_copy_string(peer->name, name, sizeof(peer->name));
16473 
16474    /* If we have channel variables, remove them (reload) */
16475    if (peer->chanvars) {
16476       ast_variables_destroy(peer->chanvars);
16477       peer->chanvars = NULL;
16478       /* XXX should unregister ? */
16479    }
16480 
16481    /* If we have realm authentication information, remove them (reload) */
16482    clear_realm_authentication(peer->auth);
16483    peer->auth = NULL;
16484 
16485    for (; v || ((v = alt) && !(alt=NULL)); v = v->next) {
16486       if (handle_common_options(&peerflags[0], &mask[0], v))
16487          continue;
16488       if (realtime && !strcasecmp(v->name, "regseconds")) {
16489          ast_get_time_t(v->value, &regseconds, 0, NULL);
16490       } else if (realtime && !strcasecmp(v->name, "ipaddr") && !ast_strlen_zero(v->value) ) {
16491          inet_aton(v->value, &(peer->addr.sin_addr));
16492       } else if (realtime && !strcasecmp(v->name, "name"))
16493          ast_copy_string(peer->name, v->value, sizeof(peer->name));
16494       else if (realtime && !strcasecmp(v->name, "fullcontact")) {
16495          ast_copy_string(peer->fullcontact, v->value, sizeof(peer->fullcontact));
16496          ast_set_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT);
16497       } else if (!strcasecmp(v->name, "secret")) 
16498          ast_copy_string(peer->secret, v->value, sizeof(peer->secret));
16499       else if (!strcasecmp(v->name, "md5secret")) 
16500          ast_copy_string(peer->md5secret, v->value, sizeof(peer->md5secret));
16501       else if (!strcasecmp(v->name, "auth"))
16502          peer->auth = add_realm_authentication(peer->auth, v->value, v->lineno);
16503       else if (!strcasecmp(v->name, "callerid")) {
16504          ast_callerid_split(v->value, peer->cid_name, sizeof(peer->cid_name), peer->cid_num, sizeof(peer->cid_num));
16505       } else if (!strcasecmp(v->name, "fullname")) {
16506          ast_copy_string(peer->cid_name, v->value, sizeof(peer->cid_name));
16507       } else if (!strcasecmp(v->name, "cid_number")) {
16508          ast_copy_string(peer->cid_num, v->value, sizeof(peer->cid_num));
16509       } else if (!strcasecmp(v->name, "context")) {
16510          ast_copy_string(peer->context, v->value, sizeof(peer->context));
16511       } else if (!strcasecmp(v->name, "subscribecontext")) {
16512          ast_copy_string(peer->subscribecontext, v->value, sizeof(peer->subscribecontext));
16513       } else if (!strcasecmp(v->name, "fromdomain")) {
16514          ast_copy_string(peer->fromdomain, v->value, sizeof(peer->fromdomain));
16515       } else if (!strcasecmp(v->name, "usereqphone")) {
16516          ast_set2_flag(&peer->flags[0], ast_true(v->value), SIP_USEREQPHONE);
16517       } else if (!strcasecmp(v->name, "fromuser")) {
16518          ast_copy_string(peer->fromuser, v->value, sizeof(peer->fromuser));
16519       } else if (!strcasecmp(v->name, "host") || !strcasecmp(v->name, "outboundproxy")) {
16520          if (!strcasecmp(v->value, "dynamic")) {
16521             if (!strcasecmp(v->name, "outboundproxy") || obproxyfound) {
16522                ast_log(LOG_WARNING, "You can't have a dynamic outbound proxy, you big silly head at line %d.\n", v->lineno);
16523             } else {
16524                /* They'll register with us */
16525                if (!found || !ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)) {
16526                   /* Initialize stuff if this is a new peer, or if it used to be
16527                    * non-dynamic before the reload. */
16528                   memset(&peer->addr.sin_addr, 0, 4);
16529                   if (peer->addr.sin_port) {
16530                      /* If we've already got a port, make it the default rather than absolute */
16531                      peer->defaddr.sin_port = peer->addr.sin_port;
16532                      peer->addr.sin_port = 0;
16533                   }
16534                }
16535                ast_set_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC);
16536             }
16537          } else {
16538             /* Non-dynamic.  Make sure we become that way if we're not */
16539             if (peer->expire > -1)
16540                ast_sched_del(sched, peer->expire);
16541             peer->expire = -1;
16542             ast_clear_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC);
16543             if (!obproxyfound || !strcasecmp(v->name, "outboundproxy")) {
16544                if (ast_get_ip_or_srv(&peer->addr, v->value, srvlookup ? "_sip._udp" : NULL)) {
16545                   ASTOBJ_UNREF(peer, sip_destroy_peer);
16546                   return NULL;
16547                }
16548             }
16549             if (!strcasecmp(v->name, "outboundproxy"))
16550                obproxyfound=1;
16551             else {
16552                ast_copy_string(peer->tohost, v->value, sizeof(peer->tohost));
16553                if (!peer->addr.sin_port)
16554                   peer->addr.sin_port = htons(STANDARD_SIP_PORT);
16555             }
16556          }
16557       } else if (!strcasecmp(v->name, "defaultip")) {
16558          if (ast_get_ip(&peer->defaddr, v->value)) {
16559             ASTOBJ_UNREF(peer, sip_destroy_peer);
16560             return NULL;
16561          }
16562       } else if (!strcasecmp(v->name, "permit") || !strcasecmp(v->name, "deny")) {
16563          peer->ha = ast_append_ha(v->name, v->value, peer->ha);
16564       } else if (!strcasecmp(v->name, "port")) {
16565          if (!realtime && ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC))
16566             peer->defaddr.sin_port = htons(atoi(v->value));
16567          else
16568             peer->addr.sin_port = htons(atoi(v->value));
16569       } else if (!strcasecmp(v->name, "callingpres")) {
16570          peer->callingpres = ast_parse_caller_presentation(v->value);
16571          if (peer->callingpres == -1)
16572             peer->callingpres = atoi(v->value);
16573       } else if (!strcasecmp(v->name, "username")) {
16574          ast_copy_string(peer->username, v->value, sizeof(peer->username));
16575       } else if (!strcasecmp(v->name, "language")) {
16576          ast_copy_string(peer->language, v->value, sizeof(peer->language));
16577       } else if (!strcasecmp(v->name, "regexten")) {
16578          ast_copy_string(peer->regexten, v->value, sizeof(peer->regexten));
16579       } else if (!strcasecmp(v->name, "call-limit") || !strcasecmp(v->name, "incominglimit")) {
16580          peer->call_limit = atoi(v->value);
16581          if (peer->call_limit < 0)
16582             peer->call_limit = 0;
16583       } else if (!strcasecmp(v->name, "amaflags")) {
16584          format = ast_cdr_amaflags2int(v->value);
16585          if (format < 0) {
16586             ast_log(LOG_WARNING, "Invalid AMA Flags for peer: %s at line %d\n", v->value, v->lineno);
16587          } else {
16588             peer->amaflags = format;
16589          }
16590       } else if (!strcasecmp(v->name, "accountcode")) {
16591          ast_copy_string(peer->accountcode, v->value, sizeof(peer->accountcode));
16592       } else if (!strcasecmp(v->name, "mohinterpret")
16593          || !strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) {
16594          ast_copy_string(peer->mohinterpret, v->value, sizeof(peer->mohinterpret));
16595       } else if (!strcasecmp(v->name, "mohsuggest")) {
16596          ast_copy_string(peer->mohsuggest, v->value, sizeof(peer->mohsuggest));
16597       } else if (!strcasecmp(v->name, "mailbox")) {
16598          ast_copy_string(peer->mailbox, v->value, sizeof(peer->mailbox));
16599       } else if (!strcasecmp(v->name, "subscribemwi")) {
16600          ast_set2_flag(&peer->flags[1], ast_true(v->value), SIP_PAGE2_SUBSCRIBEMWIONLY);
16601       } else if (!strcasecmp(v->name, "vmexten")) {
16602          ast_copy_string(peer->vmexten, v->value, sizeof(peer->vmexten));
16603       } else if (!strcasecmp(v->name, "callgroup")) {
16604          peer->callgroup = ast_get_group(v->value);
16605       } else if (!strcasecmp(v->name, "allowtransfer")) {
16606          peer->allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED;
16607       } else if (!strcasecmp(v->name, "pickupgroup")) {
16608          peer->pickupgroup = ast_get_group(v->value);
16609       } else if (!strcasecmp(v->name, "allow")) {
16610          ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1);
16611       } else if (!strcasecmp(v->name, "disallow")) {
16612          ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0);
16613       } else if (!strcasecmp(v->name, "autoframing")) {
16614          peer->autoframing = ast_true(v->value);
16615       } else if (!strcasecmp(v->name, "rtptimeout")) {
16616          if ((sscanf(v->value, "%d", &peer->rtptimeout) != 1) || (peer->rtptimeout < 0)) {
16617             ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d.  Using default.\n", v->value, v->lineno);
16618             peer->rtptimeout = global_rtptimeout;
16619          }
16620       } else if (!strcasecmp(v->name, "rtpholdtimeout")) {
16621          if ((sscanf(v->value, "%d", &peer->rtpholdtimeout) != 1) || (peer->rtpholdtimeout < 0)) {
16622             ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d.  Using default.\n", v->value, v->lineno);
16623             peer->rtpholdtimeout = global_rtpholdtimeout;
16624          }
16625       } else if (!strcasecmp(v->name, "rtpkeepalive")) {
16626          if ((sscanf(v->value, "%d", &peer->rtpkeepalive) != 1) || (peer->rtpkeepalive < 0)) {
16627             ast_log(LOG_WARNING, "'%s' is not a valid RTP keepalive time at line %d.  Using default.\n", v->value, v->lineno);
16628             peer->rtpkeepalive = global_rtpkeepalive;
16629          }
16630       } else if (!strcasecmp(v->name, "setvar")) {
16631          /* Set peer channel variable */
16632          varname = ast_strdupa(v->value);
16633          if ((varval = strchr(varname, '='))) {
16634             *varval++ = '\0';
16635             if ((tmpvar = ast_variable_new(varname, varval))) {
16636                tmpvar->next = peer->chanvars;
16637                peer->chanvars = tmpvar;
16638             }
16639          }
16640       } else if (!strcasecmp(v->name, "qualify")) {
16641          if (!strcasecmp(v->value, "no")) {
16642             peer->maxms = 0;
16643          } else if (!strcasecmp(v->value, "yes")) {
16644             peer->maxms = default_qualify ? default_qualify : DEFAULT_MAXMS;
16645          } else if (sscanf(v->value, "%d", &peer->maxms) != 1) {
16646             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);
16647             peer->maxms = 0;
16648          }
16649       } else if (!strcasecmp(v->name, "maxcallbitrate")) {
16650          peer->maxcallbitrate = atoi(v->value);
16651          if (peer->maxcallbitrate < 0)
16652             peer->maxcallbitrate = default_maxcallbitrate;
16653       }
16654    }
16655    if (!ast_test_flag(&global_flags[1], SIP_PAGE2_IGNOREREGEXPIRE) && ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC) && realtime) {
16656       time_t nowtime = time(NULL);
16657 
16658       if ((nowtime - regseconds) > 0) {
16659          destroy_association(peer);
16660          memset(&peer->addr, 0, sizeof(peer->addr));
16661          if (option_debug)
16662             ast_log(LOG_DEBUG, "Bah, we're expired (%d/%d/%d)!\n", (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
16663       }
16664    }
16665    ast_copy_flags(&peer->flags[0], &peerflags[0], mask[0].flags);
16666    ast_copy_flags(&peer->flags[1], &peerflags[1], mask[1].flags);
16667    if (ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE))
16668       global_allowsubscribe = TRUE; /* No global ban any more */
16669    if (!found && ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC) && !ast_test_flag(&peer->flags[0], SIP_REALTIME))
16670       reg_source_db(peer);
16671    ASTOBJ_UNMARK(peer);
16672    ast_free_ha(oldha);
16673    return peer;
16674 }

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

Build reply digest.

Returns:
Returns -1 if we have no auth
Note:
Build digest challenge for authentication of peers (for registration) and users (for calls). Also used for authentication of CANCEL and BYE

Definition at line 11458 of file chan_sip.c.

References append_history, ast_inet_ntoa(), ast_log(), ast_md5_hash(), ast_random(), ast_strlen_zero(), authl, find_realm_authentication(), LOG_DEBUG, LOG_WARNING, sip_auth::md5secret, sip_pvt::noncecount, sip_pvt::sa, sip_auth::secret, secret, sip_methods, sipdebug, text, sip_auth::username, and username.

Referenced by reply_digest(), transmit_register(), and transmit_request_with_auth().

11459 {
11460    char a1[256];
11461    char a2[256];
11462    char a1_hash[256];
11463    char a2_hash[256];
11464    char resp[256];
11465    char resp_hash[256];
11466    char uri[256];
11467    char cnonce[80];
11468    const char *username;
11469    const char *secret;
11470    const char *md5secret;
11471    struct sip_auth *auth = NULL; /* Realm authentication */
11472 
11473    if (!ast_strlen_zero(p->domain))
11474       ast_copy_string(uri, p->domain, sizeof(uri));
11475    else if (!ast_strlen_zero(p->uri))
11476       ast_copy_string(uri, p->uri, sizeof(uri));
11477    else
11478       snprintf(uri, sizeof(uri), "sip:%s@%s",p->username, ast_inet_ntoa(p->sa.sin_addr));
11479 
11480    snprintf(cnonce, sizeof(cnonce), "%08lx", ast_random());
11481 
11482    /* Check if we have separate auth credentials */
11483    if ((auth = find_realm_authentication(authl, p->realm))) {
11484       ast_log(LOG_WARNING, "use realm [%s] from peer [%s][%s]\n",
11485          auth->username, p->peername, p->username);
11486       username = auth->username;
11487       secret = auth->secret;
11488       md5secret = auth->md5secret;
11489       if (sipdebug)
11490          ast_log(LOG_DEBUG,"Using realm %s authentication for call %s\n", p->realm, p->callid);
11491    } else {
11492       /* No authentication, use peer or register= config */
11493       username = p->authname;
11494       secret =  p->peersecret;
11495       md5secret = p->peermd5secret;
11496    }
11497    if (ast_strlen_zero(username))   /* We have no authentication */
11498       return -1;
11499 
11500    /* Calculate SIP digest response */
11501    snprintf(a1,sizeof(a1),"%s:%s:%s", username, p->realm, secret);
11502    snprintf(a2,sizeof(a2),"%s:%s", sip_methods[method].text, uri);
11503    if (!ast_strlen_zero(md5secret))
11504       ast_copy_string(a1_hash, md5secret, sizeof(a1_hash));
11505    else
11506       ast_md5_hash(a1_hash,a1);
11507    ast_md5_hash(a2_hash,a2);
11508 
11509    p->noncecount++;
11510    if (!ast_strlen_zero(p->qop))
11511       snprintf(resp,sizeof(resp),"%s:%s:%08x:%s:%s:%s", a1_hash, p->nonce, p->noncecount, cnonce, "auth", a2_hash);
11512    else
11513       snprintf(resp,sizeof(resp),"%s:%s:%s", a1_hash, p->nonce, a2_hash);
11514    ast_md5_hash(resp_hash, resp);
11515    /* XXX We hard code our qop to "auth" for now.  XXX */
11516    if (!ast_strlen_zero(p->qop))
11517       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);
11518    else
11519       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);
11520 
11521    append_history(p, "AuthResp", "Auth response sent for %s in realm %s - nc %d", username, p->realm, p->noncecount);
11522 
11523    return 0;
11524 }

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

Build route list from Record-Route header.

Definition at line 8178 of file chan_sip.c.

References __get_header(), ast_log(), ast_malloc, ast_strlen_zero(), free_old_route(), get_header(), sip_route::hop, len, list_route(), LOG_DEBUG, sip_route::next, option_debug, sip_pvt::route, sip_pvt::route_persistant, and sip_debug_test_pvt().

Referenced by handle_request_invite(), and handle_response_invite().

08179 {
08180    struct sip_route *thishop, *head, *tail;
08181    int start = 0;
08182    int len;
08183    const char *rr, *contact, *c;
08184 
08185    /* Once a persistant route is set, don't fool with it */
08186    if (p->route && p->route_persistant) {
08187       if (option_debug)
08188          ast_log(LOG_DEBUG, "build_route: Retaining previous route: <%s>\n", p->route->hop);
08189       return;
08190    }
08191 
08192    if (p->route) {
08193       free_old_route(p->route);
08194       p->route = NULL;
08195    }
08196    
08197    p->route_persistant = backwards;
08198    
08199    /* Build a tailq, then assign it to p->route when done.
08200     * If backwards, we add entries from the head so they end up
08201     * in reverse order. However, we do need to maintain a correct
08202     * tail pointer because the contact is always at the end.
08203     */
08204    head = NULL;
08205    tail = head;
08206    /* 1st we pass through all the hops in any Record-Route headers */
08207    for (;;) {
08208       /* Each Record-Route header */
08209       rr = __get_header(req, "Record-Route", &start);
08210       if (*rr == '\0')
08211          break;
08212       for (; (rr = strchr(rr, '<')) ; rr += len) { /* Each route entry */
08213          ++rr;
08214          len = strcspn(rr, ">") + 1;
08215          /* Make a struct route */
08216          if ((thishop = ast_malloc(sizeof(*thishop) + len))) {
08217             /* ast_calloc is not needed because all fields are initialized in this block */
08218             ast_copy_string(thishop->hop, rr, len);
08219             if (option_debug > 1)
08220                ast_log(LOG_DEBUG, "build_route: Record-Route hop: <%s>\n", thishop->hop);
08221             /* Link in */
08222             if (backwards) {
08223                /* Link in at head so they end up in reverse order */
08224                thishop->next = head;
08225                head = thishop;
08226                /* If this was the first then it'll be the tail */
08227                if (!tail)
08228                   tail = thishop;
08229             } else {
08230                thishop->next = NULL;
08231                /* Link in at the end */
08232                if (tail)
08233                   tail->next = thishop;
08234                else
08235                   head = thishop;
08236                tail = thishop;
08237             }
08238          }
08239       }
08240    }
08241 
08242    /* Only append the contact if we are dealing with a strict router */
08243    if (!head || (!ast_strlen_zero(head->hop) && strstr(head->hop,";lr") == NULL) ) {
08244       /* 2nd append the Contact: if there is one */
08245       /* Can be multiple Contact headers, comma separated values - we just take the first */
08246       contact = get_header(req, "Contact");
08247       if (!ast_strlen_zero(contact)) {
08248          if (option_debug > 1)
08249             ast_log(LOG_DEBUG, "build_route: Contact hop: %s\n", contact);
08250          /* Look for <: delimited address */
08251          c = strchr(contact, '<');
08252          if (c) {
08253             /* Take to > */
08254             ++c;
08255             len = strcspn(c, ">") + 1;
08256          } else {
08257             /* No <> - just take the lot */
08258             c = contact;
08259             len = strlen(contact) + 1;
08260          }
08261          if ((thishop = ast_malloc(sizeof(*thishop) + len))) {
08262             /* ast_calloc is not needed because all fields are initialized in this block */
08263             ast_copy_string(thishop->hop, c, len);
08264             thishop->next = NULL;
08265             /* Goes at the end */
08266             if (tail)
08267                tail->next = thishop;
08268             else
08269                head = thishop;
08270          }
08271       }
08272    }
08273 
08274    /* Store as new route */
08275    p->route = head;
08276 
08277    /* For debugging dump what we ended up with */
08278    if (sip_debug_test_pvt(p))
08279       list_route(p->route);
08280 }

static void build_rpid ( struct sip_pvt p  )  [static]

Build the Remote Party-ID & From using callingpres options.

Definition at line 6791 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_string_field_build, ast_string_field_set, ast_strlen_zero(), sip_pvt::callingpres, ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, FALSE, LOG_WARNING, sip_pvt::ourip, sip_pvt::owner, S_OR, sip_pvt::tag, and TRUE.

Referenced by initreqprep().

06792 {
06793    int send_pres_tags = TRUE;
06794    const char *privacy=NULL;
06795    const char *screen=NULL;
06796    char buf[256];
06797    const char *clid = default_callerid;
06798    const char *clin = NULL;
06799    const char *fromdomain;
06800 
06801    if (!ast_strlen_zero(p->rpid) || !ast_strlen_zero(p->rpid_from))  
06802       return;
06803 
06804    if (p->owner && p->owner->cid.cid_num)
06805       clid = p->owner->cid.cid_num;
06806    if (p->owner && p->owner->cid.cid_name)
06807       clin = p->owner->cid.cid_name;
06808    if (ast_strlen_zero(clin))
06809       clin = clid;
06810 
06811    switch (p->callingpres) {
06812    case AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED:
06813       privacy = "off";
06814       screen = "no";
06815       break;
06816    case AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN:
06817       privacy = "off";
06818       screen = "yes";
06819       break;
06820    case AST_PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN:
06821       privacy = "off";
06822       screen = "no";
06823       break;
06824    case AST_PRES_ALLOWED_NETWORK_NUMBER:
06825       privacy = "off";
06826       screen = "yes";
06827       break;
06828    case AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED:
06829       privacy = "full";
06830       screen = "no";
06831       break;
06832    case AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN:
06833       privacy = "full";
06834       screen = "yes";
06835       break;
06836    case AST_PRES_PROHIB_USER_NUMBER_FAILED_SCREEN:
06837       privacy = "full";
06838       screen = "no";
06839       break;
06840    case AST_PRES_PROHIB_NETWORK_NUMBER:
06841       privacy = "full";
06842       screen = "yes";
06843       break;
06844    case AST_PRES_NUMBER_NOT_AVAILABLE:
06845       send_pres_tags = FALSE;
06846       break;
06847    default:
06848       ast_log(LOG_WARNING, "Unsupported callingpres (%d)\n", p->callingpres);
06849       if ((p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED)
06850          privacy = "full";
06851       else
06852          privacy = "off";
06853       screen = "no";
06854       break;
06855    }
06856    
06857    fromdomain = S_OR(p->fromdomain, ast_inet_ntoa(p->ourip));
06858 
06859    snprintf(buf, sizeof(buf), "\"%s\" <sip:%s@%s>", clin, clid, fromdomain);
06860    if (send_pres_tags)
06861       snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), ";privacy=%s;screen=%s", privacy, screen);
06862    ast_string_field_set(p, rpid, buf);
06863 
06864    ast_string_field_build(p, rpid_from, "\"%s\" <sip:%s@%s>;tag=%s", clin,
06865                 S_OR(p->fromuser, clid),
06866                 fromdomain, p->tag);
06867 }

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

Initiate a SIP user structure from configuration (configuration or realtime).

Definition at line 16247 of file chan_sip.c.

References sip_user::accountcode, sip_user::allowtransfer, sip_user::amaflags, ast_append_ha(), ast_callerid_split(), ast_calloc, 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_test_flag, ast_true(), ast_variable_new(), ASTOBJ_INIT, sip_user::autoframing, sip_user::call_limit, sip_user::callgroup, sip_user::callingpres, sip_user::capability, sip_user::chanvars, sip_user::cid_name, sip_user::cid_num, sip_user::context, default_prefs, ast_flags::flags, sip_user::flags, format, sip_user::ha, handle_common_options(), sip_user::language, ast_variable::lineno, LOG_WARNING, sip_user::maxcallbitrate, sip_user::md5secret, sip_user::mohinterpret, sip_user::mohsuggest, ast_variable::name, ast_variable::next, sip_user::pickupgroup, sip_user::prefs, sip_user::secret, SIP_FLAGS_TO_COPY, SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PAGE2_FLAGS_TO_COPY, sip_user::subscribecontext, TRANSFER_CLOSED, TRANSFER_OPENFORALL, TRUE, and ast_variable::value.

16248 {
16249    struct sip_user *user;
16250    int format;
16251    struct ast_ha *oldha = NULL;
16252    char *varname = NULL, *varval = NULL;
16253    struct ast_variable *tmpvar = NULL;
16254    struct ast_flags userflags[2] = {{(0)}};
16255    struct ast_flags mask[2] = {{(0)}};
16256 
16257 
16258    if (!(user = ast_calloc(1, sizeof(*user))))
16259       return NULL;
16260       
16261    suserobjs++;
16262    ASTOBJ_INIT(user);
16263    ast_copy_string(user->name, name, sizeof(user->name));
16264    oldha = user->ha;
16265    user->ha = NULL;
16266    ast_copy_flags(&user->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY);
16267    ast_copy_flags(&user->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY);
16268    user->capability = global_capability;
16269    user->allowtransfer = global_allowtransfer;
16270    user->maxcallbitrate = default_maxcallbitrate;
16271    user->autoframing = global_autoframing;
16272    user->prefs = default_prefs;
16273    /* set default context */
16274    strcpy(user->context, default_context);
16275    strcpy(user->language, default_language);
16276    strcpy(user->mohinterpret, default_mohinterpret);
16277    strcpy(user->mohsuggest, default_mohsuggest);
16278    for (; v; v = v->next) {
16279       if (handle_common_options(&userflags[0], &mask[0], v))
16280          continue;
16281 
16282       if (!strcasecmp(v->name, "context")) {
16283          ast_copy_string(user->context, v->value, sizeof(user->context));
16284       } else if (!strcasecmp(v->name, "subscribecontext")) {
16285          ast_copy_string(user->subscribecontext, v->value, sizeof(user->subscribecontext));
16286       } else if (!strcasecmp(v->name, "setvar")) {
16287          varname = ast_strdupa(v->value);
16288          if ((varval = strchr(varname,'='))) {
16289             *varval++ = '\0';
16290             if ((tmpvar = ast_variable_new(varname, varval))) {
16291                tmpvar->next = user->chanvars;
16292                user->chanvars = tmpvar;
16293             }
16294          }
16295       } else if (!strcasecmp(v->name, "permit") ||
16296                !strcasecmp(v->name, "deny")) {
16297          user->ha = ast_append_ha(v->name, v->value, user->ha);
16298       } else if (!strcasecmp(v->name, "allowtransfer")) {
16299          user->allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED;
16300       } else if (!strcasecmp(v->name, "secret")) {
16301          ast_copy_string(user->secret, v->value, sizeof(user->secret)); 
16302       } else if (!strcasecmp(v->name, "md5secret")) {
16303          ast_copy_string(user->md5secret, v->value, sizeof(user->md5secret));
16304       } else if (!strcasecmp(v->name, "callerid")) {
16305          ast_callerid_split(v->value, user->cid_name, sizeof(user->cid_name), user->cid_num, sizeof(user->cid_num));
16306       } else if (!strcasecmp(v->name, "fullname")) {
16307          ast_copy_string(user->cid_name, v->value, sizeof(user->cid_name));
16308       } else if (!strcasecmp(v->name, "cid_number")) {
16309          ast_copy_string(user->cid_num, v->value, sizeof(user->cid_num));
16310       } else if (!strcasecmp(v->name, "callgroup")) {
16311          user->callgroup = ast_get_group(v->value);
16312       } else if (!strcasecmp(v->name, "pickupgroup")) {
16313          user->pickupgroup = ast_get_group(v->value);
16314       } else if (!strcasecmp(v->name, "language")) {
16315          ast_copy_string(user->language, v->value, sizeof(user->language));
16316       } else if (!strcasecmp(v->name, "mohinterpret") 
16317          || !strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) {
16318          ast_copy_string(user->mohinterpret, v->value, sizeof(user->mohinterpret));
16319       } else if (!strcasecmp(v->name, "mohsuggest")) {
16320          ast_copy_string(user->mohsuggest, v->value, sizeof(user->mohsuggest));
16321       } else if (!strcasecmp(v->name, "accountcode")) {
16322          ast_copy_string(user->accountcode, v->value, sizeof(user->accountcode));
16323       } else if (!strcasecmp(v->name, "call-limit")) {
16324          user->call_limit = atoi(v->value);
16325          if (user->call_limit < 0)
16326             user->call_limit = 0;
16327       } else if (!strcasecmp(v->name, "amaflags")) {
16328          format = ast_cdr_amaflags2int(v->value);
16329          if (format < 0) {
16330             ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
16331          } else {
16332             user->amaflags = format;
16333          }
16334       } else if (!strcasecmp(v->name, "allow")) {
16335          ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1);
16336       } else if (!strcasecmp(v->name, "disallow")) {
16337          ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 0);
16338       } else if (!strcasecmp(v->name, "autoframing")) {
16339          user->autoframing = ast_true(v->value);
16340       } else if (!strcasecmp(v->name, "callingpres")) {
16341          user->callingpres = ast_parse_caller_presentation(v->value);
16342          if (user->callingpres == -1)
16343             user->callingpres = atoi(v->value);
16344       } else if (!strcasecmp(v->name, "maxcallbitrate")) {
16345          user->maxcallbitrate = atoi(v->value);
16346          if (user->maxcallbitrate < 0)
16347             user->maxcallbitrate = default_maxcallbitrate;
16348       }
16349       /* We can't just report unknown options here because this may be a
16350        * type=friend entry.  All user options are valid for a peer, but not
16351        * the other way around.  */
16352    }
16353    ast_copy_flags(&user->flags[0], &userflags[0], mask[0].flags);
16354    ast_copy_flags(&user->flags[1], &userflags[1], mask[1].flags);
16355    if (ast_test_flag(&user->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE))
16356       global_allowsubscribe = TRUE; /* No global ban any more */
16357    ast_free_ha(oldha);
16358    return user;
16359 }

static void build_via ( struct sip_pvt p  )  [static]

Build a Via header for a request.

Definition at line 1789 of file chan_sip.c.

References ast_inet_ntoa(), ast_string_field_build, ast_test_flag, sip_pvt::branch, sip_pvt::flags, sip_pvt::ourip, ourport, 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(), transmit_register(), and transmit_response_using_temp().

01790 {
01791    /* Work around buggy UNIDEN UIP200 firmware */
01792    const char *rport = ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_RFC3581 ? ";rport" : "";
01793 
01794    /* z9hG4bK is a magic cookie.  See RFC 3261 section 8.1.1.7 */
01795    ast_string_field_build(p, via, "SIP/2.0/UDP %s:%d;branch=z9hG4bK%08x%s",
01796           ast_inet_ntoa(p->ourip), ourport, p->branch, rport);
01797 }

static int cb_extensionstate ( char *  context,
char *  exten,
int  state,
void *  data,
char *  cid_num,
char *  cid_name 
) [static]

Callback for the devicestate notification (SUBSCRIBE) support subsystem.

Note:
If you add an "hint" priority to the extension in the dial plan, you will get notifications on device state changes

Definition at line 8470 of file chan_sip.c.

References append_history, AST_EXTENSION_DEACTIVATED, AST_EXTENSION_REMOVED, ast_extension_state2str(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), sip_pvt::autokillid, DEFAULT_TRANS_TIMEOUT, FALSE, sip_pvt::laststate, sip_pvt::lock, NONE, option_verbose, sip_cancel_destroy(), sip_scheddestroy(), sip_pvt::stateid, sip_pvt::subscribed, transmit_state_notify(), VERBOSE_PREFIX_1, and VERBOSE_PREFIX_2.

Referenced by handle_request_subscribe().

08471 {
08472    struct sip_pvt *p = data;
08473 
08474    ast_mutex_lock(&p->lock);
08475 
08476    switch(state) {
08477    case AST_EXTENSION_DEACTIVATED:  /* Retry after a while */
08478    case AST_EXTENSION_REMOVED:   /* Extension is gone */
08479       if (p->autokillid > -1)
08480          sip_cancel_destroy(p);  /* Remove subscription expiry for renewals */
08481       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);  /* Delete subscription in 32 secs */
08482       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);
08483       p->stateid = -1;
08484       p->subscribed = NONE;
08485       append_history(p, "Subscribestatus", "%s", state == AST_EXTENSION_REMOVED ? "HintRemoved" : "Deactivated");
08486       break;
08487    default: /* Tell user */
08488       p->laststate = state;
08489       break;
08490    }
08491    if (p->subscribed != NONE) /* Only send state NOTIFY if we know the format */
08492       transmit_state_notify(p, state, 1, FALSE);
08493 
08494    if (option_verbose > 1)
08495       ast_verbose(VERBOSE_PREFIX_1 "Extension Changed %s new state %s for Notify User %s\n", exten, ast_extension_state2str(state), p->username);
08496    
08497    ast_mutex_unlock(&p->lock);
08498 
08499    return 0;
08500 }

static void change_hold_state ( struct sip_pvt dialog,
struct sip_request req,
int  holdstate,
int  sendonly 
) [static]

Change hold state for a call.

Definition at line 4912 of file chan_sip.c.

References append_history, ast_clear_flag, ast_set_flag, ast_test_flag, sip_request::data, EVENT_FLAG_CALL, sip_pvt::flags, manager_event(), sip_pvt::owner, SIP_PAGE2_CALL_ONHOLD, SIP_PAGE2_CALL_ONHOLD_ACTIVE, SIP_PAGE2_CALL_ONHOLD_INACTIVE, SIP_PAGE2_CALL_ONHOLD_ONEDIR, and sip_peer_hold().

Referenced by handle_request_invite(), and process_sdp().

04913 {
04914    if (global_notifyhold && (!holdstate || !ast_test_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD)))
04915       sip_peer_hold(dialog, holdstate);
04916    if (global_callevents)
04917       manager_event(EVENT_FLAG_CALL, holdstate ? "Hold" : "Unhold",
04918                "Channel: %s\r\n"
04919                "Uniqueid: %s\r\n",
04920                dialog->owner->name, 
04921                dialog->owner->uniqueid);
04922    append_history(dialog, holdstate ? "Hold" : "Unhold", "%s", req->data);
04923    if (!holdstate) {    /* Put off remote hold */
04924       ast_clear_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD);   /* Clear both flags */
04925       return;
04926    }
04927    /* No address for RTP, we're on hold */
04928 
04929    if (sendonly == 1)   /* One directional hold (sendonly/recvonly) */
04930       ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_ONEDIR);
04931    else if (sendonly == 2) /* Inactive stream */
04932       ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_INACTIVE);
04933    else
04934       ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_ACTIVE);
04935    return;
04936 }

static enum check_auth_result check_auth ( struct sip_pvt p,
struct sip_request req,
const char *  username,
const char *  secret,
const char *  md5secret,
int  sipmethod,
char *  uri,
enum xmittype  reliable,
int  ignore 
) [static]

Check user authorization from peer definition Some actions, like REGISTER and INVITEs from peers require authentication (if peer have secret set).

Returns:
0 on success, non-zero on error

Definition at line 8288 of file chan_sip.c.

References append_history, ast_log(), ast_md5_hash(), ast_random(), ast_string_field_build, ast_strlen_zero(), AUTH_CHALLENGE_SENT, AUTH_SECRET_FAILED, AUTH_SUCCESSFUL, AUTH_USERNAME_MISMATCH, DEFAULT_TRANS_TIMEOUT, FALSE, get_header(), key(), keys, LOG_NOTICE, LOG_WARNING, s, S_OR, sip_methods, SIP_REGISTER, sip_scheddestroy(), SIP_SUBSCRIBE, sipdebug, strsep(), text, transmit_response_with_auth(), and TRUE.

Referenced by check_user_full(), and register_verify().

08291 {
08292    const char *response = "407 Proxy Authentication Required";
08293    const char *reqheader = "Proxy-Authorization";
08294    const char *respheader = "Proxy-Authenticate";
08295    const char *authtoken;
08296    char a1_hash[256];
08297    char resp_hash[256]="";
08298    char tmp[BUFSIZ * 2];                /* Make a large enough buffer */
08299    char *c;
08300    int  wrongnonce = FALSE;
08301    int  good_response;
08302    const char *usednonce = p->randdata;
08303 
08304    /* table of recognised keywords, and their value in the digest */
08305    enum keys { K_RESP, K_URI, K_USER, K_NONCE, K_LAST };
08306    struct x {
08307       const char *key;
08308       const char *s;
08309    } *i, keys[] = {
08310       [K_RESP] = { "response=", "" },
08311       [K_URI] = { "uri=", "" },
08312       [K_USER] = { "username=", "" },
08313       [K_NONCE] = { "nonce=", "" },
08314       [K_LAST] = { NULL, NULL}
08315    };
08316 
08317    /* Always OK if no secret */
08318    if (ast_strlen_zero(secret) && ast_strlen_zero(md5secret))
08319       return AUTH_SUCCESSFUL;
08320    if (sipmethod == SIP_REGISTER || sipmethod == SIP_SUBSCRIBE) {
08321       /* On a REGISTER, we have to use 401 and its family of headers instead of 407 and its family
08322          of headers -- GO SIP!  Whoo hoo!  Two things that do the same thing but are used in
08323          different circumstances! What a surprise. */
08324       response = "401 Unauthorized";
08325       reqheader = "Authorization";
08326       respheader = "WWW-Authenticate";
08327    }
08328    authtoken =  get_header(req, reqheader);  
08329    if (ignore && !ast_strlen_zero(p->randdata) && ast_strlen_zero(authtoken)) {
08330       /* This is a retransmitted invite/register/etc, don't reconstruct authentication
08331          information */
08332       if (!reliable) {
08333          /* Resend message if this was NOT a reliable delivery.   Otherwise the
08334             retransmission should get it */
08335          transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0);
08336          /* Schedule auto destroy in 32 seconds (according to RFC 3261) */
08337          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
08338       }
08339       return AUTH_CHALLENGE_SENT;
08340    } else if (ast_strlen_zero(p->randdata) || ast_strlen_zero(authtoken)) {
08341       /* We have no auth, so issue challenge and request authentication */
08342       ast_string_field_build(p, randdata, "%08lx", ast_random()); /* Create nonce for challenge */
08343       transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0);
08344       /* Schedule auto destroy in 32 seconds */
08345       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
08346       return AUTH_CHALLENGE_SENT;
08347    } 
08348 
08349    /* --- We have auth, so check it */
08350 
08351    /* Whoever came up with the authentication section of SIP can suck my %&#$&* for not putting
08352          an example in the spec of just what it is you're doing a hash on. */
08353 
08354 
08355    /* Make a copy of the response and parse it */
08356    ast_copy_string(tmp, authtoken, sizeof(tmp));
08357    c = tmp;
08358 
08359    while(c && *(c = ast_skip_blanks(c)) ) { /* lookup for keys */
08360       for (i = keys; i->key != NULL; i++) {
08361          const char *separator = ",";  /* default */
08362 
08363          if (strncasecmp(c, i->key, strlen(i->key)) != 0)
08364             continue;
08365          /* Found. Skip keyword, take text in quotes or up to the separator. */
08366          c += strlen(i->key);
08367          if (*c == '"') { /* in quotes. Skip first and look for last */
08368             c++;
08369             separator = "\"";
08370          }
08371          i->s = c;
08372          strsep(&c, separator);
08373          break;
08374       }
08375       if (i->key == NULL) /* not found, jump after space or comma */
08376          strsep(&c, " ,");
08377    }
08378 
08379    /* Verify that digest username matches  the username we auth as */
08380    if (strcmp(username, keys[K_USER].s)) {
08381       ast_log(LOG_WARNING, "username mismatch, have <%s>, digest has <%s>\n",
08382          username, keys[K_USER].s);
08383       /* Oops, we're trying something here */
08384       return AUTH_USERNAME_MISMATCH;
08385    }
08386 
08387    /* Verify nonce from request matches our nonce.  If not, send 401 with new nonce */
08388    if (strcasecmp(p->randdata, keys[K_NONCE].s)) { /* XXX it was 'n'casecmp ? */
08389       wrongnonce = TRUE;
08390       usednonce = keys[K_NONCE].s;
08391    }
08392 
08393    if (!ast_strlen_zero(md5secret))
08394       ast_copy_string(a1_hash, md5secret, sizeof(a1_hash));
08395    else {
08396       char a1[256];
08397       snprintf(a1, sizeof(a1), "%s:%s:%s", username, global_realm, secret);
08398       ast_md5_hash(a1_hash, a1);
08399    }
08400 
08401    /* compute the expected response to compare with what we received */
08402    {
08403       char a2[256];
08404       char a2_hash[256];
08405       char resp[256];
08406 
08407       snprintf(a2, sizeof(a2), "%s:%s", sip_methods[sipmethod].text,
08408             S_OR(keys[K_URI].s, uri));
08409       ast_md5_hash(a2_hash, a2);
08410       snprintf(resp, sizeof(resp), "%s:%s:%s", a1_hash, usednonce, a2_hash);
08411       ast_md5_hash(resp_hash, resp);
08412    }
08413 
08414    good_response = keys[K_RESP].s &&
08415          !strncasecmp(keys[K_RESP].s, resp_hash, strlen(resp_hash));
08416    if (wrongnonce) {
08417       ast_string_field_build(p, randdata, "%08lx", ast_random());
08418       if (good_response) {
08419          if (sipdebug)
08420             ast_log(LOG_NOTICE, "Correct auth, but based on stale nonce received from '%s'\n", get_header(req, "To"));
08421          /* We got working auth token, based on stale nonce . */
08422          transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, TRUE);
08423       } else {
08424          /* Everything was wrong, so give the device one more try with a new challenge */
08425          if (sipdebug)
08426             ast_log(LOG_NOTICE, "Bad authentication received from '%s'\n", get_header(req, "To"));
08427          transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, FALSE);
08428       }
08429 
08430       /* Schedule auto destroy in 32 seconds */
08431       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
08432       return AUTH_CHALLENGE_SENT;
08433    } 
08434    if (good_response) {
08435       append_history(p, "AuthOK", "Auth challenge succesful for %s", username);
08436       return AUTH_SUCCESSFUL;
08437    }
08438 
08439    /* Ok, we have a bad username/secret pair */
08440    /* Tell the UAS not to re-send this authentication data, because
08441       it will continue to fail
08442    */
08443 
08444    return AUTH_SECRET_FAILED;
08445 }

static void check_pendings ( struct sip_pvt p  )  [static]

Check pending actions on SIP call.

Definition at line 11919 of file chan_sip.c.

References ast_clear_flag, ast_log(), ast_test_flag, DEFAULT_TRANS_TIMEOUT, FALSE, sip_pvt::flags, INV_CALLING, INV_EARLY_MEDIA, INV_PROCEEDING, sip_pvt::invitestate, LOG_DEBUG, sip_pvt::ocseq, option_debug, sip_pvt::pendinginvite, SIP_BYE, SIP_CANCEL, SIP_NEEDREINVITE, SIP_PENDINGBYE, sip_scheddestroy(), transmit_reinvite_with_sdp(), transmit_request(), transmit_request_with_auth(), TRUE, sip_pvt::waitid, and XMIT_RELIABLE.

Referenced by handle_request(), and handle_response_invite().

11920 {
11921    if (ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) {
11922       /* if we can't BYE, then this is really a pending CANCEL */
11923       if (p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA)
11924          transmit_request(p, SIP_CANCEL, p->ocseq, XMIT_RELIABLE, FALSE);
11925          /* Actually don't destroy us yet, wait for the 487 on our original 
11926             INVITE, but do set an autodestruct just in case we never get it. */
11927       else {
11928          /* We have a pending outbound invite, don't send someting
11929             new in-transaction */
11930          if (p->pendinginvite)
11931             return;
11932 
11933          /* Perhaps there is an SD change INVITE outstanding */
11934          transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, TRUE);
11935       }
11936       ast_clear_flag(&p->flags[0], SIP_PENDINGBYE);   
11937       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
11938    } else if (ast_test_flag(&p->flags[0], SIP_NEEDREINVITE)) {
11939       /* if we can't REINVITE, hold it for later */
11940       if (p->pendinginvite || p->invitestate == INV_CALLING || p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA || p->waitid > 0) {
11941          if (option_debug)
11942             ast_log(LOG_DEBUG, "NOT Sending pending reinvite (yet) on '%s'\n", p->callid);
11943       } else {
11944          if (option_debug)
11945             ast_log(LOG_DEBUG, "Sending pending reinvite on '%s'\n", p->callid);
11946          /* Didn't get to reinvite yet, so do it now */
11947          transmit_reinvite_with_sdp(p);
11948          ast_clear_flag(&p->flags[0], SIP_NEEDREINVITE); 
11949       }
11950    }
11951 }

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

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

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

16127 {
16128    struct domain *d;
16129    int result = 0;
16130 
16131    AST_LIST_LOCK(&domain_list);
16132    AST_LIST_TRAVERSE(&domain_list, d, list) {
16133       if (strcasecmp(d->domain, domain))
16134          continue;
16135 
16136       if (len && !ast_strlen_zero(d->context))
16137          ast_copy_string(context, d->context, len);
16138       
16139       result = 1;
16140       break;
16141    }
16142    AST_LIST_UNLOCK(&domain_list);
16143 
16144    return result;
16145 }

static int check_user ( struct sip_pvt p,
struct sip_request req,
int  sipmethod,
char *  uri,
enum xmittype  reliable,
struct sockaddr_in *  sin 
) [static]

Find user If we get a match, this will add a reference pointer to the user object in ASTOBJ, that needs to be unreferenced.

Definition at line 9566 of file chan_sip.c.

References check_user_full().

Referenced by handle_request_invite().

09567 {
09568    return check_user_full(p, req, sipmethod, uri, reliable, sin, NULL);
09569 }

static enum check_auth_result check_user_full ( struct sip_pvt p,
struct sip_request req,
int  sipmethod,
char *  uri,
enum xmittype  reliable,
struct sockaddr_in *  sin,
struct sip_peer **  authpeer 
) [static]

Check if matching user or peer is defined Match user on From: user name and peer on IP/port This is used on first invite (not re-invites) and subscribe requests.

Returns:
0 on success, non-zero on failure

Definition at line 9247 of file chan_sip.c.

References sip_peer::accountcode, sip_user::accountcode, accountcode, sip_user::allowtransfer, sip_pvt::allowtransfer, sip_peer::amaflags, sip_user::amaflags, sip_pvt::amaflags, ast_apply_ha(), ast_copy_flags, AST_FORMAT_VIDEO_MASK, ast_inet_ntoa(), ast_is_shrinkable_phonenumber(), ast_log(), ast_rtp_codec_setpref(), ast_rtp_destroy(), AST_RTP_DTMF, ast_set_flag, ast_shrink_phone_number(), ast_strdupa, ast_string_field_free, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_uri_decode(), ast_variable_new(), ast_verbose(), ASTOBJ_REF, ASTOBJ_UNREF, AUTH_FAKE_AUTH, AUTH_SECRET_FAILED, AUTH_SUCCESSFUL, sip_peer::autoframing, sip_user::autoframing, sip_pvt::autoframing, build_contact(), sip_peer::call_limit, sip_user::call_limit, sip_peer::callgroup, sip_user::callgroup, sip_pvt::callgroup, sip_peer::callingpres, sip_user::callingpres, sip_pvt::callingpres, sip_peer::capability, sip_user::capability, sip_pvt::capability, sip_peer::chanvars, sip_pvt::chanvars, sip_user::chanvars, check_auth(), sip_peer::cid_name, sip_user::cid_name, cid_name, sip_peer::cid_num, sip_user::cid_num, cid_num, sip_peer::context, domain::context, sip_user::context, debug, do_setnat(), exten, find_peer(), find_user(), sip_peer::flags, sip_user::flags, sip_pvt::flags, sip_peer::fullcontact, get_calleridname(), get_header(), get_in_brackets(), get_rpid_num(), sip_user::ha, t38properties::jointcapability, sip_pvt::jointcapability, sip_pvt::jointnoncodeccapability, sip_peer::language, sip_user::language, language, sip_peer::lastms, LOG_NOTICE, sip_peer::maxcallbitrate, sip_user::maxcallbitrate, sip_pvt::maxcallbitrate, sip_peer::maxms, sip_peer::md5secret, sip_user::md5secret, sip_peer::mohinterpret, sip_user::mohinterpret, mohinterpret, sip_peer::mohsuggest, sip_user::mohsuggest, mohsuggest, ast_variable::next, sip_pvt::noncodeccapability, t38properties::peercapability, sip_pvt::peercapability, sip_peer::pickupgroup, sip_user::pickupgroup, sip_pvt::pickupgroup, sip_peer::prefs, sip_user::prefs, sip_pvt::prefs, sip_pvt::recv, sip_pvt::rtp, sip_peer::secret, sip_user::secret, SIP_CALL_LIMIT, sip_cancel_destroy(), sip_debug_test_addr(), sip_destroy_peer(), sip_destroy_user(), SIP_DTMF, SIP_DTMF_AUTO, SIP_DTMF_RFC2833, SIP_FLAGS_TO_COPY, SIP_INSECURE_INVITE, SIP_NAT_ROUTE, SIP_PAGE2_FLAGS_TO_COPY, SIP_PAGE2_VIDEOSUPPORT, SIP_PKT_IGNORE, SIP_SUBSCRIBE, SIP_TRUSTRPID, sip_peer::sipoptions, sip_user::sipoptions, sip_pvt::sipoptions, strsep(), sip_peer::subscribecontext, sip_user::subscribecontext, t, sip_pvt::t38, sip_pvt::timer_t1, sip_peer::username, username, and sip_pvt::vrtp.

Referenced by check_user(), and handle_request_subscribe().

09250 {
09251    struct sip_user *user = NULL;
09252    struct sip_peer *peer;
09253    char from[256], *c;
09254    char *of;
09255    char rpid_num[50];
09256    const char *rpid;
09257    enum check_auth_result res = AUTH_SUCCESSFUL;
09258    char *t;
09259    char calleridname[50];
09260    int debug=sip_debug_test_addr(sin);
09261    struct ast_variable *tmpvar = NULL, *v = NULL;
09262    char *uri2 = ast_strdupa(uri);
09263 
09264    /* Terminate URI */
09265    t = uri2;
09266    while (*t && *t > 32 && *t != ';')
09267       t++;
09268    *t = '\0';
09269    ast_copy_string(from, get_header(req, "From"), sizeof(from));  /* XXX bug in original code, overwrote string */
09270    if (pedanticsipchecking)
09271       ast_uri_decode(from);
09272    /* XXX here tries to map the username for invite things */
09273    memset(calleridname, 0, sizeof(calleridname));
09274    get_calleridname(from, calleridname, sizeof(calleridname));
09275    if (calleridname[0])
09276       ast_string_field_set(p, cid_name, calleridname);
09277 
09278    rpid = get_header(req, "Remote-Party-ID");
09279    memset(rpid_num, 0, sizeof(rpid_num));
09280    if (!ast_strlen_zero(rpid)) 
09281       p->callingpres = get_rpid_num(rpid, rpid_num, sizeof(rpid_num));
09282 
09283    of = get_in_brackets(from);
09284    if (ast_strlen_zero(p->exten)) {
09285       t = uri2;
09286       if (!strncasecmp(t, "sip:", 4))
09287          t+= 4;
09288       ast_string_field_set(p, exten, t);
09289       t = strchr(p->exten, '@');
09290       if (t)
09291          *t = '\0';
09292       if (ast_strlen_zero(p->our_contact))
09293          build_contact(p);
09294    }
09295    /* save the URI part of the From header */
09296    ast_string_field_set(p, from, of);
09297    if (strncasecmp(of, "sip:", 4)) {
09298       ast_log(LOG_NOTICE, "From address missing 'sip:', using it anyway\n");
09299    } else
09300       of += 4;
09301    /* Get just the username part */
09302    if ((c = strchr(of, '@'))) {
09303       char *tmp;
09304       *c = '\0';
09305       if ((c = strchr(of, ':')))
09306          *c = '\0';
09307       tmp = ast_strdupa(of);
09308       /* We need to be able to handle auth-headers looking like
09309          <sip:8164444422;phone-context=+1@1.2.3.4:5060;user=phone;tag=SDadkoa01-gK0c3bdb43>
09310       */
09311       tmp = strsep(&tmp, ";");
09312       if (ast_is_shrinkable_phonenumber(tmp))
09313          ast_shrink_phone_number(tmp);
09314       ast_string_field_set(p, cid_num, tmp);
09315    }
09316 
09317    if (!authpeer) /* If we are looking for a peer, don't check the user objects (or realtime) */
09318       user = find_user(of, 1);
09319 
09320    /* Find user based on user name in the from header */
09321    if (user && ast_apply_ha(user->ha, sin)) {
09322       ast_copy_flags(&p->flags[0], &user->flags[0], SIP_FLAGS_TO_COPY);
09323       ast_copy_flags(&p->flags[1], &user->flags[1], SIP_PAGE2_FLAGS_TO_COPY);
09324       /* copy channel vars */
09325       for (v = user->chanvars ; v ; v = v->next) {
09326          if ((tmpvar = ast_variable_new(v->name, v->value))) {
09327             tmpvar->next = p->chanvars; 
09328             p->chanvars = tmpvar;
09329          }
09330       }
09331       p->prefs = user->prefs;
09332       /* Set Frame packetization */
09333       if (p->rtp) {
09334          ast_rtp_codec_setpref(p->rtp, &p->prefs);
09335          p->autoframing = user->autoframing;
09336       }
09337       /* replace callerid if rpid found, and not restricted */
09338       if (!ast_strlen_zero(rpid_num) && ast_test_flag(&p->flags[0], SIP_TRUSTRPID)) {
09339          char *tmp;
09340          if (*calleridname)
09341             ast_string_field_set(p, cid_name, calleridname);
09342          tmp = ast_strdupa(rpid_num);
09343          if (ast_is_shrinkable_phonenumber(tmp))
09344             ast_shrink_phone_number(tmp);
09345          ast_string_field_set(p, cid_num, tmp);
09346       }
09347       
09348       do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT_ROUTE) );
09349 
09350       if (!(res = check_auth(p, req, user->name, user->secret, user->md5secret, sipmethod, uri2, reliable, ast_test_flag(req, SIP_PKT_IGNORE)))) {
09351          sip_cancel_destroy(p);
09352          ast_copy_flags(&p->flags[0], &user->flags[0], SIP_FLAGS_TO_COPY);
09353          ast_copy_flags(&p->flags[1], &user->flags[1], SIP_PAGE2_FLAGS_TO_COPY);
09354          /* Copy SIP extensions profile from INVITE */
09355          if (p->sipoptions)
09356             user->sipoptions = p->sipoptions;
09357 
09358          /* If we have a call limit, set flag */
09359          if (user->call_limit)
09360             ast_set_flag(&p->flags[0], SIP_CALL_LIMIT);
09361          if (!ast_strlen_zero(user->context))
09362             ast_string_field_set(p, context, user->context);
09363          if (!ast_strlen_zero(user->cid_num) && !ast_strlen_zero(p->cid_num)) {
09364             char *tmp = ast_strdupa(user->cid_num);
09365             if (ast_is_shrinkable_phonenumber(tmp))
09366                ast_shrink_phone_number(tmp);
09367             ast_string_field_set(p, cid_num, tmp);
09368          }
09369          if (!ast_strlen_zero(user->cid_name) && !ast_strlen_zero(p->cid_num))
09370             ast_string_field_set(p, cid_name, user->cid_name);
09371          ast_string_field_set(p, username, user->name);
09372          ast_string_field_set(p, peername, user->name);
09373          ast_string_field_set(p, peersecret, user->secret);
09374          ast_string_field_set(p, peermd5secret, user->md5secret);
09375          ast_string_field_set(p, subscribecontext, user->subscribecontext);
09376          ast_string_field_set(p, accountcode, user->accountcode);
09377          ast_string_field_set(p, language, user->language);
09378          ast_string_field_set(p, mohsuggest, user->mohsuggest);
09379          ast_string_field_set(p, mohinterpret, user->mohinterpret);
09380          p->allowtransfer = user->allowtransfer;
09381          p->amaflags = user->amaflags;
09382          p->callgroup = user->callgroup;
09383          p->pickupgroup = user->pickupgroup;
09384          if (user->callingpres)  /* User callingpres setting will override RPID header */
09385             p->callingpres = user->callingpres;
09386          
09387          /* Set default codec settings for this call */
09388          p->capability = user->capability;      /* User codec choice */
09389          p->jointcapability = user->capability;    /* Our codecs */
09390          if (p->peercapability)           /* AND with peer's codecs */
09391             p->jointcapability &= p->peercapability;
09392          if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) ||
09393              (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO))
09394             p->noncodeccapability |= AST_RTP_DTMF;
09395          else
09396             p->noncodeccapability &= ~AST_RTP_DTMF;
09397          p->jointnoncodeccapability = p->noncodeccapability;
09398          if (p->t38.peercapability)
09399             p->t38.jointcapability &= p->t38.peercapability;
09400          p->maxcallbitrate = user->maxcallbitrate;
09401          /* If we do not support video, remove video from call structure */
09402          if ((!ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) || !(p->capability & AST_FORMAT_VIDEO_MASK)) && p->vrtp) {
09403             ast_rtp_destroy(p->vrtp);
09404             p->vrtp = NULL;
09405          }
09406       }
09407       if (user && debug)
09408          ast_verbose("Found user '%s'\n", user->name);
09409    } else {
09410       if (user) {
09411          if (!authpeer && debug)
09412             ast_verbose("Found user '%s', but fails host access\n", user->name);
09413          ASTOBJ_UNREF(user,sip_destroy_user);
09414       }
09415       user = NULL;
09416    }
09417 
09418    if (!user) {
09419       /* If we didn't find a user match, check for peers */
09420       if (sipmethod == SIP_SUBSCRIBE)
09421          /* For subscribes, match on peer name only */
09422          peer = find_peer(of, NULL, 1);
09423       else
09424          /* Look for peer based on the IP address we received data from */
09425          /* If peer is registered from this IP address or have this as a default
09426             IP address, this call is from the peer 
09427          */
09428          peer = find_peer(NULL, &p->recv, 1);
09429 
09430       if (peer) {
09431          /* Set Frame packetization */
09432          if (p->rtp) {
09433             ast_rtp_codec_setpref(p->rtp, &peer->prefs);
09434             p->autoframing = peer->autoframing;
09435          }
09436          if (debug)
09437             ast_verbose("Found peer '%s'\n", peer->name);
09438 
09439          /* Take the peer */
09440          ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY);
09441          ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY);
09442 
09443          /* Copy SIP extensions profile to peer */
09444          if (p->sipoptions)
09445             peer->sipoptions = p->sipoptions;
09446 
09447          /* replace callerid if rpid found, and not restricted */
09448          if (!ast_strlen_zero(rpid_num) && ast_test_flag(&p->flags[0], SIP_TRUSTRPID)) {
09449             char *tmp = ast_strdupa(rpid_num);
09450             if (*calleridname)
09451                ast_string_field_set(p, cid_name, calleridname);
09452             if (ast_is_shrinkable_phonenumber(tmp))
09453                ast_shrink_phone_number(tmp);
09454             ast_string_field_set(p, cid_num, tmp);
09455          }
09456          do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT_ROUTE));
09457 
09458          ast_string_field_set(p, peersecret, peer->secret);
09459          ast_string_field_set(p, peermd5secret, peer->md5secret);
09460          ast_string_field_set(p, subscribecontext, peer->subscribecontext);
09461          ast_string_field_set(p, mohinterpret, peer->mohinterpret);
09462          ast_string_field_set(p, mohsuggest, peer->mohsuggest);
09463          if (peer->callingpres)  /* Peer calling pres setting will override RPID */
09464             p->callingpres = peer->callingpres;
09465          if (peer->maxms && peer->lastms)
09466             p->timer_t1 = peer->lastms < global_t1min ? global_t1min : peer->lastms;
09467          if (ast_test_flag(&peer->flags[0], SIP_INSECURE_INVITE)) {
09468             /* Pretend there is no required authentication */
09469             ast_string_field_free(p, peersecret);
09470             ast_string_field_free(p, peermd5secret);
09471          }
09472          if (!(res = check_auth(p, req, peer->name, p->peersecret, p->peermd5secret, sipmethod, uri2, reliable, ast_test_flag(req, SIP_PKT_IGNORE)))) {
09473             ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY);
09474             ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY);
09475             /* If we have a call limit, set flag */
09476             if (peer->call_limit)
09477                ast_set_flag(&p->flags[0], SIP_CALL_LIMIT);
09478             ast_string_field_set(p, peername, peer->name);
09479             ast_string_field_set(p, authname, peer->name);
09480 
09481             /* copy channel vars */
09482             for (v = peer->chanvars ; v ; v = v->next) {
09483                if ((tmpvar = ast_variable_new(v->name, v->value))) {
09484                   tmpvar->next = p->chanvars; 
09485                   p->chanvars = tmpvar;
09486                }
09487             }
09488             if (authpeer) {
09489                (*authpeer) = ASTOBJ_REF(peer);  /* Add a ref to the object here, to keep it in memory a bit longer if it is realtime */
09490             }
09491 
09492             if (!ast_strlen_zero(peer->username)) {
09493                ast_string_field_set(p, username, peer->username);
09494                /* Use the default username for authentication on outbound calls */
09495                /* XXX this takes the name from the caller... can we override ? */
09496                ast_string_field_set(p, authname, peer->username);
09497             }
09498             if (!ast_strlen_zero(peer->cid_num) && !ast_strlen_zero(p->cid_num)) {
09499                char *tmp = ast_strdupa(peer->cid_num);
09500                if (ast_is_shrinkable_phonenumber(tmp))
09501                   ast_shrink_phone_number(tmp);
09502                ast_string_field_set(p, cid_num, tmp);
09503             }
09504             if (!ast_strlen_zero(peer->cid_name) && !ast_strlen_zero(p->cid_name)) 
09505                ast_string_field_set(p, cid_name, peer->cid_name);
09506             ast_string_field_set(p, fullcontact, peer->fullcontact);
09507             if (!ast_strlen_zero(peer->context))
09508                ast_string_field_set(p, context, peer->context);
09509             ast_string_field_set(p, peersecret, peer->secret);
09510             ast_string_field_set(p, peermd5secret, peer->md5secret);
09511             ast_string_field_set(p, language, peer->language);
09512             ast_string_field_set(p, accountcode, peer->accountcode);
09513             p->amaflags = peer->amaflags;
09514             p->callgroup = peer->callgroup;
09515             p->pickupgroup = peer->pickupgroup;
09516             p->capability = peer->capability;
09517             p->prefs = peer->prefs;
09518             p->jointcapability = peer->capability;
09519             if (p->peercapability)
09520                p->jointcapability &= p->peercapability;
09521             p->maxcallbitrate = peer->maxcallbitrate;
09522             if ((!ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) || !(p->capability & AST_FORMAT_VIDEO_MASK)) && p->vrtp) {
09523                ast_rtp_destroy(p->vrtp);
09524                p->vrtp = NULL;
09525             }
09526             if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) ||
09527                 (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO))
09528                p->noncodeccapability |= AST_RTP_DTMF;
09529             else
09530                p->noncodeccapability &= ~AST_RTP_DTMF;
09531             p->jointnoncodeccapability = p->noncodeccapability;
09532             if (p->t38.peercapability)
09533                p->t38.jointcapability &= p->t38.peercapability;
09534          }
09535          ASTOBJ_UNREF(peer, sip_destroy_peer);
09536       } else { 
09537          if (debug)
09538             ast_verbose("Found no matching peer or user for '%s:%d'\n", ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port));
09539 
09540          /* do we allow guests? */
09541          if (!global_allowguest) {
09542             if (global_alwaysauthreject)
09543                res = AUTH_FAKE_AUTH; /* reject with fake authorization request */
09544             else
09545                res = AUTH_SECRET_FAILED; /* we don't want any guests, authentication will fail */
09546          } else if (!ast_strlen_zero(rpid_num) && ast_test_flag(&p->flags[0], SIP_TRUSTRPID)) {
09547             char *tmp = ast_strdupa(rpid_num);
09548             if (*calleridname)
09549                ast_string_field_set(p, cid_name, calleridname);
09550             if (ast_is_shrinkable_phonenumber(tmp))
09551                ast_shrink_phone_number(tmp);
09552             ast_string_field_set(p, cid_num, tmp);
09553                         }
09554       }
09555 
09556    }
09557 
09558    if (user)
09559       ASTOBJ_UNREF(user, sip_destroy_user);
09560    return res;
09561 }

static void check_via ( struct sip_pvt p,
struct sip_request req 
) [static]

check Via: header for hostname, port and rport request/answer

Definition at line 9115 of file chan_sip.c.

References ast_gethostbyname(), ast_inet_ntoa(), ast_log(), ast_set_flag, ast_verbose(), sip_pvt::flags, get_header(), hp, LOG_WARNING, sip_pvt::sa, sip_debug_test_pvt(), sip_nat_mode(), SIP_NAT_ROUTE, sip_real_dst(), and STANDARD_SIP_PORT.

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

09116 {
09117    char via[256];
09118    char *c, *pt;
09119    struct hostent *hp;
09120    struct ast_hostent ahp;
09121 
09122    ast_copy_string(via, get_header(req, "Via"), sizeof(via));
09123 
09124    /* Work on the leftmost value of the topmost Via header */
09125    c = strchr(via, ',');
09126    if (c)
09127       *c = '\0';
09128 
09129    /* Check for rport */
09130    c = strstr(via, ";rport");
09131    if (c && (c[6] != '=')) /* rport query, not answer */
09132       ast_set_flag(&p->flags[0], SIP_NAT_ROUTE);
09133 
09134    c = strchr(via, ';');
09135    if (c) 
09136       *c = '\0';
09137 
09138    c = strchr(via, ' ');
09139    if (c) {
09140       *c = '\0';
09141       c = ast_skip_blanks(c+1);
09142       if (strcasecmp(via, "SIP/2.0/UDP")) {
09143          ast_log(LOG_WARNING, "Don't know how to respond via '%s'\n", via);
09144          return;
09145       }
09146       pt = strchr(c, ':');
09147       if (pt)
09148          *pt++ = '\0';  /* remember port pointer */
09149       hp = ast_gethostbyname(c, &ahp);
09150       if (!hp) {
09151          ast_log(LOG_WARNING, "'%s' is not a valid host\n", c);
09152          return;
09153       }
09154       memset(&p->sa, 0, sizeof(p->sa));
09155       p->sa.sin_family = AF_INET;
09156       memcpy(&p->sa.sin_addr, hp->h_addr, sizeof(p->sa.sin_addr));
09157       p->sa.sin_port = htons(pt ? atoi(pt) : STANDARD_SIP_PORT);
09158 
09159       if (sip_debug_test_pvt(p)) {
09160          const struct sockaddr_in *dst = sip_real_dst(p);
09161          ast_verbose("Sending to %s : %d (%s)\n", ast_inet_ntoa(dst->sin_addr), ntohs(dst->sin_port), sip_nat_mode(p));
09162       }
09163    }
09164 }

static void cleanup_stale_contexts ( char *  new,
char *  old 
) [static]

Destroy disused contexts between reloads Only used in reload_config so the code for regcontext doesn't get ugly.

Definition at line 10010 of file chan_sip.c.

References ast_context_destroy(), ast_context_find(), AST_MAX_CONTEXT, and strsep().

Referenced by reload_config().

10011 {
10012    char *oldcontext, *newcontext, *stalecontext, *stringp, newlist[AST_MAX_CONTEXT];
10013 
10014    while ((oldcontext = strsep(&old, "&"))) {
10015       stalecontext = '\0';
10016       ast_copy_string(newlist, new, sizeof(newlist));
10017       stringp = newlist;
10018       while ((newcontext = strsep(&stringp, "&"))) {
10019          if (strcmp(newcontext, oldcontext) == 0) {
10020             /* This is not the context you're looking for */
10021             stalecontext = '\0';
10022             break;
10023          } else if (strcmp(newcontext, oldcontext)) {
10024             stalecontext = oldcontext;
10025          }
10026          
10027       }
10028       if (stalecontext)
10029          ast_context_destroy(ast_context_find(stalecontext), "SIP");
10030    }
10031 }

static int clear_realm_authentication ( struct sip_auth authlist  )  [static]

Clear realm authentication list (at reload).

Definition at line 16219 of file chan_sip.c.

References free, and sip_auth::next.

Referenced by build_peer(), reload_config(), sip_destroy_peer(), and unload_module().

16220 {
16221    struct sip_auth *a = authlist;
16222    struct sip_auth *b;
16223 
16224    while (a) {
16225       b = a;
16226       a = a->next;
16227       free(b);
16228    }
16229 
16230    return 1;
16231 }

static void clear_sip_domains ( void   )  [static]

Clear our domain list (at reload).

Definition at line 16148 of file chan_sip.c.

References AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, and free.

Referenced by reload_config(), and unload_module().

16149 {
16150    struct domain *d;
16151 
16152    AST_LIST_LOCK(&domain_list);
16153    while ((d = AST_LIST_REMOVE_HEAD(&domain_list, list)))
16154       free(d);
16155    AST_LIST_UNLOCK(&domain_list);
16156 }

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

Support routine for 'sip debug peer' CLI.

Definition at line 10818 of file chan_sip.c.

References complete_sip_peer().

10819 {
10820    if (pos == 3)
10821       return complete_sip_peer(word, state, 0);
10822 
10823    return NULL;
10824 }

static char * complete_sip_peer ( const char *  word,
int  state,
int  flags2 
) [static]

Do completion on peer name.

Definition at line 10792 of file chan_sip.c.

References ast_strdup, ast_test_flag, ASTOBJ_CONTAINER_TRAVERSE, and peerl.

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

10793 {
10794    char *result = NULL;
10795    int wordlen = strlen(word);
10796    int which = 0;
10797 
10798    ASTOBJ_CONTAINER_TRAVERSE(&peerl, !result, do {
10799       /* locking of the object is not required because only the name and flags are being compared */
10800       if (!strncasecmp(word, iterator->name, wordlen) &&
10801             (!flags2 || ast_test_flag(&iterator->flags[1], flags2)) &&
10802             ++which > state)
10803          result = ast_strdup(iterator->name);
10804    } while(0) );
10805    return result;
10806 }

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

Support routine for 'sip prune realtime peer' CLI.

Definition at line 10886 of file chan_sip.c.

References complete_sip_peer(), and SIP_PAGE2_RTCACHEFRIENDS.

10887 {
10888    if (pos == 4)
10889       return complete_sip_peer(word, state, SIP_PAGE2_RTCACHEFRIENDS);
10890    return NULL;
10891 }

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

Support routine for 'sip prune realtime user' CLI.

Definition at line 10894 of file chan_sip.c.

References complete_sip_user(), and SIP_PAGE2_RTCACHEFRIENDS.

10895 {
10896    if (pos == 4)
10897       return complete_sip_user(word, state, SIP_PAGE2_RTCACHEFRIENDS);
10898 
10899    return NULL;
10900 }

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

Support routine for 'sip show peer' CLI.

Definition at line 10809 of file chan_sip.c.

References complete_sip_peer().

10810 {
10811    if (pos == 3)
10812       return complete_sip_peer(word, state, 0);
10813 
10814    return NULL;
10815 }

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

Support routine for 'sip show user' CLI.

Definition at line 10847 of file chan_sip.c.

References complete_sip_user().

10848 {
10849    if (pos == 3)
10850       return complete_sip_user(word, state, 0);
10851 
10852    return NULL;
10853 }

static char * complete_sip_user ( const char *  word,
int  state,
int  flags2 
) [static]

Do completion on user name.

Definition at line 10827 of file chan_sip.c.

References ast_strdup, ast_test_flag, ASTOBJ_CONTAINER_TRAVERSE, and userl.

Referenced by complete_sip_prune_realtime_user(), and complete_sip_show_user().

10828 {
10829    char *result = NULL;
10830    int wordlen = strlen(word);
10831    int which = 0;
10832 
10833    ASTOBJ_CONTAINER_TRAVERSE(&userl, !result, do {
10834       /* locking of the object is not required because only the name and flags are being compared */
10835       if (!strncasecmp(word, iterator->name, wordlen)) {
10836          if (flags2 && !ast_test_flag(&iterator->flags[1], flags2))
10837             continue;
10838          if (++which > state) {
10839             result = ast_strdup(iterator->name);
10840          }
10841       }
10842    } while(0) );
10843    return result;
10844 }

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

Support routine for 'sip show channel' CLI.

Definition at line 10773 of file chan_sip.c.

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

10774 {
10775    int which=0;
10776    struct sip_pvt *cur;
10777    char *c = NULL;
10778    int wordlen = strlen(word);
10779 
10780    ast_mutex_lock(&iflock);
10781    for (cur = iflist; cur; cur = cur->next) {
10782       if (!strncasecmp(word, cur->callid, wordlen) && ++which > state) {
10783          c = ast_strdup(cur->callid);
10784          break;
10785       }
10786    }
10787    ast_mutex_unlock(&iflock);
10788    return c;
10789 }

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

Support routine for 'sip notify' CLI.

Definition at line 10856 of file chan_sip.c.

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

10857 {
10858    char *c = NULL;
10859 
10860    if (pos == 2) {
10861       int which = 0;
10862       char *cat = NULL;
10863       int wordlen = strlen(word);
10864 
10865       /* do completion for notify type */
10866 
10867       if (!notify_types)
10868          return NULL;
10869       
10870       while ( (cat = ast_category_browse(notify_types, cat)) ) {
10871          if (!strncasecmp(word, cat, wordlen) && ++which > state) {
10872             c = ast_strdup(cat);
10873             break;
10874          }
10875       }
10876       return c;
10877    }
10878 
10879    if (pos > 2)
10880       return complete_sip_peer(word, state, 0);
10881 
10882    return NULL;
10883 }

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

Copy all headers from one request to another.

Definition at line 5597 of file chan_sip.c.

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

Referenced by respprep().

05598 {
05599    int start = 0;
05600    int copied = 0;
05601    for (;;) {
05602       const char *tmp = __get_header(orig, field, &start);
05603 
05604       if (ast_strlen_zero(tmp))
05605          break;
05606       /* Add what we're responding to */
05607       add_header(req, field, tmp);
05608       copied++;
05609    }
05610    return copied ? 0 : -1;
05611 }

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

Copy one header field from one request to another.

Definition at line 5586 of file chan_sip.c.

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

Referenced by reqprep(), and respprep().

05587 {
05588    const char *tmp = get_header(orig, field);
05589 
05590    if (!ast_strlen_zero(tmp)) /* Add what we're responding to */
05591       return add_header(req, field, tmp);
05592    ast_log(LOG_NOTICE, "No field '%s' present to copy\n", field);
05593    return -1;
05594 }

static void copy_request ( struct sip_request dst,
const struct sip_request src 
) [static]

copy SIP request (mostly used to save request for responses)

Definition at line 6634 of file chan_sip.c.

References sip_request::header, sip_request::line, offset, sip_request::rlPart1, and sip_request::rlPart2.

Referenced by handle_request_bye(), handle_request_invite(), handle_request_refer(), handle_request_register(), handle_request_subscribe(), initialize_initreq(), sip_park(), and sip_park_thread().

06635 {
06636    long offset;
06637    int x;
06638    offset = ((void *)dst) - ((void *)src);
06639    /* First copy stuff */
06640    memcpy(dst, src, sizeof(*dst));
06641    /* Now fix pointer arithmetic */
06642    for (x=0; x < src->headers; x++)
06643       dst->header[x] += offset;
06644    for (x=0; x < src->lines; x++)
06645       dst->line[x] += offset;
06646    dst->rlPart1 += offset;
06647    dst->rlPart2 += offset;
06648 }

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

Copy SIP VIA Headers from the request to the response.

Note:
If the client indicates that it wishes to know the port we received from, it adds ;rport without an argument to the topmost via header. We need to add the port number (from our point of view) to that parameter. We always add ;received=<ip address>=""> to the topmost via header. Received: RFC 3261, rport RFC 3581

Definition at line 5619 of file chan_sip.c.

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

Referenced by respprep().

05620 {
05621    int copied = 0;
05622    int start = 0;
05623 
05624    for (;;) {
05625       char new[256];
05626       const char *oh = __get_header(orig, field, &start);
05627 
05628       if (ast_strlen_zero(oh))
05629          break;
05630 
05631       if (!copied) { /* Only check for empty rport in topmost via header */
05632          char leftmost[256], *others, *rport;
05633 
05634          /* Only work on leftmost value */
05635          ast_copy_string(leftmost, oh, sizeof(leftmost));
05636          others = strchr(leftmost, ',');
05637          if (others)
05638              *others++ = '\0';
05639 
05640          /* Find ;rport;  (empty request) */
05641          rport = strstr(leftmost, ";rport");
05642          if (rport && *(rport+6) == '=') 
05643             rport = NULL;     /* We already have a parameter to rport */
05644 
05645          /* Check rport if NAT=yes or NAT=rfc3581 (which is the default setting)  */
05646          if (rport && ((ast_test_flag(&p->flags[0], SIP_NAT) == SIP_NAT_ALWAYS) || (ast_test_flag(&p->flags[0], SIP_NAT) == SIP_NAT_RFC3581))) {
05647             /* We need to add received port - rport */
05648             char *end;
05649 
05650             rport = strstr(leftmost, ";rport");
05651 
05652             if (rport) {
05653                end = strchr(rport + 1, ';');
05654                if (end)
05655                   memmove(rport, end, strlen(end) + 1);
05656                else
05657                   *rport = '\0';
05658             }
05659 
05660             /* Add rport to first VIA header if requested */
05661             snprintf(new, sizeof(new), "%s;received=%s;rport=%d%s%s",
05662                leftmost, ast_inet_ntoa(p->recv.sin_addr),
05663                ntohs(p->recv.sin_port),
05664                others ? "," : "", others ? others : "");
05665          } else {
05666             /* We should *always* add a received to the topmost via */
05667             snprintf(new, sizeof(new), "%s;received=%s%s%s",
05668                leftmost, ast_inet_ntoa(p->recv.sin_addr),
05669                others ? "," : "", others ? others : "");
05670          }
05671          oh = new;   /* the header to copy */
05672       }  /* else add the following via headers untouched */
05673       add_header(req, field, oh);
05674       copied++;
05675    }
05676    if (!copied) {
05677       ast_log(LOG_NOTICE, "No header field '%s' present to copy\n", field);
05678       return -1;
05679    }
05680    return 0;
05681 }

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

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

References ast_get_srv(), ast_gethostbyname(), ast_log(), ast_string_field_set, ASTOBJ_UNREF, create_addr_from_peer(), find_peer(), hp, LOG_WARNING, portno, sip_pvt::recv, sip_pvt::sa, sip_destroy_peer(), STANDARD_SIP_PORT, sip_pvt::timer_t1, and sip_peer::tohost.

02862 {
02863    struct hostent *hp;
02864    struct ast_hostent ahp;
02865    struct sip_peer *p;
02866    char *port;
02867    int portno;
02868    char host[MAXHOSTNAMELEN], *hostn;
02869    char peer[256];
02870 
02871    ast_copy_string(peer, opeer, sizeof(peer));
02872    port = strchr(peer, ':');
02873    if (port)
02874       *port++ = '\0';
02875    dialog->sa.sin_family = AF_INET;
02876    dialog->timer_t1 = 500; /* Default SIP retransmission timer T1 (RFC 3261) */
02877    p = find_peer(peer, NULL, 1);
02878 
02879    if (p) {
02880       int res = create_addr_from_peer(dialog, p);
02881       ASTOBJ_UNREF(p, sip_destroy_peer);
02882       return res;
02883    }
02884    hostn = peer;
02885    portno = port ? atoi(port) : STANDARD_SIP_PORT;
02886    if (srvlookup) {
02887       char service[MAXHOSTNAMELEN];
02888       int tportno;
02889       int ret;
02890 
02891       snprintf(service, sizeof(service), "_sip._udp.%s", peer);
02892       ret = ast_get_srv(NULL, host, sizeof(host), &tportno, service);
02893       if (ret > 0) {
02894          hostn = host;
02895          portno = tportno;
02896       }
02897    }
02898    hp = ast_gethostbyname(hostn, &ahp);
02899    if (!hp) {
02900       ast_log(LOG_WARNING, "No such host: %s\n", peer);
02901       return -1;
02902    }
02903    ast_string_field_set(dialog, tohost, peer);
02904    memcpy(&dialog->sa.sin_addr, hp->h_addr, sizeof(dialog->sa.sin_addr));
02905    dialog->sa.sin_port = htons(portno);
02906    dialog->recv = dialog->sa;
02907    return 0;
02908 }

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

Create address structure from peer reference. return -1 on error, 0 on success.

Definition at line 2753 of file chan_sip.c.

References sip_peer::addr, sip_peer::allowtransfer, sip_pvt::allowtransfer, ast_copy_flags, AST_FORMAT_VIDEO_MASK, ast_inet_ntoa(), ast_log(), ast_rtp_codec_setpref(), ast_rtp_destroy(), AST_RTP_DTMF, ast_rtp_set_rtpholdtimeout(), ast_rtp_set_rtpkeepalive(), ast_rtp_set_rtptimeout(), ast_rtp_setdtmf(), ast_rtp_setdtmfcompensate(), ast_set_flag, ast_strdupa, ast_string_field_build, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_udptl_destroy(), ast_udptl_get_error_correction_scheme(), sip_peer::autoframing, sip_pvt::autoframing, sip_peer::call_limit, sip_peer::callgroup, sip_pvt::callgroup, t38properties::capability, sip_peer::capability, sip_pvt::capability, sip_peer::context, domain::context, sip_peer::defaddr, do_setnat(), sip_peer::flags, sip_pvt::flags, sip_peer::fromdomain, sip_peer::fromuser, sip_peer::fullcontact, global_t38_capability, sip_request::headers, sip_pvt::initreq, t38properties::jointcapability, sip_pvt::jointnoncodeccapability, language, sip_peer::language, sip_peer::lastms, LOG_DEBUG, sip_peer::maxcallbitrate, sip_pvt::maxcallbitrate, sip_peer::maxms, sip_pvt::maxtime, sip_peer::md5secret, sip_peer::mohinterpret, mohinterpret, sip_peer::mohsuggest, mohsuggest, sip_pvt::noncodeccapability, option_debug, sip_peer::pickupgroup, sip_pvt::pickupgroup, sip_peer::prefs, sip_pvt::prefs, sip_pvt::recv, sip_pvt::rtp, sip_peer::rtpholdtimeout, sip_peer::rtpkeepalive, sip_pvt::rtptimeout, sip_peer::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_PAGE2_FLAGS_TO_COPY, SIP_PAGE2_RFC2833_COMPENSATE, SIP_PAGE2_T38SUPPORT, SIP_PAGE2_VIDEOSUPPORT, sip_pvt::t38, T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF, T38FAX_UDP_EC_FEC, T38FAX_UDP_EC_NONE, T38FAX_UDP_EC_REDUNDANCY, sip_pvt::timer_t1, sip_peer::tohost, sip_pvt::udptl, UDPTL_ERROR_CORRECTION_FEC, UDPTL_ERROR_CORRECTION_NONE, UDPTL_ERROR_CORRECTION_REDUNDANCY, username, sip_peer::username, and sip_pvt::vrtp.

Referenced by create_addr(), and sip_send_mwi_to_peer().

02754 {
02755    if ((peer->addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr) &&
02756        (!peer->maxms || ((peer->lastms >= 0)  && (peer->lastms <= peer->maxms)))) {
02757       dialog->sa = (peer->addr.sin_addr.s_addr) ? peer->addr : peer->defaddr;
02758       dialog->recv = dialog->sa;
02759    } else 
02760       return -1;
02761 
02762    ast_copy_flags(&dialog->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY);
02763    ast_copy_flags(&dialog->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY);
02764    dialog->capability = peer->capability;
02765    if ((!ast_test_flag(&dialog->flags[1], SIP_PAGE2_VIDEOSUPPORT) || !(dialog->capability & AST_FORMAT_VIDEO_MASK)) && dialog->vrtp) {
02766       ast_rtp_destroy(dialog->vrtp);
02767       dialog->vrtp = NULL;
02768    }
02769    dialog->prefs = peer->prefs;
02770    if (ast_test_flag(&dialog->flags[1], SIP_PAGE2_T38SUPPORT)) {
02771       dialog->t38.capability = global_t38_capability;
02772       if (dialog->udptl) {
02773          if (ast_udptl_get_error_correction_scheme(dialog->udptl) == UDPTL_ERROR_CORRECTION_FEC )
02774             dialog->t38.capability |= T38FAX_UDP_EC_FEC;
02775          else if (ast_udptl_get_error_correction_scheme(dialog->udptl) == UDPTL_ERROR_CORRECTION_REDUNDANCY )
02776             dialog->t38.capability |= T38FAX_UDP_EC_REDUNDANCY;
02777          else if (ast_udptl_get_error_correction_scheme(dialog->udptl) == UDPTL_ERROR_CORRECTION_NONE )
02778             dialog->t38.capability |= T38FAX_UDP_EC_NONE;
02779          dialog->t38.capability |= T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF;
02780          if (option_debug > 1)
02781             ast_log(LOG_DEBUG,"Our T38 capability (%d)\n", dialog->t38.capability);
02782       }
02783       dialog->t38.jointcapability = dialog->t38.capability;
02784    } else if (dialog->udptl) {
02785       ast_udptl_destroy(dialog->udptl);
02786       dialog->udptl = NULL;
02787    }
02788    do_setnat(dialog, ast_test_flag(&dialog->flags[0], SIP_NAT) & SIP_NAT_ROUTE );
02789 
02790    if (dialog->rtp) {
02791       ast_rtp_setdtmf(dialog->rtp, ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833);
02792       ast_rtp_setdtmfcompensate(dialog->rtp, ast_test_flag(&dialog->flags[1], SIP_PAGE2_RFC2833_COMPENSATE));
02793       ast_rtp_set_rtptimeout(dialog->rtp, peer->rtptimeout);
02794       ast_rtp_set_rtpholdtimeout(dialog->rtp, peer->rtpholdtimeout);
02795       ast_rtp_set_rtpkeepalive(dialog->rtp, peer->rtpkeepalive);
02796       /* Set Frame packetization */
02797       ast_rtp_codec_setpref(dialog->rtp, &dialog->prefs);
02798       dialog->autoframing = peer->autoframing;
02799    }
02800    if (dialog->vrtp) {
02801       ast_rtp_setdtmf(dialog->vrtp, 0);
02802       ast_rtp_setdtmfcompensate(dialog->vrtp, 0);
02803       ast_rtp_set_rtptimeout(dialog->vrtp, peer->rtptimeout);
02804       ast_rtp_set_rtpholdtimeout(dialog->vrtp, peer->rtpholdtimeout);
02805       ast_rtp_set_rtpkeepalive(dialog->vrtp, peer->rtpkeepalive);
02806    }
02807 
02808    ast_string_field_set(dialog, peername, peer->name);
02809    ast_string_field_set(dialog, authname, peer->username);
02810    ast_string_field_set(dialog, username, peer->username);
02811    ast_string_field_set(dialog, peersecret, peer->secret);
02812    ast_string_field_set(dialog, peermd5secret, peer->md5secret);
02813    ast_string_field_set(dialog, mohsuggest, peer->mohsuggest);
02814    ast_string_field_set(dialog, mohinterpret, peer->mohinterpret);
02815    ast_string_field_set(dialog, tohost, peer->tohost);
02816    ast_string_field_set(dialog, fullcontact, peer->fullcontact);
02817    if (!dialog->initreq.headers && !ast_strlen_zero(peer->fromdomain)) {
02818       char *tmpcall;
02819       char *c;
02820       tmpcall = ast_strdupa(dialog->callid);
02821       c = strchr(tmpcall, '@');
02822       if (c) {
02823          *c = '\0';
02824          ast_string_field_build(dialog, callid, "%s@%s", tmpcall, peer->fromdomain);
02825       }
02826    }
02827    if (ast_strlen_zero(dialog->tohost))
02828       ast_string_field_set(dialog, tohost, ast_inet_ntoa(dialog->sa.sin_addr));
02829    if (!ast_strlen_zero(peer->fromdomain))
02830       ast_string_field_set(dialog, fromdomain, peer->fromdomain);
02831    if (!ast_strlen_zero(peer->fromuser))
02832       ast_string_field_set(dialog, fromuser, peer->fromuser);
02833    if (!ast_strlen_zero(peer->language))
02834       ast_string_field_set(dialog, language, peer->language);
02835    dialog->maxtime = peer->maxms;
02836    dialog->callgroup = peer->callgroup;
02837    dialog->pickupgroup = peer->pickupgroup;
02838    dialog->allowtransfer = peer->allowtransfer;
02839    /* Set timer T1 to RTT for this peer (if known by qualify=) */
02840    /* Minimum is settable or default to 100 ms */
02841    if (peer->maxms && peer->lastms)
02842       dialog->timer_t1 = peer->lastms < global_t1min ? global_t1min : peer->lastms;
02843    if ((ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) ||
02844        (ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_AUTO))
02845       dialog->noncodeccapability |= AST_RTP_DTMF;
02846    else
02847       dialog->noncodeccapability &= ~AST_RTP_DTMF;
02848    dialog->jointnoncodeccapability = dialog->noncodeccapability;
02849    ast_string_field_set(dialog, context, peer->context);
02850    dialog->rtptimeout = peer->rtptimeout;
02851    if (peer->call_limit)
02852       ast_set_flag(&dialog->flags[0], SIP_CALL_LIMIT);
02853    dialog->maxcallbitrate = peer->maxcallbitrate;
02854    
02855    return 0;
02856 }

static void destroy_association ( struct sip_peer peer  )  [static]

Remove registration data from realtime database or AST/DB when registration expires.

Definition at line 7813 of file chan_sip.c.

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

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

07814 {
07815    if (!ast_test_flag(&global_flags[1], SIP_PAGE2_IGNOREREGEXPIRE)) {
07816       if (ast_test_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT))
07817          ast_update_realtime("sippeers", "name", peer->name, "fullcontact", "", "ipaddr", "", "port", "", "regseconds", "0", "username", "", "regserver", "", NULL);
07818       else 
07819          ast_db_del("SIP/Registry", peer->name);
07820    }
07821 }

static int determine_firstline_parts ( struct sip_request req  )  [static]

Parse first line of incoming SIP request.

Definition at line 6678 of file chan_sip.c.

References ast_log(), sip_request::header, LOG_WARNING, sip_request::rlPart1, and sip_request::rlPart2.

Referenced by parse_request().

06679 {
06680    char *e = ast_skip_blanks(req->header[0]);   /* there shouldn't be any */
06681 
06682    if (!*e)
06683       return -1;
06684    req->rlPart1 = e; /* method or protocol */
06685    e = ast_skip_nonblanks(e);
06686    if (*e)
06687       *e++ = '\0';
06688    /* Get URI or status code */
06689    e = ast_skip_blanks(e);
06690    if ( !*e )
06691       return -1;
06692    ast_trim_blanks(e);
06693 
06694    if (!strcasecmp(req->rlPart1, "SIP/2.0") ) { /* We have a response */
06695       if (strlen(e) < 3)   /* status code is 3 digits */
06696          return -1;
06697       req->rlPart2 = e;
06698    } else { /* We have a request */
06699       if ( *e == '<' ) { /* XXX the spec says it must not be in <> ! */
06700          ast_log(LOG_WARNING, "bogus uri in <> %s\n", e);
06701          e++;
06702          if (!*e)
06703             return -1; 
06704       }
06705       req->rlPart2 = e; /* URI */
06706       e = ast_skip_nonblanks(e);
06707       if (*e)
06708          *e++ = '\0';
06709       e = ast_skip_blanks(e);
06710       if (strcasecmp(e, "SIP/2.0") ) {
06711          ast_log(LOG_WARNING, "Bad request protocol %s\n", e);
06712          return -1;
06713       }
06714    }
06715    return 1;
06716 }

static void * do_monitor ( void *  data  )  [static]

The SIP monitoring thread.

Note:
This thread monitors all the SIP sessions and peers that needs notification of mwi (and thus do not have a separate thread) indefinitely

Note:
If we can't get a lock on an interface, skip it and come back later. Note that there is the possibility of a deadlock with sip_hangup otherwise, because sip_hangup is called with the channel locked first, and the iface lock is attempted second.

Definition at line 15463 of file chan_sip.c.

References __sip_destroy(), ast_channel_trylock, ast_channel_unlock, ast_io_add(), ast_io_change(), AST_IO_IN, ast_io_wait(), ast_log(), ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_rtp_get_peer(), ast_rtp_get_rtpholdtimeout(), ast_rtp_get_rtpkeepalive(), ast_rtp_get_rtptimeout(), ast_rtp_sendcng(), ast_rtp_set_rtpholdtimeout(), ast_rtp_set_rtptimeout(), ast_sched_runq(), ast_sched_wait(), AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), AST_STATE_UP, ast_test_flag, ast_verbose(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_REF, ASTOBJ_UNLOCK, ASTOBJ_UNREF, ASTOBJ_WRLOCK, does_peer_need_mwi(), FALSE, iflist, LOG_DEBUG, LOG_NOTICE, sip_pvt::next, option_debug, option_verbose, peerl, sip_destroy_peer(), sip_do_reload(), SIP_NEEDDESTROY, sip_send_mwi_to_peer(), sipsock, sipsock_read(), t, T38_ENABLED, TRUE, and VERBOSE_PREFIX_1.

15464 {
15465    int res;
15466    struct sip_pvt *sip;
15467    struct sip_peer *peer = NULL;
15468    time_t t;
15469    int fastrestart = FALSE;
15470    int lastpeernum = -1;
15471    int curpeernum;
15472    int reloading;
15473 
15474    /* Add an I/O event to our SIP UDP socket */
15475    if (sipsock > -1) 
15476       sipsock_read_id = ast_io_add(io, sipsock, sipsock_read, AST_IO_IN, NULL);
15477    
15478    /* From here on out, we die whenever asked */
15479    for(;;) {
15480       /* Check for a reload request */
15481       ast_mutex_lock(&sip_reload_lock);
15482       reloading = sip_reloading;
15483       sip_reloading = FALSE;
15484       ast_mutex_unlock(&sip_reload_lock);
15485       if (reloading) {
15486          if (option_verbose > 0)
15487             ast_verbose(VERBOSE_PREFIX_1 "Reloading SIP\n");
15488          sip_do_reload(sip_reloadreason);
15489 
15490          /* Change the I/O fd of our UDP socket */
15491          if (sipsock > -1) {
15492             if (sipsock_read_id)
15493                sipsock_read_id = ast_io_change(io, sipsock_read_id, sipsock, NULL, 0, NULL);
15494             else
15495                sipsock_read_id = ast_io_add(io, sipsock, sipsock_read, AST_IO_IN, NULL);
15496          }
15497       }
15498       /* Check for interfaces needing to be killed */
15499       ast_mutex_lock(&iflock);
15500 restartsearch:    
15501       t = time(NULL);
15502       /* don't scan the interface list if it hasn't been a reasonable period
15503          of time since the last time we did it (when MWI is being sent, we can
15504          get back to this point every millisecond or less)
15505       */
15506       for (sip = iflist; !fastrestart && sip; sip = sip->next) {
15507          /*! \note If we can't get a lock on an interface, skip it and come
15508           * back later. Note that there is the possibility of a deadlock with
15509           * sip_hangup otherwise, because sip_hangup is called with the channel
15510           * locked first, and the iface lock is attempted second.
15511           */
15512          if (ast_mutex_trylock(&sip->lock))
15513             continue;
15514 
15515          /* Check RTP timeouts and kill calls if we have a timeout set and do not get RTP */
15516          if (sip->rtp && sip->owner &&
15517              (sip->owner->_state == AST_STATE_UP) &&
15518              !sip->redirip.sin_addr.s_addr &&
15519              sip->t38.state != T38_ENABLED) {
15520             if (sip->lastrtptx &&
15521                 ast_rtp_get_rtpkeepalive(sip->rtp) &&
15522                 (t > sip->lastrtptx + ast_rtp_get_rtpkeepalive(sip->rtp))) {
15523                /* Need to send an empty RTP packet */
15524                sip->lastrtptx = time(NULL);
15525                ast_rtp_sendcng(sip->rtp, 0);
15526             }
15527             if (sip->lastrtprx &&
15528                (ast_rtp_get_rtptimeout(sip->rtp) || ast_rtp_get_rtpholdtimeout(sip->rtp)) &&
15529                 (t > sip->lastrtprx + ast_rtp_get_rtptimeout(sip->rtp))) {
15530                /* Might be a timeout now -- see if we're on hold */
15531                struct sockaddr_in sin;
15532                ast_rtp_get_peer(sip->rtp, &sin);
15533                if (sin.sin_addr.s_addr || 
15534                    (ast_rtp_get_rtpholdtimeout(sip->rtp) &&
15535                     (t > sip->lastrtprx + ast_rtp_get_rtpholdtimeout(sip->rtp)))) {
15536                   /* Needs a hangup */
15537                   if (ast_rtp_get_rtptimeout(sip->rtp)) {
15538                      while (sip->owner && ast_channel_trylock(sip->owner)) {
15539                         ast_mutex_unlock(&sip->lock);
15540                         usleep(1);
15541                         ast_mutex_lock(&sip->lock);
15542                      }
15543                      if (sip->owner) {
15544                         ast_log(LOG_NOTICE,
15545                            "Disconnecting call '%s' for lack of RTP activity in %ld seconds\n",
15546                            sip->owner->name,
15547                            (long) (t - sip->lastrtprx));
15548                         /* Issue a softhangup */
15549                         ast_softhangup_nolock(sip->owner, AST_SOFTHANGUP_DEV);
15550                         ast_channel_unlock(sip->owner);
15551                         /* forget the timeouts for this call, since a hangup
15552                            has already been requested and we don't want to
15553                            repeatedly request hangups
15554                         */
15555                         ast_rtp_set_rtptimeout(sip->rtp, 0);
15556                         ast_rtp_set_rtpholdtimeout(sip->rtp, 0);
15557                         if (sip->vrtp) {
15558                            ast_rtp_set_rtptimeout(sip->vrtp, 0);
15559                            ast_rtp_set_rtpholdtimeout(sip->vrtp, 0);
15560                         }
15561                      }
15562                   }
15563                }
15564             }
15565          }
15566          /* If we have sessions that needs to be destroyed, do it now */
15567          if (ast_test_flag(&sip->flags[0], SIP_NEEDDESTROY) && !sip->packets &&
15568              !sip->owner) {
15569             ast_mutex_unlock(&sip->lock);
15570             __sip_destroy(sip, 1);
15571             goto restartsearch;
15572          }
15573          ast_mutex_unlock(&sip->lock);
15574       }
15575       ast_mutex_unlock(&iflock);
15576 
15577       pthread_testcancel();
15578       /* Wait for sched or io */
15579       res = ast_sched_wait(sched);
15580       if ((res < 0) || (res > 1000))
15581          res = 1000;
15582       /* If we might need to send more mailboxes, don't wait long at all.*/
15583       if (fastrestart)
15584          res = 1;
15585       res = ast_io_wait(io, res);
15586       if (option_debug && res > 20)
15587          ast_log(LOG_DEBUG, "chan_sip: ast_io_wait ran %d all at once\n", res);
15588       ast_mutex_lock(&monlock);
15589       if (res >= 0)  {
15590          res = ast_sched_runq(sched);
15591          if (option_debug && res >= 20)
15592             ast_log(LOG_DEBUG, "chan_sip: ast_sched_runq ran %d all at once\n", res);
15593       }
15594 
15595       /* Send MWI notifications to peers - static and cached realtime peers */
15596       t = time(NULL);
15597       fastrestart = FALSE;
15598       curpeernum = 0;
15599       peer = NULL;
15600       /* Find next peer that needs mwi */
15601       ASTOBJ_CONTAINER_TRAVERSE(&peerl, !peer, do {
15602          if ((curpeernum > lastpeernum) && does_peer_need_mwi(iterator)) {
15603             fastrestart = TRUE;
15604             lastpeernum = curpeernum;
15605             peer = ASTOBJ_REF(iterator);
15606          };
15607          curpeernum++;
15608       } while (0)
15609       );
15610       /* Send MWI to the peer */
15611       if (peer) {
15612          ASTOBJ_WRLOCK(peer);
15613          sip_send_mwi_to_peer(peer);
15614          ASTOBJ_UNLOCK(peer);
15615          ASTOBJ_UNREF(peer,sip_destroy_peer);
15616       } else {
15617          /* Reset where we come from */
15618          lastpeernum = -1;
15619       }
15620       ast_mutex_unlock(&monlock);
15621    }
15622    /* Never reached */
15623    return NULL;
15624    
15625 }

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

Add authentication on outbound SIP packet.

Definition at line 11359 of file chan_sip.c.

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

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

11360 {
11361    char digest[1024];
11362 
11363    if (!p->options && !(p->options = ast_calloc(1, sizeof(*p->options))))
11364       return -2;
11365 
11366    p->authtries++;
11367    if (option_debug > 1)
11368       ast_log(LOG_DEBUG, "Auth attempt %d on %s\n", p->authtries, sip_methods[sipmethod].text);
11369    memset(digest, 0, sizeof(digest));
11370    if (reply_digest(p, req, header, sipmethod, digest, sizeof(digest) )) {
11371       /* No way to authenticate */
11372       return -1;
11373    }
11374    /* Now we have a reply digest */
11375    p->options->auth = digest;
11376    p->options->authheader = respheader;
11377    return transmit_invite(p, sipmethod, sipmethod == SIP_INVITE, init); 
11378 }

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

Authenticate for outbound registration.

Definition at line 11338 of file chan_sip.c.

References append_history, ast_test_flag, ast_verbose(), sip_pvt::authtries, sip_pvt::flags, sip_pvt::registry, reply_digest(), sip_debug_test_pvt(), SIP_NO_HISTORY, SIP_REGISTER, and transmit_register().

Referenced by handle_response_register().

11339 {
11340    char digest[1024];
11341    p->authtries++;
11342    memset(digest,0,sizeof(digest));
11343    if (reply_digest(p, req, header, SIP_REGISTER, digest, sizeof(digest))) {
11344       /* There's nothing to use for authentication */
11345       /* No digest challenge in request */
11346       if (sip_debug_test_pvt(p) && p->registry)
11347          ast_verbose("No authentication challenge, sending blank registration to domain/host name %s\n", p->registry->hostname);
11348          /* No old challenge */
11349       return -1;
11350    }
11351    if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY))
11352       append_history(p, "RegistryAuth", "Try: %d", p->authtries);
11353    if (sip_debug_test_pvt(p) && p->registry)
11354       ast_verbose("Responding to challenge, registration to domain/host name %s\n", p->registry->hostname);
11355    return transmit_register(p->registry, SIP_REGISTER, digest, respheader); 
11356 }

static void do_setnat ( struct sip_pvt p,
int  natflags 
) [static]

Set nat mode on the various data sockets.

Definition at line 2729 of file chan_sip.c.

References ast_log(), ast_rtp_setnat(), ast_udptl_setnat(), LOG_DEBUG, domain::mode, option_debug, sip_pvt::rtp, sip_pvt::udptl, and sip_pvt::vrtp.

Referenced by check_user_full(), create_addr_from_peer(), sip_alloc(), and transmit_response_using_temp().

02730 {
02731    const char *mode = natflags ? "On" : "Off";
02732 
02733    if (p->rtp) {
02734       if (option_debug)
02735          ast_log(LOG_DEBUG, "Setting NAT on RTP to %s\n", mode);
02736       ast_rtp_setnat(p->rtp, natflags);
02737    }
02738    if (p->vrtp) {
02739       if (option_debug)
02740          ast_log(LOG_DEBUG, "Setting NAT on VRTP to %s\n", mode);
02741       ast_rtp_setnat(p->vrtp, natflags);
02742    }
02743    if (p->udptl) {
02744       if (option_debug)
02745          ast_log(LOG_DEBUG, "Setting NAT on UDPTL to %s\n", mode);
02746       ast_udptl_setnat(p->udptl, natflags);
02747    }
02748 }

static int does_peer_need_mwi ( struct sip_peer peer  )  [static]

Check whether peer needs a new MWI notification check.

Definition at line 15442 of file chan_sip.c.

References ast_strlen_zero(), ast_test_flag, FALSE, sip_peer::flags, sip_peer::lastmsgcheck, sip_peer::mailbox, sip_peer::mwipvt, SIP_PAGE2_SUBSCRIBEMWIONLY, t, and TRUE.

Referenced by do_monitor().

15443 {
15444    time_t t = time(NULL);
15445 
15446    if (ast_test_flag(&peer->flags[1], SIP_PAGE2_SUBSCRIBEMWIONLY) &&
15447        !peer->mwipvt) { /* We don't have a subscription */
15448       peer->lastmsgcheck = t; /* Reset timer */
15449       return FALSE;
15450    }
15451 
15452    if (!ast_strlen_zero(peer->mailbox) && (t - peer->lastmsgcheck) > global_mwitime)
15453       return TRUE;
15454 
15455    return FALSE;
15456 }

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

Print domain mode to cli.

Definition at line 10199 of file chan_sip.c.

References SIP_DOMAIN_AUTO, and SIP_DOMAIN_CONFIG.

Referenced by sip_show_domains().

10200 {
10201    switch (mode) {
10202    case SIP_DOMAIN_AUTO:
10203       return "[Automatic]";
10204    case SIP_DOMAIN_CONFIG:
10205       return "[Configured]";
10206    }
10207 
10208    return "";
10209 }

static const char * dtmfmode2str ( int  mode  )  [static]

Convert DTMF mode to printable string.

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

09980 {
09981    switch (mode) {
09982    case SIP_DTMF_RFC2833:
09983       return "rfc2833";
09984    case SIP_DTMF_INFO:
09985       return "info";
09986    case SIP_DTMF_INBAND:
09987       return "inband";
09988    case SIP_DTMF_AUTO:
09989       return "auto";
09990    }
09991    return "<error>";
09992 }

static int expire_register ( const void *  data  )  [static]

Expire registration of SIP peer.

Definition at line 7824 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, FALSE, sip_peer::flags, manager_event(), peerl, register_peer_exten(), sip_destroy_peer(), SIP_PAGE2_RTAUTOCLEAR, and SIP_PAGE2_SELFDESTRUCT.

Referenced by parse_register_contact(), realtime_peer(), and reg_source_db().

07825 {
07826    struct sip_peer *peer = (struct sip_peer *)data;
07827    
07828    if (!peer)     /* Hmmm. We have no peer. Weird. */
07829       return 0;
07830 
07831    memset(&peer->addr, 0, sizeof(peer->addr));
07832 
07833    destroy_association(peer); /* remove registration data from storage */
07834    
07835    manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name);
07836    register_peer_exten(peer, FALSE);   /* Remove regexten */
07837    peer->expire = -1;
07838    ast_device_state_changed("SIP/%s", peer->name);
07839 
07840    /* Do we need to release this peer from memory? 
07841       Only for realtime peers and autocreated peers
07842    */
07843    if (ast_test_flag(&peer->flags[1], SIP_PAGE2_SELFDESTRUCT) ||
07844        ast_test_flag(&peer->flags[1], SIP_PAGE2_RTAUTOCLEAR)) {
07845       peer = ASTOBJ_CONTAINER_UNLINK(&peerl, peer);   /* Remove from peer list */
07846       ASTOBJ_UNREF(peer, sip_destroy_peer);     /* Remove from memory */
07847    }
07848 
07849    return 0;
07850 }

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

Check Contact: URI of SIP message.

Definition at line 6768 of file chan_sip.c.

References ast_string_field_set, ast_strlen_zero(), get_header(), get_in_brackets(), and strsep().

Referenced by handle_request(), and handle_request_invite().

06769 {
06770    char stripped[BUFSIZ];
06771    char *c;
06772 
06773    ast_copy_string(stripped, get_header(req, "Contact"), sizeof(stripped));
06774    c = get_in_brackets(stripped);
06775    c = strsep(&c, ";"); /* trim ; and beyond */
06776    if (!ast_strlen_zero(c))
06777       ast_string_field_set(p, uri, c);
06778 }

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

Find compressed SIP alias.

Structure for conversion between compressed SIP and "normal" SIP

Definition at line 4165 of file chan_sip.c.

References aliases.

04166 {
04167    /*! \brief Structure for conversion between compressed SIP and "normal" SIP */
04168    static const struct cfalias {
04169       char * const fullname;
04170       char * const shortname;
04171    } aliases[] = {
04172       { "Content-Type",  "c" },
04173       { "Content-Encoding",    "e" },
04174       { "From",       "f" },
04175       { "Call-ID",       "i" },
04176       { "Contact",       "m" },
04177       { "Content-Length",   "l" },
04178       { "Subject",       "s" },
04179       { "To",         "t" },
04180       { "Supported",     "k" },
04181       { "Refer-To",      "r" },
04182       { "Referred-By",   "b" },
04183       { "Allow-Events",  "u" },
04184       { "Event",      "o" },
04185       { "Via",     "v" },
04186       { "Accept-Contact",      "a" },
04187       { "Reject-Contact",      "j" },
04188       { "Request-Disposition", "d" },
04189       { "Session-Expires",     "x" },
04190       { "Identity",            "y" },
04191       { "Identity-Info",       "n" },
04192    };
04193    int x;
04194 
04195    for (x=0; x<sizeof(aliases) / sizeof(aliases[0]); x++) 
04196       if (!strcasecmp(aliases[x].fullname, name))
04197          return aliases[x].shortname;
04198 
04199    return _default;
04200 }

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

Connect incoming SIP message to current dialog or create new dialog structure Called by handle_request, sipsock_read.

Definition at line 4517 of file chan_sip.c.

References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_strlen_zero(), CAN_CREATE_DIALOG, CAN_CREATE_DIALOG_UNSUPPORTED_METHOD, FALSE, get_header(), gettag(), iflist, sip_pvt::lock, LOG_DEBUG, sip_request::method, sip_pvt::next, option_debug, SIP_ACK, sip_alloc(), sip_methods, SIP_NOTIFY, SIP_PKT_WITH_TOTAG, SIP_REFER, SIP_REGISTER, SIP_RESPONSE, sip_pvt::tag, cfsip_methods::text, and transmit_response_using_temp().

Referenced by sipsock_read().

04518 {
04519    struct sip_pvt *p = NULL;
04520    char *tag = "";   /* note, tag is never NULL */
04521    char totag[128];
04522    char fromtag[128];
04523    const char *callid = get_header(req, "Call-ID");
04524    const char *from = get_header(req, "From");
04525    const char *to = get_header(req, "To");
04526    const char *cseq = get_header(req, "Cseq");
04527 
04528    /* Call-ID, to, from and Cseq are required by RFC 3261. (Max-forwards and via too - ignored now) */
04529    /* get_header always returns non-NULL so we must use ast_strlen_zero() */
04530    if (ast_strlen_zero(callid) || ast_strlen_zero(to) ||
04531          ast_strlen_zero(from) || ast_strlen_zero(cseq))
04532       return NULL;   /* Invalid packet */
04533 
04534    if (pedanticsipchecking) {
04535       /* In principle Call-ID's uniquely identify a call, but with a forking SIP proxy
04536          we need more to identify a branch - so we have to check branch, from
04537          and to tags to identify a call leg.
04538          For Asterisk to behave correctly, you need to turn on pedanticsipchecking
04539          in sip.conf
04540          */
04541       if (gettag(req, "To", totag, sizeof(totag)))
04542          ast_set_flag(req, SIP_PKT_WITH_TOTAG); /* Used in handle_request/response */
04543       gettag(req, "From", fromtag, sizeof(fromtag));
04544 
04545       tag = (req->method == SIP_RESPONSE) ? totag : fromtag;
04546 
04547       if (option_debug > 4 )
04548          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);
04549    }
04550 
04551    ast_mutex_lock(&iflock);
04552    for (p = iflist; p; p = p->next) {
04553       /* In pedantic, we do not want packets with bad syntax to be connected to a PVT */
04554       int found = FALSE;
04555       if (ast_strlen_zero(p->callid))
04556          continue;
04557       if (req->method == SIP_REGISTER)
04558          found = (!strcmp(p->callid, callid));
04559       else 
04560          found = (!strcmp(p->callid, callid) && 
04561          (!pedanticsipchecking || !tag || ast_strlen_zero(p->theirtag) || !strcmp(p->theirtag, tag))) ;
04562 
04563       if (option_debug > 4)
04564          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);
04565 
04566       /* If we get a new request within an existing to-tag - check the to tag as well */
04567       if (pedanticsipchecking && found  && req->method != SIP_RESPONSE) {  /* SIP Request */
04568          if (p->tag[0] == '\0' && totag[0]) {
04569             /* We have no to tag, but they have. Wrong dialog */
04570             found = FALSE;
04571          } else if (totag[0]) {        /* Both have tags, compare them */
04572             if (strcmp(totag, p->tag)) {
04573                found = FALSE;    /* This is not our packet */
04574             }
04575          }
04576          if (!found && option_debug > 4)
04577             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);
04578       }
04579 
04580 
04581       if (found) {
04582          /* Found the call */
04583          ast_mutex_lock(&p->lock);
04584          ast_mutex_unlock(&iflock);
04585          return p;
04586       }
04587    }
04588    ast_mutex_unlock(&iflock);
04589 
04590    /* See if the method is capable of creating a dialog */
04591    if (sip_methods[intended_method].can_create == CAN_CREATE_DIALOG) {
04592       if (intended_method == SIP_REFER) {
04593          /* We do support REFER, but not outside of a dialog yet */
04594          transmit_response_using_temp(callid, sin, 1, intended_method, req, "603 Declined (no dialog)");
04595       } else if (intended_method == SIP_NOTIFY) {
04596          /* We do not support out-of-dialog NOTIFY either,
04597             like voicemail notification, so cancel that early */
04598          transmit_response_using_temp(callid, sin, 1, intended_method, req, "489 Bad event");
04599       } else {
04600          /* Ok, time to create a new SIP dialog object, a pvt */
04601          if ((p = sip_alloc(callid, sin, 1, intended_method)))  {
04602             /* Ok, we've created a dialog, let's go and process it */
04603             ast_mutex_lock(&p->lock);
04604          } else {
04605             /* We have a memory or file/socket error (can't allocate RTP sockets or something) so we're not
04606                getting a dialog from sip_alloc. 
04607    
04608                Without a dialog we can't retransmit and handle ACKs and all that, but at least
04609                send an error message.
04610    
04611                Sorry, we apologize for the inconvienience
04612             */
04613             transmit_response_using_temp(callid, sin, 1, intended_method, req, "500 Server internal error");
04614             if (option_debug > 3)
04615                ast_log(LOG_DEBUG, "Failed allocating SIP dialog, sending 500 Server internal error and giving up\n");
04616          }
04617       }
04618       return p;
04619    } else if( sip_methods[intended_method].can_create == CAN_CREATE_DIALOG_UNSUPPORTED_METHOD) {
04620       /* A method we do not support, let's take it on the volley */
04621       transmit_response_using_temp(callid, sin, 1, intended_method, req, "501 Method Not Implemented");
04622    } else if (intended_method != SIP_RESPONSE && intended_method != SIP_ACK) {
04623       /* This is a request outside of a dialog that we don't know about 
04624          ...never reply to an ACK!
04625       */
04626       transmit_response_using_temp(callid, sin, 1, intended_method, req, "481 Call leg/transaction does not exist");
04627    }
04628    /* We do not respond to responses for dialogs that we don't know about, we just drop
04629       the session quickly */
04630 
04631    return p;
04632 }

static const char* find_closing_quote ( const char *  start,
const char *  lim 
) [static]

Locate closing quote in a string, skipping escaped quotes. optionally with a limit on the search. start must be past the first quote.

Definition at line 2293 of file chan_sip.c.

References s.

Referenced by get_in_brackets().

02294 {
02295         char last_char = '\0';
02296         const char *s;
02297         for (s = start; *s && s != lim; last_char = *s++) {
02298                 if (*s == '"' && last_char != '\\')
02299                         break;
02300         }
02301         return s;
02302 }

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

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

References ASTOBJ_CONTAINER_FIND, ASTOBJ_CONTAINER_FIND_FULL, name, peerl, realtime_peer(), and sip_addrcmp().

02642 {
02643    struct sip_peer *p = NULL;
02644 
02645    if (peer)
02646       p = ASTOBJ_CONTAINER_FIND(&peerl, peer);
02647    else
02648       p = ASTOBJ_CONTAINER_FIND_FULL(&peerl, sin, name, sip_addr_hashfunc, 1, sip_addrcmp);
02649 
02650    if (!p && realtime)
02651       p = realtime_peer(peer, sin);
02652 
02653    return p;
02654 }

static struct sip_auth * find_realm_authentication ( struct sip_auth authlist,
const char *  realm 
) [static, read]

Find authentication for a specific realm.

Definition at line 16234 of file chan_sip.c.

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

Referenced by build_reply_digest().

16235 {
16236    struct sip_auth *a;
16237 
16238    for (a = authlist; a; a = a->next) {
16239       if (!strcasecmp(a->realm, realm))
16240          break;
16241    }
16242 
16243    return a;
16244 }

static int find_sdp ( struct sip_request req  )  [static]

Determine whether a SIP message contains an SDP in its body.

Parameters:
req the SIP request to process
Returns:
1 if SDP found, 0 if not found
Also updates req->sdp_start and req->sdp_end to indicate where the SDP lives in the message body.

Definition at line 4838 of file chan_sip.c.

References ast_strdupa, ast_strlen_zero(), FALSE, get_header(), sip_request::line, sip_request::lines, sip_request::sdp_end, sip_request::sdp_start, strcasestr(), and TRUE.

Referenced by handle_request(), handle_request_invite(), handle_response(), and handle_response_invite().

04839 {
04840    const char *content_type;
04841    const char *search;
04842    char *boundary;
04843    unsigned int x;
04844    int boundaryisquoted = FALSE;
04845    int found_application_sdp = FALSE;
04846    int found_end_of_headers = FALSE;
04847 
04848    content_type = get_header(req, "Content-Type");
04849 
04850    /* if the body contains only SDP, this is easy */
04851    if (!strcasecmp(content_type, "application/sdp")) {
04852       req->sdp_start = 0;
04853       req->sdp_end = req->lines;
04854       return req->lines ? 1 : 0;
04855    }
04856 
04857    /* if it's not multipart/mixed, there cannot be an SDP */
04858    if (strncasecmp(content_type, "multipart/mixed", 15))
04859       return 0;
04860 
04861    /* if there is no boundary marker, it's invalid */
04862    if (!(search = strcasestr(content_type, ";boundary=")))
04863       return 0;
04864 
04865    search += 10;
04866    if (ast_strlen_zero(search))
04867       return 0;
04868 
04869    /* If the boundary is quoted with ", remove quote */
04870    if (*search == '\"')  {
04871       search++;
04872       boundaryisquoted = TRUE;
04873    }
04874 
04875    /* make a duplicate of the string, with two extra characters
04876       at the beginning */
04877    boundary = ast_strdupa(search - 2);
04878    boundary[0] = boundary[1] = '-';
04879    /* Remove final quote */
04880    if (boundaryisquoted)
04881       boundary[strlen(boundary) - 1] = '\0';
04882 
04883    /* search for the boundary marker, the empty line delimiting headers from
04884       sdp part and the end boundry if it exists */
04885 
04886    for (x = 0; x < (req->lines ); x++) {
04887       if(!strncasecmp(req->line[x], boundary, strlen(boundary))){
04888          if(found_application_sdp && found_end_of_headers){
04889             req->sdp_end = x-1;
04890             return 1;
04891          }
04892          found_application_sdp = FALSE;
04893       }
04894       if(!strcasecmp(req->line[x], "Content-Type: application/sdp"))
04895          found_application_sdp = TRUE;
04896       
04897       if(strlen(req->line[x]) == 0 ){
04898          if(found_application_sdp && !found_end_of_headers){
04899             req->sdp_start = x;
04900             found_end_of_headers = TRUE;
04901          }
04902       }
04903    }
04904    if(found_application_sdp && found_end_of_headers) {
04905       req->sdp_end = x;
04906       return TRUE;
04907    }
04908    return FALSE;
04909 }

static int find_sip_method ( const char *  msg  )  [static]

find_sip_method: Find SIP method from header

Definition at line 1675 of file chan_sip.c.

References ast_strlen_zero(), method_match(), and sip_methods.

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

01676 {
01677    int i, res = 0;
01678    
01679    if (ast_strlen_zero(msg))
01680       return 0;
01681    for (i = 1; i < (sizeof(sip_methods) / sizeof(sip_methods[0])) && !res; i++) {
01682       if (method_match(i, msg))
01683          res = sip_methods[i].id;
01684    }
01685    return res;
01686 }

static struct cfsubscription_types * find_subscription_type ( enum subscriptiontype  subtype  )  [static, read]

Find subscription type in array.

Definition at line 10687 of file chan_sip.c.

References subscription_types, and type.

Referenced by transmit_state_notify().

10688 {
10689    int i;
10690 
10691    for (i = 1; (i < (sizeof(subscription_types) / sizeof(subscription_types[0]))); i++) {
10692       if (subscription_types[i].type == subtype) {
10693          return &subscription_types[i];
10694       }
10695    }
10696    return &subscription_types[0];
10697 }

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

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

References ASTOBJ_CONTAINER_FIND, realtime_user(), and userl.

02721 {
02722    struct sip_user *u = ASTOBJ_CONTAINER_FIND(&userl, name);
02723    if (!u && realtime)
02724       u = realtime_user(name);
02725    return u;
02726 }

static void free_old_route ( struct sip_route route  )  [static]

Remove route from route list.

Definition at line 8155 of file chan_sip.c.

References free, and sip_route::next.

Referenced by __sip_destroy(), and build_route().

08156 {
08157    struct sip_route *next;
08158 
08159    while (route) {
08160       next = route->next;
08161       free(route);
08162       route = next;
08163    }
08164 }

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

Dial plan function to check if domain is local.

Definition at line 11685 of file chan_sip.c.

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

11686 {
11687    if (ast_strlen_zero(data)) {
11688       ast_log(LOG_WARNING, "CHECKSIPDOMAIN requires an argument - A domain name\n");
11689       return -1;
11690    }
11691    if (check_sip_domain(data, NULL, 0))
11692       ast_copy_string(buf, data, len);
11693    else
11694       buf[0] = '\0';
11695    return 0;
11696 }

static int func_header_read ( struct ast_channel chan,
char *  function,
char *  data,
char *  buf,
size_t  len 
) [static]

Read SIP header (dialplan function).

Definition at line 11621 of file chan_sip.c.

References __get_header(), AST_APP_ARG, ast_channel_lock, ast_channel_unlock, AST_DECLARE_APP_ARGS, ast_log(), AST_STANDARD_APP_ARGS, ast_strlen_zero(), sip_request::header, sip_pvt::initreq, LOG_WARNING, sip_tech, sip_tech_info, ast_channel::tech, and ast_channel::tech_pvt.

11622 {
11623    struct sip_pvt *p;
11624    const char *content = NULL;
11625    AST_DECLARE_APP_ARGS(args,
11626       AST_APP_ARG(header);
11627       AST_APP_ARG(number);
11628    );
11629    int i, number, start = 0;
11630 
11631    if (ast_strlen_zero(data)) {
11632       ast_log(LOG_WARNING, "This function requires a header name.\n");
11633       return -1;
11634    }
11635 
11636    ast_channel_lock(chan);
11637    if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) {
11638       ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n");
11639       ast_channel_unlock(chan);
11640       return -1;
11641    }
11642 
11643    AST_STANDARD_APP_ARGS(args, data);
11644    if (!args.number) {
11645       number = 1;
11646    } else {
11647       sscanf(args.number, "%d", &number);
11648       if (number < 1)
11649          number = 1;
11650    }
11651 
11652    p = chan->tech_pvt;
11653 
11654    /* If there is no private structure, this channel is no longer alive */
11655    if (!p) {
11656       ast_channel_unlock(chan);
11657       return -1;
11658    }
11659 
11660    for (i = 0; i < number; i++)
11661       content = __get_header(&p->initreq, args.header, &start);
11662 
11663    if (ast_strlen_zero(content)) {
11664       ast_channel_unlock(chan);
11665       return -1;
11666    }
11667 
11668    ast_copy_string(buf, content, len);
11669    ast_channel_unlock(chan);
11670 
11671    return 0;
11672 }

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

${SIPCHANINFO()} Dialplan function - reads sip channel data

Definition at line 11800 of file chan_sip.c.

References ast_channel_lock, ast_channel_unlock, ast_inet_ntoa(), ast_log(), LOG_WARNING, sip_pvt::recv, sip_pvt::sa, sip_tech, sip_tech_info, t38properties::state, sip_pvt::t38, T38_DISABLED, ast_channel::tech, and ast_channel::tech_pvt.

11801 {
11802    struct sip_pvt *p;
11803 
11804    *buf = 0;
11805    
11806    if (!data) {
11807       ast_log(LOG_WARNING, "This function requires a parameter name.\n");
11808       return -1;
11809    }
11810 
11811    ast_channel_lock(chan);
11812    if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) {
11813       ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n");
11814       ast_channel_unlock(chan);
11815       return -1;
11816    }
11817 
11818    p = chan->tech_pvt;
11819 
11820    /* If there is no private structure, this channel is no longer alive */
11821    if (!p) {
11822       ast_channel_unlock(chan);
11823       return -1;
11824    }
11825 
11826    if (!strcasecmp(data, "peerip")) {
11827       ast_copy_string(buf, p->sa.sin_addr.s_addr ? ast_inet_ntoa(p->sa.sin_addr) : "", len);
11828    } else  if (!strcasecmp(data, "recvip")) {
11829       ast_copy_string(buf, p->recv.sin_addr.s_addr ? ast_inet_ntoa(p->recv.sin_addr) : "", len);
11830    } else  if (!strcasecmp(data, "from")) {
11831       ast_copy_string(buf, p->from, len);
11832    } else  if (!strcasecmp(data, "uri")) {
11833       ast_copy_string(buf, p->uri, len);
11834    } else  if (!strcasecmp(data, "useragent")) {
11835       ast_copy_string(buf, p->useragent, len);
11836    } else  if (!strcasecmp(data, "peername")) {
11837       ast_copy_string(buf, p->peername, len);
11838    } else if (!strcasecmp(data, "t38passthrough")) {
11839       if (p->t38.state == T38_DISABLED)
11840          ast_copy_string(buf, "0", sizeof("0"));
11841       else    /* T38 is offered or enabled in this call */
11842          ast_copy_string(buf, "1", sizeof("1"));
11843    } else {
11844       ast_channel_unlock(chan);
11845       return -1;
11846    }
11847    ast_channel_unlock(chan);
11848 
11849    return 0;
11850 }

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

${SIPPEER()} Dialplan function - reads peer data

Todo:
Will be deprecated after 1.4

Definition at line 11710 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_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::flags, sip_peer::inUse, sip_peer::language, sip_peer::mailbox, peer_status(), sip_peer::prefs, sip_peer::regexten, sip_destroy_peer(), SIP_PAGE2_DYNAMIC, strsep(), and sip_peer::useragent.

11711 {
11712    struct sip_peer *peer;
11713    char *colname;
11714 
11715    if ((colname = strchr(data, ':')))  /*! \todo Will be deprecated after 1.4 */
11716       *colname++ = '\0';
11717    else if ((colname = strchr(data, '|')))
11718       *colname++ = '\0';
11719    else
11720       colname = "ip";
11721 
11722    if (!(peer = find_peer(data, NULL, 1)))
11723       return -1;
11724 
11725    if (!strcasecmp(colname, "ip")) {
11726       ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "", len);
11727    } else  if (!strcasecmp(colname, "status")) {
11728       peer_status(peer, buf, len);
11729    } else  if (!strcasecmp(colname, "language")) {
11730       ast_copy_string(buf, peer->language, len);
11731    } else  if (!strcasecmp(colname, "regexten")) {
11732       ast_copy_string(buf, peer->regexten, len);
11733    } else  if (!strcasecmp(colname, "limit")) {
11734       snprintf(buf, len, "%d", peer->call_limit);
11735    } else  if (!strcasecmp(colname, "curcalls")) {
11736       snprintf(buf, len, "%d", peer->inUse);
11737    } else  if (!strcasecmp(colname, "accountcode")) {
11738       ast_copy_string(buf, peer->accountcode, len);
11739    } else  if (!strcasecmp(colname, "useragent")) {
11740       ast_copy_string(buf, peer->useragent, len);
11741    } else  if (!strcasecmp(colname, "mailbox")) {
11742       ast_copy_string(buf, peer->mailbox, len);
11743    } else  if (!strcasecmp(colname, "context")) {
11744       ast_copy_string(buf, peer->context, len);
11745    } else  if (!strcasecmp(colname, "expire")) {
11746       snprintf(buf, len, "%d", peer->expire);
11747    } else  if (!strcasecmp(colname, "dynamic")) {
11748       ast_copy_string(buf, (ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC) ? "yes" : "no"), len);
11749    } else  if (!strcasecmp(colname, "callerid_name")) {
11750       ast_copy_string(buf, peer->cid_name, len);
11751    } else  if (!strcasecmp(colname, "callerid_num")) {
11752       ast_copy_string(buf, peer->cid_num, len);
11753    } else  if (!strcasecmp(colname, "codecs")) {
11754       ast_getformatname_multiple(buf, len -1, peer->capability);
11755    } else  if (!strncasecmp(colname, "codec[", 6)) {
11756       char *codecnum;
11757       int index = 0, codec = 0;
11758       
11759       codecnum = colname + 6; /* move past the '[' */
11760       codecnum = strsep(&codecnum, "]"); /* trim trailing ']' if any */
11761       index = atoi(codecnum);
11762       if((codec = ast_codec_pref_index(&peer->prefs, index))) {
11763          ast_copy_string(buf, ast_getformatname(codec), len);
11764       }
11765    }
11766 
11767    ASTOBJ_UNREF(peer, sip_destroy_peer);
11768 
11769    return 0;
11770 }

static char * generate_random_string ( char *  buf,
size_t  size 
) [static]

Generate 32 byte random string for callid's etc.

Definition at line 4350 of file chan_sip.c.

References ast_random().

Referenced by build_callid_pvt(), and build_callid_registry().

04351 {
04352    long val[4];
04353    int x;
04354 
04355    for (x=0; x<4; x++)
04356       val[x] = ast_random();
04357    snprintf(buf, size, "%08lx%08lx%08lx%08lx", val[0], val[1], val[2], val[3]);
04358 
04359    return buf;
04360 }

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

Call transfer support (old way, deprecated by the IETF)--.

Definition at line 9055 of file chan_sip.c.

References ast_canmatch_extension(), ast_exists_extension(), ast_log(), ast_string_field_set, ast_strlen_zero(), ast_uri_decode(), ast_verbose(), domain::context, get_header(), get_in_brackets(), sip_pvt::initreq, LOG_DEBUG, LOG_WARNING, ast_channel::macrocontext, option_debug, sip_pvt::owner, pbx_builtin_getvar_helper(), sip_pvt::refer, sip_refer::refer_call, sip_refer::refer_contact, sip_refer::refer_to, sip_refer::refer_to_domain, sip_refer::referred_by, S_OR, sip_debug_test_pvt(), and sip_refer_allocate().

Referenced by handle_request_bye().

09056 {
09057    char tmp[256] = "", *c, *a;
09058    struct sip_request *req = oreq ? oreq : &p->initreq;
09059    struct sip_refer *referdata = NULL;
09060    const char *transfer_context = NULL;
09061    
09062    if (!p->refer && !sip_refer_allocate(p))
09063       return -1;
09064 
09065    referdata = p->refer;
09066 
09067    ast_copy_string(tmp, get_header(req, "Also"), sizeof(tmp));
09068    c = get_in_brackets(tmp);
09069 
09070    if (pedanticsipchecking)
09071       ast_uri_decode(c);
09072    
09073    if (strncasecmp(c, "sip:", 4)) {
09074       ast_log(LOG_WARNING, "Huh?  Not a SIP header in Also: transfer (%s)?\n", c);
09075       return -1;
09076    }
09077    c += 4;
09078    if ((a = strchr(c, ';')))  /* Remove arguments */
09079       *a = '\0';
09080    
09081    if ((a = strchr(c, '@'))) {   /* Separate Domain */
09082       *a++ = '\0';
09083       ast_copy_string(referdata->refer_to_domain, a, sizeof(referdata->refer_to_domain));
09084    }
09085    
09086    if (sip_debug_test_pvt(p))
09087       ast_verbose("Looking for %s in %s\n", c, p->context);
09088 
09089    if (p->owner)  /* Mimic behaviour in res_features.c */
09090       transfer_context = pbx_builtin_getvar_helper(p->owner, "TRANSFER_CONTEXT");
09091 
09092    /* By default, use the context in the channel sending the REFER */
09093    if (ast_strlen_zero(transfer_context)) {
09094       transfer_context = S_OR(p->owner->macrocontext,
09095                S_OR(p->context, default_context));
09096    }
09097    if (ast_exists_extension(NULL, transfer_context, c, 1, NULL)) {
09098       /* This is a blind transfer */
09099       if (option_debug)
09100          ast_log(LOG_DEBUG,"SIP Bye-also transfer to Extension %s@%s \n", c, transfer_context);
09101       ast_copy_string(referdata->refer_to, c, sizeof(referdata->refer_to));
09102       ast_copy_string(referdata->referred_by, "", sizeof(referdata->referred_by));
09103       ast_copy_string(referdata->refer_contact, "", sizeof(referdata->refer_contact));
09104       referdata->refer_call = NULL;
09105       /* Set new context */
09106       ast_string_field_set(p, context, transfer_context);
09107       return 0;
09108    } else if (ast_canmatch_extension(NULL, p->context, c, 1, NULL)) {
09109       return 1;
09110    }
09111 
09112    return -1;
09113 }

static char* get_body ( struct sip_request req,
char *  name 
) [static]

Get a specific line from the message body.

Definition at line 4149 of file chan_sip.c.

References get_body_by_line(), len, sip_request::line, and sip_request::lines.

Referenced by handle_request_info().

04150 {
04151    int x;
04152    int len = strlen(name);
04153    char *r;
04154 
04155    for (x = 0; x < req->lines; x++) {
04156       r = get_body_by_line(req->line[x], name, len);
04157       if (r[0] != '\0')
04158          return r;
04159    }
04160 
04161    return "";
04162 }

static char* get_body_by_line ( const char *  line,
const char *  name,
int  nameLen 
) [static]

Reads one line of SIP message body.

Definition at line 4115 of file chan_sip.c.

Referenced by get_body(), and get_sdp_iterate().

04116 {
04117    if (strncasecmp(line, name, nameLen) == 0 && line[nameLen] == '=')
04118       return ast_skip_blanks(line + nameLen + 1);
04119 
04120    return "";
04121 }

static char * get_calleridname ( const char *  input,
char *  output,
size_t  outputsize 
) [static]

Get caller id name from SIP headers.

Definition at line 9167 of file chan_sip.c.

Referenced by check_user_full().

09168 {
09169    const char *end = strchr(input,'<');   /* first_bracket */
09170    const char *tmp = strchr(input,'"');   /* first quote */
09171    int bytes = 0;
09172    int maxbytes = outputsize - 1;
09173 
09174    if (!end || end == input)  /* we require a part in brackets */
09175       return NULL;
09176 
09177    end--; /* move just before "<" */
09178 
09179    if (tmp && tmp <= end) {
09180       /* The quote (tmp) precedes the bracket (end+1).
09181        * Find the matching quote and return the content.
09182        */
09183       end = strchr(tmp+1, '"');
09184       if (!end)
09185          return NULL;
09186       bytes = (int) (end - tmp);
09187       /* protect the output buffer */
09188       if (bytes > maxbytes)
09189          bytes = maxbytes;
09190       ast_copy_string(output, tmp + 1, bytes);
09191    } else {
09192       /* No quoted string, or it is inside brackets. */
09193       /* clear the empty characters in the begining*/
09194       input = ast_skip_blanks(input);
09195       /* clear the empty characters in the end */
09196       while(*end && *end < 33 && end > input)
09197          end--;
09198       if (end >= input) {
09199          bytes = (int) (end - input) + 2;
09200          /* protect the output buffer */
09201          if (bytes > maxbytes)
09202             bytes = maxbytes;
09203          ast_copy_string(output, input, bytes);
09204       } else
09205          return NULL;
09206    }
09207    return output;
09208 }

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

Find out who the call is for We use the INVITE uri to find out.

Definition at line 8710 of file chan_sip.c.

References ast_canmatch_extension(), ast_exists_extension(), ast_get_hint(), AST_LIST_EMPTY, ast_log(), AST_MAX_EXTENSION, ast_pickup_ext(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_uri_decode(), ast_verbose(), check_sip_domain(), domain::context, exten, get_header(), get_in_brackets(), sip_pvt::initreq, LOG_DEBUG, LOG_WARNING, sip_request::method, option_debug, sip_request::rlPart2, S_OR, sip_debug_test_pvt(), SIP_INVITE, sip_methods, SIP_PAGE2_ALLOWOVERLAP, SIP_REFER, SIP_SUBSCRIBE, strsep(), and cfsip_methods::text.

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

08711 {
08712    char tmp[256] = "", *uri, *a;
08713    char tmpf[256] = "", *from;
08714    struct sip_request *req;
08715    char *colon;
08716    
08717    req = oreq;
08718    if (!req)
08719       req = &p->initreq;
08720 
08721    /* Find the request URI */
08722    if (req->rlPart2)
08723       ast_copy_string(tmp, req->rlPart2, sizeof(tmp));
08724    
08725    if (pedanticsipchecking)
08726       ast_uri_decode(tmp);
08727 
08728    uri = get_in_brackets(tmp);
08729 
08730    if (strncasecmp(uri, "sip:", 4)) {
08731       ast_log(LOG_WARNING, "Huh?  Not a SIP header (%s)?\n", uri);
08732       return -1;
08733    }
08734    uri += 4;
08735 
08736    /* Now find the From: caller ID and name */
08737    ast_copy_string(tmpf, get_header(req, "From"), sizeof(tmpf));
08738    if (!ast_strlen_zero(tmpf)) {
08739       if (pedanticsipchecking)
08740          ast_uri_decode(tmpf);
08741       from = get_in_brackets(tmpf);
08742    } else {
08743       from = NULL;
08744    }
08745    
08746    if (!ast_strlen_zero(from)) {
08747       if (strncasecmp(from, "sip:", 4)) {
08748          ast_log(LOG_WARNING, "Huh?  Not a SIP header (%s)?\n", from);
08749          return -1;
08750       }
08751       from += 4;
08752       if ((a = strchr(from, '@')))
08753          *a++ = '\0';
08754       else
08755          a = from;   /* just a domain */
08756       from = strsep(&from, ";"); /* Remove userinfo options */
08757       a = strsep(&a, ";");    /* Remove URI options */
08758       ast_string_field_set(p, fromdomain, a);
08759    }
08760 
08761    /* Skip any options and find the domain */
08762 
08763    /* Get the target domain */
08764    if ((a = strchr(uri, '@'))) {
08765       *a++ = '\0';
08766    } else { /* No username part */
08767       a = uri;
08768       uri = "s";  /* Set extension to "s" */
08769    }
08770    colon = strchr(a, ':'); /* Remove :port */
08771    if (colon)
08772       *colon = '\0';
08773 
08774    uri = strsep(&uri, ";");   /* Remove userinfo options */
08775    a = strsep(&a, ";");    /* Remove URI options */
08776 
08777    ast_string_field_set(p, domain, a);
08778 
08779    if (!AST_LIST_EMPTY(&domain_list)) {
08780       char domain_context[AST_MAX_EXTENSION];
08781 
08782       domain_context[0] = '\0';
08783       if (!check_sip_domain(p->domain, domain_context, sizeof(domain_context))) {
08784          if (!allow_external_domains && (req->method == SIP_INVITE || req->method == SIP_REFER)) {
08785             if (option_debug)
08786                ast_log(LOG_DEBUG, "Got SIP %s to non-local domain '%s'; refusing request.\n", sip_methods[req->method].text, p->domain);
08787             return -2;
08788          }
08789       }
08790       /* If we have a context defined, overwrite the original context */
08791       if (!ast_strlen_zero(domain_context))
08792          ast_string_field_set(p, context, domain_context);
08793    }
08794 
08795    /* If the request coming in is a subscription and subscribecontext has been specified use it */
08796    if (req->method == SIP_SUBSCRIBE && !ast_strlen_zero(p->subscribecontext))
08797       ast_string_field_set(p, context, p->subscribecontext);
08798 
08799    if (sip_debug_test_pvt(p))
08800       ast_verbose("Looking for %s in %s (domain %s)\n", uri, p->context, p->domain);
08801 
08802    /* If this is a subscription we actually just need to see if a hint exists for the extension */
08803    if (req->method == SIP_SUBSCRIBE) {
08804       char hint[AST_MAX_EXTENSION];
08805       return (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, p->context, p->exten) ? 0 : -1);
08806    } else {
08807       /* Check the dialplan for the username part of the request URI,
08808          the domain will be stored in the SIPDOMAIN variable
08809          Since extensions.conf can have unescaped characters, try matching a decoded
08810          uri in addition to the non-decoded uri
08811          Return 0 if we have a matching extension */
08812       char *decoded_uri = ast_strdupa(uri);
08813       ast_uri_decode(decoded_uri);
08814       if (ast_exists_extension(NULL, p->context, uri, 1, S_OR(p->cid_num, from)) || ast_exists_extension(NULL, p->context, decoded_uri, 1, S_OR(p->cid_num, from)) ||
08815           !strcmp(uri, ast_pickup_ext())) {
08816          if (!oreq)
08817             ast_string_field_set(p, exten, uri);
08818          return 0;
08819       } 
08820    }
08821 
08822    /* Return 1 for pickup extension or overlap dialling support (if we support it) */
08823    if((ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP) && 
08824        ast_canmatch_extension(NULL, p->context, uri, 1, S_OR(p->cid_num, from))) ||
08825        !strncmp(uri, ast_pickup_ext(), strlen(uri))) {
08826       return 1;
08827    }
08828    
08829    return -1;
08830 }

static const char * get_header ( const struct sip_request req,
const char *  name 
) [static]

Get header from SIP request.

Definition at line 4238 of file chan_sip.c.

References __get_header().

04239 {
04240    int start = 0;
04241    return __get_header(req, name, &start);
04242 }

static char * get_in_brackets ( char *  tmp  )  [static]

Pick out text in brackets from character string.

Returns:
pointer to terminated stripped string
Parameters:
tmp input string that will be modified Examples:
"foo" <bar> valid input, returns bar foo returns the whole string < "foo ... > returns the string between brackets < "foo... bogus (missing closing bracket), returns the whole string XXX maybe should still skip the opening bracket

Definition at line 2315 of file chan_sip.c.

References ast_log(), find_closing_quote(), 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().

02316 {
02317    const char *parse = tmp;
02318    char *first_bracket;
02319 
02320    /*
02321     * Skip any quoted text until we find the part in brackets.
02322          * On any error give up and return the full string.
02323          */
02324         while ( (first_bracket = strchr(parse, '<')) ) {
02325                 char *first_quote = strchr(parse, '"');
02326 
02327       if (!first_quote || first_quote > first_bracket)
02328          break; /* no need to look at quoted part */
02329       /* the bracket is within quotes, so ignore it */
02330       parse = find_closing_quote(first_quote + 1, NULL);
02331       if (!*parse) { /* not found, return full string ? */
02332          /* XXX or be robust and return in-bracket part ? */
02333          ast_log(LOG_WARNING, "No closing quote found in '%s'\n", tmp);
02334          break;
02335       }
02336       parse++;
02337    }
02338    if (first_bracket) {
02339       char *second_bracket = strchr(first_bracket + 1, '>');
02340       if (second_bracket) {
02341          *second_bracket = '\0';
02342          tmp = first_bracket + 1;
02343       } else {
02344          ast_log(LOG_WARNING, "No closing bracket found in '%s'\n", tmp);
02345       }
02346    }
02347    return tmp;
02348 }

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

Get text out of a SIP MESSAGE packet.

Definition at line 9572 of file chan_sip.c.

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

Referenced by handle_request_notify(), and receive_message().

09573 {
09574    int x;
09575    int y;
09576 
09577    buf[0] = '\0';
09578    y = len - strlen(buf) - 5;
09579    if (y < 0)
09580       y = 0;
09581    for (x=0;x<req->lines;x++) {
09582       strncat(buf, req->line[x], y); /* safe */
09583       y -= strlen(req->line[x]) + 1;
09584       if (y < 0)
09585          y = 0;
09586       if (y != 0)
09587          strcat(buf, "\n"); /* safe */
09588    }
09589    return 0;
09590 }

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

Get referring dnis.

Definition at line 8681 of file chan_sip.c.

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

Referenced by handle_request_invite().

08682 {
08683    char tmp[256], *c, *a;
08684    struct sip_request *req;
08685    
08686    req = oreq;
08687    if (!req)
08688       req = &p->initreq;
08689    ast_copy_string(tmp, get_header(req, "Diversion"), sizeof(tmp));
08690    if (ast_strlen_zero(tmp))
08691       return 0;
08692    c = get_in_brackets(tmp);
08693    if (strncasecmp(c, "sip:", 4)) {
08694       ast_log(LOG_WARNING, "Huh?  Not an RDNIS SIP header (%s)?\n", c);
08695       return -1;
08696    }
08697    c += 4;
08698    a = c;
08699    strsep(&a, "@;"); /* trim anything after @ or ; */
08700    if (sip_debug_test_pvt(p))
08701       ast_verbose("RDNIS is %s\n", c);
08702    ast_string_field_set(p, rdnis, c);
08703 
08704    return 0;
08705 }

static int get_refer_info ( struct sip_pvt transferer,
struct sip_request outgoing_req 
) [static]

Call transfer support (the REFER method) Extracts Refer headers into pvt dialog structure.

Definition at line 8889 of file chan_sip.c.

References ast_exists_extension(), ast_log(), ast_strdupa, ast_strlen_zero(), ast_uri_decode(), ast_verbose(), sip_refer::attendedtransfer, get_header(), get_in_brackets(), sip_pvt::initreq, LOG_DEBUG, LOG_WARNING, ast_channel::macrocontext, option_debug, sip_pvt::owner, pbx_builtin_getvar_helper(), sip_pvt::refer, sip_refer::refer_to, sip_refer::refer_to_context, sip_refer::refer_to_domain, sip_refer::refer_to_urioption, sip_refer::referred_by, sip_refer::referred_by_name, sip_refer::replaces_callid, sip_refer::replaces_callid_fromtag, sip_refer::replaces_callid_totag, S_OR, sip_debug_test_pvt(), and strcasestr().

Referenced by handle_request_refer().

08890 {
08891 
08892    const char *p_referred_by = NULL;
08893    char *h_refer_to = NULL; 
08894    char *h_referred_by = NULL;
08895    char *refer_to;
08896    const char *p_refer_to;
08897    char *referred_by_uri = NULL;
08898    char *ptr;
08899    struct sip_request *req = NULL;
08900    const char *transfer_context = NULL;
08901    struct sip_refer *referdata;
08902 
08903 
08904    req = outgoing_req;
08905    referdata = transferer->refer;
08906 
08907    if (!req)
08908       req = &transferer->initreq;
08909 
08910    p_refer_to = get_header(req, "Refer-To");
08911    if (ast_strlen_zero(p_refer_to)) {
08912       ast_log(LOG_WARNING, "Refer-To Header missing. Skipping transfer.\n");
08913       return -2;  /* Syntax error */
08914    }
08915    h_refer_to = ast_strdupa(p_refer_to);
08916    refer_to = get_in_brackets(h_refer_to);
08917    if (pedanticsipchecking)
08918       ast_uri_decode(refer_to);
08919 
08920    if (strncasecmp(refer_to, "sip:", 4)) {
08921       ast_log(LOG_WARNING, "Can't transfer to non-sip: URI.  (Refer-to: %s)?\n", refer_to);
08922       return -3;
08923    }
08924    refer_to += 4;       /* Skip sip: */
08925 
08926    /* Get referred by header if it exists */
08927    p_referred_by = get_header(req, "Referred-By");
08928    if (!ast_strlen_zero(p_referred_by)) {
08929       char *lessthan;
08930       h_referred_by = ast_strdupa(p_referred_by);
08931       if (pedanticsipchecking)
08932          ast_uri_decode(h_referred_by);
08933 
08934       /* Store referrer's caller ID name */
08935       ast_copy_string(referdata->referred_by_name, h_referred_by, sizeof(referdata->referred_by_name));
08936       if ((lessthan = strchr(referdata->referred_by_name, '<'))) {
08937          *(lessthan - 1) = '\0'; /* Space */
08938       }
08939 
08940       referred_by_uri = get_in_brackets(h_referred_by);
08941       if(strncasecmp(referred_by_uri, "sip:", 4)) {
08942          ast_log(LOG_WARNING, "Huh?  Not a sip: header (Referred-by: %s). Skipping.\n", referred_by_uri);
08943          referred_by_uri = (char *) NULL;
08944       } else {
08945          referred_by_uri += 4;      /* Skip sip: */
08946       }
08947    }
08948 
08949    /* Check for arguments in the refer_to header */
08950    if ((ptr = strchr(refer_to, '?'))) { /* Search for arguments */
08951       *ptr++ = '\0';
08952       if (!strncasecmp(ptr, "REPLACES=", 9)) {
08953          char *to = NULL, *from = NULL;
08954 
08955          /* This is an attended transfer */
08956          referdata->attendedtransfer = 1;
08957          ast_copy_string(referdata->replaces_callid, ptr+9, sizeof(referdata->replaces_callid));
08958          ast_uri_decode(referdata->replaces_callid);
08959          if ((ptr = strchr(referdata->replaces_callid, ';')))  /* Find options */ {
08960             *ptr++ = '\0';
08961          }
08962 
08963          if (ptr) {
08964             /* Find the different tags before we destroy the string */
08965             to = strcasestr(ptr, "to-tag=");
08966             from = strcasestr(ptr, "from-tag=");
08967          }
08968 
08969          /* Grab the to header */
08970          if (to) {
08971             ptr = to + 7;
08972             if ((to = strchr(ptr, '&')))
08973                *to = '\0';
08974             if ((to = strchr(ptr, ';')))
08975                *to = '\0';
08976             ast_copy_string(referdata->replaces_callid_totag, ptr, sizeof(referdata->replaces_callid_totag));
08977          }
08978 
08979          if (from) {
08980             ptr = from + 9;
08981             if ((to = strchr(ptr, '&')))
08982                *to = '\0';
08983             if ((to = strchr(ptr, ';')))
08984                *to = '\0';
08985             ast_copy_string(referdata->replaces_callid_fromtag, ptr, sizeof(referdata->replaces_callid_fromtag));
08986          }
08987 
08988          if (option_debug > 1) {
08989             if (!pedanticsipchecking)
08990                ast_log(LOG_DEBUG,"Attended transfer: Will use Replace-Call-ID : %s (No check of from/to tags)\n", referdata->replaces_callid );
08991             else
08992                ast_log(LOG_DEBUG,"Attended transfer: Will use Replace-Call-ID : %s F-tag: %s T-tag: %s\n", referdata->replaces_callid, referdata->replaces_callid_fromtag ? referdata->replaces_callid_fromtag : "<none>", referdata->replaces_callid_totag ? referdata->replaces_callid_totag : "<none>" );
08993          }
08994       }
08995    }
08996    
08997    if ((ptr = strchr(refer_to, '@'))) {   /* Separate domain */
08998       char *urioption = NULL, *domain;
08999       *ptr++ = '\0';
09000 
09001       if ((urioption = strchr(ptr, ';'))) /* Separate urioptions */
09002          *urioption++ = '\0';
09003       
09004       domain = ptr;
09005       if ((ptr = strchr(domain, ':'))) /* Remove :port */
09006          *ptr = '\0';
09007       
09008       /* Save the domain for the dial plan */
09009       ast_copy_string(referdata->refer_to_domain, domain, sizeof(referdata->refer_to_domain));
09010       if (urioption)
09011          ast_copy_string(referdata->refer_to_urioption, urioption, sizeof(referdata->refer_to_urioption));
09012    }
09013 
09014    if ((ptr = strchr(refer_to, ';')))  /* Remove options */
09015       *ptr = '\0';
09016    ast_copy_string(referdata->refer_to, refer_to, sizeof(referdata->refer_to));
09017    
09018    if (referred_by_uri) {
09019       if ((ptr = strchr(referred_by_uri, ';')))    /* Remove options */
09020          *ptr = '\0';
09021       ast_copy_string(referdata->referred_by, referred_by_uri, sizeof(referdata->referred_by));
09022    } else {
09023       referdata->referred_by[0] = '\0';
09024    }
09025 
09026    /* Determine transfer context */
09027    if (transferer->owner)  /* Mimic behaviour in res_features.c */
09028       transfer_context = pbx_builtin_getvar_helper(transferer->owner, "TRANSFER_CONTEXT");
09029 
09030    /* By default, use the context in the channel sending the REFER */
09031    if (ast_strlen_zero(transfer_context)) {
09032       transfer_context = S_OR(transferer->owner->macrocontext,
09033                S_OR(transferer->context, default_context));
09034    }
09035 
09036    ast_copy_string(referdata->refer_to_context, transfer_context, sizeof(referdata->refer_to_context));
09037    
09038    /* Either an existing extension or the parking extension */
09039    if (ast_exists_extension(NULL, transfer_context, refer_to, 1, NULL) ) {
09040       if (sip_debug_test_pvt(transferer)) {
09041          ast_verbose("SIP transfer to extension %s@%s by %s\n", refer_to, transfer_context, referred_by_uri);
09042       }
09043       /* We are ready to transfer to the extension */
09044       return 0;
09045    } 
09046    if (sip_debug_test_pvt(transferer))
09047       ast_verbose("Failed SIP Transfer to non-existing extension %s in context %s\n n", refer_to, transfer_context);
09048 
09049    /* Failure, we can't find this extension */
09050    return -1;
09051 }

static int get_rpid_num ( const char *  input,
char *  output,
int  maxlen 
) [static]

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

References AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED.

Referenced by check_user_full().

09215 {
09216    char *start;
09217    char *end;
09218 
09219    start = strchr(input,':');
09220    if (!start) {
09221       output[0] = '\0';
09222       return 0;
09223    }
09224    start++;
09225 
09226    /* we found "number" */
09227    ast_copy_string(output,start,maxlen);
09228    output[maxlen-1] = '\0';
09229 
09230    end = strchr(output,'@');
09231    if (end)
09232       *end = '\0';
09233    else
09234       output[0] = '\0';
09235    if (strstr(input,"privacy=full") || strstr(input,"privacy=uri"))
09236       return AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED;
09237 
09238    return 0;
09239 }

static const char * get_sdp ( struct sip_request req,
const char *  name 
) [static]

Get a line from an SDP message body.

Definition at line 4141 of file chan_sip.c.

References get_sdp_iterate().

04142 {
04143    int dummy = 0;
04144 
04145    return get_sdp_iterate(&dummy, req, name);
04146 }

static const char * get_sdp_iterate ( int *  start,
struct sip_request req,
const char *  name 
) [static]

Lookup 'name' in the SDP starting at the 'start' line. Returns the matching line, and 'start' is updated with the next line number.

Definition at line 4127 of file chan_sip.c.

References get_body_by_line(), len, and sip_request::line.

04128 {
04129    int len = strlen(name);
04130 
04131    while (*start < req->sdp_end) {
04132       const char *r = get_body_by_line(req->line[(*start)++], name, len);
04133       if (r[0] != '\0')
04134          return r;
04135    }
04136 
04137    return "";
04138 }

static struct sip_pvt * get_sip_pvt_byid_locked ( const char *  callid,
const char *  totag,
const char *  fromtag 
) [static, read]

Lock interface lock and find matching pvt lock

  • Their tag is fromtag, our tag is to-tag
  • This means that in some transactions, totag needs to be their tag :-) depending upon the direction.

Definition at line 8837 of file chan_sip.c.

References ast_channel_trylock, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_strlen_zero(), ast_test_flag, sip_pvt::flags, iflist, sip_pvt::lock, LOG_DEBUG, match(), sip_pvt::next, option_debug, sip_pvt::owner, SIP_OUTGOING, and sip_pvt::tag.

Referenced by handle_request_invite(), and local_attended_transfer().

08838 {
08839    struct sip_pvt *sip_pvt_ptr;
08840 
08841    ast_mutex_lock(&iflock);
08842 
08843    if (option_debug > 3 && totag)
08844       ast_log(LOG_DEBUG, "Looking for callid %s (fromtag %s totag %s)\n", callid, fromtag ? fromtag : "<no fromtag>", totag ? totag : "<no totag>");
08845 
08846    /* Search interfaces and find the match */
08847    for (sip_pvt_ptr = iflist; sip_pvt_ptr; sip_pvt_ptr = sip_pvt_ptr->next) {
08848       if (!strcmp(sip_pvt_ptr->callid, callid)) {
08849          int match = 1;
08850          char *ourtag = sip_pvt_ptr->tag;
08851 
08852          /* Go ahead and lock it (and its owner) before returning */
08853          ast_mutex_lock(&sip_pvt_ptr->lock);
08854 
08855          /* Check if tags match. If not, this is not the call we want
08856             (With a forking SIP proxy, several call legs share the
08857             call id, but have different tags)
08858          */
08859          if (pedanticsipchecking && (strcmp(fromtag, sip_pvt_ptr->theirtag) || (!ast_strlen_zero(totag) && strcmp(totag, ourtag))))
08860             match = 0;
08861 
08862          if (!match) {
08863             ast_mutex_unlock(&sip_pvt_ptr->lock);
08864             continue;
08865          }
08866 
08867          if (option_debug > 3 && totag)             
08868             ast_log(LOG_DEBUG, "Matched %s call - their tag is %s Our tag is %s\n",
08869                ast_test_flag(&sip_pvt_ptr->flags[0], SIP_OUTGOING) ? "OUTGOING": "INCOMING",
08870                sip_pvt_ptr->theirtag, sip_pvt_ptr->tag);
08871 
08872          /* deadlock avoidance... */
08873          while (sip_pvt_ptr->owner && ast_channel_trylock(sip_pvt_ptr->owner)) {
08874             ast_mutex_unlock(&sip_pvt_ptr->lock);
08875             usleep(1);
08876             ast_mutex_lock(&sip_pvt_ptr->lock);
08877          }
08878          break;
08879       }
08880    }
08881    ast_mutex_unlock(&iflock);
08882    if (option_debug > 3 && !sip_pvt_ptr)
08883       ast_log(LOG_DEBUG, "Found no match for callid %s to-tag %s from-tag %s\n", callid, totag, fromtag);
08884    return sip_pvt_ptr;
08885 }

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

Get tag from packet.

Returns:
Returns the pointer to the provided tag buffer, or NULL if the tag was not found.

Definition at line 13236 of file chan_sip.c.

References get_header(), strcasestr(), and strsep().

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

13237 {
13238    const char *thetag;
13239 
13240    if (!tagbuf)
13241       return NULL;
13242    tagbuf[0] = '\0';    /* reset the buffer */
13243    thetag = get_header(req, header);
13244    thetag = strcasestr(thetag, ";tag=");
13245    if (thetag) {
13246       thetag += 5;
13247       ast_copy_string(tagbuf, thetag, tagbufsize);
13248       return strsep(&tagbuf, ";");
13249    }
13250    return NULL;
13251 }

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

Handle flag-type options common to configuration of devices - users and peers.

Parameters:
flags array of two struct ast_flags
mask array of two struct ast_flags
v linked list of config variables to process
Returns:
non-zero if any config options were handled, zero otherwise

Definition at line 15986 of file chan_sip.c.

References ast_clear_flag, ast_false(), ast_log(), ast_set2_flag, ast_set_flag, ast_true(), ast_variable::lineno, LOG_WARNING, ast_variable::name, set_insecure_flags(), SIP_CAN_REINVITE, SIP_CAN_REINVITE_NAT, SIP_DTMF, SIP_DTMF_AUTO, SIP_DTMF_INBAND, SIP_DTMF_INFO, SIP_DTMF_RFC2833, SIP_G726_NONSTANDARD, SIP_INSECURE_INVITE, SIP_INSECURE_PORT, SIP_NAT, SIP_NAT_ALWAYS, SIP_NAT_NEVER, SIP_NAT_RFC3581, SIP_NAT_ROUTE, SIP_PAGE2_ALLOWOVERLAP, SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PAGE2_BUGGY_MWI, SIP_PAGE2_RFC2833_COMPENSATE, SIP_PAGE2_T38SUPPORT_RTP, SIP_PAGE2_T38SUPPORT_TCP, SIP_PAGE2_T38SUPPORT_UDPTL, SIP_PAGE2_VIDEOSUPPORT, 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().

15987 {
15988    int res = 1;
15989 
15990    if (!strcasecmp(v->name, "trustrpid")) {
15991       ast_set_flag(&mask[0], SIP_TRUSTRPID);
15992       ast_set2_flag(&flags[0], ast_true(v->value), SIP_TRUSTRPID);
15993    } else if (!strcasecmp(v->name, "sendrpid")) {
15994       ast_set_flag(&mask[0], SIP_SENDRPID);
15995       ast_set2_flag(&flags[0], ast_true(v->value), SIP_SENDRPID);
15996    } else if (!strcasecmp(v->name, "g726nonstandard")) {
15997       ast_set_flag(&mask[0], SIP_G726_NONSTANDARD);
15998       ast_set2_flag(&flags[0], ast_true(v->value), SIP_G726_NONSTANDARD);
15999    } else if (!strcasecmp(v->name, "useclientcode")) {
16000       ast_set_flag(&mask[0], SIP_USECLIENTCODE);
16001       ast_set2_flag(&flags[0], ast_true(v->value), SIP_USECLIENTCODE);
16002    } else if (!strcasecmp(v->name, "dtmfmode")) {
16003       ast_set_flag(&mask[0], SIP_DTMF);
16004       ast_clear_flag(&flags[0], SIP_DTMF);
16005       if (!strcasecmp(v->value, "inband"))
16006          ast_set_flag(&flags[0], SIP_DTMF_INBAND);
16007       else if (!strcasecmp(v->value, "rfc2833"))
16008          ast_set_flag(&flags[0], SIP_DTMF_RFC2833);
16009       else if (!strcasecmp(v->value, "info"))
16010          ast_set_flag(&flags[0], SIP_DTMF_INFO);
16011       else if (!strcasecmp(v->value, "auto"))
16012          ast_set_flag(&flags[0], SIP_DTMF_AUTO);
16013       else {
16014          ast_log(LOG_WARNING, "Unknown dtmf mode '%s' on line %d, using rfc2833\n", v->value, v->lineno);
16015          ast_set_flag(&flags[0], SIP_DTMF_RFC2833);
16016       }
16017    } else if (!strcasecmp(v->name, "nat")) {
16018       ast_set_flag(&mask[0], SIP_NAT);
16019       ast_clear_flag(&flags[0], SIP_NAT);
16020       if (!strcasecmp(v->value, "never"))
16021          ast_set_flag(&flags[0], SIP_NAT_NEVER);
16022       else if (!strcasecmp(v->value, "route"))
16023          ast_set_flag(&flags[0], SIP_NAT_ROUTE);
16024       else if (ast_true(v->value))
16025          ast_set_flag(&flags[0], SIP_NAT_ALWAYS);
16026       else
16027          ast_set_flag(&flags[0], SIP_NAT_RFC3581);
16028    } else if (!strcasecmp(v->name, "canreinvite")) {
16029       ast_set_flag(&mask[0], SIP_REINVITE);
16030       ast_clear_flag(&flags[0], SIP_REINVITE);
16031       if(ast_true(v->value)) {
16032          ast_set_flag(&flags[0], SIP_CAN_REINVITE | SIP_CAN_REINVITE_NAT);
16033       } else if (!ast_false(v->value)) {
16034          char buf[64];
16035          char *word, *next = buf;
16036 
16037          ast_copy_string(buf, v->value, sizeof(buf));
16038          while ((word = strsep(&next, ","))) {
16039             if(!strcasecmp(word, "update")) {
16040                ast_set_flag(&flags[0], SIP_REINVITE_UPDATE | SIP_CAN_REINVITE);
16041             } else if(!strcasecmp(word, "nonat")) {
16042                ast_set_flag(&flags[0], SIP_CAN_REINVITE);
16043                ast_clear_flag(&flags[0], SIP_CAN_REINVITE_NAT);
16044             } else {
16045                ast_log(LOG_WARNING, "Unknown canreinvite mode '%s' on line %d\n", v->value, v->lineno);
16046             }
16047          }
16048       }
16049    } else if (!strcasecmp(v->name, "insecure")) {
16050       ast_set_flag(&mask[0], SIP_INSECURE_PORT | SIP_INSECURE_INVITE);
16051       ast_clear_flag(&flags[0], SIP_INSECURE_PORT | SIP_INSECURE_INVITE);
16052       set_insecure_flags(flags, v->value, v->lineno);
16053    } else if (!strcasecmp(v->name, "progressinband")) {
16054       ast_set_flag(&mask[0], SIP_PROG_INBAND);
16055       ast_clear_flag(&flags[0], SIP_PROG_INBAND);
16056       if (ast_true(v->value))
16057          ast_set_flag(&flags[0], SIP_PROG_INBAND_YES);
16058       else if (strcasecmp(v->value, "never"))
16059          ast_set_flag(&flags[0], SIP_PROG_INBAND_NO);
16060    } else if (!strcasecmp(v->name, "promiscredir")) {
16061       ast_set_flag(&mask[0], SIP_PROMISCREDIR);
16062       ast_set2_flag(&flags[0], ast_true(v->value), SIP_PROMISCREDIR);
16063    } else if (!strcasecmp(v->name, "videosupport")) {
16064       ast_set_flag(&mask[1], SIP_PAGE2_VIDEOSUPPORT);
16065       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_VIDEOSUPPORT);
16066    } else if (!strcasecmp(v->name, "allowoverlap")) {
16067       ast_set_flag(&mask[1], SIP_PAGE2_ALLOWOVERLAP);
16068       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_ALLOWOVERLAP);
16069    } else if (!strcasecmp(v->name, "allowsubscribe")) {
16070       ast_set_flag(&mask[1], SIP_PAGE2_ALLOWSUBSCRIBE);
16071       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_ALLOWSUBSCRIBE);
16072    } else if (!strcasecmp(v->name, "t38pt_udptl")) {
16073       ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT_UDPTL);
16074       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_T38SUPPORT_UDPTL);
16075 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS
16076    } else if (!strcasecmp(v->name, "t38pt_rtp")) {
16077       ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT_RTP);
16078       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_T38SUPPORT_RTP);
16079    } else if (!strcasecmp(v->name, "t38pt_tcp")) {
16080       ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT_TCP);
16081       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_T38SUPPORT_TCP);
16082 #endif
16083    } else if (!strcasecmp(v->name, "rfc2833compensate")) {
16084       ast_set_flag(&mask[1], SIP_PAGE2_RFC2833_COMPENSATE);
16085       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_RFC2833_COMPENSATE);
16086    } else if (!strcasecmp(v->name, "buggymwi")) {
16087       ast_set_flag(&mask[1], SIP_PAGE2_BUGGY_MWI);
16088       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_BUGGY_MWI);
16089    } else
16090       res = 0;
16091 
16092    return res;
16093 }

static int handle_invite_replaces ( struct sip_pvt p,
struct sip_request req,
int  debug,
int  ignore,
int  seqno,
struct sockaddr_in *  sin 
) [static]

Handle the transfer part of INVITE with a replaces: header, meaning a target pickup or an attended transfer.

Definition at line 13415 of file chan_sip.c.

References ast_channel::_state, append_history, ast_bridged_channel(), AST_CAUSE_SWITCH_CONGESTION, ast_channel_masquerade(), ast_channel_unlock, ast_frfree, ast_hangup(), ast_log(), ast_mutex_unlock(), ast_quiet_chan(), ast_read(), ast_set_flag, ast_setstate(), ast_state2str(), AST_STATE_DOWN, AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, DEFAULT_TRANS_TIMEOUT, f, sip_pvt::flags, ast_channel::hangupcause, sip_pvt::lock, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, LOG_WARNING, option_debug, sip_pvt::owner, sip_pvt::refer, sip_refer::refer_call, SIP_DEFER_BYE_ON_TRANSFER, sip_scheddestroy(), ast_channel::tech_pvt, transmit_response(), transmit_response_reliable(), transmit_response_with_sdp(), and XMIT_RELIABLE.

Referenced by handle_request_invite().

13416 {
13417    struct ast_frame *f;
13418    int earlyreplace = 0;
13419    int oneleggedreplace = 0;     /* Call with no bridge, propably IVR or voice message */
13420    struct ast_channel *c = p->owner;   /* Our incoming call */
13421    struct ast_channel *replacecall = p->refer->refer_call->owner; /* The channel we're about to take over */
13422    struct ast_channel *targetcall;     /* The bridge to the take-over target */
13423 
13424    /* Check if we're in ring state */
13425    if (replacecall->_state == AST_STATE_RING)
13426       earlyreplace = 1;
13427 
13428    /* Check if we have a bridge */
13429    if (!(targetcall = ast_bridged_channel(replacecall))) {
13430       /* We have no bridge */
13431       if (!earlyreplace) {
13432          if (option_debug > 1)
13433             ast_log(LOG_DEBUG, " Attended transfer attempted to replace call with no bridge (maybe ringing). Channel %s!\n", replacecall->name);
13434          oneleggedreplace = 1;
13435       }
13436    } 
13437    if (option_debug > 3 && targetcall && targetcall->_state == AST_STATE_RINGING)
13438          ast_log(LOG_DEBUG, "SIP transfer: Target channel is in ringing state\n");
13439 
13440    if (option_debug > 3) {
13441       if (targetcall) 
13442          ast_log(LOG_DEBUG, "SIP transfer: Invite Replace incoming channel should bridge to channel %s while hanging up channel %s\n", targetcall->name, replacecall->name); 
13443       else
13444          ast_log(LOG_DEBUG, "SIP transfer: Invite Replace incoming channel should replace and hang up channel %s (one call leg)\n", replacecall->name); 
13445    }
13446 
13447    if (ignore) {
13448       ast_log(LOG_NOTICE, "Ignoring this INVITE with replaces in a stupid way.\n");
13449       /* We should answer something here. If we are here, the
13450          call we are replacing exists, so an accepted 
13451          can't harm */
13452       transmit_response_with_sdp(p, "200 OK", req, XMIT_RELIABLE);
13453       /* Do something more clever here */
13454       ast_channel_unlock(c);
13455       ast_mutex_unlock(&p->refer->refer_call->lock);
13456       return 1;
13457    } 
13458    if (!c) {
13459       /* What to do if no channel ??? */
13460       ast_log(LOG_ERROR, "Unable to create new channel.  Invite/replace failed.\n");
13461       transmit_response_reliable(p, "503 Service Unavailable", req);
13462       append_history(p, "Xfer", "INVITE/Replace Failed. No new channel.");
13463       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
13464       ast_mutex_unlock(&p->refer->refer_call->lock);
13465       return 1;
13466    }
13467    append_history(p, "Xfer", "INVITE/Replace received");
13468    /* We have three channels to play with
13469       channel c: New incoming call
13470       targetcall: Call from PBX to target
13471       p->refer->refer_call: SIP pvt dialog from transferer to pbx.
13472       replacecall: The owner of the previous
13473       We need to masq C into refer_call to connect to 
13474       targetcall;
13475       If we are talking to internal audio stream, target call is null.
13476    */
13477 
13478    /* Fake call progress */
13479    transmit_response(p, "100 Trying", req);
13480    ast_setstate(c, AST_STATE_RING);
13481 
13482    /* Masquerade the new call into the referred call to connect to target call 
13483       Targetcall is not touched by the masq */
13484 
13485    /* Answer the incoming call and set channel to UP state */
13486    transmit_response_with_sdp(p, "200 OK", req, XMIT_RELIABLE);
13487       
13488    ast_setstate(c, AST_STATE_UP);
13489    
13490    /* Stop music on hold and other generators */
13491    ast_quiet_chan(replacecall);
13492    ast_quiet_chan(targetcall);
13493    if (option_debug > 3)
13494       ast_log(LOG_DEBUG, "Invite/Replaces: preparing to masquerade %s into %s\n", c->name, replacecall->name);
13495    /* Unlock clone, but not original (replacecall) */
13496    if (!oneleggedreplace)
13497       ast_channel_unlock(c);
13498 
13499    /* Unlock PVT */
13500    ast_mutex_unlock(&p->refer->refer_call->lock);
13501 
13502    /* Make sure that the masq does not free our PVT for the old call */
13503    if (! earlyreplace && ! oneleggedreplace )
13504       ast_set_flag(&p->refer->refer_call->flags[0], SIP_DEFER_BYE_ON_TRANSFER);  /* Delay hangup */
13505       
13506    /* Prepare the masquerade - if this does not happen, we will be gone */
13507    if(ast_channel_masquerade(replacecall, c))
13508       ast_log(LOG_ERROR, "Failed to masquerade C into Replacecall\n");
13509    else if (option_debug > 3)
13510       ast_log(LOG_DEBUG, "Invite/Replaces: Going to masquerade %s into %s\n", c->name, replacecall->name);
13511 
13512    /* The masquerade will happen as soon as someone reads a frame from the channel */
13513 
13514    /* C should now be in place of replacecall */
13515    /* ast_read needs to lock channel */
13516    ast_channel_unlock(c);
13517    
13518    if (earlyreplace || oneleggedreplace ) {
13519       /* Force the masq to happen */
13520       if ((f = ast_read(replacecall))) {  /* Force the masq to happen */
13521          ast_frfree(f);
13522          f = NULL;
13523          if (option_debug > 3)
13524             ast_log(LOG_DEBUG, "Invite/Replace:  Could successfully read frame from RING channel!\n");
13525       } else {
13526          ast_log(LOG_WARNING, "Invite/Replace:  Could not read frame from RING channel \n");
13527       }
13528       c->hangupcause = AST_CAUSE_SWITCH_CONGESTION;
13529       if (!oneleggedreplace)
13530          ast_channel_unlock(replacecall);
13531    } else { /* Bridged call, UP channel */
13532       if ((f = ast_read(replacecall))) {  /* Force the masq to happen */
13533          /* Masq ok */
13534          ast_frfree(f);
13535          f = NULL;
13536          if (option_debug > 2)
13537             ast_log(LOG_DEBUG, "Invite/Replace:  Could successfully read frame from channel! Masq done.\n");
13538       } else {
13539          ast_log(LOG_WARNING, "Invite/Replace:  Could not read frame from channel. Transfer failed\n");
13540       }
13541       ast_channel_unlock(replacecall);
13542    }
13543    ast_mutex_unlock(&p->refer->refer_call->lock);
13544 
13545    ast_setstate(c, AST_STATE_DOWN);
13546    if (option_debug > 3) {
13547       struct ast_channel *test;
13548       ast_log(LOG_DEBUG, "After transfer:----------------------------\n");
13549       ast_log(LOG_DEBUG, " -- C:        %s State %s\n", c->name, ast_state2str(c->_state));
13550       if (replacecall)
13551          ast_log(LOG_DEBUG, " -- replacecall:        %s State %s\n", replacecall->name, ast_state2str(replacecall->_state));
13552       if (p->owner) {
13553          ast_log(LOG_DEBUG, " -- P->owner: %s State %s\n", p->owner->name, ast_state2str(p->owner->_state));
13554          test = ast_bridged_channel(p->owner);
13555          if (test)
13556             ast_log(LOG_DEBUG, " -- Call bridged to P->owner: %s State %s\n", test->name, ast_state2str(test->_state));
13557          else
13558             ast_log(LOG_DEBUG, " -- No call bridged to C->owner \n");
13559       } else 
13560          ast_log(LOG_DEBUG, " -- No channel yet \n");
13561       ast_log(LOG_DEBUG, "End After transfer:----------------------------\n");
13562    }
13563 
13564    ast_channel_unlock(p->owner); /* Unlock new owner */
13565    if (!oneleggedreplace)
13566       ast_mutex_unlock(&p->lock);   /* Unlock SIP structure */
13567 
13568    /* The call should be down with no ast_channel, so hang it up */
13569    c->tech_pvt = NULL;
13570    ast_hangup(c);
13571    return 0;
13572 }

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

Handle incoming SIP requests (methods).

Note:
This is where all incoming requests go first

Definition at line 15073 of file chan_sip.c.

References __sip_ack(), append_history, ast_inet_ntoa(), ast_log(), ast_set_flag, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_verbose(), check_pendings(), debug, DEFAULT_TRANS_TIMEOUT, error(), extract_uri(), FALSE, find_sdp(), FLAG_RESPONSE, sip_pvt::flags, get_header(), gettag(), handle_request_bye(), handle_request_cancel(), handle_request_info(), handle_request_invite(), handle_request_message(), handle_request_notify(), handle_request_options(), handle_request_refer(), handle_request_register(), handle_request_subscribe(), handle_response(), sip_request::header, sip_request::headers, sip_pvt::icseq, cfsip_methods::id, sip_pvt::initreq, INV_TERMINATED, sip_pvt::invitestate, sip_pvt::lastinvite, sip_pvt::lastmsg, sip_pvt::lastnoninvite, len, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, LOG_WARNING, sip_pvt::method, sip_request::method, sip_pvt::ocseq, option_debug, sip_pvt::pendinginvite, process_sdp(), sip_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_DEBUG, SIP_PKT_IGNORE, SIP_PKT_IGNORE_REQ, SIP_PKT_IGNORE_RESP, SIP_PKT_WITH_TOTAG, SIP_REFER, SIP_REGISTER, SIP_RESPONSE, sip_scheddestroy(), SIP_SUBSCRIBE, sip_pvt::tag, cfsip_methods::text, transmit_response(), transmit_response_reliable(), transmit_response_with_allow(), and TRUE.

15074 {
15075    /* Called with p->lock held, as well as p->owner->lock if appropriate, keeping things
15076       relatively static */
15077    const char *cmd;
15078    const char *cseq;
15079    const char *useragent;
15080    int seqno;
15081    int len;
15082    int ignore = FALSE;
15083    int respid;
15084    int res = 0;
15085    int debug = sip_debug_test_pvt(p);
15086    char *e;
15087    int error = 0;
15088 
15089    /* Get Method and Cseq */
15090    cseq = get_header(req, "Cseq");
15091    cmd = req->header[0];
15092 
15093    /* Must have Cseq */
15094    if (ast_strlen_zero(cmd) || ast_strlen_zero(cseq)) {
15095       ast_log(LOG_ERROR, "Missing Cseq. Dropping this SIP message, it's incomplete.\n");
15096       error = 1;
15097    }
15098    if (!error && sscanf(cseq, "%d%n", &seqno, &len) != 1) {
15099       ast_log(LOG_ERROR, "No seqno in '%s'. Dropping incomplete message.\n", cmd);
15100       error = 1;
15101    }
15102    if (error) {
15103       if (!p->initreq.headers)   /* New call */
15104          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); /* Make sure we destroy this dialog */
15105       return -1;
15106    }
15107    /* Get the command XXX */
15108 
15109    cmd = req->rlPart1;
15110    e = req->rlPart2;
15111 
15112    /* Save useragent of the client */
15113    useragent = get_header(req, "User-Agent");
15114    if (!ast_strlen_zero(useragent))
15115       ast_string_field_set(p, useragent, useragent);
15116 
15117    /* Find out SIP method for incoming request */
15118    if (req->method == SIP_RESPONSE) {  /* Response to our request */
15119       /* Response to our request -- Do some sanity checks */   
15120       if (!p->initreq.headers) {
15121          if (option_debug)
15122             ast_log(LOG_DEBUG, "That's odd...  Got a response on a call we dont know about. Cseq %d Cmd %s\n", seqno, cmd);
15123          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
15124          return 0;
15125       } else if (p->ocseq && (p->ocseq < seqno) && (seqno != p->lastnoninvite)) {
15126          if (option_debug)
15127             ast_log(LOG_DEBUG, "Ignoring out of order response %d (expecting %d)\n", seqno, p->ocseq);
15128          return -1;
15129       } else if (p->ocseq && (p->ocseq != seqno) && (seqno != p->lastnoninvite)) {
15130          /* ignore means "don't do anything with it" but still have to 
15131             respond appropriately  */
15132          ignore = TRUE;
15133          ast_set_flag(req, SIP_PKT_IGNORE);
15134          ast_set_flag(req, SIP_PKT_IGNORE_RESP);
15135          append_history(p, "Ignore", "Ignoring this retransmit\n");
15136       } else if (e) {
15137          e = ast_skip_blanks(e);
15138          if (sscanf(e, "%d %n", &respid, &len) != 1) {
15139             ast_log(LOG_WARNING, "Invalid response: '%s'\n", e);
15140          } else {
15141             if (respid <= 0) {
15142                ast_log(LOG_WARNING, "Invalid SIP response code: '%d'\n", respid);
15143                return 0;
15144             }
15145             /* More SIP ridiculousness, we have to ignore bogus contacts in 100 etc responses */
15146             if ((respid == 200) || ((respid >= 300) && (respid <= 399)))
15147                extract_uri(p, req);
15148             handle_response(p, respid, e + len, req, ignore, seqno);
15149          }
15150       }
15151       return 0;
15152    }
15153 
15154    /* New SIP request coming in 
15155       (could be new request in existing SIP dialog as well...) 
15156     */         
15157    
15158    p->method = req->method;   /* Find out which SIP method they are using */
15159    if (option_debug > 3)
15160       ast_log(LOG_DEBUG, "**** Received %s (%d) - Command in SIP %s\n", sip_methods[p->method].text, sip_methods[p->method].id, cmd); 
15161 
15162    if (p->icseq && (p->icseq > seqno)) {
15163       if (option_debug)
15164          ast_log(LOG_DEBUG, "Ignoring too old SIP packet packet %d (expecting >= %d)\n", seqno, p->icseq);
15165       if (req->method != SIP_ACK)
15166          transmit_response(p, "503 Server error", req);  /* We must respond according to RFC 3261 sec 12.2 */
15167       return -1;
15168    } else if (p->icseq &&
15169          p->icseq == seqno &&
15170          req->method != SIP_ACK &&
15171          (p->method != SIP_CANCEL || ast_test_flag(&p->flags[0], SIP_ALREADYGONE))) {
15172       /* ignore means "don't do anything with it" but still have to 
15173          respond appropriately.  We do this if we receive a repeat of
15174          the last sequence number  */
15175       ignore = 2;
15176       ast_set_flag(req, SIP_PKT_IGNORE);
15177       ast_set_flag(req, SIP_PKT_IGNORE_REQ);
15178       if (option_debug > 2)
15179          ast_log(LOG_DEBUG, "Ignoring SIP message because of retransmit (%s Seqno %d, ours %d)\n", sip_methods[p->method].text, p->icseq, seqno);
15180    }
15181       
15182    if (seqno >= p->icseq)
15183       /* Next should follow monotonically (but not necessarily 
15184          incrementally -- thanks again to the genius authors of SIP --
15185          increasing */
15186       p->icseq = seqno;
15187 
15188    /* Find their tag if we haven't got it */
15189    if (ast_strlen_zero(p->theirtag)) {
15190       char tag[128];
15191 
15192       gettag(req, "From", tag, sizeof(tag));
15193       ast_string_field_set(p, theirtag, tag);
15194    }
15195    snprintf(p->lastmsg, sizeof(p->lastmsg), "Rx: %s", cmd);
15196 
15197    if (pedanticsipchecking) {
15198       /* If this is a request packet without a from tag, it's not
15199          correct according to RFC 3261  */
15200       /* Check if this a new request in a new dialog with a totag already attached to it,
15201          RFC 3261 - section 12.2 - and we don't want to mess with recovery  */
15202       if (!p->initreq.headers && ast_test_flag(req, SIP_PKT_WITH_TOTAG)) {
15203          /* If this is a first request and it got a to-tag, it is not for us */
15204          if (!ast_test_flag(req, SIP_PKT_IGNORE) && req->method == SIP_INVITE) {
15205             transmit_response_reliable(p, "481 Call/Transaction Does Not Exist", req);
15206             /* Will cease to exist after ACK */
15207          } else if (req->method != SIP_ACK) {
15208             transmit_response(p, "481 Call/Transaction Does Not Exist", req);
15209             sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
15210          }
15211          return res;
15212       }
15213    }
15214 
15215    if (!e && (p->method == SIP_INVITE || p->method == SIP_SUBSCRIBE || p->method == SIP_REGISTER || p->method == SIP_NOTIFY)) {
15216       transmit_response(p, "400 Bad request", req);
15217       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
15218       return -1;
15219    }
15220 
15221    /* Handle various incoming SIP methods in requests */
15222    switch (p->method) {
15223    case SIP_OPTIONS:
15224       res = handle_request_options(p, req);
15225       break;
15226    case SIP_INVITE:
15227       res = handle_request_invite(p, req, debug, seqno, sin, recount, e, nounlock);
15228       break;
15229    case SIP_REFER:
15230       res = handle_request_refer(p, req, debug, ignore, seqno, nounlock);
15231       break;
15232    case SIP_CANCEL:
15233       res = handle_request_cancel(p, req);
15234       break;
15235    case SIP_BYE:
15236       res = handle_request_bye(p, req);
15237       break;
15238    case SIP_MESSAGE:
15239       res = handle_request_message(p, req);
15240       break;
15241    case SIP_SUBSCRIBE:
15242       res = handle_request_subscribe(p, req, sin, seqno, e);
15243       break;
15244    case SIP_REGISTER:
15245       res = handle_request_register(p, req, sin, e);
15246       break;
15247    case SIP_INFO:
15248       if (ast_test_flag(req, SIP_PKT_DEBUG))
15249          ast_verbose("Receiving INFO!\n");
15250       if (!ignore) 
15251          handle_request_info(p, req);
15252       else  /* if ignoring, transmit response */
15253          transmit_response(p, "200 OK", req);
15254       break;
15255    case SIP_NOTIFY:
15256       res = handle_request_notify(p, req, sin, seqno, e);
15257       break;
15258    case SIP_ACK:
15259       /* Make sure we don't ignore this */
15260       if (seqno == p->pendinginvite) {
15261          p->invitestate = INV_TERMINATED;
15262          p->pendinginvite = 0;
15263          __sip_ack(p, seqno, FLAG_RESPONSE, 0);
15264          if (find_sdp(req)) {
15265             if (process_sdp(p, req))
15266                return -1;
15267          } 
15268          check_pendings(p);
15269       }
15270       /* Got an ACK that we did not match. Ignore silently */
15271       if (!p->lastinvite && ast_strlen_zero(p->randdata))
15272          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
15273       break;
15274    default:
15275       transmit_response_with_allow(p, "501 Method Not Implemented", req, 0);
15276       ast_log(LOG_NOTICE, "Unknown SIP command '%s' from '%s'\n", 
15277          cmd, ast_inet_ntoa(p->sa.sin_addr));
15278       /* If this is some new method, and we don't have a call, destroy it now */
15279       if (!p->initreq.headers)
15280          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
15281       break;
15282    }
15283    return res;
15284 }

static int handle_request_bye ( struct sip_pvt p,
struct sip_request req 
) [static]

Handle incoming BYE request.

Definition at line 14650 of file chan_sip.c.

References append_history, ast_async_goto(), ast_bridged_channel(), AST_CONTROL_UNHOLD, ast_inet_ntoa(), ast_log(), ast_queue_control(), ast_queue_hangup(), ast_rtp_get_quality(), ast_string_field_set, ast_strlen_zero(), ast_test_flag, check_via(), context, copy_request(), DEFAULT_TRANS_TIMEOUT, sip_pvt::flags, get_also_info(), get_header(), sip_pvt::initreq, INV_TERMINATED, sip_pvt::invitestate, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, option_debug, sip_pvt::owner, pbx_builtin_setvar_helper(), sip_pvt::pendinginvite, sip_pvt::recv, sip_pvt::refer, sip_refer::refer_to, sip_pvt::rtp, sip_alreadygone(), SIP_NO_HISTORY, SIP_OUTGOING, SIP_PKT_IGNORE, sip_scheddestroy(), stop_media_flows(), transmit_response(), transmit_response_reliable(), and sip_pvt::vrtp.

Referenced by handle_request().

14651 {
14652    struct ast_channel *c=NULL;
14653    int res;
14654    struct ast_channel *bridged_to;
14655    
14656    /* If we have an INCOMING invite that we haven't answered, terminate that transaction */
14657    if (p->pendinginvite && !ast_test_flag(&p->flags[0], SIP_OUTGOING) && !ast_test_flag(req, SIP_PKT_IGNORE) && !p->owner) 
14658       transmit_response_reliable(p, "487 Request Terminated", &p->initreq);
14659 
14660    p->invitestate = INV_TERMINATED;
14661 
14662    copy_request(&p->initreq, req);
14663    check_via(p, req);
14664    sip_alreadygone(p);
14665 
14666    /* Get RTCP quality before end of call */
14667    if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY) || p->owner) {
14668       char *audioqos, *videoqos;
14669       if (p->rtp) {
14670          audioqos = ast_rtp_get_quality(p->rtp, NULL);
14671          if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY))
14672             append_history(p, "RTCPaudio", "Quality:%s", audioqos);
14673          if (p->owner)
14674             pbx_builtin_setvar_helper(p->owner, "RTPAUDIOQOS", audioqos);
14675       }
14676       if (p->vrtp) {
14677          videoqos = ast_rtp_get_quality(p->vrtp, NULL);
14678          if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY))
14679             append_history(p, "RTCPvideo", "Quality:%s", videoqos);
14680          if (p->owner)
14681             pbx_builtin_setvar_helper(p->owner, "RTPVIDEOQOS", videoqos);
14682       }
14683    }
14684 
14685    stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */
14686 
14687    if (!ast_strlen_zero(get_header(req, "Also"))) {
14688       ast_log(LOG_NOTICE, "Client '%s' using deprecated BYE/Also transfer method.  Ask vendor to support REFER instead\n",
14689          ast_inet_ntoa(p->recv.sin_addr));
14690       if (ast_strlen_zero(p->context))
14691          ast_string_field_set(p, context, default_context);
14692       res = get_also_info(p, req);
14693       if (!res) {
14694          c = p->owner;
14695          if (c) {
14696             bridged_to = ast_bridged_channel(c);
14697             if (bridged_to) {
14698                /* Don't actually hangup here... */
14699                ast_queue_control(c, AST_CONTROL_UNHOLD);
14700                ast_async_goto(bridged_to, p->context, p->refer->refer_to,1);
14701             } else
14702                ast_queue_hangup(p->owner);
14703          }
14704       } else {
14705          ast_log(LOG_WARNING, "Invalid transfer information from '%s'\n", ast_inet_ntoa(p->recv.sin_addr));
14706          if (p->owner)
14707             ast_queue_hangup(p->owner);
14708       }
14709    } else if (p->owner) {
14710       ast_queue_hangup(p->owner);
14711       if (option_debug > 2)
14712          ast_log(LOG_DEBUG, "Received bye, issuing owner hangup\n");
14713    } else {
14714       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
14715       if (option_debug > 2)
14716          ast_log(LOG_DEBUG, "Received bye, no owner, selfdestruct soon.\n");
14717    }
14718    transmit_response(p, "200 OK", req);
14719 
14720    return 1;
14721 }

static int handle_request_cancel ( struct sip_pvt p,
struct sip_request req 
) [static]

Handle incoming CANCEL request.

Definition at line 14543 of file chan_sip.c.

References __sip_pretend_ack(), ast_channel::_state, ast_log(), ast_queue_hangup(), AST_STATE_UP, ast_test_flag, check_via(), DEC_CALL_LIMIT, DEFAULT_TRANS_TIMEOUT, sip_pvt::flags, sip_pvt::initreq, INV_CANCELLED, INV_TERMINATED, sip_pvt::invitestate, sip_request::len, LOG_DEBUG, option_debug, sip_pvt::owner, sip_alreadygone(), SIP_INC_COUNT, SIP_PAGE2_CALL_ONHOLD, sip_scheddestroy(), stop_media_flows(), transmit_response(), transmit_response_reliable(), and update_call_counter().

Referenced by handle_request().

14544 {
14545       
14546    check_via(p, req);
14547    sip_alreadygone(p);
14548 
14549    /* At this point, we could have cancelled the invite at the same time
14550       as the other side sends a CANCEL. Our final reply with error code
14551       might not have been received by the other side before the CANCEL
14552       was sent, so let's just give up retransmissions and waiting for
14553       ACK on our error code. The call is hanging up any way. */
14554    if (p->invitestate == INV_TERMINATED)
14555       __sip_pretend_ack(p);
14556    else
14557       p->invitestate = INV_CANCELLED;
14558    
14559    if (p->owner && p->owner->_state == AST_STATE_UP) {
14560       /* This call is up, cancel is ignored, we need a bye */
14561       transmit_response(p, "200 OK", req);
14562       if (option_debug)
14563          ast_log(LOG_DEBUG, "Got CANCEL on an answered call. Ignoring... \n");
14564       return 0;
14565    }
14566 
14567    if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) 
14568       update_call_counter(p, DEC_CALL_LIMIT);
14569 
14570    stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */
14571 
14572    if (p->owner)
14573       ast_queue_hangup(p->owner);
14574    else
14575       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
14576    if (p->initreq.len > 0) {
14577       transmit_response_reliable(p, "487 Request Terminated", &p->initreq);
14578       transmit_response(p, "200 OK", req);
14579       return 1;
14580    } else {
14581       transmit_response(p, "481 Call Leg Does Not Exist", req);
14582       return 0;
14583    }
14584 }

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

Receive SIP INFO Message.

Note:
Doesn't read the duration of the DTMF signal

Definition at line 11041 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_strlen_zero(), ast_test_flag, ast_verbose(), ast_channel::cdr, DEFAULT_TRANS_TIMEOUT, event, sip_pvt::flags, get_body(), get_header(), ast_frame::len, LOG_WARNING, sip_pvt::owner, sip_scheddestroy(), SIP_USECLIENTCODE, sipdebug, ast_frame::subclass, and transmit_response().

Referenced by handle_request().

11042 {
11043    char buf[1024];
11044    unsigned int event;
11045    const char *c = get_header(req, "Content-Type");
11046 
11047    /* Need to check the media/type */
11048    if (!strcasecmp(c, "application/dtmf-relay") ||
11049        !strcasecmp(c, "application/vnd.nortelnetworks.digits")) {
11050       unsigned int duration = 0;
11051 
11052       /* Try getting the "signal=" part */
11053       if (ast_strlen_zero(c = get_body(req, "Signal")) && ast_strlen_zero(c = get_body(req, "d"))) {
11054          ast_log(LOG_WARNING, "Unable to retrieve DTMF signal from INFO message from %s\n", p->callid);
11055          transmit_response(p, "200 OK", req); /* Should return error */
11056          return;
11057       } else {
11058          ast_copy_string(buf, c, sizeof(buf));
11059       }
11060 
11061       if (!ast_strlen_zero((c = get_body(req, "Duration"))))
11062          duration = atoi(c);
11063       if (!duration)
11064          duration = 100; /* 100 ms */
11065 
11066       if (!p->owner) {  /* not a PBX call */
11067          transmit_response(p, "481 Call leg/transaction does not exist", req);
11068          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
11069          return;
11070       }
11071 
11072       if (ast_strlen_zero(buf)) {
11073          transmit_response(p, "200 OK", req);
11074          return;
11075       }
11076 
11077       if (buf[0] == '*')
11078          event = 10;
11079       else if (buf[0] == '#')
11080          event = 11;
11081       else if ((buf[0] >= 'A') && (buf[0] <= 'D'))
11082          event = 12 + buf[0] - 'A';
11083       else
11084          event = atoi(buf);
11085       if (event == 16) {
11086          /* send a FLASH event */
11087          struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_FLASH, };
11088          ast_queue_frame(p->owner, &f);
11089          if (sipdebug)
11090             ast_verbose("* DTMF-relay event received: FLASH\n");
11091       } else {
11092          /* send a DTMF event */
11093          struct ast_frame f = { AST_FRAME_DTMF, };
11094          if (event < 10) {
11095             f.subclass = '0' + event;
11096          } else if (event < 11) {
11097             f.subclass = '*';
11098          } else if (event < 12) {
11099             f.subclass = '#';
11100          } else if (event < 16) {
11101             f.subclass = 'A' + (event - 12);
11102          }
11103          f.len = duration;
11104          ast_queue_frame(p->owner, &f);
11105          if (sipdebug)
11106             ast_verbose("* DTMF-relay event received: %c\n", f.subclass);
11107       }
11108       transmit_response(p, "200 OK", req);
11109       return;
11110    } else if (!strcasecmp(c, "application/media_control+xml")) {
11111       /* Eh, we'll just assume it's a fast picture update for now */
11112       if (p->owner)
11113          ast_queue_control(p->owner, AST_CONTROL_VIDUPDATE);
11114       transmit_response(p, "200 OK", req);
11115       return;
11116    } else if (!ast_strlen_zero(c = get_header(req, "X-ClientCode"))) {
11117       /* Client code (from SNOM phone) */
11118       if (ast_test_flag(&p->flags[0], SIP_USECLIENTCODE)) {
11119          if (p->owner && p->owner->cdr)
11120             ast_cdr_setuserfield(p->owner, c);
11121          if (p->owner && ast_bridged_channel(p->owner) && ast_bridged_channel(p->owner)->cdr)
11122             ast_cdr_setuserfield(ast_bridged_channel(p->owner), c);
11123          transmit_response(p, "200 OK", req);
11124       } else {
11125          transmit_response(p, "403 Unauthorized", req);
11126       }
11127       return;
11128    } else if (ast_strlen_zero(c = get_header(req, "Content-Length")) || !strcasecmp(c, "0")) {
11129       /* This is probably just a packet making sure the signalling is still up, just send back a 200 OK */
11130       transmit_response(p, "200 OK", req);
11131       return;
11132    }
11133 
11134    /* Other type of INFO message, not really understood by Asterisk */
11135    /* if (get_msg_text(buf, sizeof(buf), req)) { */
11136 
11137    ast_log(LOG_WARNING, "Unable to parse INFO message from %s. Content %s\n", p->callid, buf);
11138    transmit_response(p, "415 Unsupported media type", req);
11139    return;
11140 }

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

Handle incoming INVITE request.

Note:
If the INVITE has a Replaces header, it is part of an attended transfer. If so, we do not go through the dial plan but tries to find the active call and masquerade into it

XXX: we should also check here does the other side supports t38 at all !!! XXX

Definition at line 13581 of file chan_sip.c.

References ast_channel::_state, append_history, ast_bridged_channel(), AST_CAUSE_CALL_REJECTED, AST_CAUSE_NORMAL_CLEARING, ast_channel_lock, ast_channel_unlock, ast_clear_flag, ast_hangup(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_null_frame, AST_PBX_CALL_LIMIT, AST_PBX_FAILED, ast_pbx_start(), AST_PBX_SUCCESS, ast_pickup_call(), ast_pickup_ext(), ast_queue_frame(), ast_rtp_setdtmf(), ast_rtp_setdtmfcompensate(), ast_setstate(), AST_STATE_DOWN, AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, ast_strdupa, ast_string_field_free, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_uri_decode(), ast_verbose(), AUTH_CHALLENGE_SENT, AUTH_FAKE_AUTH, sip_pvt::autokillid, build_contact(), build_route(), sip_pvt::capability, change_hold_state(), check_user(), check_via(), context, copy_request(), DEC_CALL_LIMIT, DEFAULT_TRANS_TIMEOUT, error(), exten, extract_uri(), FALSE, find_sdp(), sip_pvt::flags, get_destination(), get_header(), get_rdnis(), get_sip_pvt_byid_locked(), handle_invite_replaces(), ast_channel::hangupcause, sip_request::headers, INC_CALL_LIMIT, sip_pvt::initreq, INV_COMPLETED, INV_PROCEEDING, INV_TERMINATED, sip_pvt::invitestate, sip_pvt::jointcapability, sip_pvt::lastinvite, ast_channel::lock, sip_pvt::lock, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, make_our_tag(), option_debug, sip_pvt::owner, parse_ok_contact(), parse_sip_options(), sip_pvt::pendinginvite, process_sdp(), sip_pvt::refer, sip_refer::refer_call, sip_pvt::rtp, S_OR, sip_alreadygone(), sip_cancel_destroy(), SIP_DTMF, SIP_DTMF_RFC2833, sip_handle_t38_reinvite(), SIP_INVITE, sip_new(), SIP_NO_HISTORY, SIP_OPT_REPLACES, SIP_OUTGOING, SIP_PAGE2_ALLOWOVERLAP, SIP_PAGE2_CALL_ONHOLD, SIP_PAGE2_RFC2833_COMPENSATE, SIP_PKT_IGNORE, sip_refer_allocate(), sip_scheddestroy(), sip_tech, sip_tech_info, sipdebug, sip_pvt::sipoptions, t38properties::state, strcasestr(), strsep(), sip_pvt::t38, T38_DISABLED, T38_ENABLED, T38_PEER_REINVITE, sip_pvt::tag, ast_channel::tech, ast_channel::tech_pvt, transmit_fake_auth_response(), transmit_response(), transmit_response_reliable(), transmit_response_with_sdp(), transmit_response_with_t38_sdp(), transmit_response_with_unsupported(), TRUE, sip_pvt::udptl, update_call_counter(), XMIT_CRITICAL, XMIT_RELIABLE, and XMIT_UNRELIABLE.

Referenced by handle_request().

13582 {
13583    int res = 1;
13584    int gotdest;
13585    const char *p_replaces;
13586    char *replace_id = NULL;
13587    const char *required;
13588    unsigned int required_profile = 0;
13589    struct ast_channel *c = NULL;    /* New channel */
13590    int reinvite = 0;
13591 
13592    /* Find out what they support */
13593    if (!p->sipoptions) {
13594       const char *supported = get_header(req, "Supported");
13595       if (!ast_strlen_zero(supported))
13596          parse_sip_options(p, supported);
13597    }
13598 
13599    /* Find out what they require */
13600    required = get_header(req, "Require");
13601    if (!ast_strlen_zero(required)) {
13602       required_profile = parse_sip_options(NULL, required);
13603       if (required_profile && required_profile != SIP_OPT_REPLACES) {
13604          /* At this point we only support REPLACES */
13605          transmit_response_with_unsupported(p, "420 Bad extension (unsupported)", req, required);
13606          ast_log(LOG_WARNING,"Received SIP INVITE with unsupported required extension: %s\n", required);
13607          p->invitestate = INV_COMPLETED;
13608          if (!p->lastinvite)
13609             sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
13610          return -1;
13611       }
13612    }
13613 
13614    /* Check if this is a loop */
13615    if (ast_test_flag(&p->flags[0], SIP_OUTGOING) && p->owner && (p->owner->_state != AST_STATE_UP)) {
13616       /* This is a call to ourself.  Send ourselves an error code and stop
13617          processing immediately, as SIP really has no good mechanism for
13618          being able to call yourself */
13619       /* If pedantic is on, we need to check the tags. If they're different, this is
13620          in fact a forked call through a SIP proxy somewhere. */
13621       transmit_response(p, "482 Loop Detected", req);
13622       p->invitestate = INV_COMPLETED;
13623       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
13624       return 0;
13625    }
13626    
13627    if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->pendinginvite) {
13628       /* We already have a pending invite. Sorry. You are on hold. */
13629       transmit_response(p, "491 Request Pending", req);
13630       if (option_debug)
13631          ast_log(LOG_DEBUG, "Got INVITE on call where we already have pending INVITE, deferring that - %s\n", p->callid);
13632       /* Don't destroy dialog here */
13633       return 0;
13634    }
13635 
13636    p_replaces = get_header(req, "Replaces");
13637    if (!ast_strlen_zero(p_replaces)) {
13638       /* We have a replaces header */
13639       char *ptr;
13640       char *fromtag = NULL;
13641       char *totag = NULL;
13642       char *start, *to;
13643       int error = 0;
13644 
13645       if (p->owner) {
13646          if (option_debug > 2)
13647             ast_log(LOG_DEBUG, "INVITE w Replaces on existing call? Refusing action. [%s]\n", p->callid);
13648          transmit_response(p, "400 Bad request", req);   /* The best way to not not accept the transfer */
13649          /* Do not destroy existing call */
13650          return -1;
13651       }
13652 
13653       if (sipdebug && option_debug > 2)
13654          ast_log(LOG_DEBUG, "INVITE part of call transfer. Replaces [%s]\n", p_replaces);
13655       /* Create a buffer we can manipulate */
13656       replace_id = ast_strdupa(p_replaces);
13657       ast_uri_decode(replace_id);
13658 
13659       if (!p->refer && !sip_refer_allocate(p)) {
13660          transmit_response(p, "500 Server Internal Error", req);
13661          append_history(p, "Xfer", "INVITE/Replace Failed. Out of memory.");
13662          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
13663          p->invitestate = INV_COMPLETED;
13664          return -1;
13665       }
13666 
13667       /*  Todo: (When we find phones that support this)
13668          if the replaces header contains ";early-only"
13669          we can only replace the call in early
13670          stage, not after it's up.
13671 
13672          If it's not in early mode, 486 Busy.
13673       */
13674       
13675       /* Skip leading whitespace */
13676       replace_id = ast_skip_blanks(replace_id);
13677 
13678       start = replace_id;
13679       while ( (ptr = strsep(&start, ";")) ) {
13680          ptr = ast_skip_blanks(ptr); /* XXX maybe unnecessary ? */
13681          if ( (to = strcasestr(ptr, "to-tag=") ) )
13682             totag = to + 7;   /* skip the keyword */
13683          else if ( (to = strcasestr(ptr, "from-tag=") ) ) {
13684             fromtag = to + 9; /* skip the keyword */
13685             fromtag = strsep(&fromtag, "&"); /* trim what ? */
13686          }
13687       }
13688 
13689       if (sipdebug && option_debug > 3) 
13690          ast_log(LOG_DEBUG,"Invite/replaces: Will use Replace-Call-ID : %s Fromtag: %s Totag: %s\n", replace_id, fromtag ? fromtag : "<no from tag>", totag ? totag : "<no to tag>");
13691 
13692 
13693       /* Try to find call that we are replacing 
13694          If we have a Replaces  header, we need to cancel that call if we succeed with this call 
13695       */
13696       if ((p->refer->refer_call = get_sip_pvt_byid_locked(replace_id, totag, fromtag)) == NULL) {
13697          ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-existent call id (%s)!\n", replace_id);
13698          transmit_response(p, "481 Call Leg Does Not Exist (Replaces)", req);
13699          error = 1;
13700       }
13701 
13702       /* At this point, bot the pvt and the owner of the call to be replaced is locked */
13703 
13704       /* The matched call is the call from the transferer to Asterisk .
13705          We want to bridge the bridged part of the call to the 
13706          incoming invite, thus taking over the refered call */
13707 
13708       if (p->refer->refer_call == p) {
13709          ast_log(LOG_NOTICE, "INVITE with replaces into it's own call id (%s == %s)!\n", replace_id, p->callid);
13710          p->refer->refer_call = NULL;
13711          transmit_response(p, "400 Bad request", req);   /* The best way to not not accept the transfer */
13712          error = 1;
13713       }
13714 
13715       if (!error && !p->refer->refer_call->owner) {
13716          /* Oops, someting wrong anyway, no owner, no call */
13717          ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-existing call id (%s)!\n", replace_id);
13718          /* Check for better return code */
13719          transmit_response(p, "481 Call Leg Does Not Exist (Replace)", req);
13720          error = 1;
13721       }
13722 
13723       if (!error && p->refer->refer_call->owner->_state != AST_STATE_RINGING && p->refer->refer_call->owner->_state != AST_STATE_RING && p->refer->refer_call->owner->_state != AST_STATE_UP ) {
13724          ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-ringing or active call id (%s)!\n", replace_id);
13725          transmit_response(p, "603 Declined (Replaces)", req);
13726          error = 1;
13727       }
13728 
13729       if (error) {   /* Give up this dialog */
13730          append_history(p, "Xfer", "INVITE/Replace Failed.");
13731          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
13732          ast_mutex_unlock(&p->lock);
13733          if (p->refer->refer_call) {
13734             ast_mutex_unlock(&p->refer->refer_call->lock);
13735             ast_channel_unlock(p->refer->refer_call->owner);
13736          }
13737          p->invitestate = INV_COMPLETED;
13738          return -1;
13739       }
13740    }
13741 
13742 
13743    /* Check if this is an INVITE that sets up a new dialog or
13744       a re-invite in an existing dialog */
13745 
13746    if (!ast_test_flag(req, SIP_PKT_IGNORE)) {
13747       int newcall = (p->initreq.headers ? TRUE : FALSE);
13748 
13749       sip_cancel_destroy(p);
13750       /* This also counts as a pending invite */
13751       p->pendinginvite = seqno;
13752       check_via(p, req);
13753 
13754       copy_request(&p->initreq, req);     /* Save this INVITE as the transaction basis */
13755       if (!p->owner) {  /* Not a re-invite */
13756          if (debug)
13757             ast_verbose("Using INVITE request as basis request - %s\n", p->callid);
13758          if (newcall)
13759             append_history(p, "Invite", "New call: %s", p->callid);
13760          parse_ok_contact(p, req);
13761       } else { /* Re-invite on existing call */
13762          ast_clear_flag(&p->flags[0], SIP_OUTGOING);  /* This is now an inbound dialog */
13763          /* Handle SDP here if we already have an owner */
13764          if (find_sdp(req)) {
13765             if (process_sdp(p, req)) {
13766                transmit_response(p, "488 Not acceptable here", req);
13767                if (!p->lastinvite)
13768                   sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
13769                return -1;
13770             }
13771          } else {
13772             p->jointcapability = p->capability;
13773             if (option_debug > 2)
13774                ast_log(LOG_DEBUG, "Hm....  No sdp for the moment\n");
13775             /* Some devices signal they want to be put off hold by sending a re-invite
13776                *without* an SDP, which is supposed to mean "Go back to your state"
13777                and since they put os on remote hold, we go back to off hold */
13778             if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD))
13779                change_hold_state(p, req, FALSE, 0);
13780          }
13781          if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) /* This is a response, note what it was for */
13782             append_history(p, "ReInv", "Re-invite received");
13783       }
13784    } else if (debug)
13785       ast_verbose("Ignoring this INVITE request\n");
13786 
13787    
13788    if (!p->lastinvite && !ast_test_flag(req, SIP_PKT_IGNORE) && !p->owner) {
13789       /* This is a new invite */
13790       /* Handle authentication if this is our first invite */
13791       res = check_user(p, req, SIP_INVITE, e, XMIT_RELIABLE, sin);
13792       if (res == AUTH_CHALLENGE_SENT) {
13793          p->invitestate = INV_COMPLETED;     /* Needs to restart in another INVITE transaction */
13794          return 0;
13795       }
13796       if (res < 0) { /* Something failed in authentication */
13797          if (res == AUTH_FAKE_AUTH) {
13798             ast_log(LOG_NOTICE, "Sending fake auth rejection for user %s\n", get_header(req, "From"));
13799             transmit_fake_auth_response(p, req, 1);
13800          } else {
13801             ast_log(LOG_NOTICE, "Failed to authenticate user %s\n", get_header(req, "From"));
13802             transmit_response_reliable(p, "403 Forbidden", req);
13803          }
13804          p->invitestate = INV_COMPLETED;  
13805          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
13806          ast_string_field_free(p, theirtag);
13807          return 0;
13808       }
13809 
13810       /* We have a succesful authentication, process the SDP portion if there is one */
13811       if (find_sdp(req)) {
13812          if (process_sdp(p, req)) {
13813             /* Unacceptable codecs */
13814             transmit_response_reliable(p, "488 Not acceptable here", req);
13815             p->invitestate = INV_COMPLETED;  
13816             sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
13817             if (option_debug)
13818                ast_log(LOG_DEBUG, "No compatible codecs for this SIP call.\n");
13819             return -1;
13820          }
13821       } else { /* No SDP in invite, call control session */
13822          p->jointcapability = p->capability;
13823          if (option_debug > 1)
13824             ast_log(LOG_DEBUG, "No SDP in Invite, third party call control\n");
13825       }
13826 
13827       /* Queue NULL frame to prod ast_rtp_bridge if appropriate */
13828       /* This seems redundant ... see !p-owner above */
13829       if (p->owner)
13830          ast_queue_frame(p->owner, &ast_null_frame);
13831 
13832 
13833       /* Initialize the context if it hasn't been already */
13834       if (ast_strlen_zero(p->context))
13835          ast_string_field_set(p, context, default_context);
13836 
13837 
13838       /* Check number of concurrent calls -vs- incoming limit HERE */
13839       if (option_debug)
13840          ast_log(LOG_DEBUG, "Checking SIP call limits for device %s\n", p->username);
13841       if ((res = update_call_counter(p, INC_CALL_LIMIT))) {
13842          if (res < 0) {
13843             ast_log(LOG_NOTICE, "Failed to place call for user %s, too many calls\n", p->username);
13844             transmit_response_reliable(p, "480 Temporarily Unavailable (Call limit) ", req);
13845             sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
13846             p->invitestate = INV_COMPLETED;  
13847          }
13848          return 0;
13849       }
13850       gotdest = get_destination(p, NULL); /* Get destination right away */
13851       get_rdnis(p, NULL);        /* Get redirect information */
13852       extract_uri(p, req);       /* Get the Contact URI */
13853       build_contact(p);       /* Build our contact header */
13854 
13855       if (p->rtp) {
13856          ast_rtp_setdtmf(p->rtp, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833);
13857          ast_rtp_setdtmfcompensate(p->rtp, ast_test_flag(&p->flags[1], SIP_PAGE2_RFC2833_COMPENSATE));
13858       }
13859 
13860       if (!replace_id && gotdest) { /* No matching extension found */
13861          if (gotdest == 1 && ast_test_flag(&p->flags[1], SIP_PAGE2_ALLOWOVERLAP))
13862             transmit_response_reliable(p, "484 Address Incomplete", req);
13863          else {
13864             transmit_response_reliable(p, "404 Not Found", req);
13865             ast_log(LOG_NOTICE, "Call from '%s' to extension"
13866                " '%s' rejected because extension not found.\n",
13867                S_OR(p->username, p->peername), p->exten);
13868          }
13869          p->invitestate = INV_COMPLETED;  
13870          update_call_counter(p, DEC_CALL_LIMIT);
13871          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
13872          return 0;
13873       } else {
13874          /* If no extension was specified, use the s one */
13875          /* Basically for calling to IP/Host name only */
13876          if (ast_strlen_zero(p->exten))
13877             ast_string_field_set(p, exten, "s");
13878          /* Initialize our tag */   
13879 
13880          make_our_tag(p->tag, sizeof(p->tag));
13881          /* First invitation - create the channel */
13882          c = sip_new(p, AST_STATE_DOWN, S_OR(p->username, NULL));
13883          *recount = 1;
13884 
13885          /* Save Record-Route for any later requests we make on this dialogue */
13886          build_route(p, req, 0);
13887 
13888          if (c) {
13889             /* Pre-lock the call */
13890             ast_channel_lock(c);
13891          }
13892       }
13893    } else {
13894       if (option_debug > 1 && sipdebug) {
13895          if (!ast_test_flag(req, SIP_PKT_IGNORE))
13896             ast_log(LOG_DEBUG, "Got a SIP re-invite for call %s\n", p->callid);
13897          else
13898             ast_log(LOG_DEBUG, "Got a SIP re-transmit of INVITE for call %s\n", p->callid);
13899       }
13900       reinvite = 1;
13901       c = p->owner;
13902    }
13903 
13904    if (!ast_test_flag(req, SIP_PKT_IGNORE) && p)
13905       p->lastinvite = seqno;
13906 
13907    if (replace_id) {    /* Attended transfer or call pickup - we're the target */
13908       /* Go and take over the target call */
13909       if (sipdebug && option_debug > 3)
13910          ast_log(LOG_DEBUG, "Sending this call to the invite/replcaes handler %s\n", p->callid);
13911       return handle_invite_replaces(p, req, debug, ast_test_flag(req, SIP_PKT_IGNORE), seqno, sin);
13912    }
13913 
13914 
13915    if (c) { /* We have a call  -either a new call or an old one (RE-INVITE) */
13916       switch(c->_state) {
13917       case AST_STATE_DOWN:
13918          if (option_debug > 1)
13919             ast_log(LOG_DEBUG, "%s: New call is still down.... Trying... \n", c->name);
13920          transmit_response(p, "100 Trying", req);
13921          p->invitestate = INV_PROCEEDING;
13922          ast_setstate(c, AST_STATE_RING);
13923          if (strcmp(p->exten, ast_pickup_ext())) { /* Call to extension -start pbx on this call */
13924             enum ast_pbx_result res;
13925 
13926             res = ast_pbx_start(c);
13927 
13928             switch(res) {
13929             case AST_PBX_FAILED:
13930                ast_log(LOG_WARNING, "Failed to start PBX :(\n");
13931                p->invitestate = INV_COMPLETED;
13932                if (ast_test_flag(req, SIP_PKT_IGNORE))
13933                   transmit_response(p, "503 Unavailable", req);
13934                else
13935                   transmit_response_reliable(p, "503 Unavailable", req);
13936                break;
13937             case AST_PBX_CALL_LIMIT:
13938                ast_log(LOG_WARNING, "Failed to start PBX (call limit reached) \n");
13939                p->invitestate = INV_COMPLETED;
13940                if (ast_test_flag(req, SIP_PKT_IGNORE))
13941                   transmit_response(p, "480 Temporarily Unavailable", req);
13942                else
13943                   transmit_response_reliable(p, "480 Temporarily Unavailable", req);
13944                break;
13945             case AST_PBX_SUCCESS:
13946                /* nothing to do */
13947                break;
13948             }
13949 
13950             if (res) {
13951 
13952                /* Unlock locks so ast_hangup can do its magic */
13953                ast_mutex_unlock(&c->lock);
13954                ast_mutex_unlock(&p->lock);
13955                ast_hangup(c);
13956                ast_mutex_lock(&p->lock);
13957                c = NULL;
13958             }
13959          } else { /* Pickup call in call group */
13960             ast_channel_unlock(c);
13961             *nounlock = 1;
13962             if (ast_pickup_call(c)) {
13963                ast_log(LOG_NOTICE, "Nothing to pick up for %s\n", p->callid);
13964                if (ast_test_flag(req, SIP_PKT_IGNORE))
13965                   transmit_response(p, "503 Unavailable", req);   /* OEJ - Right answer? */
13966                else
13967                   transmit_response_reliable(p, "503 Unavailable", req);
13968                sip_alreadygone(p);
13969                /* Unlock locks so ast_hangup can do its magic */
13970                ast_mutex_unlock(&p->lock);
13971                c->hangupcause = AST_CAUSE_CALL_REJECTED;
13972             } else {
13973                ast_mutex_unlock(&p->lock);
13974                ast_setstate(c, AST_STATE_DOWN);
13975                c->hangupcause = AST_CAUSE_NORMAL_CLEARING;
13976             }
13977             p->invitestate = INV_COMPLETED;
13978             ast_hangup(c);
13979             ast_mutex_lock(&p->lock);
13980             c = NULL;
13981          }
13982          break;
13983       case AST_STATE_RING:
13984          transmit_response(p, "100 Trying", req);
13985          p->invitestate = INV_PROCEEDING;
13986          break;
13987       case AST_STATE_RINGING:
13988          transmit_response(p, "180 Ringing", req);
13989          p->invitestate = INV_PROCEEDING;
13990          break;
13991       case AST_STATE_UP:
13992          if (option_debug > 1)
13993             ast_log(LOG_DEBUG, "%s: This call is UP.... \n", c->name);
13994 
13995          transmit_response(p, "100 Trying", req);
13996 
13997          if (p->t38.state == T38_PEER_REINVITE) {
13998             struct ast_channel *bridgepeer = NULL;
13999             struct sip_pvt *bridgepvt = NULL;
14000             
14001             if ((bridgepeer = ast_bridged_channel(p->owner))) {
14002                /* We have a bridge, and this is re-invite to switchover to T38 so we send re-invite with T38 SDP, to other side of bridge*/
14003                /*! XXX: we should also check here does the other side supports t38 at all !!! XXX */
14004                if (bridgepeer->tech == &sip_tech || bridgepeer->tech == &sip_tech_info) {
14005                   bridgepvt = (struct sip_pvt*)bridgepeer->tech_pvt;
14006                   if (bridgepvt->t38.state == T38_DISABLED) {
14007                      if (bridgepvt->udptl) { /* If everything is OK with other side's udptl struct */
14008                         /* Send re-invite to the bridged channel */
14009                         sip_handle_t38_reinvite(bridgepeer, p, 1);
14010                      } else { /* Something is wrong with peers udptl struct */
14011                         ast_log(LOG_WARNING, "Strange... The other side of the bridge don't have udptl struct\n");
14012                         ast_mutex_lock(&bridgepvt->lock);
14013                         bridgepvt->t38.state = T38_DISABLED;
14014                         ast_mutex_unlock(&bridgepvt->lock);
14015                         if (option_debug > 1)
14016                            ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", bridgepvt->t38.state, bridgepeer->name);
14017                         if (ast_test_flag(req, SIP_PKT_IGNORE))
14018                            transmit_response(p, "488 Not acceptable here", req);
14019                         else
14020                            transmit_response_reliable(p, "488 Not acceptable here", req);
14021                      
14022                      }
14023                   } else {
14024                      /* The other side is already setup for T.38 most likely so we need to acknowledge this too */
14025                      transmit_response_with_t38_sdp(p, "200 OK", req, XMIT_CRITICAL);
14026                      p->t38.state = T38_ENABLED;
14027                      if (option_debug)
14028                         ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>");
14029                   }
14030                } else {
14031                   /* Other side is not a SIP channel */
14032                   if (ast_test_flag(req, SIP_PKT_IGNORE))
14033                      transmit_response(p, "488 Not acceptable here", req);
14034                   else
14035                      transmit_response_reliable(p, "488 Not acceptable here", req);
14036                   p->t38.state = T38_DISABLED;
14037                   if (option_debug > 1)
14038                      ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>");
14039 
14040                   if (!p->lastinvite) /* Only destroy if this is *not* a re-invite */
14041                      sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
14042                }
14043             } else {
14044                /* we are not bridged in a call */
14045                transmit_response_with_t38_sdp(p, "200 OK", req, XMIT_CRITICAL);
14046                p->t38.state = T38_ENABLED;
14047                if (option_debug)
14048                   ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>");
14049             }
14050          } else if (p->t38.state == T38_DISABLED) { /* Channel doesn't have T38 offered or enabled */
14051             int sendok = TRUE;
14052 
14053             /* If we are bridged to a channel that has T38 enabled than this is a case of RTP re-invite after T38 session */
14054             /* so handle it here (re-invite other party to RTP) */
14055             struct ast_channel *bridgepeer = NULL;
14056             struct sip_pvt *bridgepvt = NULL;
14057             if ((bridgepeer = ast_bridged_channel(p->owner))) {
14058                if (bridgepeer->tech == &sip_tech || bridgepeer->tech == &sip_tech_info) {
14059                   bridgepvt = (struct sip_pvt*)bridgepeer->tech_pvt;
14060                   /* Does the bridged peer have T38 ? */
14061                   if (bridgepvt->t38.state == T38_ENABLED) {
14062                      ast_log(LOG_WARNING, "RTP re-invite after T38 session not handled yet !\n");
14063                      /* Insted of this we should somehow re-invite the other side of the bridge to RTP */
14064                      if (ast_test_flag(req, SIP_PKT_IGNORE))
14065                         transmit_response(p, "488 Not Acceptable Here (unsupported)", req);
14066                      else
14067                         transmit_response_reliable(p, "488 Not Acceptable Here (unsupported)", req);
14068                      sendok = FALSE;
14069                   } 
14070                   /* No bridged peer with T38 enabled*/
14071                }
14072             } 
14073             /* Respond to normal re-invite */
14074             if (sendok)
14075                /* If this is not a re-invite or something to ignore - it's critical */
14076                transmit_response_with_sdp(p, "200 OK", req, (reinvite || ast_test_flag(req, SIP_PKT_IGNORE)) ?  XMIT_UNRELIABLE : XMIT_CRITICAL);
14077          }
14078          p->invitestate = INV_TERMINATED;
14079          break;
14080       default:
14081          ast_log(LOG_WARNING, "Don't know how to handle INVITE in state %d\n", c->_state);
14082          transmit_response(p, "100 Trying", req);
14083          break;
14084       }
14085    } else {
14086       if (p && (p->autokillid == -1)) {
14087          const char *msg;
14088 
14089          if (!p->jointcapability)
14090             msg = "488 Not Acceptable Here (codec error)";
14091          else {
14092             ast_log(LOG_NOTICE, "Unable to create/find SIP channel for this INVITE\n");
14093             msg = "503 Unavailable";
14094          }
14095          if (ast_test_flag(req, SIP_PKT_IGNORE))
14096             transmit_response(p, msg, req);
14097          else
14098             transmit_response_reliable(p, msg, req);
14099          p->invitestate = INV_COMPLETED;
14100          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
14101       }
14102    }
14103    return res;
14104 }

static int handle_request_message ( struct sip_pvt p,
struct sip_request req 
) [static]

Handle incoming MESSAGE request.

Definition at line 14724 of file chan_sip.c.

References ast_test_flag, ast_verbose(), receive_message(), SIP_PKT_DEBUG, SIP_PKT_IGNORE, and transmit_response().

Referenced by handle_request().

14725 {
14726    if (!ast_test_flag(req, SIP_PKT_IGNORE)) {
14727       if (ast_test_flag(req, SIP_PKT_DEBUG))
14728          ast_verbose("Receiving message!\n");
14729       receive_message(p, req);
14730    } else
14731       transmit_response(p, "202 Accepted", req);
14732    return 1;
14733 }

static int handle_request_notify ( struct sip_pvt p,
struct sip_request req,
struct sockaddr_in *  sin,
int  seqno,
char *  e 
) [static]

Handle incoming notifications.

Definition at line 13254 of file chan_sip.c.

References ast_log(), DEFAULT_TRANS_TIMEOUT, event, FALSE, get_header(), get_msg_text(), sip_pvt::lastinvite, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, option_debug, sip_scheddestroy(), sipdebug, transmit_response(), and TRUE.

Referenced by handle_request().

13255 {
13256    /* This is mostly a skeleton for future improvements */
13257    /* Mostly created to return proper answers on notifications on outbound REFER's */
13258    int res = 0;
13259    const char *event = get_header(req, "Event");
13260    char *eventid = NULL;
13261    char *sep;
13262 
13263    if( (sep = strchr(event, ';')) ) {  /* XXX bug here - overwriting string ? */
13264       *sep++ = '\0';
13265       eventid = sep;
13266    }
13267    
13268    if (option_debug > 1 && sipdebug)
13269       ast_log(LOG_DEBUG, "Got NOTIFY Event: %s\n", event);
13270 
13271    if (strcmp(event, "refer")) {
13272       /* We don't understand this event. */
13273       /* Here's room to implement incoming voicemail notifications :-) */
13274       transmit_response(p, "489 Bad event", req);
13275       res = -1;
13276    } else {
13277       /* Save nesting depth for now, since there might be other events we will
13278          support in the future */
13279 
13280       /* Handle REFER notifications */
13281 
13282       char buf[1024];
13283       char *cmd, *code;
13284       int respcode;
13285       int success = TRUE;
13286 
13287       /* EventID for each transfer... EventID is basically the REFER cseq 
13288 
13289        We are getting notifications on a call that we transfered
13290        We should hangup when we are getting a 200 OK in a sipfrag
13291        Check if we have an owner of this event */
13292       
13293       /* Check the content type */
13294       if (strncasecmp(get_header(req, "Content-Type"), "message/sipfrag", strlen("message/sipfrag"))) {
13295          /* We need a sipfrag */
13296          transmit_response(p, "400 Bad request", req);
13297          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
13298          return -1;
13299       }
13300 
13301       /* Get the text of the attachment */
13302       if (get_msg_text(buf, sizeof(buf), req)) {
13303          ast_log(LOG_WARNING, "Unable to retrieve attachment from NOTIFY %s\n", p->callid);
13304          transmit_response(p, "400 Bad request", req);
13305          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
13306          return -1;
13307       }
13308 
13309       /*
13310       From the RFC...
13311       A minimal, but complete, implementation can respond with a single
13312          NOTIFY containing either the body:
13313                SIP/2.0 100 Trying
13314       
13315          if the subscription is pending, the body:
13316                SIP/2.0 200 OK
13317          if the reference was successful, the body:
13318                SIP/2.0 503 Service Unavailable
13319          if the reference failed, or the body:
13320                SIP/2.0 603 Declined
13321 
13322          if the REFER request was accepted before approval to follow the
13323          reference could be obtained and that approval was subsequently denied
13324          (see Section 2.4.7).
13325       
13326       If there are several REFERs in the same dialog, we need to
13327       match the ID of the event header...
13328       */
13329       if (option_debug > 2)
13330          ast_log(LOG_DEBUG, "* SIP Transfer NOTIFY Attachment: \n---%s\n---\n", buf);
13331       cmd = ast_skip_blanks(buf);
13332       code = cmd;
13333       /* We are at SIP/2.0 */
13334       while(*code && (*code > 32)) {   /* Search white space */
13335          code++;
13336       }
13337       *code++ = '\0';
13338       code = ast_skip_blanks(code);
13339       sep = code;
13340       sep++;
13341       while(*sep && (*sep > 32)) {  /* Search white space */
13342          sep++;
13343       }
13344       *sep++ = '\0';       /* Response string */
13345       respcode = atoi(code);
13346       switch (respcode) {
13347       case 100:   /* Trying: */
13348       case 101:   /* dialog establishment */
13349          /* Don't do anything yet */
13350          break;
13351       case 183:   /* Ringing: */
13352          /* Don't do anything yet */
13353          break;
13354       case 200:   /* OK: The new call is up, hangup this call */
13355          /* Hangup the call that we are replacing */
13356          break;
13357       case 301: /* Moved permenantly */
13358       case 302: /* Moved temporarily */
13359          /* Do we get the header in the packet in this case? */
13360          success = FALSE;
13361          break;
13362       case 503:   /* Service Unavailable: The new call failed */
13363             /* Cancel transfer, continue the call */
13364          success = FALSE;
13365          break;
13366       case 603:   /* Declined: Not accepted */
13367             /* Cancel transfer, continue the current call */
13368          success = FALSE;
13369          break;
13370       }
13371       if (!success) {
13372          ast_log(LOG_NOTICE, "Transfer failed. Sorry. Nothing further to do with this call\n");
13373       }
13374       
13375       /* Confirm that we received this packet */
13376       transmit_response(p, "200 OK", req);
13377    };
13378 
13379    if (!p->lastinvite)
13380       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
13381 
13382    return res;
13383 }

static int handle_request_options ( struct sip_pvt p,
struct sip_request req 
) [static]

Handle incoming OPTIONS request.

Definition at line 13386 of file chan_sip.c.

References ast_shutting_down(), ast_string_field_set, ast_strlen_zero(), build_contact(), context, DEFAULT_TRANS_TIMEOUT, get_destination(), sip_pvt::lastinvite, sip_scheddestroy(), and transmit_response_with_allow().

Referenced by handle_request().

13387 {
13388    int res;
13389 
13390    res = get_destination(p, req);
13391    build_contact(p);
13392 
13393    /* XXX Should we authenticate OPTIONS? XXX */
13394 
13395    if (ast_strlen_zero(p->context))
13396       ast_string_field_set(p, context, default_context);
13397 
13398    if (ast_shutting_down())
13399       transmit_response_with_allow(p, "503 Unavailable", req, 0);
13400    else if (res < 0)
13401       transmit_response_with_allow(p, "404 Not Found", req, 0);
13402    else 
13403       transmit_response_with_allow(p, "200 OK", req, 0);
13404 
13405    /* Destroy if this OPTIONS was the opening request, but not if
13406       it's in the middle of a normal call flow. */
13407    if (!p->lastinvite)
13408       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
13409 
13410    return res;
13411 }

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

Definition at line 14272 of file chan_sip.c.

References sip_pvt::allowtransfer, append_history, ast_async_goto(), ast_bridged_channel(), AST_CAUSE_NORMAL_CLEARING, ast_channel_unlock, ast_clear_flag, AST_CONTROL_UNHOLD, AST_LIST_EMPTY, ast_log(), ast_parking_ext(), ast_queue_control(), ast_set_flag, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_verbose(), sip_refer::attendedtransfer, sip_dual::chan1, sip_dual::chan2, check_sip_domain(), context, copy_request(), FALSE, sip_pvt::flags, get_refer_info(), ast_channel::hangupcause, local_attended_transfer(), sip_refer::localtransfer, LOG_DEBUG, option_debug, sip_pvt::owner, pbx_builtin_setvar_helper(), sip_pvt::refer, REFER_200OK, REFER_FAILED, REFER_SENT, sip_refer::refer_to, sip_refer::refer_to_context, sip_refer::refer_to_domain, sip_refer::referred_by, sip_refer::replaces_callid, sip_refer::replaces_callid_fromtag, sip_refer::replaces_callid_totag, sip_dual::req, sip_alreadygone(), SIP_DEFER_BYE_ON_TRANSFER, SIP_GOTREFER, SIP_NEEDDESTROY, SIP_OUTGOING, sip_park(), SIP_PKT_DEBUG, SIP_PKT_IGNORE, sip_refer_allocate(), sipdebug, sip_refer::status, TRANSFER_CLOSED, transmit_notify_with_sipfrag(), transmit_response(), and TRUE.

Referenced by handle_request().

14273 {
14274    struct sip_dual current;   /* Chan1: Call between asterisk and transferer */
14275                /* Chan2: Call between asterisk and transferee */
14276 
14277    int res = 0;
14278 
14279    if (ast_test_flag(req, SIP_PKT_DEBUG))
14280       ast_verbose("Call %s got a SIP call transfer from %s: (REFER)!\n", p->callid, ast_test_flag(&p->flags[0], SIP_OUTGOING) ? "callee" : "caller");
14281 
14282    if (!p->owner) {
14283       /* This is a REFER outside of an existing SIP dialog */
14284       /* We can't handle that, so decline it */
14285       if (option_debug > 2)
14286          ast_log(LOG_DEBUG, "Call %s: Declined REFER, outside of dialog...\n", p->callid);
14287       transmit_response(p, "603 Declined (No dialog)", req);
14288       if (!ast_test_flag(req, SIP_PKT_IGNORE)) {
14289          append_history(p, "Xfer", "Refer failed. Outside of dialog.");
14290          sip_alreadygone(p);
14291          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
14292       }
14293       return 0;
14294    }  
14295 
14296 
14297    /* Check if transfer is allowed from this device */
14298    if (p->allowtransfer == TRANSFER_CLOSED ) {
14299       /* Transfer not allowed, decline */
14300       transmit_response(p, "603 Declined (policy)", req);
14301       append_history(p, "Xfer", "Refer failed. Allowtransfer == closed.");
14302       /* Do not destroy SIP session */
14303       return 0;
14304    }
14305 
14306    if(!ignore && ast_test_flag(&p->flags[0], SIP_GOTREFER)) {
14307       /* Already have a pending REFER */  
14308       transmit_response(p, "491 Request pending", req);
14309       append_history(p, "Xfer", "Refer failed. Request pending.");
14310       return 0;
14311    }
14312 
14313    /* Allocate memory for call transfer data */
14314    if (!p->refer && !sip_refer_allocate(p)) {
14315       transmit_response(p, "500 Internal Server Error", req);
14316       append_history(p, "Xfer", "Refer failed. Memory allocation error.");
14317       return -3;
14318    }
14319 
14320    res = get_refer_info(p, req); /* Extract headers */
14321 
14322    p->refer->status = REFER_SENT;
14323 
14324    if (res != 0) {
14325       switch (res) {
14326       case -2: /* Syntax error */
14327          transmit_response(p, "400 Bad Request (Refer-to missing)", req);
14328          append_history(p, "Xfer", "Refer failed. Refer-to missing.");
14329          if (ast_test_flag(req, SIP_PKT_DEBUG) && option_debug)
14330             ast_log(LOG_DEBUG, "SIP transfer to black hole can't be handled (no refer-to: )\n");
14331          break;
14332       case -3:
14333          transmit_response(p, "603 Declined (Non sip: uri)", req);
14334          append_history(p, "Xfer", "Refer failed. Non SIP uri");
14335          if (ast_test_flag(req, SIP_PKT_DEBUG) && option_debug)
14336             ast_log(LOG_DEBUG, "SIP transfer to non-SIP uri denied\n");
14337          break;
14338       default:
14339          /* Refer-to extension not found, fake a failed transfer */
14340          transmit_response(p, "202 Accepted", req);
14341          append_history(p, "Xfer", "Refer failed. Bad extension.");
14342          transmit_notify_with_sipfrag(p, seqno, "404 Not found", TRUE);
14343          ast_clear_flag(&p->flags[0], SIP_GOTREFER);  
14344          if (ast_test_flag(req, SIP_PKT_DEBUG) && option_debug)
14345             ast_log(LOG_DEBUG, "SIP transfer to bad extension: %s\n", p->refer->refer_to);
14346          break;
14347       } 
14348       return 0;
14349    }
14350    if (ast_strlen_zero(p->context))
14351       ast_string_field_set(p, context, default_context);
14352 
14353    /* If we do not support SIP domains, all transfers are local */
14354    if (allow_external_domains && check_sip_domain(p->refer->refer_to_domain, NULL, 0)) {
14355       p->refer->localtransfer = 1;
14356       if (sipdebug && option_debug > 2)
14357          ast_log(LOG_DEBUG, "This SIP transfer is local : %s\n", p->refer->refer_to_domain);
14358    } else if (AST_LIST_EMPTY(&domain_list) || check_sip_domain(p->refer->refer_to_domain, NULL, 0)) {
14359       /* This PBX doesn't bother with SIP domains or domain is local, so this transfer is local */
14360       p->refer->localtransfer = 1;
14361    } else if (sipdebug && option_debug > 2)
14362          ast_log(LOG_DEBUG, "This SIP transfer is to a remote SIP extension (remote domain %s)\n", p->refer->refer_to_domain);
14363    
14364    /* Is this a repeat of a current request? Ignore it */
14365    /* Don't know what else to do right now. */
14366    if (ignore) 
14367       return res;
14368 
14369    /* If this is a blind transfer, we have the following
14370       channels to work with:
14371       - chan1, chan2: The current call between transferer and transferee (2 channels)
14372       - target_channel: A new call from the transferee to the target (1 channel)
14373       We need to stay tuned to what happens in order to be able
14374       to bring back the call to the transferer */
14375 
14376    /* If this is a attended transfer, we should have all call legs within reach:
14377       - chan1, chan2: The call between the transferer and transferee (2 channels)
14378       - target_channel, targetcall_pvt: The call between the transferer and the target (2 channels)
14379    We want to bridge chan2 with targetcall_pvt!
14380    
14381       The replaces call id in the refer message points
14382       to the call leg between Asterisk and the transferer.
14383       So we need to connect the target and the transferee channel
14384       and hangup the two other channels silently 
14385    
14386       If the target is non-local, the call ID could be on a remote
14387       machine and we need to send an INVITE with replaces to the
14388       target. We basically handle this as a blind transfer
14389       and let the sip_call function catch that we need replaces
14390       header in the INVITE.
14391    */
14392 
14393 
14394    /* Get the transferer's channel */
14395    current.chan1 = p->owner;
14396 
14397    /* Find the other part of the bridge (2) - transferee */
14398    current.chan2 = ast_bridged_channel(current.chan1);
14399    
14400    if (sipdebug && option_debug > 2)
14401       ast_log(LOG_DEBUG, "SIP %s transfer: Transferer channel %s, transferee channel %s\n", p->refer->attendedtransfer ? "attended" : "blind", current.chan1->name, current.chan2 ? current.chan2->name : "<none>");
14402 
14403    if (!current.chan2 && !p->refer->attendedtransfer) {
14404       /* No bridged channel, propably IVR or echo or similar... */
14405       /* Guess we should masquerade or something here */
14406       /* Until we figure it out, refuse transfer of such calls */
14407       if (sipdebug && option_debug > 2)
14408          ast_log(LOG_DEBUG,"Refused SIP transfer on non-bridged channel.\n");
14409       p->refer->status = REFER_FAILED;
14410       append_history(p, "Xfer", "Refer failed. Non-bridged channel.");
14411       transmit_response(p, "603 Declined", req);
14412       return -1;
14413    }
14414 
14415    if (current.chan2) {
14416       if (sipdebug && option_debug > 3)
14417          ast_log(LOG_DEBUG, "Got SIP transfer, applying to bridged peer '%s'\n", current.chan2->name);
14418 
14419       ast_queue_control(current.chan1, AST_CONTROL_UNHOLD);
14420    }
14421 
14422    ast_set_flag(&p->flags[0], SIP_GOTREFER); 
14423 
14424    /* Attended transfer: Find all call legs and bridge transferee with target*/
14425    if (p->refer->attendedtransfer) {
14426       if ((res = local_attended_transfer(p, &current, req, seqno)))
14427          return res; /* We're done with the transfer */
14428       /* Fall through for remote transfers that we did not find locally */
14429       if (sipdebug && option_debug > 3)
14430          ast_log(LOG_DEBUG, "SIP attended transfer: Still not our call - generating INVITE with replaces\n");
14431       /* Fallthrough if we can't find the call leg internally */
14432    }
14433 
14434 
14435    /* Parking a call */
14436    if (p->refer->localtransfer && !strcmp(p->refer->refer_to, ast_parking_ext())) {
14437       /* Must release c's lock now, because it will not longer be accessible after the transfer! */
14438       *nounlock = 1;
14439       ast_channel_unlock(current.chan1);
14440       copy_request(&current.req, req);
14441       ast_clear_flag(&p->flags[0], SIP_GOTREFER);  
14442       p->refer->status = REFER_200OK;
14443       append_history(p, "Xfer", "REFER to call parking.");
14444       if (sipdebug && option_debug > 3)
14445          ast_log(LOG_DEBUG, "SIP transfer to parking: trying to park %s. Parked by %s\n", current.chan2->name, current.chan1->name);
14446       sip_park(current.chan2, current.chan1, req, seqno);
14447       return res;
14448    } 
14449 
14450    /* Blind transfers and remote attended xfers */
14451    transmit_response(p, "202 Accepted", req);
14452 
14453    if (current.chan1 && current.chan2) {
14454       if (option_debug > 2)
14455          ast_log(LOG_DEBUG, "chan1->name: %s\n", current.chan1->name);
14456       pbx_builtin_setvar_helper(current.chan1, "BLINDTRANSFER", current.chan2->name);
14457    }
14458    if (current.chan2) {
14459       pbx_builtin_setvar_helper(current.chan2, "BLINDTRANSFER", current.chan1->name);
14460       pbx_builtin_setvar_helper(current.chan2, "SIPDOMAIN", p->refer->refer_to_domain);
14461       pbx_builtin_setvar_helper(current.chan2, "SIPTRANSFER", "yes");
14462       /* One for the new channel */
14463       pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER", "yes");
14464       /* Attended transfer to remote host, prepare headers for the INVITE */
14465       if (p->refer->referred_by) 
14466          pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER_REFERER", p->refer->referred_by);
14467    }
14468    /* Generate a Replaces string to be used in the INVITE during attended transfer */
14469    if (p->refer->replaces_callid && !ast_strlen_zero(p->refer->replaces_callid)) {
14470       char tempheader[BUFSIZ];
14471       snprintf(tempheader, sizeof(tempheader), "%s%s%s%s%s", p->refer->replaces_callid, 
14472             p->refer->replaces_callid_totag ? ";to-tag=" : "", 
14473             p->refer->replaces_callid_totag, 
14474             p->refer->replaces_callid_fromtag ? ";from-tag=" : "",
14475             p->refer->replaces_callid_fromtag);
14476       if (current.chan2)
14477          pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER_REPLACES", tempheader);
14478    }
14479    /* Must release lock now, because it will not longer
14480          be accessible after the transfer! */
14481    *nounlock = 1;
14482    ast_channel_unlock(current.chan1);
14483 
14484    /* Connect the call */
14485 
14486    /* FAKE ringing if not attended transfer */
14487    if (!p->refer->attendedtransfer)
14488       transmit_notify_with_sipfrag(p, seqno, "183 Ringing", FALSE); 
14489       
14490    /* For blind transfer, this will lead to a new call */
14491    /* For attended transfer to remote host, this will lead to
14492          a new SIP call with a replaces header, if the dial plan allows it 
14493    */
14494    if (!current.chan2) {
14495       /* We have no bridge, so we're talking with Asterisk somehow */
14496       /* We need to masquerade this call */
14497       /* What to do to fix this situation:
14498          * Set up the new call in a new channel 
14499          * Let the new channel masq into this channel
14500          Please add that code here :-)
14501       */
14502       p->refer->status = REFER_FAILED;
14503       transmit_notify_with_sipfrag(p, seqno, "503 Service Unavailable (can't handle one-legged xfers)", TRUE);
14504       ast_clear_flag(&p->flags[0], SIP_GOTREFER);  
14505       append_history(p, "Xfer", "Refer failed (only bridged calls).");
14506       return -1;
14507    }
14508    ast_set_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER);   /* Delay hangup */
14509 
14510    /* For blind transfers, move the call to the new extensions. For attended transfers on multiple
14511       servers - generate an INVITE with Replaces. Either way, let the dial plan decided  */
14512    res = ast_async_goto(current.chan2, p->refer->refer_to_context, p->refer->refer_to, 1);
14513 
14514    if (!res) {
14515       /* Success  - we have a new channel */
14516       if (option_debug > 2)
14517          ast_log(LOG_DEBUG, "%s transfer succeeded. Telling transferer.\n", p->refer->attendedtransfer? "Attended" : "Blind");
14518       transmit_notify_with_sipfrag(p, seqno, "200 Ok", TRUE);
14519       if (p->refer->localtransfer)
14520          p->refer->status = REFER_200OK;
14521       if (p->owner)
14522          p->owner->hangupcause = AST_CAUSE_NORMAL_CLEARING;
14523       append_history(p, "Xfer", "Refer succeeded.");
14524       ast_clear_flag(&p->flags[0], SIP_GOTREFER);  
14525       /* Do not hangup call, the other side do that when we say 200 OK */
14526       /* We could possibly implement a timer here, auto congestion */
14527       res = 0;
14528    } else {
14529       ast_clear_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Don't delay hangup */
14530       if (option_debug > 2)
14531          ast_log(LOG_DEBUG, "%s transfer failed. Resuming original call.\n", p->refer->attendedtransfer? "Attended" : "Blind");
14532       append_history(p, "Xfer", "Refer failed.");
14533       /* Failure of some kind */
14534       p->refer->status = REFER_FAILED;
14535       transmit_notify_with_sipfrag(p, seqno, "503 Service Unavailable", TRUE);
14536       ast_clear_flag(&p->flags[0], SIP_GOTREFER);  
14537       res = -1;
14538    }
14539    return res;
14540 }

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

Handle incoming REGISTER request.

Definition at line 15020 of file chan_sip.c.

References append_history, ast_inet_ntoa(), ast_log(), ast_test_flag, ast_verbose(), AUTH_ACL_FAILED, AUTH_NOT_FOUND, AUTH_PEER_NOT_DYNAMIC, AUTH_SECRET_FAILED, AUTH_UNKNOWN_DOMAIN, AUTH_USERNAME_MISMATCH, check_via(), copy_request(), DEFAULT_TRANS_TIMEOUT, get_header(), sip_pvt::initreq, LOG_NOTICE, register_verify(), SIP_PKT_DEBUG, and sip_scheddestroy().

Referenced by handle_request().

15021 {
15022    enum check_auth_result res;
15023 
15024    /* Use this as the basis */
15025    if (ast_test_flag(req, SIP_PKT_DEBUG))
15026       ast_verbose("Using latest REGISTER request as basis request\n");
15027    copy_request(&p->initreq, req);
15028    check_via(p, req);
15029    if ((res = register_verify(p, sin, req, e)) < 0) {
15030       const char *reason;
15031 
15032       switch (res) {
15033       case AUTH_SECRET_FAILED:
15034          reason = "Wrong password";
15035          break;
15036       case AUTH_USERNAME_MISMATCH:
15037          reason = "Username/auth name mismatch";
15038          break;
15039       case AUTH_NOT_FOUND:
15040          reason = "No matching peer found";
15041          break;
15042       case AUTH_UNKNOWN_DOMAIN:
15043          reason = "Not a local domain";
15044          break;
15045       case AUTH_PEER_NOT_DYNAMIC:
15046          reason = "Peer is not supposed to register";
15047          break;
15048       case AUTH_ACL_FAILED:
15049          reason = "Device does not match ACL";
15050          break;
15051       default:
15052          reason = "Unknown failure";
15053          break;
15054       }
15055       ast_log(LOG_NOTICE, "Registration from '%s' failed for '%s' - %s\n",
15056          get_header(req, "To"), ast_inet_ntoa(sin->sin_addr),
15057          reason);
15058       append_history(p, "RegRequest", "Failed : Account %s : %s", get_header(req, "To"), reason);
15059    } else
15060       append_history(p, "RegRequest", "Succeeded : Account %s", get_header(req, "To"));
15061 
15062    if (res < 1) {
15063       /* Destroy the session, but keep us around for just a bit in case they don't
15064          get our 200 OK */
15065       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
15066    }
15067    return res;
15068 }

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

Handle incoming SUBSCRIBE request.

Definition at line 14736 of file chan_sip.c.

References append_history, AST_EXTENSION_REMOVED, ast_extension_state(), ast_extension_state2str(), ast_extension_state_add(), ast_extension_state_del(), ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_strdupa, ast_string_field_build, ast_strlen_zero(), ast_test_flag, ast_verbose(), ASTOBJ_UNLOCK, ASTOBJ_UNREF, ASTOBJ_WRLOCK, AUTH_CHALLENGE_SENT, AUTH_FAKE_AUTH, sip_pvt::autokillid, build_contact(), cb_extensionstate(), check_user_full(), check_via(), copy_request(), CPIM_PIDF_XML, DIALOG_INFO_XML, sip_pvt::dialogver, event, sip_pvt::expiry, FALSE, sip_pvt::flags, get_destination(), get_header(), sip_request::headers, iflist, sip_pvt::initreq, sip_pvt::lastinvite, sip_pvt::laststate, sip_pvt::lock, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, sip_peer::mailbox, make_our_tag(), sip_request::method, MWI_NOTIFICATION, sip_peer::mwipvt, sip_pvt::next, NONE, option_debug, parse_ok_contact(), PIDF_XML, sip_pvt::relatedpeer, sip_pvt::sa, sip_cancel_destroy(), sip_destroy(), sip_destroy_peer(), sip_methods, SIP_NEEDDESTROY, SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PKT_DEBUG, SIP_PKT_IGNORE, sip_scheddestroy(), sip_send_mwi_to_peer(), SIP_SUBSCRIBE, sipdebug, sip_pvt::stateid, sip_pvt::subscribed, sip_pvt::tag, cfsip_methods::text, transmit_fake_auth_response(), transmit_response(), transmit_response_reliable(), transmit_state_notify(), and XPIDF_XML.

Referenced by handle_request().

14737 {
14738    int gotdest;
14739    int res = 0;
14740    int firststate = AST_EXTENSION_REMOVED;
14741    struct sip_peer *authpeer = NULL;
14742    const char *eventheader = get_header(req, "Event");   /* Get Event package name */
14743    const char *accept = get_header(req, "Accept");
14744    int resubscribe = (p->subscribed != NONE);
14745    char *temp, *event;
14746 
14747    if (p->initreq.headers) {  
14748       /* We already have a dialog */
14749       if (p->initreq.method != SIP_SUBSCRIBE) {
14750          /* This is a SUBSCRIBE within another SIP dialog, which we do not support */
14751          /* For transfers, this could happen, but since we haven't seen it happening, let us just refuse this */
14752          transmit_response(p, "403 Forbidden (within dialog)", req);
14753          /* Do not destroy session, since we will break the call if we do */
14754          if (option_debug)
14755             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);
14756          return 0;
14757       } else if (ast_test_flag(req, SIP_PKT_DEBUG)) {
14758          if (option_debug) {
14759             if (resubscribe)
14760                ast_log(LOG_DEBUG, "Got a re-subscribe on existing subscription %s\n", p->callid);
14761             else
14762                ast_log(LOG_DEBUG, "Got a new subscription %s (possibly with auth)\n", p->callid);
14763          }
14764       }
14765    }
14766 
14767    /* Check if we have a global disallow setting on subscriptions. 
14768       if so, we don't have to check peer/user settings after auth, which saves a lot of processing
14769    */
14770    if (!global_allowsubscribe) {
14771       transmit_response(p, "403 Forbidden (policy)", req);
14772       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
14773       return 0;
14774    }
14775 
14776    if (!ast_test_flag(req, SIP_PKT_IGNORE) && !resubscribe) {  /* Set up dialog, new subscription */
14777       /* Use this as the basis */
14778       if (ast_test_flag(req, SIP_PKT_DEBUG))
14779          ast_verbose("Creating new subscription\n");
14780 
14781       copy_request(&p->initreq, req);
14782       check_via(p, req);
14783    } else if (ast_test_flag(req, SIP_PKT_DEBUG) && ast_test_flag(req, SIP_PKT_IGNORE))
14784       ast_verbose("Ignoring this SUBSCRIBE request\n");
14785 
14786    /* Find parameters to Event: header value and remove them for now */
14787    if (ast_strlen_zero(eventheader)) {
14788       transmit_response(p, "489 Bad Event", req);
14789       if (option_debug > 1)
14790          ast_log(LOG_DEBUG, "Received SIP subscribe for unknown event package: <none>\n");
14791       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
14792       return 0;
14793    }
14794 
14795    if ( (strchr(eventheader, ';'))) {
14796       event = ast_strdupa(eventheader);   /* Since eventheader is a const, we can't change it */
14797       temp = strchr(event, ';');       
14798       *temp = '\0';           /* Remove any options for now */
14799                      /* We might need to use them later :-) */
14800    } else
14801       event = (char *) eventheader;    /* XXX is this legal ? */
14802 
14803    /* Handle authentication */
14804    res = check_user_full(p, req, SIP_SUBSCRIBE, e, 0, sin, &authpeer);
14805    /* if an authentication response was sent, we are done here */
14806    if (res == AUTH_CHALLENGE_SENT) {
14807       if (authpeer)
14808          ASTOBJ_UNREF(authpeer, sip_destroy_peer);
14809       return 0;
14810    }
14811    if (res < 0) {
14812       if (res == AUTH_FAKE_AUTH) {
14813          ast_log(LOG_NOTICE, "Sending fake auth rejection for user %s\n", get_header(req, "From"));
14814          transmit_fake_auth_response(p, req, 1);
14815       } else {
14816          ast_log(LOG_NOTICE, "Failed to authenticate user %s for SUBSCRIBE\n", get_header(req, "From"));
14817          transmit_response_reliable(p, "403 Forbidden", req);
14818       }
14819       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
14820       if (authpeer)
14821          ASTOBJ_UNREF(authpeer, sip_destroy_peer);
14822       return 0;
14823    }
14824 
14825    /* Check if this user/peer is allowed to subscribe at all */
14826    if (!ast_test_flag(&p->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)) {
14827       transmit_response(p, "403 Forbidden (policy)", req);
14828       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
14829       if (authpeer)
14830          ASTOBJ_UNREF(authpeer, sip_destroy_peer);
14831       return 0;
14832    }
14833 
14834    /* Get destination right away */
14835    gotdest = get_destination(p, NULL);
14836 
14837    /* Get full contact header - this needs to be used as a request URI in NOTIFY's */
14838    parse_ok_contact(p, req);
14839 
14840    build_contact(p);
14841    if (gotdest) {
14842       transmit_response(p, "404 Not Found", req);
14843       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
14844       if (authpeer)
14845          ASTOBJ_UNREF(authpeer, sip_destroy_peer);
14846       return 0;
14847    }
14848 
14849    /* Initialize tag for new subscriptions */   
14850    if (ast_strlen_zero(p->tag))
14851       make_our_tag(p->tag, sizeof(p->tag));
14852 
14853    if (!strcmp(event, "presence") || !strcmp(event, "dialog")) { /* Presence, RFC 3842 */
14854       if (authpeer)  /* No need for authpeer here */
14855          ASTOBJ_UNREF(authpeer, sip_destroy_peer);
14856 
14857       /* Header from Xten Eye-beam Accept: multipart/related, application/rlmi+xml, application/pidf+xml, application/xpidf+xml */
14858       /* Polycom phones only handle xpidf+xml, even if they say they can
14859          handle pidf+xml as well
14860       */
14861       if (strstr(p->useragent, "Polycom")) {
14862          p->subscribed = XPIDF_XML;
14863       } else if (strstr(accept, "application/pidf+xml")) {
14864          p->subscribed = PIDF_XML;         /* RFC 3863 format */
14865       } else if (strstr(accept, "application/dialog-info+xml")) {
14866          p->subscribed = DIALOG_INFO_XML;
14867          /* IETF draft: draft-ietf-sipping-dialog-package-05.txt */
14868       } else if (strstr(accept, "application/cpim-pidf+xml")) {
14869          p->subscribed = CPIM_PIDF_XML;    /* RFC 3863 format */
14870       } else if (strstr(accept, "application/xpidf+xml")) {
14871          p->subscribed = XPIDF_XML;        /* Early pre-RFC 3863 format with MSN additions (Microsoft Messenger) */
14872       } else if (ast_strlen_zero(accept)) {
14873          if (p->subscribed == NONE) { /* if the subscribed field is not already set, and there is no accept header... */
14874             transmit_response(p, "489 Bad Event", req);
14875   
14876             ast_log(LOG_WARNING,"SUBSCRIBE failure: no Accept header: pvt: stateid: %d, laststate: %d, dialogver: %d, subscribecont: '%s', subscribeuri: '%s'\n",
14877                p->stateid, p->laststate, p->dialogver, p->subscribecontext, p->subscribeuri);
14878             ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
14879             return 0;
14880          }
14881          /* if p->subscribed is non-zero, then accept is not obligatory; according to rfc 3265 section 3.1.3, at least.
14882             so, we'll just let it ride, keeping the value from a previous subscription, and not abort the subscription */
14883       } else {
14884          /* Can't find a format for events that we know about */
14885          char mybuf[200];
14886          snprintf(mybuf,sizeof(mybuf),"489 Bad Event (format %s)", accept);
14887          transmit_response(p, mybuf, req);
14888  
14889          ast_log(LOG_WARNING,"SUBSCRIBE failure: unrecognized format: '%s' pvt: subscribed: %d, stateid: %d, laststate: %d, dialogver: %d, subscribecont: '%s', subscribeuri: '%s'\n",
14890             accept, (int)p->subscribed, p->stateid, p->laststate, p->dialogver, p->subscribecontext, p->subscribeuri);
14891          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
14892          return 0;
14893       }
14894    } else if (!strcmp(event, "message-summary")) { 
14895       if (!ast_strlen_zero(accept) && strcmp(accept, "application/simple-message-summary")) {
14896          /* Format requested that we do not support */
14897          transmit_response(p, "406 Not Acceptable", req);
14898          if (option_debug > 1)
14899             ast_log(LOG_DEBUG, "Received SIP mailbox subscription for unknown format: %s\n", accept);
14900          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
14901          if (authpeer)  /* No need for authpeer here */
14902             ASTOBJ_UNREF(authpeer, sip_destroy_peer);
14903          return 0;
14904       }
14905       /* Looks like they actually want a mailbox status 
14906         This version of Asterisk supports mailbox subscriptions
14907         The subscribed URI needs to exist in the dial plan
14908         In most devices, this is configurable to the voicemailmain extension you use
14909       */
14910       if (!authpeer || ast_strlen_zero(authpeer->mailbox)) {
14911          transmit_response(p, "404 Not found (no mailbox)", req);
14912          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
14913          ast_log(LOG_NOTICE, "Received SIP subscribe for peer without mailbox: %s\n", authpeer->name);
14914          if (authpeer)  /* No need for authpeer here */
14915             ASTOBJ_UNREF(authpeer, sip_destroy_peer);
14916          return 0;
14917       }
14918 
14919       p->subscribed = MWI_NOTIFICATION;
14920       if (authpeer->mwipvt && authpeer->mwipvt != p)  /* Destroy old PVT if this is a new one */
14921          /* We only allow one subscription per peer */
14922          sip_destroy(authpeer->mwipvt);
14923       authpeer->mwipvt = p;      /* Link from peer to pvt */
14924       p->relatedpeer = authpeer; /* Link from pvt to peer */
14925    } else { /* At this point, Asterisk does not understand the specified event */
14926       transmit_response(p, "489 Bad Event", req);
14927       if (option_debug > 1)
14928          ast_log(LOG_DEBUG, "Received SIP subscribe for unknown event package: %s\n", event);
14929       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
14930       if (authpeer)  /* No need for authpeer here */
14931          ASTOBJ_UNREF(authpeer, sip_destroy_peer);
14932       return 0;
14933    }
14934 
14935    if (p->subscribed != MWI_NOTIFICATION && !resubscribe) {
14936       if (p->stateid > -1)
14937          ast_extension_state_del(p->stateid, cb_extensionstate);
14938       p->stateid = ast_extension_state_add(p->context, p->exten, cb_extensionstate, p);
14939    }
14940 
14941    if (!ast_test_flag(req, SIP_PKT_IGNORE) && p)
14942       p->lastinvite = seqno;
14943    if (p && !ast_test_flag(&p->flags[0], SIP_NEEDDESTROY)) {
14944       p->expiry = atoi(get_header(req, "Expires"));
14945 
14946       /* check if the requested expiry-time is within the approved limits from sip.conf */
14947       if (p->expiry > max_expiry)
14948          p->expiry = max_expiry;
14949       if (p->expiry < min_expiry && p->expiry > 0)
14950          p->expiry = min_expiry;
14951 
14952       if (sipdebug || option_debug > 1) {
14953          if (p->subscribed == MWI_NOTIFICATION && p->relatedpeer)
14954             ast_log(LOG_DEBUG, "Adding subscription for mailbox notification - peer %s Mailbox %s\n", p->relatedpeer->name, p->relatedpeer->mailbox);
14955          else
14956             ast_log(LOG_DEBUG, "Adding subscription for extension %s context %s for peer %s\n", p->exten, p->context, p->username);
14957       }
14958       if (p->autokillid > -1)
14959          sip_cancel_destroy(p);  /* Remove subscription expiry for renewals */
14960       if (p->expiry > 0)
14961          sip_scheddestroy(p, (p->expiry + 10) * 1000);   /* Set timer for destruction of call at expiration */
14962 
14963       if (p->subscribed == MWI_NOTIFICATION) {
14964          transmit_response(p, "200 OK", req);
14965          if (p->relatedpeer) {   /* Send first notification */
14966             ASTOBJ_WRLOCK(p->relatedpeer);
14967             sip_send_mwi_to_peer(p->relatedpeer);
14968             ASTOBJ_UNLOCK(p->relatedpeer);
14969          }
14970       } else {
14971          struct sip_pvt *p_old;
14972 
14973          if ((firststate = ast_extension_state(NULL, p->context, p->exten)) < 0) {
14974 
14975             ast_log(LOG_NOTICE, "Got SUBSCRIBE for extension %s@%s from %s, but there is no hint for that extension.\n", p->exten, p->context, ast_inet_ntoa(p->sa.sin_addr));
14976             transmit_response(p, "404 Not found", req);
14977             ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
14978             return 0;
14979          }
14980 
14981          transmit_response(p, "200 OK", req);
14982          transmit_state_notify(p, firststate, 1, FALSE); /* Send first notification */
14983          append_history(p, "Subscribestatus", "%s", ast_extension_state2str(firststate));
14984          /* hide the 'complete' exten/context in the refer_to field for later display */
14985          ast_string_field_build(p, subscribeuri, "%s@%s", p->exten, p->context);
14986 
14987          /* remove any old subscription from this peer for the same exten/context,
14988          as the peer has obviously forgotten about it and it's wasteful to wait
14989          for it to expire and send NOTIFY messages to the peer only to have them
14990          ignored (or generate errors)
14991          */
14992          ast_mutex_lock(&iflock);
14993          for (p_old = iflist; p_old; p_old = p_old->next) {
14994             if (p_old == p)
14995                continue;
14996             if (p_old->initreq.method != SIP_SUBSCRIBE)
14997                continue;
14998             if (p_old->subscribed == NONE)
14999                continue;
15000             ast_mutex_lock(&p_old->lock);
15001             if (!strcmp(p_old->username, p->username)) {
15002                if (!strcmp(p_old->exten, p->exten) &&
15003                    !strcmp(p_old->context, p->context)) {
15004                   ast_set_flag(&p_old->flags[0], SIP_NEEDDESTROY);
15005                   ast_mutex_unlock(&p_old->lock);
15006                   break;
15007                }
15008             }
15009             ast_mutex_unlock(&p_old->lock);
15010          }
15011          ast_mutex_unlock(&iflock);
15012       }
15013       if (!p->expiry)
15014          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
15015    }
15016    return 1;
15017 }

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

Handle SIP response in dialogue.

Definition at line 12555 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_set_flag, ast_string_field_build, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_verbose(), sip_pvt::authtries, do_proxy_auth(), FALSE, find_sdp(), find_sip_method(), sip_pvt::flags, get_header(), gettag(), handle_response_invite(), handle_response_peerpoke(), handle_response_refer(), handle_response_register(), hangup_sip2cause(), ast_channel::hangupcause, sip_pvt::initreq, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, MAX_AUTHTRIES, sip_pvt::method, NONE, option_debug, option_verbose, sip_pvt::owner, parse_moved_contact(), process_sdp(), sip_pvt::recv, sip_pvt::refer, sip_pvt::registry, sip_pvt::relatedpeer, sip_pvt::sa, SIP_ACK, sip_alreadygone(), SIP_BYE, SIP_CANCEL, sip_cancel_destroy(), SIP_INFO, SIP_INVITE, SIP_MESSAGE, sip_methods, SIP_NEEDDESTROY, SIP_NOTIFY, SIP_OPTIONS, SIP_OUTGOING, SIP_PKT_DEBUG, SIP_PKT_IGNORE, SIP_REFER, SIP_REGISTER, sipdebug, stop_media_flows(), sip_pvt::subscribed, text, transmit_request(), VERBOSE_PREFIX_3, and XMIT_UNRELIABLE.

12556 {
12557    struct ast_channel *owner;
12558    int sipmethod;
12559    int res = 1;
12560    const char *c = get_header(req, "Cseq");
12561    const char *msg = strchr(c, ' ');
12562 
12563    if (!msg)
12564       msg = "";
12565    else
12566       msg++;
12567    sipmethod = find_sip_method(msg);
12568 
12569    owner = p->owner;
12570    if (owner) 
12571       owner->hangupcause = hangup_sip2cause(resp);
12572 
12573    /* Acknowledge whatever it is destined for */
12574    if ((resp >= 100) && (resp <= 199))
12575       __sip_semi_ack(p, seqno, 0, sipmethod);
12576    else
12577       __sip_ack(p, seqno, 0, sipmethod);
12578 
12579    /* Get their tag if we haven't already */
12580    if (ast_strlen_zero(p->theirtag) || (resp >= 200)) {
12581       char tag[128];
12582 
12583       gettag(req, "To", tag, sizeof(tag));
12584       ast_string_field_set(p, theirtag, tag);
12585    }
12586    if (p->relatedpeer && p->method == SIP_OPTIONS) {
12587       /* We don't really care what the response is, just that it replied back. 
12588          Well, as long as it's not a 100 response...  since we might
12589          need to hang around for something more "definitive" */
12590       if (resp != 100)
12591          handle_response_peerpoke(p, resp, req);
12592    } else if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
12593       switch(resp) {
12594       case 100:   /* 100 Trying */
12595       case 101:   /* 101 Dialog establishment */
12596          if (sipmethod == SIP_INVITE) 
12597             handle_response_invite(p, resp, rest, req, seqno);
12598          break;
12599       case 183:   /* 183 Session Progress */
12600          if (sipmethod == SIP_INVITE) 
12601             handle_response_invite(p, resp, rest, req, seqno);
12602          break;
12603       case 180:   /* 180 Ringing */
12604          if (sipmethod == SIP_INVITE) 
12605             handle_response_invite(p, resp, rest, req, seqno);
12606          break;
12607       case 182:       /* 182 Queued */
12608          if (sipmethod == SIP_INVITE)
12609             handle_response_invite(p, resp, rest, req, seqno);
12610          break;
12611       case 200:   /* 200 OK */
12612          p->authtries = 0; /* Reset authentication counter */
12613          if (sipmethod == SIP_MESSAGE || sipmethod == SIP_INFO) {
12614             /* We successfully transmitted a message 
12615                or a video update request in INFO */
12616             /* Nothing happens here - the message is inside a dialog */
12617          } else if (sipmethod == SIP_INVITE) {
12618             handle_response_invite(p, resp, rest, req, seqno);
12619          } else if (sipmethod == SIP_NOTIFY) {
12620             /* They got the notify, this is the end */
12621             if (p->owner) {
12622                if (!p->refer) {
12623                   ast_log(LOG_WARNING, "Notify answer on an owned channel? - %s\n", p->owner->name);
12624                   ast_queue_hangup(p->owner);
12625                } else if (option_debug > 3) 
12626                   ast_log(LOG_DEBUG, "Got OK on REFER Notify message\n");
12627             } else {
12628                if (p->subscribed == NONE) 
12629                   ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12630             }
12631          } else if (sipmethod == SIP_REGISTER) 
12632             res = handle_response_register(p, resp, rest, req, ignore, seqno);
12633          else if (sipmethod == SIP_BYE)      /* Ok, we're ready to go */
12634             ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12635          break;
12636       case 202:   /* Transfer accepted */
12637          if (sipmethod == SIP_REFER) 
12638             handle_response_refer(p, resp, rest, req, seqno);
12639          break;
12640       case 401: /* Not www-authorized on SIP method */
12641          if (sipmethod == SIP_INVITE)
12642             handle_response_invite(p, resp, rest, req, seqno);
12643          else if (sipmethod == SIP_REFER)
12644             handle_response_refer(p, resp, rest, req, seqno);
12645          else if (p->registry && sipmethod == SIP_REGISTER)
12646             res = handle_response_register(p, resp, rest, req, ignore, seqno);
12647          else if (sipmethod == SIP_BYE) {
12648             if (ast_strlen_zero(p->authname)) {
12649                ast_log(LOG_WARNING, "Asked to authenticate %s, to %s:%d but we have no matching peer!\n",
12650                      msg, ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port));
12651                ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12652             } else if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, "WWW-Authenticate", "Authorization", sipmethod, 0)) {
12653                ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From"));
12654                ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12655                /* We fail to auth bye on our own call, but still needs to tear down the call. 
12656                   Life, they call it. */
12657             }
12658          } else {
12659             ast_log(LOG_WARNING, "Got authentication request (401) on unknown %s to '%s'\n", sip_methods[sipmethod].text, get_header(req, "To"));
12660             ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12661          }
12662          break;
12663       case 403: /* Forbidden - we failed authentication */
12664          if (sipmethod == SIP_INVITE)
12665             handle_response_invite(p, resp, rest, req, seqno);
12666          else if (p->registry && sipmethod == SIP_REGISTER) 
12667             res = handle_response_register(p, resp, rest, req, ignore, seqno);
12668          else {
12669             ast_log(LOG_WARNING, "Forbidden - maybe wrong password on authentication for %s\n", msg);
12670             ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12671          }
12672          break;
12673       case 404: /* Not found */
12674          if (p->registry && sipmethod == SIP_REGISTER)
12675             res = handle_response_register(p, resp, rest, req, ignore, seqno);
12676          else if (sipmethod == SIP_INVITE)
12677             handle_response_invite(p, resp, rest, req, seqno);
12678          else if (owner)
12679             ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
12680          break;
12681       case 407: /* Proxy auth required */
12682          if (sipmethod == SIP_INVITE)
12683             handle_response_invite(p, resp, rest, req, seqno);
12684          else if (sipmethod == SIP_REFER)
12685             handle_response_refer(p, resp, rest, req, seqno);
12686          else if (p->registry && sipmethod == SIP_REGISTER)
12687             res = handle_response_register(p, resp, rest, req, ignore, seqno);
12688          else if (sipmethod == SIP_BYE) {
12689             if (ast_strlen_zero(p->authname)) {
12690                ast_log(LOG_WARNING, "Asked to authenticate %s, to %s:%d but we have no matching peer!\n",
12691                      msg, ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port));
12692                ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12693             } else if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, "Proxy-Authenticate", "Proxy-Authorization", sipmethod, 0)) {
12694                ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From"));
12695                ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12696             }
12697          } else   /* We can't handle this, giving up in a bad way */
12698             ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12699 
12700          break;
12701       case 408: /* Request timeout - terminate dialog */
12702          if (sipmethod == SIP_INVITE)
12703             handle_response_invite(p, resp, rest, req, seqno);
12704          else if (sipmethod == SIP_REGISTER) 
12705             res = handle_response_register(p, resp, rest, req, ignore, seqno);
12706          else if (sipmethod == SIP_BYE) {
12707             ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12708             if (option_debug)
12709                ast_log(LOG_DEBUG, "Got timeout on bye. Thanks for the answer. Now, kill this call\n");
12710          } else {
12711             if (owner)
12712                ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
12713             ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12714          }
12715          break;
12716       case 481: /* Call leg does not exist */
12717          if (sipmethod == SIP_INVITE) {
12718             handle_response_invite(p, resp, rest, req, seqno);
12719          } else if (sipmethod == SIP_REFER) {
12720             handle_response_refer(p, resp, rest, req, seqno);
12721          } else if (sipmethod == SIP_BYE) {
12722             /* The other side has no transaction to bye,
12723             just assume it's all right then */
12724             ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid);
12725          } else if (sipmethod == SIP_CANCEL) {
12726             /* The other side has no transaction to cancel,
12727             just assume it's all right then */
12728             ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid);
12729          } else {
12730             ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid);
12731             /* Guessing that this is not an important request */
12732          }
12733          break;
12734       case 487:
12735          if (sipmethod == SIP_INVITE)
12736             handle_response_invite(p, resp, rest, req, seqno);
12737          break;
12738       case 488: /* Not acceptable here - codec error */
12739          if (sipmethod == SIP_INVITE)
12740             handle_response_invite(p, resp, rest, req, seqno);
12741          break;
12742       case 491: /* Pending */
12743          if (sipmethod == SIP_INVITE)
12744             handle_response_invite(p, resp, rest, req, seqno);
12745          else {
12746             if (option_debug)
12747                ast_log(LOG_DEBUG, "Got 491 on %s, unspported. Call ID %s\n", sip_methods[sipmethod].text, p->callid);
12748             ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12749          }
12750          break;
12751       case 501: /* Not Implemented */
12752          if (sipmethod == SIP_INVITE)
12753             handle_response_invite(p, resp, rest, req, seqno);
12754          else if (sipmethod == SIP_REFER)
12755             handle_response_refer(p, resp, rest, req, seqno);
12756          else
12757             ast_log(LOG_WARNING, "Host '%s' does not implement '%s'\n", ast_inet_ntoa(p->sa.sin_addr), msg);
12758          break;
12759       case 603:   /* Declined transfer */
12760          if (sipmethod == SIP_REFER) {
12761             handle_response_refer(p, resp, rest, req, seqno);
12762             break;
12763          }
12764          /* Fallthrough */
12765       default:
12766          if ((resp >= 300) && (resp < 700)) {
12767             /* Fatal response */
12768             if ((option_verbose > 2) && (resp != 487))
12769                ast_verbose(VERBOSE_PREFIX_3 "Got SIP response %d \"%s\" back from %s\n", resp, rest, ast_inet_ntoa(p->sa.sin_addr));
12770    
12771             if (sipmethod == SIP_INVITE)
12772                stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */
12773 
12774             /* XXX Locking issues?? XXX */
12775             switch(resp) {
12776             case 300: /* Multiple Choices */
12777             case 301: /* Moved permenantly */
12778             case 302: /* Moved temporarily */
12779             case 305: /* Use Proxy */
12780                parse_moved_contact(p, req);
12781                /* Fall through */
12782             case 486: /* Busy here */
12783             case 600: /* Busy everywhere */
12784             case 603: /* Decline */
12785                if (p->owner)
12786                   ast_queue_control(p->owner, AST_CONTROL_BUSY);
12787                break;
12788             case 482: /*
12789                \note SIP is incapable of performing a hairpin call, which
12790                is yet another failure of not having a layer 2 (again, YAY
12791                 IETF for thinking ahead).  So we treat this as a call
12792                 forward and hope we end up at the right place... */
12793                if (option_debug)
12794                   ast_log(LOG_DEBUG, "Hairpin detected, setting up call forward for what it's worth\n");
12795                if (p->owner)
12796                   ast_string_field_build(p->owner, call_forward,
12797                                "Local/%s@%s", p->username, p->context);
12798                /* Fall through */
12799             case 480: /* Temporarily Unavailable */
12800             case 404: /* Not Found */
12801             case 410: /* Gone */
12802             case 400: /* Bad Request */
12803             case 500: /* Server error */
12804                if (sipmethod == SIP_REFER) {
12805                   handle_response_refer(p, resp, rest, req, seqno);
12806                   break;
12807                }
12808                /* Fall through */
12809             case 503: /* Service Unavailable */
12810             case 504: /* Server Timeout */
12811                if (owner)
12812                   ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
12813                break;
12814             default:
12815                /* Send hangup */ 
12816                if (owner && sipmethod != SIP_MESSAGE && sipmethod != SIP_INFO && sipmethod != SIP_BYE)
12817                   ast_queue_hangup(p->owner);
12818                break;
12819             }
12820             /* ACK on invite */
12821             if (sipmethod == SIP_INVITE) 
12822                transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
12823             if (sipmethod != SIP_MESSAGE && sipmethod != SIP_INFO) 
12824                sip_alreadygone(p);
12825             if (!p->owner)
12826                ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12827          } else if ((resp >= 100) && (resp < 200)) {
12828             if (sipmethod == SIP_INVITE) {
12829                if (!ast_test_flag(req, SIP_PKT_IGNORE))
12830                   sip_cancel_destroy(p);
12831                if (find_sdp(req))
12832                   process_sdp(p, req);
12833                if (p->owner) {
12834                   /* Queue a progress frame */
12835                   ast_queue_control(p->owner, AST_CONTROL_PROGRESS);
12836                }
12837             }
12838          } else
12839             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(p->sa.sin_addr));
12840       }
12841    } else { 
12842       /* Responses to OUTGOING SIP requests on INCOMING calls 
12843          get handled here. As well as out-of-call message responses */
12844       if (ast_test_flag(req, SIP_PKT_DEBUG))
12845          ast_verbose("SIP Response message for INCOMING dialog %s arrived\n", msg);
12846 
12847       if (sipmethod == SIP_INVITE && resp == 200) {
12848          /* Tags in early session is replaced by the tag in 200 OK, which is 
12849          the final reply to our INVITE */
12850          char tag[128];
12851 
12852          gettag(req, "To", tag, sizeof(tag));
12853          ast_string_field_set(p, theirtag, tag);
12854       }
12855 
12856       switch(resp) {
12857       case 200:
12858          if (sipmethod == SIP_INVITE) {
12859             handle_response_invite(p, resp, rest, req, seqno);
12860          } else if (sipmethod == SIP_CANCEL) {
12861             if (option_debug)
12862                ast_log(LOG_DEBUG, "Got 200 OK on CANCEL\n");
12863 
12864             /* Wait for 487, then destroy */
12865          } else if (sipmethod == SIP_NOTIFY) {
12866             /* They got the notify, this is the end */
12867             if (p->owner) {
12868                if (p->refer) {
12869                   if (option_debug)
12870                      ast_log(LOG_DEBUG, "Got 200 OK on NOTIFY for transfer\n");
12871                } else
12872                   ast_log(LOG_WARNING, "Notify answer on an owned channel?\n");
12873                /* ast_queue_hangup(p->owner); Disabled */
12874             } else {
12875                if (!p->subscribed && !p->refer)
12876                   ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12877             }
12878          } else if (sipmethod == SIP_BYE)
12879             ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12880          else if (sipmethod == SIP_MESSAGE || sipmethod == SIP_INFO)
12881             /* We successfully transmitted a message or
12882                a video update request in INFO */
12883             ;
12884          else if (sipmethod == SIP_BYE) 
12885             /* Ok, we're ready to go */
12886             ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12887          break;
12888       case 202:   /* Transfer accepted */
12889          if (sipmethod == SIP_REFER) 
12890             handle_response_refer(p, resp, rest, req, seqno);
12891          break;
12892       case 401:   /* www-auth */
12893       case 407:
12894          if (sipmethod == SIP_REFER)
12895             handle_response_refer(p, resp, rest, req, seqno);
12896          else if (sipmethod == SIP_INVITE) 
12897             handle_response_invite(p, resp, rest, req, seqno);
12898          else if (sipmethod == SIP_BYE) {
12899             char *auth, *auth2;
12900 
12901             auth = (resp == 407 ? "Proxy-Authenticate" : "WWW-Authenticate");
12902             auth2 = (resp == 407 ? "Proxy-Authorization" : "Authorization");
12903             if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, auth, auth2, sipmethod, 0)) {
12904                ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From"));
12905                ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12906             }
12907          }
12908          break;
12909       case 481:   /* Call leg does not exist */
12910          if (sipmethod == SIP_INVITE) {
12911             /* Re-invite failed */
12912             handle_response_invite(p, resp, rest, req, seqno);
12913          } else if (sipmethod == SIP_BYE) {
12914             ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12915          } else if (sipdebug) {
12916             ast_log  (LOG_DEBUG, "Remote host can't match request %s to call '%s'. Giving up\n", sip_methods[sipmethod].text, p->callid);
12917          }
12918          break;
12919       case 501: /* Not Implemented */
12920          if (sipmethod == SIP_INVITE) 
12921             handle_response_invite(p, resp, rest, req, seqno);
12922          else if (sipmethod == SIP_REFER) 
12923             handle_response_refer(p, resp, rest, req, seqno);
12924          break;
12925       case 603:   /* Declined transfer */
12926          if (sipmethod == SIP_REFER) {
12927             handle_response_refer(p, resp, rest, req, seqno);
12928             break;
12929          }
12930          /* Fallthrough */
12931       default: /* Errors without handlers */
12932          if ((resp >= 100) && (resp < 200)) {
12933             if (sipmethod == SIP_INVITE) {   /* re-invite */
12934                if (!ast_test_flag(req, SIP_PKT_IGNORE))
12935                   sip_cancel_destroy(p);
12936             }
12937          }
12938          if ((resp >= 300) && (resp < 700)) {
12939             if ((option_verbose > 2) && (resp != 487))
12940                ast_verbose(VERBOSE_PREFIX_3 "Incoming call: Got SIP response %d \"%s\" back from %s\n", resp, rest, ast_inet_ntoa(p->sa.sin_addr));
12941             switch(resp) {
12942             case 488: /* Not acceptable here - codec error */
12943             case 603: /* Decline */
12944             case 500: /* Server error */
12945             case 503: /* Service Unavailable */
12946             case 504: /* Server timeout */
12947 
12948                if (sipmethod == SIP_INVITE) {   /* re-invite failed */
12949                   sip_cancel_destroy(p);
12950                }
12951                break;
12952             }
12953          }
12954          break;
12955       }
12956    }
12957 }

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

Handle SIP response to INVITE dialogue.

Bug:
Is there any way we can go back to the audio call on both sides here?

Definition at line 11968 of file chan_sip.c.

References ast_channel::_state, append_history, ast_bridged_channel(), AST_CONTROL_ANSWER, AST_CONTROL_CONGESTION, AST_CONTROL_PROGRESS, AST_CONTROL_RINGING, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_null_frame, ast_queue_control(), ast_queue_frame(), ast_queue_hangup(), ast_random(), ast_rtp_set_rtptimers_onhold(), ast_sched_add(), ast_sched_del(), ast_set_flag, ast_setstate(), AST_STATE_RINGING, AST_STATE_UP, ast_string_field_free, ast_test_flag, sip_invite_param::auth_type, authenticate(), sip_pvt::authtries, build_route(), check_pendings(), DEC_CALL_LIMIT, DEC_CALL_RINGING, DEFAULT_TRANS_TIMEOUT, do_proxy_auth(), FALSE, find_sdp(), sip_pvt::flags, get_header(), sip_pvt::initid, sip_pvt::initreq, INV_CALLING, INV_COMPLETED, INV_EARLY_MEDIA, INV_PROCEEDING, INV_TERMINATED, sip_pvt::invitestate, sip_pvt::lock, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, LOG_WARNING, MAX_AUTHTRIES, option_debug, sip_pvt::options, sip_pvt::owner, parse_ok_contact(), process_sdp(), PROXY_AUTH, sip_pvt::rtp, set_address_from_contact(), SIP_ACK, sip_alreadygone(), SIP_ALREADYGONE, sip_cancel_destroy(), sip_handle_t38_reinvite(), SIP_INVITE, SIP_NEEDDESTROY, SIP_OUTGOING, SIP_PENDINGBYE, SIP_PKT_IGNORE, sip_reinvite_retry(), sip_scheddestroy(), sip_tech, sip_tech_info, t38properties::state, sip_pvt::t38, T38_DISABLED, T38_ENABLED, T38_LOCAL_DIRECT, T38_LOCAL_REINVITE, T38_PEER_REINVITE, ast_channel::tech, ast_channel::tech_pvt, transmit_request(), TRUE, ast_channel_tech::type, sip_pvt::udptl, update_call_counter(), sip_pvt::vrtp, sip_pvt::waitid, WWW_AUTH, XMIT_ERROR, and XMIT_UNRELIABLE.

Referenced by handle_response().

11969 {
11970    int outgoing = ast_test_flag(&p->flags[0], SIP_OUTGOING);
11971    int res = 0;
11972    int xmitres = 0;
11973    int reinvite = (p->owner && p->owner->_state == AST_STATE_UP);
11974    struct ast_channel *bridgepeer = NULL;
11975    
11976    if (option_debug > 3) {
11977       if (reinvite)
11978          ast_log(LOG_DEBUG, "SIP response %d to RE-invite on %s call %s\n", resp, outgoing ? "outgoing" : "incoming", p->callid);
11979       else
11980          ast_log(LOG_DEBUG, "SIP response %d to standard invite\n", resp);
11981    }
11982 
11983    if (ast_test_flag(&p->flags[0], SIP_ALREADYGONE)) { /* This call is already gone */
11984       if (option_debug)
11985          ast_log(LOG_DEBUG, "Got response on call that is already terminated: %s (ignoring)\n", p->callid);
11986       return;
11987    }
11988 
11989    /* Acknowledge sequence number - This only happens on INVITE from SIP-call */
11990    if (p->initid > -1) {
11991       /* Don't auto congest anymore since we've gotten something useful back */
11992       ast_sched_del(sched, p->initid);
11993       p->initid = -1;
11994    }
11995 
11996    /* RFC3261 says we must treat every 1xx response (but not 100)
11997       that we don't recognize as if it was 183.
11998    */
11999    if (resp > 100 && resp < 200 && resp!=101 && resp != 180 && resp != 182 && resp != 183)
12000       resp = 183;
12001 
12002    /* Any response between 100 and 199 is PROCEEDING */
12003    if (resp >= 100 && resp < 200 && p->invitestate == INV_CALLING)
12004       p->invitestate = INV_PROCEEDING;
12005  
12006    /* Final response, not 200 ? */
12007    if (resp >= 300 && (p->invitestate == INV_CALLING || p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA ))
12008       p->invitestate = INV_COMPLETED;
12009       
12010 
12011    switch (resp) {
12012    case 100:   /* Trying */
12013    case 101:   /* Dialog establishment */
12014       if (!ast_test_flag(req, SIP_PKT_IGNORE))
12015          sip_cancel_destroy(p);
12016       check_pendings(p);
12017       break;
12018 
12019    case 180:   /* 180 Ringing */
12020    case 182:       /* 182 Queued */
12021       if (!ast_test_flag(req, SIP_PKT_IGNORE))
12022          sip_cancel_destroy(p);
12023       if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) {
12024          ast_queue_control(p->owner, AST_CONTROL_RINGING);
12025          if (p->owner->_state != AST_STATE_UP) {
12026             ast_setstate(p->owner, AST_STATE_RINGING);
12027          }
12028       }
12029       if (find_sdp(req)) {
12030          p->invitestate = INV_EARLY_MEDIA;
12031          res = process_sdp(p, req);
12032          if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) {
12033             /* Queue a progress frame only if we have SDP in 180 or 182 */
12034             ast_queue_control(p->owner, AST_CONTROL_PROGRESS);
12035          }
12036       }
12037       check_pendings(p);
12038       break;
12039 
12040    case 183:   /* Session progress */
12041       if (!ast_test_flag(req, SIP_PKT_IGNORE))
12042          sip_cancel_destroy(p);
12043       /* Ignore 183 Session progress without SDP */
12044       if (find_sdp(req)) {
12045          p->invitestate = INV_EARLY_MEDIA;
12046          res = process_sdp(p, req);
12047          if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) {
12048             /* Queue a progress frame */
12049             ast_queue_control(p->owner, AST_CONTROL_PROGRESS);
12050          }
12051       }
12052       check_pendings(p);
12053       break;
12054 
12055    case 200:   /* 200 OK on invite - someone's answering our call */
12056       if (!ast_test_flag(req, SIP_PKT_IGNORE))
12057          sip_cancel_destroy(p);
12058       p->authtries = 0;
12059       if (find_sdp(req)) {
12060          if ((res = process_sdp(p, req)) && !ast_test_flag(req, SIP_PKT_IGNORE))
12061             if (!reinvite)
12062                /* This 200 OK's SDP is not acceptable, so we need to ack, then hangup */
12063                /* For re-invites, we try to recover */
12064                ast_set_flag(&p->flags[0], SIP_PENDINGBYE);  
12065       }
12066 
12067       /* Parse contact header for continued conversation */
12068       /* When we get 200 OK, we know which device (and IP) to contact for this call */
12069       /* This is important when we have a SIP proxy between us and the phone */
12070       if (outgoing) {
12071          update_call_counter(p, DEC_CALL_RINGING);
12072          parse_ok_contact(p, req);
12073          if(set_address_from_contact(p)) {
12074             /* Bad contact - we don't know how to reach this device */
12075             /* We need to ACK, but then send a bye */
12076             /* OEJ: Possible issue that may need a check:
12077                If we have a proxy route between us and the device,
12078                should we care about resolving the contact
12079                or should we just send it?
12080             */
12081             if (!ast_test_flag(req, SIP_PKT_IGNORE))
12082                ast_set_flag(&p->flags[0], SIP_PENDINGBYE);  
12083          } 
12084 
12085          /* Save Record-Route for any later requests we make on this dialogue */
12086          build_route(p, req, 1);
12087       }
12088       
12089       if (p->owner && (p->owner->_state == AST_STATE_UP) && (bridgepeer = ast_bridged_channel(p->owner))) { /* if this is a re-invite */
12090          struct sip_pvt *bridgepvt = NULL;
12091 
12092          if (!bridgepeer->tech) {
12093             ast_log(LOG_WARNING, "Ooooh.. no tech!  That's REALLY bad\n");
12094             break;
12095          }
12096          if (bridgepeer->tech == &sip_tech || bridgepeer->tech == &sip_tech_info) {
12097             bridgepvt = (struct sip_pvt*)(bridgepeer->tech_pvt);
12098             if (bridgepvt->udptl) {
12099                if (p->t38.state == T38_PEER_REINVITE) {
12100                   sip_handle_t38_reinvite(bridgepeer, p, 0);
12101                   ast_rtp_set_rtptimers_onhold(p->rtp);
12102                   if (p->vrtp)
12103                      ast_rtp_set_rtptimers_onhold(p->vrtp); /* Turn off RTP timers while we send fax */
12104                } else if (p->t38.state == T38_DISABLED && bridgepeer && (bridgepvt->t38.state == T38_ENABLED)) {
12105                   ast_log(LOG_WARNING, "RTP re-invite after T38 session not handled yet !\n");
12106                   /* Insted of this we should somehow re-invite the other side of the bridge to RTP */
12107                   /* XXXX Should we really destroy this session here, without any response at all??? */
12108                   sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
12109                }
12110             } else {
12111                if (option_debug > 1)
12112                   ast_log(LOG_DEBUG, "Strange... The other side of the bridge does not have a udptl struct\n");
12113                ast_mutex_lock(&bridgepvt->lock);
12114                bridgepvt->t38.state = T38_DISABLED;
12115                ast_mutex_unlock(&bridgepvt->lock);
12116                if (option_debug)
12117                   ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", bridgepvt->t38.state, bridgepeer->tech->type);
12118                p->t38.state = T38_DISABLED;
12119                if (option_debug > 1)
12120                   ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>");
12121             }
12122          } else {
12123             /* Other side is not a SIP channel */
12124             if (option_debug > 1)
12125                ast_log(LOG_DEBUG, "Strange... The other side of the bridge is not a SIP channel\n");
12126             p->t38.state = T38_DISABLED;
12127             if (option_debug > 1)
12128                ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>");
12129          }
12130       }
12131       if ((p->t38.state == T38_LOCAL_REINVITE) || (p->t38.state == T38_LOCAL_DIRECT)) {
12132          /* If there was T38 reinvite and we are supposed to answer with 200 OK than this should set us to T38 negotiated mode */
12133          p->t38.state = T38_ENABLED;
12134          if (option_debug)
12135             ast_log(LOG_DEBUG, "T38 changed state to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>");
12136       }
12137 
12138       if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) {
12139          if (!reinvite) {
12140             ast_queue_control(p->owner, AST_CONTROL_ANSWER);
12141          } else { /* RE-invite */
12142             ast_queue_frame(p->owner, &ast_null_frame);
12143          }
12144       } else {
12145           /* It's possible we're getting an 200 OK after we've tried to disconnect
12146               by sending CANCEL */
12147          /* First send ACK, then send bye */
12148          if (!ast_test_flag(req, SIP_PKT_IGNORE))
12149             ast_set_flag(&p->flags[0], SIP_PENDINGBYE);  
12150       }
12151       /* If I understand this right, the branch is different for a non-200 ACK only */
12152       p->invitestate = INV_TERMINATED;
12153       xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, TRUE);
12154       check_pendings(p);
12155       break;
12156    case 407: /* Proxy authentication */
12157    case 401: /* Www auth */
12158       /* First we ACK */
12159       xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
12160       if (p->options)
12161          p->options->auth_type = (resp == 401 ? WWW_AUTH : PROXY_AUTH);
12162 
12163       /* Then we AUTH */
12164       ast_string_field_free(p, theirtag); /* forget their old tag, so we don't match tags when getting response */
12165       if (!ast_test_flag(req, SIP_PKT_IGNORE)) {
12166          char *authenticate = (resp == 401 ? "WWW-Authenticate" : "Proxy-Authenticate");
12167          char *authorization = (resp == 401 ? "Authorization" : "Proxy-Authorization");
12168          if (p->authtries < MAX_AUTHTRIES)
12169             p->invitestate = INV_CALLING;
12170          if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, authenticate, authorization, SIP_INVITE, 1)) {
12171             ast_log(LOG_NOTICE, "Failed to authenticate on INVITE to '%s'\n", get_header(&p->initreq, "From"));
12172             ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12173             sip_alreadygone(p);
12174             if (p->owner)
12175                ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
12176          }
12177       }
12178       break;
12179 
12180    case 403: /* Forbidden */
12181       /* First we ACK */
12182       xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
12183       ast_log(LOG_WARNING, "Received response: \"Forbidden\" from '%s'\n", get_header(&p->initreq, "From"));
12184       if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner)
12185          ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
12186       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12187       sip_alreadygone(p);
12188       break;
12189 
12190    case 404: /* Not found */
12191       xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
12192       if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE))
12193          ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
12194       sip_alreadygone(p);
12195       break;
12196 
12197    case 408: /* Request timeout */
12198    case 481: /* Call leg does not exist */
12199       /* Could be REFER caused INVITE with replaces */
12200       ast_log(LOG_WARNING, "Re-invite to non-existing call leg on other UA. SIP dialog '%s'. Giving up.\n", p->callid);
12201       xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
12202       if (p->owner)
12203          ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
12204       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
12205       break;
12206    case 487: /* Cancelled transaction */
12207       /* We have sent CANCEL on an outbound INVITE 
12208          This transaction is already scheduled to be killed by sip_hangup().
12209       */
12210       xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
12211       if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) {
12212          ast_queue_hangup(p->owner);
12213          append_history(p, "Hangup", "Got 487 on CANCEL request from us. Queued AST hangup request");
12214       } else if (!ast_test_flag(req, SIP_PKT_IGNORE)) {
12215          update_call_counter(p, DEC_CALL_LIMIT);
12216          append_history(p, "Hangup", "Got 487 on CANCEL request from us on call without owner. Killing this dialog.");
12217          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12218          sip_alreadygone(p);
12219       }
12220       break;
12221    case 488: /* Not acceptable here */
12222       xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
12223       if (reinvite && p->udptl) {
12224          /* If this is a T.38 call, we should go back to 
12225             audio. If this is an audio call - something went
12226             terribly wrong since we don't renegotiate codecs,
12227             only IP/port .
12228          */
12229          p->t38.state = T38_DISABLED;
12230          /* Try to reset RTP timers */
12231          ast_rtp_set_rtptimers_onhold(p->rtp);
12232          ast_log(LOG_ERROR, "Got error on T.38 re-invite. Bad configuration. Peer needs to have T.38 disabled.\n");
12233 
12234          /*! \bug Is there any way we can go back to the audio call on both
12235             sides here? 
12236          */
12237          /* While figuring that out, hangup the call */
12238          if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE))
12239             ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
12240          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12241       } else if (p->udptl && p->t38.state == T38_LOCAL_DIRECT) {
12242          /* We tried to send T.38 out in an initial INVITE and the remote side rejected it,
12243             right now we can't fall back to audio so totally abort.
12244          */
12245          p->t38.state = T38_DISABLED;
12246          /* Try to reset RTP timers */
12247          ast_rtp_set_rtptimers_onhold(p->rtp);
12248          ast_log(LOG_ERROR, "Got error on T.38 initial invite. Bailing out.\n");
12249 
12250          /* The dialog is now terminated */
12251          if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE))
12252             ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
12253          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
12254          sip_alreadygone(p);
12255       } else {
12256          /* We can't set up this call, so give up */
12257          if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE))
12258             ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
12259          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12260       }
12261       break;
12262    case 491: /* Pending */
12263       /* we really should have to wait a while, then retransmit */
12264          /* We should support the retry-after at some point */
12265       /* At this point, we treat this as a congestion */
12266       xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
12267       if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) {
12268          if (p->owner->_state != AST_STATE_UP) {
12269             ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
12270             ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12271          } else {
12272             /* This is a re-invite that failed. */
12273             /* Reset the flag after a while 
12274              */
12275             int wait = 3 + ast_random() % 5;
12276             p->waitid = ast_sched_add(sched, wait, sip_reinvite_retry, p); 
12277             if (option_debug > 2)
12278                ast_log(LOG_DEBUG, "Reinvite race. Waiting %d secs before retry\n", wait);
12279          }
12280       }
12281       break;
12282 
12283    case 501: /* Not implemented */
12284       xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
12285       if (p->owner)
12286          ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
12287       break;
12288    }
12289    if (xmitres == XMIT_ERROR)
12290       ast_log(LOG_WARNING, "Could not transmit message in dialog %s\n", p->callid);
12291 }

static void handle_response_peerpoke ( struct sip_pvt p,
int  resp,
struct sip_request req 
) [static]

Handle qualification responses (OPTIONS).

Definition at line 12495 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_pvt::flags, sip_peer::lastms, LOG_NOTICE, manager_event(), sip_peer::maxms, sip_peer::pokeexpire, sip_peer::ps, sip_pvt::relatedpeer, s, SIP_NEEDDESTROY, and sip_poke_peer_s().

Referenced by handle_response().

12496 {
12497    struct sip_peer *peer = p->relatedpeer;
12498    int statechanged, is_reachable, was_reachable;
12499    int pingtime = ast_tvdiff_ms(ast_tvnow(), peer->ps);
12500 
12501    /*
12502     * Compute the response time to a ping (goes in peer->lastms.)
12503     * -1 means did not respond, 0 means unknown,
12504     * 1..maxms is a valid response, >maxms means late response.
12505     */
12506    if (pingtime < 1) /* zero = unknown, so round up to 1 */
12507       pingtime = 1;
12508 
12509    /* Now determine new state and whether it has changed.
12510     * Use some helper variables to simplify the writing
12511     * of the expressions.
12512     */
12513    was_reachable = peer->lastms > 0 && peer->lastms <= peer->maxms;
12514    is_reachable = pingtime <= peer->maxms;
12515    statechanged = peer->lastms == 0 /* yes, unknown before */
12516       || was_reachable != is_reachable;
12517 
12518    peer->lastms = pingtime;
12519    peer->call = NULL;
12520    if (statechanged) {
12521       const char *s = is_reachable ? "Reachable" : "Lagged";
12522 
12523       ast_log(LOG_NOTICE, "Peer '%s' is now %s. (%dms / %dms)\n",
12524          peer->name, s, pingtime, peer->maxms);
12525       ast_device_state_changed("SIP/%s", peer->name);
12526       manager_event(EVENT_FLAG_SYSTEM, "PeerStatus",
12527          "Peer: SIP/%s\r\nPeerStatus: %s\r\nTime: %d\r\n",
12528          peer->name, s, pingtime);
12529    }
12530 
12531    if (peer->pokeexpire > -1)
12532       ast_sched_del(sched, peer->pokeexpire);
12533    ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12534 
12535    /* Try again eventually */
12536    peer->pokeexpire = ast_sched_add(sched,
12537       is_reachable ? DEFAULT_FREQ_OK : DEFAULT_FREQ_NOTOK,
12538       sip_poke_peer_s, peer);
12539 }

static void handle_response_refer ( struct sip_pvt p,
int  resp,
char *  rest,
struct sip_request req,
int  seqno 
) [static]

Definition at line 12296 of file chan_sip.c.

References AST_CONTROL_CONGESTION, ast_inet_ntoa(), ast_log(), ast_queue_control(), ast_set_flag, ast_strlen_zero(), sip_pvt::authtries, do_proxy_auth(), sip_pvt::flags, get_header(), sip_pvt::initreq, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, option_debug, sip_pvt::owner, sip_pvt::recv, sip_pvt::refer, REFER_ACCEPTED, REFER_FAILED, REFER_NOAUTH, sip_refer::refer_to, SIP_NEEDDESTROY, SIP_REFER, and sip_refer::status.

Referenced by handle_response().

12297 {
12298    char *auth = "Proxy-Authenticate";
12299    char *auth2 = "Proxy-Authorization";
12300 
12301    /* If no refer structure exists, then do nothing */
12302    if (!p->refer)
12303       return;
12304 
12305    switch (resp) {
12306    case 202:   /* Transfer accepted */
12307       /* We need  to do something here */
12308       /* The transferee is now sending INVITE to target */
12309       p->refer->status = REFER_ACCEPTED;
12310       /* Now wait for next message */
12311       if (option_debug > 2)
12312          ast_log(LOG_DEBUG, "Got 202 accepted on transfer\n");
12313       /* We should hang along, waiting for NOTIFY's here */
12314       break;
12315 
12316    case 401:   /* Not www-authorized on SIP method */
12317    case 407:   /* Proxy auth */
12318       if (ast_strlen_zero(p->authname)) {
12319          ast_log(LOG_WARNING, "Asked to authenticate REFER to %s:%d but we have no matching peer or realm auth!\n",
12320             ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port));
12321          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
12322       }
12323       if (resp == 401) {
12324          auth = "WWW-Authenticate";
12325          auth2 = "Authorization";
12326       }
12327       if ((p->authtries > 1) || do_proxy_auth(p, req, auth, auth2, SIP_REFER, 0)) {
12328          ast_log(LOG_NOTICE, "Failed to authenticate on REFER to '%s'\n", get_header(&p->initreq, "From"));
12329          p->refer->status = REFER_NOAUTH;
12330          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
12331       }
12332       break;
12333    case 481: /* Call leg does not exist */
12334 
12335       /* A transfer with Replaces did not work */
12336       /* OEJ: We should Set flag, cancel the REFER, go back
12337       to original call - but right now we can't */
12338       ast_log(LOG_WARNING, "Remote host can't match REFER request to call '%s'. Giving up.\n", p->callid);
12339       if (p->owner)
12340          ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
12341       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
12342       break;
12343 
12344    case 500:   /* Server error */
12345    case 501:   /* Method not implemented */
12346       /* Return to the current call onhold */
12347       /* Status flag needed to be reset */
12348       ast_log(LOG_NOTICE, "SIP transfer to %s failed, call miserably fails. \n", p->refer->refer_to);
12349       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
12350       p->refer->status = REFER_FAILED;
12351       break;
12352    case 603:   /* Transfer declined */
12353       ast_log(LOG_NOTICE, "SIP transfer to %s declined, call miserably fails. \n", p->refer->refer_to);
12354       p->refer->status = REFER_FAILED;
12355       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
12356       break;
12357    }
12358 }

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

Handle responses on REGISTER to services.

Definition at line 12361 of file chan_sip.c.

References __get_header(), ast_log(), ast_sched_add(), ast_sched_del(), ast_set_flag, ast_strlen_zero(), ASTOBJ_UNREF, sip_pvt::authtries, sip_registry::call, DEFAULT_TRANS_TIMEOUT, do_register_auth(), EVENT_FLAG_SYSTEM, sip_registry::expire, EXPIRY_GUARD_LIMIT, EXPIRY_GUARD_MIN, EXPIRY_GUARD_PCT, EXPIRY_GUARD_SECS, sip_pvt::flags, get_header(), sip_pvt::initreq, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, manager_event(), MAX, MAX_AUTHTRIES, option_debug, sip_registry::refresh, REG_STATE_REGISTERED, sip_registry::regattempts, sip_pvt::registry, sip_registry::regstate, regstate2str(), sip_registry::regtime, SIP_NEEDDESTROY, sip_registry_destroy(), sip_reregister(), sip_scheddestroy(), sipdebug, strcasestr(), and sip_registry::timeout.

Referenced by handle_response().

12362 {
12363    int expires, expires_ms;
12364    struct sip_registry *r;
12365    r=p->registry;
12366 
12367    switch (resp) {
12368    case 401:   /* Unauthorized */
12369       if ((p->authtries == MAX_AUTHTRIES) || do_register_auth(p, req, "WWW-Authenticate", "Authorization")) {
12370          ast_log(LOG_NOTICE, "Failed to authenticate on REGISTER to '%s@%s' (Tries %d)\n", p->registry->username, p->registry->hostname, p->authtries);
12371          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12372          }
12373       break;
12374    case 403:   /* Forbidden */
12375       ast_log(LOG_WARNING, "Forbidden - wrong password on authentication for REGISTER for '%s' to '%s'\n", p->registry->username, p->registry->hostname);
12376       if (global_regattempts_max)
12377          p->registry->regattempts = global_regattempts_max+1;
12378       ast_sched_del(sched, r->timeout);
12379       r->timeout = -1;
12380       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12381       break;
12382    case 404:   /* Not found */
12383       ast_log(LOG_WARNING, "Got 404 Not found on SIP register to service %s@%s, giving up\n", p->registry->username,p->registry->hostname);
12384       if (global_regattempts_max)
12385          p->registry->regattempts = global_regattempts_max+1;
12386       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12387       r->call = NULL;
12388       ast_sched_del(sched, r->timeout);
12389       r->timeout = -1;
12390       break;
12391    case 407:   /* Proxy auth */
12392       if ((p->authtries == MAX_AUTHTRIES) || do_register_auth(p, req, "Proxy-Authenticate", "Proxy-Authorization")) {
12393          ast_log(LOG_NOTICE, "Failed to authenticate on REGISTER to '%s' (tries '%d')\n", get_header(&p->initreq, "From"), p->authtries);
12394          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12395       }
12396       break;
12397    case 408:   /* Request timeout */
12398       if (global_regattempts_max)
12399          p->registry->regattempts = global_regattempts_max+1;
12400       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12401       r->call = NULL;
12402       ast_sched_del(sched, r->timeout);
12403       r->timeout = -1;
12404       break;
12405    case 479:   /* SER: Not able to process the URI - address is wrong in register*/
12406       ast_log(LOG_WARNING, "Got error 479 on register to %s@%s, giving up (check config)\n", p->registry->username,p->registry->hostname);
12407       if (global_regattempts_max)
12408          p->registry->regattempts = global_regattempts_max+1;
12409       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12410       r->call = NULL;
12411       ast_sched_del(sched, r->timeout);
12412       r->timeout = -1;
12413       break;
12414    case 200:   /* 200 OK */
12415       if (!r) {
12416          ast_log(LOG_WARNING, "Got 200 OK on REGISTER that isn't a register\n");
12417          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12418          return 0;
12419       }
12420 
12421       r->regstate = REG_STATE_REGISTERED;
12422       r->regtime = time(NULL);      /* Reset time of last succesful registration */
12423       manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelDriver: SIP\r\nDomain: %s\r\nStatus: %s\r\n", r->hostname, regstate2str(r->regstate));
12424       r->regattempts = 0;
12425       if (option_debug)
12426          ast_log(LOG_DEBUG, "Registration successful\n");
12427       if (r->timeout > -1) {
12428          if (option_debug)
12429             ast_log(LOG_DEBUG, "Cancelling timeout %d\n", r->timeout);
12430          ast_sched_del(sched, r->timeout);
12431       }
12432       r->timeout=-1;
12433       r->call = NULL;
12434       p->registry = NULL;
12435       /* Let this one hang around until we have all the responses */
12436       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
12437       /* ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); */
12438 
12439       /* set us up for re-registering */
12440       /* figure out how long we got registered for */
12441       if (r->expire > -1)
12442          ast_sched_del(sched, r->expire);
12443       /* according to section 6.13 of RFC, contact headers override
12444          expires headers, so check those first */
12445       expires = 0;
12446 
12447       /* XXX todo: try to save the extra call */
12448       if (!ast_strlen_zero(get_header(req, "Contact"))) {
12449          const char *contact = NULL;
12450          const char *tmptmp = NULL;
12451          int start = 0;
12452          for(;;) {
12453             contact = __get_header(req, "Contact", &start);
12454             /* this loop ensures we get a contact header about our register request */
12455             if(!ast_strlen_zero(contact)) {
12456                if( (tmptmp=strstr(contact, p->our_contact))) {
12457                   contact=tmptmp;
12458                   break;
12459                }
12460             } else
12461                break;
12462          }
12463          tmptmp = strcasestr(contact, "expires=");
12464          if (tmptmp) {
12465             if (sscanf(tmptmp + 8, "%d;", &expires) != 1)
12466                expires = 0;
12467          }
12468 
12469       }
12470       if (!expires) 
12471          expires=atoi(get_header(req, "expires"));
12472       if (!expires)
12473          expires=default_expiry;
12474 
12475       expires_ms = expires * 1000;
12476       if (expires <= EXPIRY_GUARD_LIMIT)
12477          expires_ms -= MAX((expires_ms * EXPIRY_GUARD_PCT),EXPIRY_GUARD_MIN);
12478       else
12479          expires_ms -= EXPIRY_GUARD_SECS * 1000;
12480       if (sipdebug)
12481          ast_log(LOG_NOTICE, "Outbound Registration: Expiry for %s is %d sec (Scheduling reregistration in %d s)\n", r->hostname, expires, expires_ms/1000); 
12482 
12483       r->refresh= (int) expires_ms / 1000;
12484 
12485       /* Schedule re-registration before we expire */
12486       if (r->expire > -1)
12487          ast_sched_del(sched, r->expire);
12488       r->expire = ast_sched_add(sched, expires_ms, sip_reregister, r); 
12489       ASTOBJ_UNREF(r, sip_registry_destroy);
12490    }
12491    return 1;
12492 }

static const char * hangup_cause2sip ( int  cause  )  [static]

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

Referenced by sip_hangup().

03403 {
03404    switch (cause) {
03405       case AST_CAUSE_UNALLOCATED:      /* 1 */
03406       case AST_CAUSE_NO_ROUTE_DESTINATION:   /* 3 IAX2: Can't find extension in context */
03407       case AST_CAUSE_NO_ROUTE_TRANSIT_NET:   /* 2 */
03408          return "404 Not Found";
03409       case AST_CAUSE_CONGESTION:    /* 34 */
03410       case AST_CAUSE_SWITCH_CONGESTION:   /* 42 */
03411          return "503 Service Unavailable";
03412       case AST_CAUSE_NO_USER_RESPONSE: /* 18 */
03413          return "408 Request Timeout";
03414       case AST_CAUSE_NO_ANSWER:     /* 19 */
03415          return "480 Temporarily unavailable";
03416       case AST_CAUSE_CALL_REJECTED:    /* 21 */
03417          return "403 Forbidden";
03418       case AST_CAUSE_NUMBER_CHANGED:      /* 22 */
03419          return "410 Gone";
03420       case AST_CAUSE_NORMAL_UNSPECIFIED:  /* 31 */
03421          return "480 Temporarily unavailable";
03422       case AST_CAUSE_INVALID_NUMBER_FORMAT:
03423          return "484 Address incomplete";
03424       case AST_CAUSE_USER_BUSY:
03425          return "486 Busy here";
03426       case AST_CAUSE_FAILURE:
03427          return "500 Server internal failure";
03428       case AST_CAUSE_FACILITY_REJECTED:   /* 29 */
03429          return "501 Not Implemented";
03430       case AST_CAUSE_CHAN_NOT_IMPLEMENTED:
03431          return "503 Service Unavailable";
03432       /* Used in chan_iax2 */
03433       case AST_CAUSE_DESTINATION_OUT_OF_ORDER:
03434          return "502 Bad Gateway";
03435       case AST_CAUSE_BEARERCAPABILITY_NOTAVAIL: /* Can't find codec to connect to host */
03436          return "488 Not Acceptable Here";
03437          
03438       case AST_CAUSE_NOTDEFINED:
03439       default:
03440          if (option_debug)
03441             ast_log(LOG_DEBUG, "AST hangup cause %d (no match found in SIP)\n", cause);
03442          return NULL;
03443    }
03444 
03445    /* Never reached */
03446    return 0;
03447 }

static int hangup_sip2cause ( int  cause  )  [static]

Convert SIP hangup causes to Asterisk hangup causes.

Definition at line 3290 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_INTERWORKING, AST_CAUSE_INVALID_NUMBER_FORMAT, AST_CAUSE_NO_ANSWER, AST_CAUSE_NO_ROUTE_DESTINATION, AST_CAUSE_NO_USER_RESPONSE, AST_CAUSE_NORMAL, AST_CAUSE_NORMAL_TEMPORARY_FAILURE, AST_CAUSE_RECOVERY_ON_TIMER_EXPIRE, AST_CAUSE_UNALLOCATED, and AST_CAUSE_USER_BUSY.

Referenced by handle_response().

03291 {
03292    /* Possible values taken from causes.h */
03293 
03294    switch(cause) {
03295       case 401:   /* Unauthorized */
03296          return AST_CAUSE_CALL_REJECTED;
03297       case 403:   /* Not found */
03298          return AST_CAUSE_CALL_REJECTED;
03299       case 404:   /* Not found */
03300          return AST_CAUSE_UNALLOCATED;
03301       case 405:   /* Method not allowed */
03302          return AST_CAUSE_INTERWORKING;
03303       case 407:   /* Proxy authentication required */
03304          return AST_CAUSE_CALL_REJECTED;
03305       case 408:   /* No reaction */
03306          return AST_CAUSE_NO_USER_RESPONSE;
03307       case 409:   /* Conflict */
03308          return AST_CAUSE_NORMAL_TEMPORARY_FAILURE;
03309       case 410:   /* Gone */
03310          return AST_CAUSE_UNALLOCATED;
03311       case 411:   /* Length required */
03312          return AST_CAUSE_INTERWORKING;
03313       case 413:   /* Request entity too large */
03314          return AST_CAUSE_INTERWORKING;
03315       case 414:   /* Request URI too large */
03316          return AST_CAUSE_INTERWORKING;
03317       case 415:   /* Unsupported media type */
03318          return AST_CAUSE_INTERWORKING;
03319       case 420:   /* Bad extension */
03320          return AST_CAUSE_NO_ROUTE_DESTINATION;
03321       case 480:   /* No answer */
03322          return AST_CAUSE_NO_ANSWER;
03323       case 481:   /* No answer */
03324          return AST_CAUSE_INTERWORKING;
03325       case 482:   /* Loop detected */
03326          return AST_CAUSE_INTERWORKING;
03327       case 483:   /* Too many hops */
03328          return AST_CAUSE_NO_ANSWER;
03329       case 484:   /* Address incomplete */
03330          return AST_CAUSE_INVALID_NUMBER_FORMAT;
03331       case 485:   /* Ambigous */
03332          return AST_CAUSE_UNALLOCATED;
03333       case 486:   /* Busy everywhere */
03334          return AST_CAUSE_BUSY;
03335       case 487:   /* Request terminated */
03336          return AST_CAUSE_INTERWORKING;
03337       case 488:   /* No codecs approved */
03338          return AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;
03339       case 491:   /* Request pending */
03340          return AST_CAUSE_INTERWORKING;
03341       case 493:   /* Undecipherable */
03342          return AST_CAUSE_INTERWORKING;
03343       case 500:   /* Server internal failure */
03344          return AST_CAUSE_FAILURE;
03345       case 501:   /* Call rejected */
03346          return AST_CAUSE_FACILITY_REJECTED;
03347       case 502:   
03348          return AST_CAUSE_DESTINATION_OUT_OF_ORDER;
03349       case 503:   /* Service unavailable */
03350          return AST_CAUSE_CONGESTION;
03351       case 504:   /* Gateway timeout */
03352          return AST_CAUSE_RECOVERY_ON_TIMER_EXPIRE;
03353       case 505:   /* SIP version not supported */
03354          return AST_CAUSE_INTERWORKING;
03355       case 600:   /* Busy everywhere */
03356          return AST_CAUSE_USER_BUSY;
03357       case 603:   /* Decline */
03358          return AST_CAUSE_CALL_REJECTED;
03359       case 604:   /* Does not exist anywhere */
03360          return AST_CAUSE_UNALLOCATED;
03361       case 606:   /* Not acceptable */
03362          return AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;
03363       default:
03364          return AST_CAUSE_NORMAL;
03365    }
03366    /* Never reached */
03367    return 0;
03368 }

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

Initialize SIP request.

Definition at line 5789 of file chan_sip.c.

References sip_request::data, sip_request::header, sip_request::headers, sip_request::len, sip_request::method, sip_methods, and cfsip_methods::text.

05790 {
05791    /* Initialize a request */
05792    memset(req, 0, sizeof(*req));
05793         req->method = sipmethod;
05794    req->header[0] = req->data;
05795    snprintf(req->header[0], sizeof(req->data), "%s %s SIP/2.0\r\n", sip_methods[sipmethod].text, recip);
05796    req->len = strlen(req->header[0]);
05797    req->headers++;
05798    return 0;
05799 }

static int init_resp ( struct sip_request resp,
const char *  msg 
) [static]

Initialize SIP response, based on SIP request.

Definition at line 5776 of file chan_sip.c.

References sip_request::data, sip_request::header, sip_request::headers, sip_request::len, sip_request::method, and SIP_RESPONSE.

05777 {
05778    /* Initialize a response */
05779    memset(resp, 0, sizeof(*resp));
05780    resp->method = SIP_RESPONSE;
05781    resp->header[0] = resp->data;
05782    snprintf(resp->header[0], sizeof(resp->data), "SIP/2.0 %s\r\n", msg);
05783    resp->len = strlen(resp->header[0]);
05784    resp->headers++;
05785    return 0;
05786 }

static void initialize_initreq ( struct sip_pvt p,
struct sip_request req 
) [static]

Initialize the initital request packet in the pvt structure. This packet is used for creating replies and future requests in a dialog.

Definition at line 1639 of file chan_sip.c.

References ast_log(), ast_test_flag, ast_verbose(), copy_request(), sip_request::headers, sip_pvt::initreq, sip_request::lines, LOG_DEBUG, option_debug, parse_request(), and SIP_PKT_DEBUG.

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

01640 {
01641    if (p->initreq.headers && option_debug) {
01642       ast_log(LOG_DEBUG, "Initializing already initialized SIP dialog %s (presumably reinvite)\n", p->callid);
01643    }
01644    /* Use this as the basis */
01645    copy_request(&p->initreq, req);
01646    parse_request(&p->initreq);
01647    if (ast_test_flag(req, SIP_PKT_DEBUG))
01648       ast_verbose("%d headers, %d lines\n", p->initreq.headers, p->initreq.lines);
01649 }

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

Initiate new SIP request to peer/user.

Definition at line 6870 of file chan_sip.c.

References add_header(), ast_build_string(), AST_DIGIT_ANYNUM, ast_inet_ntoa(), AST_PRES_ALLOWED, AST_PRES_RESTRICTION, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_uri_encode(), build_contact(), build_rpid(), CALLERID_UNKNOWN, sip_pvt::callingpres, ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, DEFAULT_MAX_FORWARDS, exten, sip_pvt::flags, init_req(), sip_pvt::lastmsg, sip_pvt::ocseq, sip_pvt::options, sip_pvt::ourip, ourport, sip_pvt::owner, s, S_OR, sip_pvt::sa, SIP_INVITE, sip_methods, SIP_NOTIFY, SIP_SENDRPID, SIP_USEREQPHONE, STANDARD_SIP_PORT, sip_pvt::tag, cfsip_methods::text, sip_invite_param::uri_options, and sip_invite_param::vxml_url.

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

06871 {
06872    char invite_buf[256] = "";
06873    char *invite = invite_buf;
06874    size_t invite_max = sizeof(invite_buf);
06875    char from[256];
06876    char to[256];
06877    char tmp[BUFSIZ/2];
06878    char tmp2[BUFSIZ/2];
06879    const char *l = NULL, *n = NULL;
06880    const char *urioptions = "";
06881 
06882    if (ast_test_flag(&p->flags[0], SIP_USEREQPHONE)) {
06883       const char *s = p->username;  /* being a string field, cannot be NULL */
06884 
06885       /* Test p->username against allowed characters in AST_DIGIT_ANY
06886          If it matches the allowed characters list, then sipuser = ";user=phone"
06887          If not, then sipuser = ""
06888       */
06889       /* + is allowed in first position in a tel: uri */
06890       if (*s == '+')
06891          s++;
06892       for (; *s; s++) {
06893          if (!strchr(AST_DIGIT_ANYNUM, *s) )
06894             break;
06895       }
06896       /* If we have only digits, add ;user=phone to the uri */
06897       if (*s)
06898          urioptions = ";user=phone";
06899    }
06900 
06901 
06902    snprintf(p->lastmsg, sizeof(p->lastmsg), "Init: %s", sip_methods[sipmethod].text);
06903 
06904    if (p->owner) {
06905       l = p->owner->cid.cid_num;
06906       n = p->owner->cid.cid_name;
06907    }
06908    /* if we are not sending RPID and user wants his callerid restricted */
06909    if (!ast_test_flag(&p->flags[0], SIP_SENDRPID) &&
06910        ((p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED)) {
06911       l = CALLERID_UNKNOWN;
06912       n = l;
06913    }
06914    if (ast_strlen_zero(l))
06915       l = default_callerid;
06916    if (ast_strlen_zero(n))
06917       n = l;
06918    /* Allow user to be overridden */
06919    if (!ast_strlen_zero(p->fromuser))
06920       l = p->fromuser;
06921    else /* Save for any further attempts */
06922       ast_string_field_set(p, fromuser, l);
06923 
06924    /* Allow user to be overridden */
06925    if (!ast_strlen_zero(p->fromname))
06926       n = p->fromname;
06927    else /* Save for any further attempts */
06928       ast_string_field_set(p, fromname, n);
06929 
06930    if (pedanticsipchecking) {
06931       ast_uri_encode(n, tmp, sizeof(tmp), 0);
06932       n = tmp;
06933       ast_uri_encode(l, tmp2, sizeof(tmp2), 0);
06934       l = tmp2;
06935    }
06936 
06937    if (ourport != STANDARD_SIP_PORT && ast_strlen_zero(p->fromdomain))
06938       snprintf(from, sizeof(from), "\"%s\" <sip:%s@%s:%d>;tag=%s", n, l, S_OR(p->fromdomain, ast_inet_ntoa(p->ourip)), ourport, p->tag);
06939    else
06940       snprintf(from, sizeof(from), "\"%s\" <sip:%s@%s>;tag=%s", n, l, S_OR(p->fromdomain, ast_inet_ntoa(p->ourip)), p->tag);
06941 
06942    /* If we're calling a registered SIP peer, use the fullcontact to dial to the peer */
06943    if (!ast_strlen_zero(p->fullcontact)) {
06944       /* If we have full contact, trust it */
06945       ast_build_string(&invite, &invite_max, "%s", p->fullcontact);
06946    } else {
06947       /* Otherwise, use the username while waiting for registration */
06948       ast_build_string(&invite, &invite_max, "sip:");
06949       if (!ast_strlen_zero(p->username)) {
06950          n = p->username;
06951          if (pedanticsipchecking) {
06952             ast_uri_encode(n, tmp, sizeof(tmp), 0);
06953             n = tmp;
06954          }
06955          ast_build_string(&invite, &invite_max, "%s@", n);
06956       }
06957       ast_build_string(&invite, &invite_max, "%s", p->tohost);
06958       if (ntohs(p->sa.sin_port) != STANDARD_SIP_PORT)
06959          ast_build_string(&invite, &invite_max, ":%d", ntohs(p->sa.sin_port));
06960       ast_build_string(&invite, &invite_max, "%s", urioptions);
06961    }
06962 
06963    /* If custom URI options have been provided, append them */
06964    if (p->options && p->options->uri_options)
06965       ast_build_string(&invite, &invite_max, ";%s", p->options->uri_options);
06966    
06967    ast_string_field_set(p, uri, invite_buf);
06968 
06969    if (sipmethod == SIP_NOTIFY && !ast_strlen_zero(p->theirtag)) { 
06970       /* If this is a NOTIFY, use the From: tag in the subscribe (RFC 3265) */
06971       snprintf(to, sizeof(to), "<%s%s>;tag=%s", (strncasecmp(p->uri, "sip:", 4) ? "" : "sip:"), p->uri, p->theirtag);
06972    } else if (p->options && p->options->vxml_url) {
06973       /* If there is a VXML URL append it to the SIP URL */
06974       snprintf(to, sizeof(to), "<%s>;%s", p->uri, p->options->vxml_url);
06975    } else 
06976       snprintf(to, sizeof(to), "<%s>", p->uri);
06977    
06978    init_req(req, sipmethod, p->uri);
06979    snprintf(tmp, sizeof(tmp), "%d %s", ++p->ocseq, sip_methods[sipmethod].text);
06980 
06981    add_header(req, "Via", p->via);
06982    /* SLD: FIXME?: do Route: here too?  I think not cos this is the first request.
06983     * OTOH, then we won't have anything in p->route anyway */
06984    /* Build Remote Party-ID and From */
06985    if (ast_test_flag(&p->flags[0], SIP_SENDRPID) && (sipmethod == SIP_INVITE)) {
06986       build_rpid(p);
06987       add_header(req, "From", p->rpid_from);
06988    } else 
06989       add_header(req, "From", from);
06990    add_header(req, "To", to);
06991    ast_string_field_set(p, exten, l);
06992    build_contact(p);
06993    add_header(req, "Contact", p->our_contact);
06994    add_header(req, "Call-ID", p->callid);
06995    add_header(req, "CSeq", tmp);
06996    if (!ast_strlen_zero(global_useragent))
06997       add_header(req, "User-Agent", global_useragent);
06998    add_header(req, "Max-Forwards", DEFAULT_MAX_FORWARDS);
06999    if (!ast_strlen_zero(p->rpid))
07000       add_header(req, "Remote-Party-ID", p->rpid);
07001 }

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

Convert Insecure setting to printable string.

Definition at line 9995 of file chan_sip.c.

Referenced by _sip_show_peer().

09996 {
09997    if (port && invite)
09998       return "port,invite";
09999    else if (port)
10000       return "port";
10001    else if (invite)
10002       return "invite";
10003    else
10004       return "no";
10005 }

static void list_route ( struct sip_route route  )  [static]

List all routes - mostly for debugging.

Definition at line 8167 of file chan_sip.c.

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

Referenced by build_route().

08168 {
08169    if (!route)
08170       ast_verbose("list_route: no route\n");
08171    else {
08172       for (;route; route = route->next)
08173          ast_verbose("list_route: hop: <%s>\n", route->hop);
08174    }
08175 }

static int load_module ( void   )  [static]

PBX load module - initialization.

Definition at line 17899 of file chan_sip.c.

References ast_channel_register(), ast_cli_register_multiple(), ast_custom_function_register(), ast_log(), ast_manager_register2(), AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_SUCCESS, ast_register_application(), ast_rtp_proto_register(), ast_udptl_proto_register(), ASTOBJ_CONTAINER_INIT, CHANNEL_MODULE_LOAD, EVENT_FLAG_SYSTEM, io_context_create(), io_context_destroy(), LOG_ERROR, manager_sip_show_peer(), manager_sip_show_peers(), mandescr_show_peer, mandescr_show_peers, peerl, regl, reload_config(), restart_monitor(), sched_context_create(), sched_context_destroy(), sip_addheader(), sip_dtmfmode(), sip_poke_all_peers(), sip_rtp, sip_send_all_registers(), sip_tech, sip_udptl, and userl.

17900 {
17901    ASTOBJ_CONTAINER_INIT(&userl);   /* User object list */
17902    ASTOBJ_CONTAINER_INIT(&peerl);   /* Peer object list */
17903    ASTOBJ_CONTAINER_INIT(&regl); /* Registry object list */
17904 
17905    if (!(sched = sched_context_create())) {
17906       ast_log(LOG_ERROR, "Unable to create scheduler context\n");
17907       return AST_MODULE_LOAD_FAILURE;
17908    }
17909 
17910    if (!(io = io_context_create())) {
17911       ast_log(LOG_ERROR, "Unable to create I/O context\n");
17912       sched_context_destroy(sched);
17913       return AST_MODULE_LOAD_FAILURE;
17914    }
17915 
17916    sip_reloadreason = CHANNEL_MODULE_LOAD;
17917 
17918    if(reload_config(sip_reloadreason)) /* Load the configuration from sip.conf */
17919       return AST_MODULE_LOAD_DECLINE;
17920 
17921    /* Make sure we can register our sip channel type */
17922    if (ast_channel_register(&sip_tech)) {
17923       ast_log(LOG_ERROR, "Unable to register channel type 'SIP'\n");
17924       io_context_destroy(io);
17925       sched_context_destroy(sched);
17926       return AST_MODULE_LOAD_FAILURE;
17927    }
17928 
17929    /* Register all CLI functions for SIP */
17930    ast_cli_register_multiple(cli_sip, sizeof(cli_sip)/ sizeof(struct ast_cli_entry));
17931 
17932    /* Tell the RTP subdriver that we're here */
17933    ast_rtp_proto_register(&sip_rtp);
17934 
17935    /* Tell the UDPTL subdriver that we're here */
17936    ast_udptl_proto_register(&sip_udptl);
17937 
17938    /* Register dialplan applications */
17939    ast_register_application(app_dtmfmode, sip_dtmfmode, synopsis_dtmfmode, descrip_dtmfmode);
17940    ast_register_application(app_sipaddheader, sip_addheader, synopsis_sipaddheader, descrip_sipaddheader);
17941 
17942    /* Register dialplan functions */
17943    ast_custom_function_register(&sip_header_function);
17944    ast_custom_function_register(&sippeer_function);
17945    ast_custom_function_register(&sipchaninfo_function);
17946    ast_custom_function_register(&checksipdomain_function);
17947 
17948    /* Register manager commands */
17949    ast_manager_register2("SIPpeers", EVENT_FLAG_SYSTEM, manager_sip_show_peers,
17950          "List SIP peers (text format)", mandescr_show_peers);
17951    ast_manager_register2("SIPshowpeer", EVENT_FLAG_SYSTEM, manager_sip_show_peer,
17952          "Show SIP peer (text format)", mandescr_show_peer);
17953 
17954    sip_poke_all_peers();   
17955    sip_send_all_registers();
17956    
17957    /* And start the monitor for the first time */
17958    restart_monitor();
17959 
17960    return AST_MODULE_LOAD_SUCCESS;
17961 }

static int local_attended_transfer ( struct sip_pvt transferer,
struct sip_dual current,
struct sip_request req,
int  seqno 
) [static]

Find all call legs and bridge transferee with target called from handle_request_refer.

Definition at line 14108 of file chan_sip.c.

References ast_channel::_state, append_history, ast_bridged_channel(), ast_channel_unlock, ast_clear_flag, ast_hangup(), ast_log(), ast_mutex_unlock(), ast_set_flag, ast_state2str(), AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, attempt_transfer(), sip_dual::chan1, sip_dual::chan2, sip_pvt::flags, get_sip_pvt_byid_locked(), sip_refer::localtransfer, sip_pvt::lock, LOG_DEBUG, option_debug, sip_pvt::owner, sip_pvt::refer, REFER_200OK, REFER_FAILED, sip_refer::replaces_callid, sip_refer::replaces_callid_fromtag, sip_refer::replaces_callid_totag, SIP_DEFER_BYE_ON_TRANSFER, SIP_GOTREFER, sipdebug, sip_refer::status, transmit_notify_with_sipfrag(), transmit_response(), and TRUE.

Referenced by handle_request_refer().

14109 {
14110    struct sip_dual target;    /* Chan 1: Call from tranferer to Asterisk */
14111                /* Chan 2: Call from Asterisk to target */
14112    int res = 0;
14113    struct sip_pvt *targetcall_pvt;
14114 
14115    /* Check if the call ID of the replaces header does exist locally */
14116    if (!(targetcall_pvt = get_sip_pvt_byid_locked(transferer->refer->replaces_callid, transferer->refer->replaces_callid_totag, 
14117       transferer->refer->replaces_callid_fromtag))) {
14118       if (transferer->refer->localtransfer) {
14119          /* We did not find the refered call. Sorry, can't accept then */
14120          transmit_response(transferer, "202 Accepted", req);
14121          /* Let's fake a response from someone else in order
14122             to follow the standard */
14123          transmit_notify_with_sipfrag(transferer, seqno, "481 Call leg/transaction does not exist", TRUE);
14124          append_history(transferer, "Xfer", "Refer failed");
14125          ast_clear_flag(&transferer->flags[0], SIP_GOTREFER);  
14126          transferer->refer->status = REFER_FAILED;
14127          return -1;
14128       }
14129       /* Fall through for remote transfers that we did not find locally */
14130       if (option_debug > 2)
14131          ast_log(LOG_DEBUG, "SIP attended transfer: Not our call - generating INVITE with replaces\n");
14132       return 0;
14133    }
14134 
14135    /* Ok, we can accept this transfer */
14136    transmit_response(transferer, "202 Accepted", req);
14137    append_history(transferer, "Xfer", "Refer accepted");
14138    if (!targetcall_pvt->owner) { /* No active channel */
14139       if (option_debug > 3)
14140          ast_log(LOG_DEBUG, "SIP attended transfer: Error: No owner of target call\n");
14141       /* Cancel transfer */
14142       transmit_notify_with_sipfrag(transferer, seqno, "503 Service Unavailable", TRUE);
14143       append_history(transferer, "Xfer", "Refer failed");
14144       ast_clear_flag(&transferer->flags[0], SIP_GOTREFER);
14145       transferer->refer->status = REFER_FAILED;
14146       ast_mutex_unlock(&targetcall_pvt->lock);
14147       ast_channel_unlock(current->chan1);
14148       return -1;
14149    }
14150 
14151    /* We have a channel, find the bridge */
14152    target.chan1 = targetcall_pvt->owner;           /* Transferer to Asterisk */
14153    target.chan2 = ast_bridged_channel(targetcall_pvt->owner);  /* Asterisk to target */
14154 
14155    if (!target.chan2 || !(target.chan2->_state == AST_STATE_UP || target.chan2->_state == AST_STATE_RINGING) ) {
14156       /* Wrong state of new channel */
14157       if (option_debug > 3) {
14158          if (target.chan2) 
14159             ast_log(LOG_DEBUG, "SIP attended transfer: Error: Wrong state of target call: %s\n", ast_state2str(target.chan2->_state));
14160          else if (target.chan1->_state != AST_STATE_RING)
14161             ast_log(LOG_DEBUG, "SIP attended transfer: Error: No target channel\n");
14162          else
14163             ast_log(LOG_DEBUG, "SIP attended transfer: Attempting transfer in ringing state\n");
14164       }
14165    }
14166 
14167    /* Transfer */
14168    if (option_debug > 3 && sipdebug) {
14169       if (current->chan2)  /* We have two bridges */
14170          ast_log(LOG_DEBUG, "SIP attended transfer: trying to bridge %s and %s\n", target.chan1->name, current->chan2->name);
14171       else        /* One bridge, propably transfer of IVR/voicemail etc */
14172          ast_log(LOG_DEBUG, "SIP attended transfer: trying to make %s take over (masq) %s\n", target.chan1->name, current->chan1->name);
14173    }
14174 
14175    ast_set_flag(&transferer->flags[0], SIP_DEFER_BYE_ON_TRANSFER);   /* Delay hangup */
14176 
14177    /* Perform the transfer */
14178    res = attempt_transfer(current, &target);
14179    ast_mutex_unlock(&targetcall_pvt->lock);
14180    if (res) {
14181       /* Failed transfer */
14182       transmit_notify_with_sipfrag(transferer, seqno, "486 Busy Here", TRUE);
14183       append_history(transferer, "Xfer", "Refer failed");
14184       transferer->refer->status = REFER_FAILED;
14185       if (targetcall_pvt->owner)
14186          ast_channel_unlock(targetcall_pvt->owner);
14187       /* Right now, we have to hangup, sorry. Bridge is destroyed */
14188       if (res != -2)
14189          ast_hangup(transferer->owner);
14190       else
14191          ast_clear_flag(&transferer->flags[0], SIP_DEFER_BYE_ON_TRANSFER);
14192    } else {
14193       /* Transfer succeeded! */
14194 
14195       /* Tell transferer that we're done. */
14196       transmit_notify_with_sipfrag(transferer, seqno, "200 OK", TRUE);
14197       append_history(transferer, "Xfer", "Refer succeeded");
14198       transferer->refer->status = REFER_200OK;
14199       if (targetcall_pvt->owner) {
14200          if (option_debug)
14201             ast_log(LOG_DEBUG, "SIP attended transfer: Unlocking channel %s\n", targetcall_pvt->owner->name);
14202          ast_channel_unlock(targetcall_pvt->owner);
14203       }
14204    }
14205    return 1;
14206 }

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

Parse multiline SIP headers into one header This is enabled if pedanticsipchecking is enabled.

Definition at line 4713 of file chan_sip.c.

References t.

Referenced by sipsock_read().

04714 {
04715    int h = 0, t = 0; 
04716    int lws = 0; 
04717 
04718    for (; h < len;) { 
04719       /* Eliminate all CRs */ 
04720       if (msgbuf[h] == '\r') { 
04721          h++; 
04722          continue; 
04723       } 
04724       /* Check for end-of-line */ 
04725       if (msgbuf[h] == '\n') { 
04726          /* Check for end-of-message */ 
04727          if (h + 1 == len) 
04728             break; 
04729          /* Check for a continuation line */ 
04730          if (msgbuf[h + 1] == ' ' || msgbuf[h + 1] == '\t') { 
04731             /* Merge continuation line */ 
04732             h++; 
04733             continue; 
04734          } 
04735          /* Propagate LF and start new line */ 
04736          msgbuf[t++] = msgbuf[h++]; 
04737          lws = 0;
04738          continue; 
04739       } 
04740       if (msgbuf[h] == ' ' || msgbuf[h] == '\t') { 
04741          if (lws) { 
04742             h++; 
04743             continue; 
04744          } 
04745          msgbuf[t++] = msgbuf[h++]; 
04746          lws = 1; 
04747          continue; 
04748       } 
04749       msgbuf[t++] = msgbuf[h++]; 
04750       if (lws) 
04751          lws = 0; 
04752    } 
04753    msgbuf[t] = '\0'; 
04754    return t; 
04755 }

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

Make our SIP dialog tag.

Definition at line 4384 of file chan_sip.c.

References ast_random().

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

04385 {
04386    snprintf(tagbuf, len, "as%08lx", ast_random());
04387 }

static int manager_sip_show_peer ( struct mansession s,
const struct message m 
) [static]

Show SIP peers in the manager API.

Definition at line 10240 of file chan_sip.c.

References _sip_show_peer(), ast_strlen_zero(), astman_append(), astman_get_header(), and astman_send_error().

Referenced by load_module().

10241 {
10242    const char *a[4];
10243    const char *peer;
10244    int ret;
10245 
10246    peer = astman_get_header(m,"Peer");
10247    if (ast_strlen_zero(peer)) {
10248       astman_send_error(s, m, "Peer: <name> missing.\n");
10249       return 0;
10250    }
10251    a[0] = "sip";
10252    a[1] = "show";
10253    a[2] = "peer";
10254    a[3] = peer;
10255 
10256    ret = _sip_show_peer(1, -1, s, m, 4, a);
10257    astman_append(s, "\r\n\r\n" );
10258    return ret;
10259 }

static int manager_sip_show_peers ( struct mansession s,
const struct message m 
) [static]

Show SIP peers in the manager API.

Definition at line 9791 of file chan_sip.c.

References _sip_show_peers(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_ack(), and total.

Referenced by load_module().

09792 {
09793    const char *id = astman_get_header(m,"ActionID");
09794    const char *a[] = {"sip", "show", "peers"};
09795    char idtext[256] = "";
09796    int total = 0;
09797 
09798    if (!ast_strlen_zero(id))
09799       snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
09800 
09801    astman_send_ack(s, m, "Peer status list will follow");
09802    /* List the peers in separate manager events */
09803    _sip_show_peers(-1, &total, s, m, 3, a);
09804    /* Send final confirmation */
09805    astman_append(s,
09806    "Event: PeerlistComplete\r\n"
09807    "ListItems: %d\r\n"
09808    "%s"
09809    "\r\n", total, idtext);
09810    return 0;
09811 }

static int method_match ( enum sipmethod  id,
const char *  name 
) [static]

returns true if 'name' (with optional trailing whitespace) matches the sip method 'id'. Strictly speaking, SIP methods are case SENSITIVE, but we do a case-insensitive comparison to be more tolerant. following Jon Postel's rule: Be gentle in what you accept, strict with what you send

Definition at line 1665 of file chan_sip.c.

References len, sip_methods, and text.

Referenced by __sip_semi_ack(), and find_sip_method().

01666 {
01667    int len = strlen(sip_methods[id].text);
01668    int l_name = name ? strlen(name) : 0;
01669    /* true if the string is long enough, and ends with whitespace, and matches */
01670    return (l_name >= len && name[len] < 33 &&
01671       !strncasecmp(sip_methods[id].text, name, len));
01672 }

static char * nat2str ( int  nat  )  [static]

Convert NAT setting to text string.

Definition at line 9694 of file chan_sip.c.

References SIP_NAT_ALWAYS, SIP_NAT_NEVER, SIP_NAT_RFC3581, and SIP_NAT_ROUTE.

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

09695 {
09696    switch(nat) {
09697    case SIP_NAT_NEVER:
09698       return "No";
09699    case SIP_NAT_ROUTE:
09700       return "Route";
09701    case SIP_NAT_ALWAYS:
09702       return "Always";
09703    case SIP_NAT_RFC3581:
09704       return "RFC3581";
09705    default:
09706       return "Unknown";
09707    }
09708 }

static void parse_copy ( struct sip_request dst,
const struct sip_request src 
) [static]

Copy SIP request, parse it.

Definition at line 2220 of file chan_sip.c.

References sip_request::data, sip_request::len, and parse_request().

Referenced by send_request(), and send_response().

02221 {
02222    memset(dst, 0, sizeof(*dst));
02223    memcpy(dst->data, src->data, sizeof(dst->data));
02224    dst->len = src->len;
02225    parse_request(dst);
02226 }

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

Parse 302 Moved temporalily response.

Definition at line 11869 of file chan_sip.c.

References ast_log(), ast_strdupa, ast_string_field_build, ast_string_field_set, ast_test_flag, sip_pvt::flags, get_header(), get_in_brackets(), LOG_DEBUG, option_debug, sip_pvt::owner, pbx_builtin_setvar_helper(), s, SIP_PROMISCREDIR, and t.

Referenced by handle_response().

11870 {
11871    char tmp[BUFSIZ];
11872    char *s, *e, *uri, *t;
11873    char *domain;
11874 
11875    ast_copy_string(tmp, get_header(req, "Contact"), sizeof(tmp));
11876    if ((t = strchr(tmp, ',')))
11877       *t = '\0';
11878    s = get_in_brackets(tmp);
11879    uri = ast_strdupa(s);
11880    if (ast_test_flag(&p->flags[0], SIP_PROMISCREDIR)) {
11881       if (!strncasecmp(s, "sip:", 4))
11882          s += 4;
11883       e = strchr(s, ';');
11884       if (e)
11885          *e = '\0';
11886       if (option_debug)
11887          ast_log(LOG_DEBUG, "Found promiscuous redirection to 'SIP/%s'\n", s);
11888       if (p->owner)
11889          ast_string_field_build(p->owner, call_forward, "SIP/%s", s);
11890    } else {
11891       e = strchr(tmp, '@');
11892       if (e) {
11893          *e++ = '\0';
11894          domain = e;
11895       } else {
11896          /* No username part */
11897          domain = tmp;
11898       }
11899       e = strchr(s, ';');  /* Strip of parameters in the username part */
11900       if (e)
11901          *e = '\0';
11902       e = strchr(domain, ';');   /* Strip of parameters in the domain part */
11903       if (e)
11904          *e = '\0';
11905    
11906       if (!strncasecmp(s, "sip:", 4))
11907          s += 4;
11908       if (option_debug > 1)
11909          ast_log(LOG_DEBUG, "Received 302 Redirect to extension '%s' (domain %s)\n", s, domain);
11910       if (p->owner) {
11911          pbx_builtin_setvar_helper(p->owner, "SIPREDIRECTURI", uri);
11912          pbx_builtin_setvar_helper(p->owner, "SIPDOMAIN", domain);
11913          ast_string_field_set(p->owner, call_forward, s);
11914       }
11915    }
11916 }

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

Save contact header for 200 OK on INVITE.

Definition at line 7923 of file chan_sip.c.

References ast_string_field_set, get_header(), get_in_brackets(), and TRUE.

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

07924 {
07925    char contact[BUFSIZ]; 
07926    char *c;
07927 
07928    /* Look for brackets */
07929    ast_copy_string(contact, get_header(req, "Contact"), sizeof(contact));
07930    c = get_in_brackets(contact);
07931 
07932    /* Save full contact to call pvt for later bye or re-invite */
07933    ast_string_field_set(pvt, fullcontact, c);
07934 
07935    /* Save URI for later ACKs, BYE or RE-invites */
07936    ast_string_field_set(pvt, okcontacturi, c);
07937 
07938    /* We should return false for URI:s we can't handle,
07939       like sips:, tel:, mailto:,ldap: etc */
07940    return TRUE;      
07941 }

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

Parse contact header and save registration (peer registration).

Definition at line 8007 of file chan_sip.c.

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

Referenced by register_verify().

08008 {
08009    char contact[BUFSIZ]; 
08010    char data[BUFSIZ];
08011    const char *expires = get_header(req, "Expires");
08012    int expiry = atoi(expires);
08013    char *curi, *n, *pt;
08014    int port;
08015    const char *useragent;
08016    struct hostent *hp;
08017    struct ast_hostent ahp;
08018    struct sockaddr_in oldsin;
08019 
08020    ast_copy_string(contact, get_header(req, "Contact"), sizeof(contact));
08021 
08022    if (ast_strlen_zero(expires)) {  /* No expires header */
08023       expires = strcasestr(contact, ";expires=");
08024       if (expires) {
08025          /* XXX bug here, we overwrite the string */
08026          expires = strsep((char **) &expires, ";"); /* trim ; and beyond */
08027          if (sscanf(expires + 9, "%d", &expiry) != 1)
08028             expiry = default_expiry;
08029       } else {
08030          /* Nothing has been specified */
08031          expiry = default_expiry;
08032       }
08033    }
08034 
08035    /* Look for brackets */
08036    curi = contact;
08037    if (strchr(contact, '<') == NULL)   /* No <, check for ; and strip it */
08038       strsep(&curi, ";");  /* This is Header options, not URI options */
08039    curi = get_in_brackets(contact);
08040 
08041    /* if they did not specify Contact: or Expires:, they are querying
08042       what we currently have stored as their contact address, so return
08043       it
08044    */
08045    if (ast_strlen_zero(curi) && ast_strlen_zero(expires)) {
08046       /* If we have an active registration, tell them when the registration is going to expire */
08047       if (peer->expire > -1 && !ast_strlen_zero(peer->fullcontact))
08048          pvt->expiry = ast_sched_when(sched, peer->expire);
08049       return PARSE_REGISTER_QUERY;
08050    } else if (!strcasecmp(curi, "*") || !expiry) { /* Unregister this peer */
08051       /* This means remove all registrations and return OK */
08052       memset(&peer->addr, 0, sizeof(peer->addr));
08053       if (peer->expire > -1)
08054          ast_sched_del(sched, peer->expire);
08055       peer->expire = -1;
08056 
08057       destroy_association(peer);
08058       
08059       register_peer_exten(peer, 0); /* Add extension from regexten= setting in sip.conf */
08060       peer->fullcontact[0] = '\0';
08061       peer->useragent[0] = '\0';
08062       peer->sipoptions = 0;
08063       peer->lastms = 0;
08064 
08065       if (option_verbose > 2)
08066          ast_verbose(VERBOSE_PREFIX_3 "Unregistered SIP '%s'\n", peer->name);
08067          manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unregistered\r\n", peer->name);
08068       return PARSE_REGISTER_UPDATE;
08069    }
08070 
08071    /* Store whatever we got as a contact from the client */
08072    ast_copy_string(peer->fullcontact, curi, sizeof(peer->fullcontact));
08073 
08074    /* For the 200 OK, we should use the received contact */
08075    ast_string_field_build(pvt, our_contact, "<%s>", curi);
08076 
08077    /* Make sure it's a SIP URL */
08078    if (strncasecmp(curi, "sip:", 4)) {
08079       ast_log(LOG_NOTICE, "'%s' is not a valid SIP contact (missing sip:) trying to use anyway\n", curi);
08080    } else
08081       curi += 4;
08082    /* Ditch q */
08083    curi = strsep(&curi, ";");
08084    /* Grab host */
08085    n = strchr(curi, '@');
08086    if (!n) {
08087       n = curi;
08088       curi = NULL;
08089    } else
08090       *n++ = '\0';
08091    pt = strchr(n, ':');
08092    if (pt) {
08093       *pt++ = '\0';
08094       port = atoi(pt);
08095    } else
08096       port = STANDARD_SIP_PORT;
08097    oldsin = peer->addr;
08098    if (!ast_test_flag(&peer->flags[0], SIP_NAT_ROUTE)) {
08099       /* XXX This could block for a long time XXX */
08100       hp = ast_gethostbyname(n, &ahp);
08101       if (!hp)  {
08102          ast_log(LOG_WARNING, "Invalid host '%s'\n", n);
08103          return PARSE_REGISTER_FAILED;
08104       }
08105       peer->addr.sin_family = AF_INET;
08106       memcpy(&peer->addr.sin_addr, hp->h_addr, sizeof(peer->addr.sin_addr));
08107       peer->addr.sin_port = htons(port);
08108    } else {
08109       /* Don't trust the contact field.  Just use what they came to us
08110          with */
08111       peer->addr = pvt->recv;
08112    }
08113 
08114    /* Save SIP options profile */
08115    peer->sipoptions = pvt->sipoptions;
08116 
08117    if (curi && ast_strlen_zero(peer->username))
08118       ast_copy_string(peer->username, curi, sizeof(peer->username));
08119 
08120    if (peer->expire > -1) {
08121       ast_sched_del(sched, peer->expire);
08122       peer->expire = -1;
08123    }
08124    if (expiry > max_expiry)
08125       expiry = max_expiry;
08126    if (expiry < min_expiry)
08127       expiry = min_expiry;
08128    peer->expire = ast_test_flag(&peer->flags[0], SIP_REALTIME) ? -1 :
08129       ast_sched_add(sched, (expiry + 10) * 1000, expire_register, peer);
08130    pvt->expiry = expiry;
08131    snprintf(data, sizeof(data), "%s:%d:%d:%s:%s", ast_inet_ntoa(peer->addr.sin_addr), ntohs(peer->addr.sin_port), expiry, peer->username, peer->fullcontact);
08132    if (!ast_test_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT)) 
08133       ast_db_put("SIP/Registry", peer->name, data);
08134    manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Registered\r\n", peer->name);
08135 
08136    /* Is this a new IP address for us? */
08137    if (inaddrcmp(&peer->addr, &oldsin)) {
08138       sip_poke_peer(peer);
08139       if (option_verbose > 2)
08140          ast_verbose(VERBOSE_PREFIX_3 "Registered SIP '%s' at %s port %d expires %d\n", peer->name, ast_inet_ntoa(peer->addr.sin_addr), ntohs(peer->addr.sin_port), expiry);
08141       register_peer_exten(peer, 1);
08142    }
08143    
08144    /* Save User agent */
08145    useragent = get_header(req, "User-Agent");
08146    if (strcasecmp(useragent, peer->useragent)) {   /* XXX copy if they are different ? */
08147       ast_copy_string(peer->useragent, useragent, sizeof(peer->useragent));
08148       if (option_verbose > 3)
08149          ast_verbose(VERBOSE_PREFIX_3 "Saved useragent \"%s\" for peer %s\n", peer->useragent, peer->name);  
08150    }
08151    return PARSE_REGISTER_UPDATE;
08152 }

static void parse_request ( struct sip_request req  )  [static]

Parse a SIP message.

Note:
this function is used both on incoming and outgoing packets

Definition at line 4760 of file chan_sip.c.

References ast_log(), ast_strlen_zero(), sip_request::data, determine_firstline_parts(), f, 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 initialize_initreq(), parse_copy(), and sipsock_read().

04761 {
04762    /* Divide fields by NULL's */
04763    char *c;
04764    int f = 0;
04765 
04766    c = req->data;
04767 
04768    /* First header starts immediately */
04769    req->header[f] = c;
04770    while(*c) {
04771       if (*c == '\n') {
04772          /* We've got a new header */
04773          *c = 0;
04774 
04775          if (sipdebug && option_debug > 3)
04776             ast_log(LOG_DEBUG, "Header %d: %s (%d)\n", f, req->header[f], (int) strlen(req->header[f]));
04777          if (ast_strlen_zero(req->header[f])) {
04778             /* Line by itself means we're now in content */
04779             c++;
04780             break;
04781          }
04782          if (f >= SIP_MAX_HEADERS - 1) {
04783             ast_log(LOG_WARNING, "Too many SIP headers. Ignoring.\n");
04784          } else
04785             f++;
04786          req->header[f] = c + 1;
04787       } else if (*c == '\r') {
04788          /* Ignore but eliminate \r's */
04789          *c = 0;
04790       }
04791       c++;
04792    }
04793    /* Check for last header */
04794    if (!ast_strlen_zero(req->header[f])) {
04795       if (sipdebug && option_debug > 3)
04796          ast_log(LOG_DEBUG, "Header %d: %s (%d)\n", f, req->header[f], (int) strlen(req->header[f]));
04797       f++;
04798    }
04799    req->headers = f;
04800    /* Now we process any mime content */
04801    f = 0;
04802    req->line[f] = c;
04803    while(*c) {
04804       if (*c == '\n') {
04805          /* We've got a new line */
04806          *c = 0;
04807          if (sipdebug && option_debug > 3)
04808             ast_log(LOG_DEBUG, "Line: %s (%d)\n", req->line[f], (int) strlen(req->line[f]));
04809          if (f >= SIP_MAX_LINES - 1) {
04810             ast_log(LOG_WARNING, "Too many SDP lines. Ignoring.\n");
04811          } else
04812             f++;
04813          req->line[f] = c + 1;
04814       } else if (*c == '\r') {
04815          /* Ignore and eliminate \r's */
04816          *c = 0;
04817       }
04818       c++;
04819    }
04820    /* Check for last line */
04821    if (!ast_strlen_zero(req->line[f])) 
04822       f++;
04823    req->lines = f;
04824    if (*c) 
04825       ast_log(LOG_WARNING, "Odd content, extra stuff left over ('%s')\n", c);
04826    /* Split up the first line parts */
04827    determine_firstline_parts(req);
04828 }

static unsigned int parse_sip_options ( struct sip_pvt pvt,
const char *  supported 
) [static]

Parse supported header in incoming packet.

Definition at line 1689 of file chan_sip.c.

References ast_log(), ast_strdupa, ast_strlen_zero(), FALSE, cfsip_options::id, LOG_DEBUG, ast_udptl_protocol::next, option_debug, sip_options, sipdebug, sip_pvt::sipoptions, text, and TRUE.

Referenced by handle_request_invite().

01690 {
01691    char *next, *sep;
01692    char *temp;
01693    unsigned int profile = 0;
01694    int i, found;
01695 
01696    if (ast_strlen_zero(supported) )
01697       return 0;
01698    temp = ast_strdupa(supported);
01699 
01700    if (option_debug > 2 && sipdebug)
01701       ast_log(LOG_DEBUG, "Begin: parsing SIP \"Supported: %s\"\n", supported);
01702 
01703    for (next = temp; next; next = sep) {
01704       found = FALSE;
01705       if ( (sep = strchr(next, ',')) != NULL)
01706          *sep++ = '\0';
01707       next = ast_skip_blanks(next);
01708       if (option_debug > 2 && sipdebug)
01709          ast_log(LOG_DEBUG, "Found SIP option: -%s-\n", next);
01710       for (i=0; i < (sizeof(sip_options) / sizeof(sip_options[0])); i++) {
01711          if (!strcasecmp(next, sip_options[i].text)) {
01712             profile |= sip_options[i].id;
01713             found = TRUE;
01714             if (option_debug > 2 && sipdebug)
01715                ast_log(LOG_DEBUG, "Matched SIP option: %s\n", next);
01716             break;
01717          }
01718       }
01719       if (!found && option_debug > 2 && sipdebug) {
01720          if (!strncasecmp(next, "x-", 2))
01721             ast_log(LOG_DEBUG, "Found private SIP option, not supported: %s\n", next);
01722          else
01723             ast_log(LOG_DEBUG, "Found no match for SIP option: %s (Please file bug report!)\n", next);
01724       }
01725    }
01726 
01727    if (pvt)
01728       pvt->sipoptions = profile;
01729    return profile;
01730 }

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

Report Peer status in character string.

Returns:
0 if peer is unreachable, 1 if peer is online, -1 if unmonitored

Definition at line 9713 of file chan_sip.c.

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

09714 {
09715    int res = 0;
09716    if (peer->maxms) {
09717       if (peer->lastms < 0) {
09718          ast_copy_string(status, "UNREACHABLE", statuslen);
09719       } else if (peer->lastms > peer->maxms) {
09720          snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms);
09721          res = 1;
09722       } else if (peer->lastms) {
09723          snprintf(status, statuslen, "OK (%d ms)", peer->lastms);
09724          res = 1;
09725       } else {
09726          ast_copy_string(status, "UNKNOWN", statuslen);
09727       }
09728    } else { 
09729       ast_copy_string(status, "Unmonitored", statuslen);
09730       /* Checking if port is 0 */
09731       res = -1;
09732    }
09733    return res;
09734 }

static void print_codec_to_cli ( int  fd,
struct ast_codec_pref pref 
) [static]

Print codec list from preference to CLI/manager.

Definition at line 10181 of file chan_sip.c.

References ast_cli(), ast_codec_pref_index(), ast_getformatname(), and ast_codec_pref::framing.

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

10182 {
10183    int x, codec;
10184 
10185    for(x = 0; x < 32 ; x++) {
10186       codec = ast_codec_pref_index(pref, x);
10187       if (!codec)
10188          break;
10189       ast_cli(fd, "%s", ast_getformatname(codec));
10190       ast_cli(fd, ":%d", pref->framing[x]);
10191       if (x < 31 && ast_codec_pref_index(pref, x + 1))
10192          ast_cli(fd, ",");
10193    }
10194    if (!x)
10195       ast_cli(fd, "none");
10196 }

static void print_group ( int  fd,
ast_group_t  group,
int  crlf 
) [static]

Print call group and pickup group.

Definition at line 9972 of file chan_sip.c.

References ast_cli(), and ast_print_group().

Referenced by _sip_show_peer(), and sip_show_user().

09973 {
09974    char buf[256];
09975    ast_cli(fd, crlf ? "%s\r\n" : "%s\n", ast_print_group(buf, sizeof(buf), group) );
09976 }

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

Process SIP SDP offer, select formats and activate RTP channels If offer is rejected, we will not change any properties of the call Return 0 on success, a negative value on errors. Must be called after find_sdp().

< RTP Audio port number

< RTP Video port number

< media socket address

< Video socket address

< RTP Audio host IP

< RTP video host IP

Definition at line 4943 of file chan_sip.c.

References ast_clear_flag, ast_codec_choose(), ast_codec_pref_setsize(), AST_CONTROL_HOLD, AST_CONTROL_UNHOLD, AST_FORMAT_AUDIO_MASK, ast_getformatname_multiple(), ast_gethostbyname(), ast_inet_ntoa(), ast_log(), ast_null_frame, ast_queue_control(), ast_queue_control_data(), ast_queue_frame(), ast_rtp_alloc_size(), ast_rtp_codec_getformat(), ast_rtp_codec_getpref(), ast_rtp_codec_setpref(), AST_RTP_DTMF, ast_rtp_get_current_formats(), ast_rtp_lookup_mime_multiple(), ast_rtp_new_init(), AST_RTP_OPT_G726_NONSTANDARD, ast_rtp_pt_clear(), ast_rtp_pt_copy(), ast_rtp_set_m_type(), ast_rtp_set_peer(), ast_rtp_set_rtpmap_type(), ast_rtp_setdtmf(), ast_rtp_setdtmfcompensate(), ast_rtp_stop(), ast_rtp_unset_m_type(), ast_set_flag, ast_set_read_format(), ast_set_write_format(), ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_udptl_set_error_correction_scheme(), ast_udptl_set_far_max_datagram(), ast_udptl_set_local_max_datagram(), ast_udptl_set_peer(), ast_udptl_stop(), ast_verbose(), sip_pvt::autoframing, sip_pvt::capability, t38properties::capability, change_hold_state(), debug, FALSE, sip_pvt::flags, format, get_sdp(), get_sdp_iterate(), hp, sip_pvt::jointcapability, t38properties::jointcapability, sip_pvt::jointnoncodeccapability, sip_pvt::lastinvite, sip_pvt::lastrtprx, sip_pvt::lastrtptx, len, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, LOG_WARNING, LONG_MAX, LONG_MIN, ast_channel::nativeformats, sip_pvt::noncodeccapability, option_debug, sip_pvt::owner, sip_pvt::peercapability, t38properties::peercapability, portno, sip_pvt::prefs, ast_channel::readformat, sip_pvt::rtp, s, S_OR, SDP_MAX_RTPMAP_CODECS, sip_request::sdp_start, sip_debug_test_pvt(), SIP_DTMF, SIP_DTMF_AUTO, SIP_DTMF_INBAND, SIP_DTMF_RFC2833, SIP_G726_NONSTANDARD, SIP_NOVIDEO, SIP_PAGE2_CALL_ONHOLD, SIP_PAGE2_RFC2833_COMPENSATE, t38properties::state, sip_pvt::t38, T38_DISABLED, T38_PEER_DIRECT, T38_PEER_REINVITE, T38FAX_FILL_BIT_REMOVAL, T38FAX_RATE_12000, T38FAX_RATE_14400, T38FAX_RATE_2400, T38FAX_RATE_4800, T38FAX_RATE_7200, T38FAX_RATE_9600, T38FAX_RATE_MANAGEMENT_LOCAL_TCF, T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF, T38FAX_TRANSCODING_JBIG, T38FAX_TRANSCODING_MMR, T38FAX_UDP_EC_FEC, T38FAX_UDP_EC_NONE, T38FAX_UDP_EC_REDUNDANCY, T38FAX_VERSION_0, T38FAX_VERSION_1, TRUE, sip_pvt::udptl, UDPTL_ERROR_CORRECTION_FEC, UDPTL_ERROR_CORRECTION_NONE, UDPTL_ERROR_CORRECTION_REDUNDANCY, sip_pvt::vrtp, and ast_channel::writeformat.

04944 {
04945    const char *m;    /* SDP media offer */
04946    const char *c;
04947    const char *a;
04948    char host[258];
04949    int len = -1;
04950    int portno = -1;     /*!< RTP Audio port number */
04951    int vportno = -1;    /*!< RTP Video port number */
04952    int udptlportno = -1;
04953    int peert38capability = 0;
04954    char s[256];
04955    int old = 0;
04956 
04957    /* Peer capability is the capability in the SDP, non codec is RFC2833 DTMF (101) */ 
04958    int peercapability = 0, peernoncodeccapability = 0;
04959    int vpeercapability = 0, vpeernoncodeccapability = 0;
04960    struct sockaddr_in sin;    /*!< media socket address */
04961    struct sockaddr_in vsin;   /*!< Video socket address */
04962 
04963    const char *codecs;
04964    struct hostent *hp;     /*!< RTP Audio host IP */
04965    struct hostent *vhp = NULL;   /*!< RTP video host IP */
04966    struct ast_hostent audiohp;
04967    struct ast_hostent videohp;
04968    int codec;
04969    int destiterator = 0;
04970    int iterator;
04971    int sendonly = -1;
04972    int numberofports;
04973    struct ast_rtp *newaudiortp, *newvideortp;   /* Buffers for codec handling */
04974    int newjointcapability;          /* Negotiated capability */
04975    int newpeercapability;
04976    int newnoncodeccapability;
04977    int numberofmediastreams = 0;
04978    int debug = sip_debug_test_pvt(p);
04979       
04980    int found_rtpmap_codecs[SDP_MAX_RTPMAP_CODECS];
04981    int last_rtpmap_codec=0;
04982 
04983    if (!p->rtp) {
04984       ast_log(LOG_ERROR, "Got SDP but have no RTP session allocated.\n");
04985       return -1;
04986    }
04987 
04988    /* Initialize the temporary RTP structures we use to evaluate the offer from the peer */
04989    newaudiortp = alloca(ast_rtp_alloc_size());
04990    memset(newaudiortp, 0, ast_rtp_alloc_size());
04991    ast_rtp_new_init(newaudiortp);
04992    ast_rtp_pt_clear(newaudiortp);
04993 
04994    newvideortp = alloca(ast_rtp_alloc_size());
04995    memset(newvideortp, 0, ast_rtp_alloc_size());
04996    ast_rtp_new_init(newvideortp);
04997    ast_rtp_pt_clear(newvideortp);
04998 
04999    /* Update our last rtprx when we receive an SDP, too */
05000    p->lastrtprx = p->lastrtptx = time(NULL); /* XXX why both ? */
05001 
05002 
05003    /* Try to find first media stream */
05004    m = get_sdp(req, "m");
05005    destiterator = req->sdp_start;
05006    c = get_sdp_iterate(&destiterator, req, "c");
05007    if (ast_strlen_zero(m) || ast_strlen_zero(c)) {
05008       ast_log(LOG_WARNING, "Insufficient information for SDP (m = '%s', c = '%s')\n", m, c);
05009       return -1;
05010    }
05011 
05012    /* Check for IPv4 address (not IPv6 yet) */
05013    if (sscanf(c, "IN IP4 %256s", host) != 1) {
05014       ast_log(LOG_WARNING, "Invalid host in c= line, '%s'\n", c);
05015       return -1;
05016    }
05017 
05018    /* XXX This could block for a long time, and block the main thread! XXX */
05019    hp = ast_gethostbyname(host, &audiohp);
05020    if (!hp) {
05021       ast_log(LOG_WARNING, "Unable to lookup host in c= line, '%s'\n", c);
05022       return -1;
05023    }
05024    vhp = hp;   /* Copy to video address as default too */
05025    
05026    iterator = req->sdp_start;
05027    ast_set_flag(&p->flags[0], SIP_NOVIDEO);  
05028 
05029 
05030    /* Find media streams in this SDP offer */
05031    while ((m = get_sdp_iterate(&iterator, req, "m"))[0] != '\0') {
05032       int x;
05033       int audio = FALSE;
05034 
05035       numberofports = 1;
05036       if ((sscanf(m, "audio %d/%d RTP/AVP %n", &x, &numberofports, &len) == 2) ||
05037           (sscanf(m, "audio %d RTP/AVP %n", &x, &len) == 1)) {
05038          audio = TRUE;
05039          numberofmediastreams++;
05040          /* Found audio stream in this media definition */
05041          portno = x;
05042          /* Scan through the RTP payload types specified in a "m=" line: */
05043          for (codecs = m + len; !ast_strlen_zero(codecs); codecs = ast_skip_blanks(codecs + len)) {
05044             if (sscanf(codecs, "%d%n", &codec, &len) != 1) {
05045                ast_log(LOG_WARNING, "Error in codec string '%s'\n", codecs);
05046                return -1;
05047             }
05048             if (debug)
05049                ast_verbose("Found RTP audio format %d\n", codec);
05050             ast_rtp_set_m_type(newaudiortp, codec);
05051          }
05052       } else if ((sscanf(m, "video %d/%d RTP/AVP %n", &x, &numberofports, &len) == 2) ||
05053           (sscanf(m, "video %d RTP/AVP %n", &x, &len) == 1)) {
05054          /* If it is not audio - is it video ? */
05055          ast_clear_flag(&p->flags[0], SIP_NOVIDEO);   
05056          numberofmediastreams++;
05057          vportno = x;
05058          /* Scan through the RTP payload types specified in a "m=" line: */
05059          for (codecs = m + len; !ast_strlen_zero(codecs); codecs = ast_skip_blanks(codecs + len)) {
05060             if (sscanf(codecs, "%d%n", &codec, &len) != 1) {
05061                ast_log(LOG_WARNING, "Error in codec string '%s'\n", codecs);
05062                return -1;
05063             }
05064             if (debug)
05065                ast_verbose("Found RTP video format %d\n", codec);
05066             ast_rtp_set_m_type(newvideortp, codec);
05067          }
05068       } else if (p->udptl && ( (sscanf(m, "image %d udptl t38%n", &x, &len) == 1) || 
05069        (sscanf(m, "image %d UDPTL t38%n", &x, &len) == 1) )) {
05070          if (debug)
05071             ast_verbose("Got T.38 offer in SDP in dialog %s\n", p->callid);
05072          udptlportno = x;
05073          numberofmediastreams++;
05074          
05075          if (p->owner && p->lastinvite) {
05076             p->t38.state = T38_PEER_REINVITE; /* T38 Offered in re-invite from remote party */
05077             if (option_debug > 1)
05078                ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>" );
05079          } else {
05080             p->t38.state = T38_PEER_DIRECT; /* T38 Offered directly from peer in first invite */
05081             if (option_debug > 1)
05082                ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>");
05083          }
05084       } else 
05085          ast_log(LOG_WARNING, "Unsupported SDP media type in offer: %s\n", m);
05086       if (numberofports > 1)
05087          ast_log(LOG_WARNING, "SDP offered %d ports for media, not supported by Asterisk. Will try anyway...\n", numberofports);
05088       
05089 
05090       /* Check for Media-description-level-address for audio */
05091       c = get_sdp_iterate(&destiterator, req, "c");
05092       if (!ast_strlen_zero(c)) {
05093          if (sscanf(c, "IN IP4 %256s", host) != 1) {
05094             ast_log(LOG_WARNING, "Invalid secondary host in c= line, '%s'\n", c);
05095          } else {
05096             /* XXX This could block for a long time, and block the main thread! XXX */
05097             if (audio) {
05098                if ( !(hp = ast_gethostbyname(host, &audiohp))) {
05099                   ast_log(LOG_WARNING, "Unable to lookup RTP Audio host in secondary c= line, '%s'\n", c);
05100                   return -2;
05101                }
05102             } else if (!(vhp = ast_gethostbyname(host, &videohp))) {
05103                ast_log(LOG_WARNING, "Unable to lookup RTP video host in secondary c= line, '%s'\n", c);
05104                return -2;
05105             }
05106          }
05107 
05108       }
05109    }
05110    if (portno == -1 && vportno == -1 && udptlportno == -1)
05111       /* No acceptable offer found in SDP  - we have no ports */
05112       /* Do not change RTP or VRTP if this is a re-invite */
05113       return -2;
05114 
05115    if (numberofmediastreams > 2)
05116       /* We have too many fax, audio and/or video media streams, fail this offer */
05117       return -3;
05118 
05119    /* RTP addresses and ports for audio and video */
05120    sin.sin_family = AF_INET;
05121    vsin.sin_family = AF_INET;
05122    memcpy(&sin.sin_addr, hp->h_addr, sizeof(sin.sin_addr));
05123    if (vhp)
05124       memcpy(&vsin.sin_addr, vhp->h_addr, sizeof(vsin.sin_addr));
05125 
05126    /* Setup UDPTL port number */
05127    if (p->udptl) {
05128       if (udptlportno > 0) {
05129          sin.sin_port = htons(udptlportno);
05130          ast_udptl_set_peer(p->udptl, &sin);
05131          if (debug)
05132             ast_log(LOG_DEBUG,"Peer T.38 UDPTL is at port %s:%d\n",ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
05133       } else {
05134          ast_udptl_stop(p->udptl);
05135          if (debug)
05136             ast_log(LOG_DEBUG, "Peer doesn't provide T.38 UDPTL\n");
05137       }
05138    }
05139 
05140       
05141    if (p->rtp) {
05142       if (portno > 0) {
05143          sin.sin_port = htons(portno);
05144          ast_rtp_set_peer(p->rtp, &sin);
05145          if (debug)
05146             ast_verbose("Peer audio RTP is at port %s:%d\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
05147       } else {
05148          if (udptlportno > 0) {
05149             if (debug)
05150                ast_verbose("Got T.38 Re-invite without audio. Keeping RTP active during T.38 session. Callid %s\n", p->callid);
05151          } else {
05152             ast_rtp_stop(p->rtp);
05153             if (debug)
05154                ast_verbose("Peer doesn't provide audio. Callid %s\n", p->callid);
05155          }
05156       }
05157    }
05158    /* Setup video port number */
05159    if (vportno != -1)
05160       vsin.sin_port = htons(vportno);
05161 
05162    /* Next, scan through each "a=rtpmap:" line, noting each
05163     * specified RTP payload type (with corresponding MIME subtype):
05164     */
05165    /* XXX This needs to be done per media stream, since it's media stream specific */
05166    iterator = req->sdp_start;
05167    while ((a = get_sdp_iterate(&iterator, req, "a"))[0] != '\0') {
05168       char* mimeSubtype = ast_strdupa(a); /* ensures we have enough space */
05169       if (option_debug > 1) {
05170          int breakout = FALSE;
05171       
05172          /* If we're debugging, check for unsupported sdp options */
05173          if (!strncasecmp(a, "rtcp:", (size_t) 5)) {
05174             if (debug)
05175                ast_verbose("Got unsupported a:rtcp in SDP offer \n");
05176             breakout = TRUE;
05177          } else if (!strncasecmp(a, "fmtp:", (size_t) 5)) {
05178             /* Format parameters:  Not supported */
05179             /* Note: This is used for codec parameters, like bitrate for
05180                G722 and video formats for H263 and H264 
05181                See RFC2327 for an example */
05182             if (debug)
05183                ast_verbose("Got unsupported a:fmtp in SDP offer \n");
05184             breakout = TRUE;
05185          } else if (!strncasecmp(a, "framerate:", (size_t) 10)) {
05186             /* Video stuff:  Not supported */
05187             if (debug)
05188                ast_verbose("Got unsupported a:framerate in SDP offer \n");
05189             breakout = TRUE;
05190          } else if (!strncasecmp(a, "maxprate:", (size_t) 9)) {
05191             /* Video stuff:  Not supported */
05192             if (debug)
05193                ast_verbose("Got unsupported a:maxprate in SDP offer \n");
05194             breakout = TRUE;
05195          } else if (!strncasecmp(a, "crypto:", (size_t) 7)) {
05196             /* SRTP stuff, not yet supported */
05197             if (debug)
05198                ast_verbose("Got unsupported a:crypto in SDP offer \n");
05199             breakout = TRUE;
05200          }
05201          if (breakout)  /* We have a match, skip to next header */
05202             continue;
05203       }
05204       if (!strcasecmp(a, "sendonly")) {
05205          if (sendonly == -1)
05206             sendonly = 1;
05207          continue;
05208       } else if (!strcasecmp(a, "inactive")) {
05209          if (sendonly == -1)
05210             sendonly = 2;
05211          continue;
05212       }  else if (!strcasecmp(a, "sendrecv")) {
05213          if (sendonly == -1)
05214             sendonly = 0;
05215          continue;
05216       } else if (strlen(a) > 5 && !strncasecmp(a, "ptime", 5)) {
05217          char *tmp = strrchr(a, ':');
05218          long int framing = 0;
05219          if (tmp) {
05220             tmp++;
05221             framing = strtol(tmp, NULL, 10);
05222             if (framing == LONG_MIN || framing == LONG_MAX) {
05223                framing = 0;
05224                if (option_debug)
05225                   ast_log(LOG_DEBUG, "Can't read framing from SDP: %s\n", a);
05226             }
05227          }
05228          if (framing && last_rtpmap_codec) {
05229             if (p->autoframing) {
05230                struct ast_codec_pref *pref = ast_rtp_codec_getpref(p->rtp);
05231                int codec_n;
05232                int format = 0;
05233                for (codec_n = 0; codec_n < last_rtpmap_codec; codec_n++) {
05234                   format = ast_rtp_codec_getformat(found_rtpmap_codecs[codec_n]);
05235                   if (!format)   /* non-codec or not found */
05236                      continue;
05237                   if (option_debug)
05238                      ast_log(LOG_DEBUG, "Setting framing for %d to %ld\n", format, framing);
05239                   ast_codec_pref_setsize(pref, format, framing);
05240                }
05241                ast_rtp_codec_setpref(p->rtp, pref);
05242             }
05243          }
05244          memset(&found_rtpmap_codecs, 0, sizeof(found_rtpmap_codecs));
05245          last_rtpmap_codec = 0;
05246          continue;
05247       } else if (sscanf(a, "rtpmap: %u %[^/]/", &codec, mimeSubtype) == 2) {
05248          /* We have a rtpmap to handle */
05249          int found = FALSE;
05250          /* We should propably check if this is an audio or video codec
05251             so we know where to look */
05252 
05253          if (last_rtpmap_codec < SDP_MAX_RTPMAP_CODECS) {
05254             /* Note: should really look at the 'freq' and '#chans' params too */
05255             if(ast_rtp_set_rtpmap_type(newaudiortp, codec, "audio", mimeSubtype,
05256                         ast_test_flag(&p->flags[0], SIP_G726_NONSTANDARD) ? AST_RTP_OPT_G726_NONSTANDARD : 0) != -1) {
05257                if (debug)
05258                   ast_verbose("Found audio description format %s for ID %d\n", mimeSubtype, codec);
05259                found_rtpmap_codecs[last_rtpmap_codec] = codec;
05260                last_rtpmap_codec++;
05261                found = TRUE;
05262                
05263             } else if (p->vrtp) {
05264                if(ast_rtp_set_rtpmap_type(newvideortp, codec, "video", mimeSubtype, 0) != -1) {
05265                   if (debug)
05266                      ast_verbose("Found video description format %s for ID %d\n", mimeSubtype, codec);
05267                   found_rtpmap_codecs[last_rtpmap_codec] = codec;
05268                   last_rtpmap_codec++;
05269                   found = TRUE;
05270                }
05271             }
05272          } else {
05273             if (debug)
05274                ast_verbose("Discarded description format %s for ID %d\n", mimeSubtype, codec);
05275          }
05276 
05277          if (!found) {
05278             /* Remove this codec since it's an unknown media type for us */
05279             /* XXX This is buggy since the media line for audio and video can have the
05280                same numbers. We need to check as described above, but for testing this works... */
05281             ast_rtp_unset_m_type(newaudiortp, codec);
05282             ast_rtp_unset_m_type(newvideortp, codec);
05283             if (debug) 
05284                ast_verbose("Found unknown media description format %s for ID %d\n", mimeSubtype, codec);
05285          }
05286       }
05287    }
05288    
05289    if (udptlportno != -1) {
05290       int found = 0, x;
05291       
05292       old = 0;
05293       
05294       /* Scan trough the a= lines for T38 attributes and set apropriate fileds */
05295       iterator = req->sdp_start;
05296       while ((a = get_sdp_iterate(&iterator, req, "a"))[0] != '\0') {
05297          if ((sscanf(a, "T38FaxMaxBuffer:%d", &x) == 1)) {
05298             found = 1;
05299             if (option_debug > 2)
05300                ast_log(LOG_DEBUG, "MaxBufferSize:%d\n",x);
05301          } else if ((sscanf(a, "T38MaxBitRate:%d", &x) == 1)) {
05302             found = 1;
05303             if (option_debug > 2)
05304                ast_log(LOG_DEBUG,"T38MaxBitRate: %d\n",x);
05305             switch (x) {
05306             case 14400:
05307                peert38capability |= T38FAX_RATE_14400 | T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400;
05308                break;
05309             case 12000:
05310                peert38capability |= T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400;
05311                break;
05312             case 9600:
05313                peert38capability |= T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400;
05314                break;
05315             case 7200:
05316                peert38capability |= T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400;
05317                break;
05318             case 4800:
05319                peert38capability |= T38FAX_RATE_4800 | T38FAX_RATE_2400;
05320                break;
05321             case 2400:
05322                peert38capability |= T38FAX_RATE_2400;
05323                break;
05324             }
05325          } else if ((sscanf(a, "T38FaxVersion:%d", &x) == 1)) {
05326             found = 1;
05327             if (option_debug > 2)
05328                ast_log(LOG_DEBUG, "FaxVersion: %d\n",x);
05329             if (x == 0)
05330                peert38capability |= T38FAX_VERSION_0;
05331             else if (x == 1)
05332                peert38capability |= T38FAX_VERSION_1;
05333          } else if ((sscanf(a, "T38FaxMaxDatagram:%d", &x) == 1)) {
05334             found = 1;
05335             if (option_debug > 2)
05336                ast_log(LOG_DEBUG, "FaxMaxDatagram: %d\n",x);
05337             ast_udptl_set_far_max_datagram(p->udptl, x);
05338             ast_udptl_set_local_max_datagram(p->udptl, x);
05339          } else if ((sscanf(a, "T38FaxFillBitRemoval:%d", &x) == 1)) {
05340             found = 1;
05341             if (option_debug > 2)
05342                ast_log(LOG_DEBUG, "FillBitRemoval: %d\n",x);
05343             if (x == 1)
05344                peert38capability |= T38FAX_FILL_BIT_REMOVAL;
05345          } else if ((sscanf(a, "T38FaxTranscodingMMR:%d", &x) == 1)) {
05346             found = 1;
05347             if (option_debug > 2)
05348                ast_log(LOG_DEBUG, "Transcoding MMR: %d\n",x);
05349             if (x == 1)
05350                peert38capability |= T38FAX_TRANSCODING_MMR;
05351          }
05352          if ((sscanf(a, "T38FaxTranscodingJBIG:%d", &x) == 1)) {
05353             found = 1;
05354             if (option_debug > 2)
05355                ast_log(LOG_DEBUG, "Transcoding JBIG: %d\n",x);
05356             if (x == 1)
05357                peert38capability |= T38FAX_TRANSCODING_JBIG;
05358          } else if ((sscanf(a, "T38FaxRateManagement:%255s", s) == 1)) {
05359             found = 1;
05360             if (option_debug > 2)
05361                ast_log(LOG_DEBUG, "RateManagement: %s\n", s);
05362             if (!strcasecmp(s, "localTCF"))
05363                peert38capability |= T38FAX_RATE_MANAGEMENT_LOCAL_TCF;
05364             else if (!strcasecmp(s, "transferredTCF"))
05365                peert38capability |= T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF;
05366          } else if ((sscanf(a, "T38FaxUdpEC:%255s", s) == 1)) {
05367             found = 1;
05368             if (option_debug > 2)
05369                ast_log(LOG_DEBUG, "UDP EC: %s\n", s);
05370             if (!strcasecmp(s, "t38UDPRedundancy")) {
05371                peert38capability |= T38FAX_UDP_EC_REDUNDANCY;
05372                ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_REDUNDANCY);
05373             } else if (!strcasecmp(s, "t38UDPFEC")) {
05374                peert38capability |= T38FAX_UDP_EC_FEC;
05375                ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_FEC);
05376             } else {
05377                peert38capability |= T38FAX_UDP_EC_NONE;
05378                ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_NONE);
05379             }
05380          }
05381       }
05382       if (found) { /* Some cisco equipment returns nothing beside c= and m= lines in 200 OK T38 SDP */
05383          p->t38.peercapability = peert38capability;
05384          p->t38.jointcapability = (peert38capability & 255); /* Put everything beside supported speeds settings */
05385          peert38capability &= (T38FAX_RATE_14400 | T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400);
05386          p->t38.jointcapability |= (peert38capability & p->t38.capability); /* Put the lower of our's and peer's speed */
05387       }
05388       if (debug)
05389          ast_log(LOG_DEBUG, "Our T38 capability = (%d), peer T38 capability (%d), joint T38 capability (%d)\n",
05390             p->t38.capability,
05391             p->t38.peercapability,
05392             p->t38.jointcapability);
05393    } else {
05394       p->t38.state = T38_DISABLED;
05395       if (option_debug > 2)
05396          ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>");
05397    }
05398 
05399    /* Now gather all of the codecs that we are asked for: */
05400    ast_rtp_get_current_formats(newaudiortp, &peercapability, &peernoncodeccapability);
05401    ast_rtp_get_current_formats(newvideortp, &vpeercapability, &vpeernoncodeccapability);
05402 
05403    newjointcapability = p->capability & (peercapability | vpeercapability);
05404    newpeercapability = (peercapability | vpeercapability);
05405    newnoncodeccapability = p->noncodeccapability & peernoncodeccapability;
05406       
05407       
05408    if (debug) {
05409       /* shame on whoever coded this.... */
05410       char s1[BUFSIZ], s2[BUFSIZ], s3[BUFSIZ], s4[BUFSIZ];
05411 
05412       ast_verbose("Capabilities: us - %s, peer - audio=%s/video=%s, combined - %s\n",
05413              ast_getformatname_multiple(s1, BUFSIZ, p->capability),
05414              ast_getformatname_multiple(s2, BUFSIZ, newpeercapability),
05415              ast_getformatname_multiple(s3, BUFSIZ, vpeercapability),
05416              ast_getformatname_multiple(s4, BUFSIZ, newjointcapability));
05417 
05418       ast_verbose("Non-codec capabilities (dtmf): us - %s, peer - %s, combined - %s\n",
05419              ast_rtp_lookup_mime_multiple(s1, BUFSIZ, p->noncodeccapability, 0, 0),
05420              ast_rtp_lookup_mime_multiple(s2, BUFSIZ, peernoncodeccapability, 0, 0),
05421              ast_rtp_lookup_mime_multiple(s3, BUFSIZ, newnoncodeccapability, 0, 0));
05422    }
05423    if (!newjointcapability) {
05424       /* If T.38 was not negotiated either, totally bail out... */
05425       if (!p->t38.jointcapability) {
05426          ast_log(LOG_NOTICE, "No compatible codecs, not accepting this offer!\n");
05427          /* Do NOT Change current setting */
05428          return -1;
05429       } else {
05430          if (option_debug > 2)
05431             ast_log(LOG_DEBUG, "Have T.38 but no audio codecs, accepting offer anyway\n");
05432          return 0;
05433       }
05434    }
05435 
05436    /* We are now ready to change the sip session and p->rtp and p->vrtp with the offered codecs, since
05437       they are acceptable */
05438    p->jointcapability = newjointcapability;          /* Our joint codec profile for this call */
05439    p->peercapability = newpeercapability;            /* The other sides capability in latest offer */
05440    p->jointnoncodeccapability = newnoncodeccapability;   /* DTMF capabilities */
05441 
05442    ast_rtp_pt_copy(p->rtp, newaudiortp);
05443    if (p->vrtp)
05444       ast_rtp_pt_copy(p->vrtp, newvideortp);
05445 
05446    if (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO) {
05447       ast_clear_flag(&p->flags[0], SIP_DTMF);
05448       if (newnoncodeccapability & AST_RTP_DTMF) {
05449          /* XXX Would it be reasonable to drop the DSP at this point? XXX */
05450          ast_set_flag(&p->flags[0], SIP_DTMF_RFC2833);
05451          /* Since RFC2833 is now negotiated we need to change some properties of the RTP stream */
05452          ast_rtp_setdtmf(p->rtp, 1);
05453          ast_rtp_setdtmfcompensate(p->rtp, ast_test_flag(&p->flags[1], SIP_PAGE2_RFC2833_COMPENSATE));
05454       } else {
05455          ast_set_flag(&p->flags[0], SIP_DTMF_INBAND);
05456       }
05457    }
05458 
05459    /* Setup audio port number */
05460    if (p->rtp && sin.sin_port) {
05461       ast_rtp_set_peer(p->rtp, &sin);
05462       if (debug)
05463          ast_verbose("Peer audio RTP is at port %s:%d\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
05464    }
05465 
05466    /* Setup video port number */
05467    if (p->vrtp && vsin.sin_port) {
05468       ast_rtp_set_peer(p->vrtp, &vsin);
05469       if (debug) 
05470          ast_verbose("Peer video RTP is at port %s:%d\n", ast_inet_ntoa(vsin.sin_addr), ntohs(vsin.sin_port));
05471    }
05472 
05473    /* Ok, we're going with this offer */
05474    if (option_debug > 1) {
05475       char buf[BUFSIZ];
05476       ast_log(LOG_DEBUG, "We're settling with these formats: %s\n", ast_getformatname_multiple(buf, BUFSIZ, p->jointcapability));
05477    }
05478 
05479    if (!p->owner)    /* There's no open channel owning us so we can return here. For a re-invite or so, we proceed */
05480       return 0;
05481 
05482    if (option_debug > 3)
05483       ast_log(LOG_DEBUG, "We have an owner, now see if we need to change this call\n");
05484 
05485    if (!(p->owner->nativeformats & p->jointcapability) && (p->jointcapability & AST_FORMAT_AUDIO_MASK)) {
05486       if (debug) {
05487          char s1[BUFSIZ], s2[BUFSIZ];
05488          ast_log(LOG_DEBUG, "Oooh, we need to change our audio formats since our peer supports only %s and not %s\n", 
05489             ast_getformatname_multiple(s1, BUFSIZ, p->jointcapability),
05490             ast_getformatname_multiple(s2, BUFSIZ, p->owner->nativeformats));
05491       }
05492       p->owner->nativeformats = ast_codec_choose(&p->prefs, p->jointcapability, 1) | (p->capability & vpeercapability);
05493       ast_set_read_format(p->owner, p->owner->readformat);
05494       ast_set_write_format(p->owner, p->owner->writeformat);
05495    }
05496    
05497    if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) && sin.sin_addr.s_addr && (!sendonly || sendonly == -1)) {
05498       ast_queue_control(p->owner, AST_CONTROL_UNHOLD);
05499       /* Activate a re-invite */
05500       ast_queue_frame(p->owner, &ast_null_frame);
05501    } else if (!sin.sin_addr.s_addr || (sendonly && sendonly != -1)) {
05502       ast_queue_control_data(p->owner, AST_CONTROL_HOLD, 
05503                    S_OR(p->mohsuggest, NULL),
05504                    !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
05505       if (sendonly)
05506          ast_rtp_stop(p->rtp);
05507       /* RTCP needs to go ahead, even if we're on hold!!! */
05508       /* Activate a re-invite */
05509       ast_queue_frame(p->owner, &ast_null_frame);
05510    }
05511 
05512    /* Manager Hold and Unhold events must be generated, if necessary */
05513    if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) && sin.sin_addr.s_addr && (!sendonly || sendonly == -1))
05514       change_hold_state(p, req, FALSE, sendonly);
05515    else if (!sin.sin_addr.s_addr || (sendonly && sendonly != -1))
05516       change_hold_state(p, req, TRUE, sendonly);
05517    return 0;
05518 }

static struct sip_peer * realtime_peer ( const char *  newpeername,
struct sockaddr_in *  sin 
) [static, read]

realtime_peer: Get peer from realtime storage Checks the "sippeers" realtime family from extconfig.conf

Todo:
Consider adding check of port address when matching here to follow the same algorithm as for static peers. Will we break anything by adding that?

Note:
If this one loaded something, then we need to ensure that the host field matched. The only reason why we can't have this as a criteria is because we only have the IP address and the host field might be set as a name (and the reverse PTR might not match).

Definition at line 2489 of file chan_sip.c.

References ast_category_browse(), ast_category_root(), ast_config_destroy(), ast_copy_flags, ast_dnsmgr_lookup(), ast_inet_ntoa(), ast_load_realtime(), ast_load_realtime_multientry(), ast_log(), ast_sched_add(), ast_sched_del(), ast_set_flag, ast_test_flag, ast_variable_retrieve(), ast_variables_destroy(), ASTOBJ_CONTAINER_LINK, build_peer(), sip_peer::expire, expire_register(), sip_peer::flags, LOG_WARNING, ast_variable::name, ast_variable::next, peerl, set_insecure_flags(), SIP_INSECURE_PORT, SIP_PAGE2_RTAUTOCLEAR, SIP_PAGE2_RTCACHEFRIENDS, SIP_REALTIME, ast_variable::value, and var.

02490 {
02491    struct sip_peer *peer=NULL;
02492    struct ast_variable *var = NULL;
02493    struct ast_config *peerlist = NULL;
02494    struct ast_variable *tmp;
02495    struct ast_flags flags = {0};
02496    const char *iabuf = NULL;
02497    char portstring[6]; /*up to five digits plus null terminator*/
02498    const char *insecure; 
02499    char *cat = NULL;
02500    unsigned short portnum;
02501 
02502    /* First check on peer name */
02503    if (newpeername) {
02504       var = ast_load_realtime("sippeers", "name", newpeername, "host", "dynamic", NULL);
02505       if (!var && sin)
02506          var = ast_load_realtime("sippeers", "name", newpeername, "host", ast_inet_ntoa(sin->sin_addr), NULL);
02507       if (!var) {
02508          var = ast_load_realtime("sippeers", "name", newpeername, NULL);
02509          /*!\note
02510           * If this one loaded something, then we need to ensure that the host
02511           * field matched.  The only reason why we can't have this as a criteria
02512           * is because we only have the IP address and the host field might be
02513           * set as a name (and the reverse PTR might not match).
02514           */
02515          if (var) {
02516             for (tmp = var; tmp; tmp = tmp->next) {
02517                if (!strcasecmp(var->name, "host")) {
02518                   struct in_addr sin2 = { 0, };
02519                   struct ast_dnsmgr_entry *dnsmgr = NULL;
02520                   if ((ast_dnsmgr_lookup(tmp->value, &sin2, &dnsmgr) < 0) || (memcmp(&sin2, &sin->sin_addr, sizeof(sin2)) != 0)) {
02521                      /* No match */
02522                      ast_variables_destroy(var);
02523                      var = NULL;
02524                   }
02525                   break;
02526                }
02527             }
02528          }
02529       }
02530    }
02531 
02532    if (!var && sin) {   /* Then check on IP address */
02533       iabuf = ast_inet_ntoa(sin->sin_addr);
02534       portnum = ntohs(sin->sin_port);
02535       sprintf(portstring, "%d", portnum);
02536       var = ast_load_realtime("sippeers", "host", iabuf, "port", portstring, NULL); /* First check for fixed IP hosts */
02537       if (!var)
02538          var = ast_load_realtime("sippeers", "ipaddr", iabuf, "port", portstring, NULL);  /* Then check for registered hosts */
02539       if (!var) { 
02540          peerlist = ast_load_realtime_multientry("sippeers", "host", iabuf, NULL); /*No exact match, see if port is insecure, try host match first*/
02541          if(peerlist){ 
02542             while((cat = ast_category_browse(peerlist, cat)))
02543             {
02544                insecure = ast_variable_retrieve(peerlist, cat, "insecure");
02545                set_insecure_flags(&flags, insecure, -1);
02546                if(ast_test_flag(&flags, SIP_INSECURE_PORT)) {
02547                   var = ast_category_root(peerlist, cat);
02548                   break;
02549                }
02550             }
02551          }
02552          if(!var) {
02553             ast_config_destroy(peerlist);
02554             peerlist = NULL; /*for safety's sake*/
02555             cat = NULL;
02556             peerlist = ast_load_realtime_multientry("sippeers", "ipaddr", iabuf, NULL); /*No exact match, see if port is insecure, now try ip address match*/
02557             if(peerlist) {
02558                while((cat = ast_category_browse(peerlist, cat)))
02559                {
02560                   insecure = ast_variable_retrieve(peerlist, cat, "insecure");
02561                   set_insecure_flags(&flags, insecure, -1);
02562                   if(ast_test_flag(&flags, SIP_INSECURE_PORT)) {
02563                      var = ast_category_root(peerlist, cat);
02564                      break;
02565                   }
02566                }
02567             }
02568          }
02569       }
02570    }
02571 
02572    if (!var) {
02573       if(peerlist)
02574          ast_config_destroy(peerlist);
02575       return NULL;
02576    }
02577 
02578    for (tmp = var; tmp; tmp = tmp->next) {
02579       /* If this is type=user, then skip this object. */
02580       if (!strcasecmp(tmp->name, "type") &&
02581           !strcasecmp(tmp->value, "user")) {
02582          ast_variables_destroy(var);
02583          return NULL;
02584       } else if (!newpeername && !strcasecmp(tmp->name, "name")) {
02585          newpeername = tmp->value;
02586       }
02587    }
02588    
02589    if (!newpeername) {  /* Did not find peer in realtime */
02590       ast_log(LOG_WARNING, "Cannot Determine peer name ip=%s\n", iabuf);
02591       if(peerlist)
02592          ast_config_destroy(peerlist);
02593       else
02594          ast_variables_destroy(var);
02595       return NULL;
02596    }
02597 
02598    /* Peer found in realtime, now build it in memory */
02599    peer = build_peer(newpeername, var, NULL, !ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS));
02600    if (!peer) {
02601       if(peerlist)
02602          ast_config_destroy(peerlist);
02603       else
02604          ast_variables_destroy(var);
02605       return NULL;
02606    }
02607 
02608    if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) {
02609       /* Cache peer */
02610       ast_copy_flags(&peer->flags[1],&global_flags[1], SIP_PAGE2_RTAUTOCLEAR|SIP_PAGE2_RTCACHEFRIENDS);
02611       if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTAUTOCLEAR)) {
02612          if (peer->expire > -1) {
02613             ast_sched_del(sched, peer->expire);
02614          }
02615          peer->expire = ast_sched_add(sched, (global_rtautoclear) * 1000, expire_register, (void *)peer);
02616       }
02617       ASTOBJ_CONTAINER_LINK(&peerl,peer);
02618    } else {
02619       ast_set_flag(&peer->flags[0], SIP_REALTIME);
02620    }
02621    if(peerlist)
02622       ast_config_destroy(peerlist);
02623    else
02624       ast_variables_destroy(var);
02625    return peer;
02626 }

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

Update peer object in realtime storage If the Asterisk system name is set in asterisk.conf, we will use that name and store that in the "regserver" field in the sippeers table to facilitate multi-server setups.

Definition at line 2374 of file chan_sip.c.

References ast_config_AST_SYSTEM_NAME, ast_inet_ntoa(), ast_strlen_zero(), ast_test_flag, ast_update_realtime(), ipaddr, and SIP_PAGE2_RTSAVE_SYSNAME.

02375 {
02376    char port[10];
02377    char ipaddr[INET_ADDRSTRLEN];
02378    char regseconds[20];
02379 
02380    char *sysname = ast_config_AST_SYSTEM_NAME;
02381    char *syslabel = NULL;
02382 
02383    time_t nowtime = time(NULL) + expirey;
02384    const char *fc = fullcontact ? "fullcontact" : NULL;
02385    
02386    snprintf(regseconds, sizeof(regseconds), "%d", (int)nowtime);  /* Expiration time */
02387    ast_copy_string(ipaddr, ast_inet_ntoa(sin->sin_addr), sizeof(ipaddr));
02388    snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port));
02389    
02390    if (ast_strlen_zero(sysname)) /* No system name, disable this */
02391       sysname = NULL;
02392    else if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTSAVE_SYSNAME))
02393       syslabel = "regserver";
02394 
02395    if (fc)
02396       ast_update_realtime("sippeers", "name", peername, "ipaddr", ipaddr,
02397          "port", port, "regseconds", regseconds,
02398          "username", username, fc, fullcontact, syslabel, sysname, NULL); /* note fc and syslabel _can_ be NULL */
02399    else
02400       ast_update_realtime("sippeers", "name", peername, "ipaddr", ipaddr,
02401          "port", port, "regseconds", regseconds,
02402          "username", username, syslabel, sysname, NULL); /* note syslabel _can_ be NULL */
02403 }

static struct sip_user * realtime_user ( const char *  username  )  [static, read]

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

References ast_load_realtime(), ast_set_flag, ast_test_flag, ast_variables_destroy(), ASTOBJ_CONTAINER_LINK, build_user(), sip_user::flags, ast_variable::name, ast_variable::next, SIP_PAGE2_RTCACHEFRIENDS, SIP_REALTIME, userl, ast_variable::value, and var.

02677 {
02678    struct ast_variable *var;
02679    struct ast_variable *tmp;
02680    struct sip_user *user = NULL;
02681 
02682    var = ast_load_realtime("sipusers", "name", username, NULL);
02683 
02684    if (!var)
02685       return NULL;
02686 
02687    for (tmp = var; tmp; tmp = tmp->next) {
02688       if (!strcasecmp(tmp->name, "type") &&
02689          !strcasecmp(tmp->value, "peer")) {
02690          ast_variables_destroy(var);
02691          return NULL;
02692       }
02693    }
02694 
02695    user = build_user(username, var, !ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS));
02696    
02697    if (!user) {   /* No user found */
02698       ast_variables_destroy(var);
02699       return NULL;
02700    }
02701 
02702    if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) {
02703       ast_set_flag(&user->flags[1], SIP_PAGE2_RTCACHEFRIENDS);
02704       suserobjs++;
02705       ASTOBJ_CONTAINER_LINK(&userl,user);
02706    } else {
02707       /* Move counter from s to r... */
02708       suserobjs--;
02709       ruserobjs++;
02710       ast_set_flag(&user->flags[0], SIP_REALTIME);
02711    }
02712    ast_variables_destroy(var);
02713    return user;
02714 }

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

Receive SIP MESSAGE method messages.

Note:
We only handle messages within current calls currently Reference: RFC 3428

Definition at line 9596 of file chan_sip.c.

References AST_FRAME_TEXT, ast_log(), ast_queue_frame(), ast_verbose(), ast_frame::data, ast_frame::datalen, DEFAULT_TRANS_TIMEOUT, ast_frame::frametype, get_header(), get_msg_text(), LOG_WARNING, ast_frame::offset, sip_pvt::owner, sip_debug_test_pvt(), sip_scheddestroy(), ast_frame::subclass, and transmit_response().

Referenced by handle_request_message().

09597 {
09598    char buf[1024];
09599    struct ast_frame f;
09600    const char *content_type = get_header(req, "Content-Type");
09601 
09602    if (strcmp(content_type, "text/plain")) { /* No text/plain attachment */
09603       transmit_response(p, "415 Unsupported Media Type", req); /* Good enough, or? */
09604       if (!p->owner)
09605          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
09606       return;
09607    }
09608 
09609    if (get_msg_text(buf, sizeof(buf), req)) {
09610       ast_log(LOG_WARNING, "Unable to retrieve text from %s\n", p->callid);
09611       transmit_response(p, "202 Accepted", req);
09612       if (!p->owner)
09613          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
09614       return;
09615    }
09616 
09617    if (p->owner) {
09618       if (sip_debug_test_pvt(p))
09619          ast_verbose("Message received: '%s'\n", buf);
09620       memset(&f, 0, sizeof(f));
09621       f.frametype = AST_FRAME_TEXT;
09622       f.subclass = 0;
09623       f.offset = 0;
09624       f.data = buf;
09625       f.datalen = strlen(buf);
09626       ast_queue_frame(p->owner, &f);
09627       transmit_response(p, "202 Accepted", req); /* We respond 202 accepted, since we relay the message */
09628    } else { /* Message outside of a call, we do not support that */
09629       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);
09630       transmit_response(p, "405 Method Not Allowed", req); /* Good enough, or? */
09631       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
09632    }
09633    return;
09634 }

static char * referstatus2str ( enum referstatus  rstatus  )  [static]

Convert transfer status to string.

Definition at line 1624 of file chan_sip.c.

References referstatusstrings, and c_referstatusstring::text.

Referenced by __sip_show_channels().

01625 {
01626    int i = (sizeof(referstatusstrings) / sizeof(referstatusstrings[0]));
01627    int x;
01628 
01629    for (x = 0; x < i; x++) {
01630       if (referstatusstrings[x].status ==  rstatus)
01631          return (char *) referstatusstrings[x].text;
01632    }
01633    return "";
01634 }

static void reg_source_db ( struct sip_peer peer  )  [static]

Get registration details from Asterisk DB.

Definition at line 7863 of file chan_sip.c.

References sip_peer::addr, ast_db_get(), ast_inet_ntoa(), ast_log(), ast_random(), ast_sched_add(), ast_sched_del(), ast_test_flag, sip_peer::expire, expire_register(), sip_peer::flags, sip_peer::fullcontact, LOG_DEBUG, option_debug, sip_peer::pokeexpire, register_peer_exten(), SIP_PAGE2_RT_FROMCONTACT, sip_poke_peer(), sip_poke_peer_s(), sipsock, strsep(), TRUE, sip_peer::username, and username.

07864 {
07865    char data[256];
07866    struct in_addr in;
07867    int expiry;
07868    int port;
07869    char *scan, *addr, *port_str, *expiry_str, *username, *contact;
07870 
07871    if (ast_test_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT)) 
07872       return;
07873    if (ast_db_get("SIP/Registry", peer->name, data, sizeof(data)))
07874       return;
07875 
07876    scan = data;
07877    addr = strsep(&scan, ":");
07878    port_str = strsep(&scan, ":");
07879    expiry_str = strsep(&scan, ":");
07880    username = strsep(&scan, ":");
07881    contact = scan;   /* Contact include sip: and has to be the last part of the database entry as long as we use : as a separator */
07882 
07883    if (!inet_aton(addr, &in))
07884       return;
07885 
07886    if (port_str)
07887       port = atoi(port_str);
07888    else
07889       return;
07890 
07891    if (expiry_str)
07892       expiry = atoi(expiry_str);
07893    else
07894       return;
07895 
07896    if (username)
07897       ast_copy_string(peer->username, username, sizeof(peer->username));
07898    if (contact)
07899       ast_copy_string(peer->fullcontact, contact, sizeof(peer->fullcontact));
07900 
07901    if (option_debug > 1)
07902       ast_log(LOG_DEBUG, "SIP Seeding peer from astdb: '%s' at %s@%s:%d for %d\n",
07903              peer->name, peer->username, ast_inet_ntoa(in), port, expiry);
07904 
07905    memset(&peer->addr, 0, sizeof(peer->addr));
07906    peer->addr.sin_family = AF_INET;
07907    peer->addr.sin_addr = in;
07908    peer->addr.sin_port = htons(port);
07909    if (sipsock < 0) {
07910       /* SIP isn't up yet, so schedule a poke only, pretty soon */
07911       if (peer->pokeexpire > -1)
07912          ast_sched_del(sched, peer->pokeexpire);
07913       peer->pokeexpire = ast_sched_add(sched, ast_random() % 5000 + 1, sip_poke_peer_s, peer);
07914    } else
07915       sip_poke_peer(peer);
07916    if (peer->expire > -1)
07917       ast_sched_del(sched, peer->expire);
07918    peer->expire = ast_sched_add(sched, (expiry + 10) * 1000, expire_register, peer);
07919    register_peer_exten(peer, TRUE);
07920 }

static void register_peer_exten ( struct sip_peer peer,
int  onoff 
) [static]

Automatically add peer extension to dial plan.

Definition at line 2406 of file chan_sip.c.

References ast_add_extension(), ast_context_find(), ast_context_remove_extension(), ast_free, ast_log(), ast_strdup, ast_strlen_zero(), domain::context, ext, LOG_WARNING, sip_peer::regexten, S_OR, and strsep().

02407 {
02408    char multi[256];
02409    char *stringp, *ext, *context;
02410 
02411    /* XXX note that global_regcontext is both a global 'enable' flag and
02412     * the name of the global regexten context, if not specified
02413     * individually.
02414     */
02415    if (ast_strlen_zero(global_regcontext))
02416       return;
02417 
02418    ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi));
02419    stringp = multi;
02420    while ((ext = strsep(&stringp, "&"))) {
02421       if ((context = strchr(ext, '@'))) {
02422          *context++ = '\0';   /* split ext@context */
02423          if (!ast_context_find(context)) {
02424             ast_log(LOG_WARNING, "Context %s must exist in regcontext= in sip.conf!\n", context);
02425             continue;
02426          }
02427       } else {
02428          context = global_regcontext;
02429       }
02430       if (onoff)
02431          ast_add_extension(context, 1, ext, 1, NULL, NULL, "Noop",
02432              ast_strdup(peer->name), ast_free, "SIP");
02433       else
02434          ast_context_remove_extension(context, ext, 1, NULL);
02435    }
02436 }

static enum check_auth_result register_verify ( struct sip_pvt p,
struct sockaddr_in *  sin,
struct sip_request req,
char *  uri 
) [static]

Verify registration of user

  • Registration is done in several steps, first a REGISTER without auth to get a challenge (nonce) then a second one with auth
  • Registration requests are only matched with peers that are marked as "dynamic".

Definition at line 8516 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_rtp_codec_setpref(), ast_string_field_set, ast_test_flag, ast_uri_decode(), ASTOBJ_CONTAINER_LINK, ASTOBJ_UNREF, AUTH_ACL_FAILED, AUTH_NOT_FOUND, AUTH_PEER_NOT_DYNAMIC, AUTH_SECRET_FAILED, AUTH_UNKNOWN_DOMAIN, AUTH_USERNAME_MISMATCH, sip_peer::autoframing, sip_pvt::autoframing, build_contact(), check_auth(), check_sip_domain(), EVENT_FLAG_SYSTEM, sip_pvt::expiry, exten, find_peer(), sip_pvt::flags, sip_peer::flags, get_header(), get_in_brackets(), sip_peer::ha, sip_pvt::initreq, sip_peer::lastmsgssent, LOG_ERROR, LOG_NOTICE, LOG_WARNING, manager_event(), sip_peer::md5secret, name, parse_register_contact(), PARSE_REGISTER_FAILED, PARSE_REGISTER_QUERY, PARSE_REGISTER_UPDATE, peerl, sip_peer::prefs, sip_pvt::rtp, sip_peer::secret, sip_cancel_destroy(), sip_destroy_peer(), SIP_NAT, SIP_PAGE2_DYNAMIC, SIP_PAGE2_SUBSCRIBEMWIONLY, SIP_PKT_IGNORE, SIP_REGISTER, strsep(), t, temp_peer(), transmit_fake_auth_response(), transmit_response(), transmit_response_with_date(), update_peer(), and XMIT_UNRELIABLE.

08518 {
08519    enum check_auth_result res = AUTH_NOT_FOUND;
08520    struct sip_peer *peer;
08521    char tmp[256];
08522    char *name, *c;
08523    char *t;
08524    char *domain;
08525 
08526    /* Terminate URI */
08527    t = uri;
08528    while(*t && (*t > 32) && (*t != ';'))
08529       t++;
08530    *t = '\0';
08531    
08532    ast_copy_string(tmp, get_header(req, "To"), sizeof(tmp));
08533    if (pedanticsipchecking)
08534       ast_uri_decode(tmp);
08535 
08536    c = get_in_brackets(tmp);
08537    c = strsep(&c, ";"); /* Ditch ;user=phone */
08538 
08539    if (!strncasecmp(c, "sip:", 4)) {
08540       name = c + 4;
08541    } else {
08542       name = c;
08543       ast_log(LOG_NOTICE, "Invalid to address: '%s' from %s (missing sip:) trying to use anyway...\n", c, ast_inet_ntoa(sin->sin_addr));
08544    }
08545 
08546    /* Strip off the domain name */
08547    if ((c = strchr(name, '@'))) {
08548       *c++ = '\0';
08549       domain = c;
08550       if ((c = strchr(domain, ':')))   /* Remove :port */
08551          *c = '\0';
08552       if (!AST_LIST_EMPTY(&domain_list)) {
08553          if (!check_sip_domain(domain, NULL, 0)) {
08554             transmit_response(p, "404 Not found (unknown domain)", &p->initreq);
08555             return AUTH_UNKNOWN_DOMAIN;
08556          }
08557       }
08558    }
08559 
08560    ast_string_field_set(p, exten, name);
08561    build_contact(p);
08562    peer = find_peer(name, NULL, 1);
08563    if (!(peer && ast_apply_ha(peer->ha, sin))) {
08564       /* Peer fails ACL check */
08565       if (peer) {
08566          ASTOBJ_UNREF(peer, sip_destroy_peer);
08567          peer = NULL;
08568          res = AUTH_ACL_FAILED;
08569       } else
08570          res = AUTH_NOT_FOUND;
08571    }
08572    if (peer) {
08573       /* Set Frame packetization */
08574       if (p->rtp) {
08575          ast_rtp_codec_setpref(p->rtp, &peer->prefs);
08576          p->autoframing = peer->autoframing;
08577       }
08578       if (!ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)) {
08579          ast_log(LOG_ERROR, "Peer '%s' is trying to register, but not configured as host=dynamic\n", peer->name);
08580          res = AUTH_PEER_NOT_DYNAMIC;
08581       } else {
08582          ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_NAT);
08583          transmit_response(p, "100 Trying", req);
08584          if (!(res = check_auth(p, req, peer->name, peer->secret, peer->md5secret, SIP_REGISTER, uri, XMIT_UNRELIABLE, ast_test_flag(req, SIP_PKT_IGNORE)))) {
08585             sip_cancel_destroy(p);
08586 
08587             /* We have a succesful registration attemp with proper authentication,
08588                now, update the peer */
08589             switch (parse_register_contact(p, peer, req)) {
08590             case PARSE_REGISTER_FAILED:
08591                ast_log(LOG_WARNING, "Failed to parse contact info\n");
08592                transmit_response_with_date(p, "400 Bad Request", req);
08593                peer->lastmsgssent = -1;
08594                res = 0;
08595                break;
08596             case PARSE_REGISTER_QUERY:
08597                transmit_response_with_date(p, "200 OK", req);
08598                peer->lastmsgssent = -1;
08599                res = 0;
08600                break;
08601             case PARSE_REGISTER_UPDATE:
08602                update_peer(peer, p->expiry);
08603                /* Say OK and ask subsystem to retransmit msg counter */
08604                transmit_response_with_date(p, "200 OK", req);
08605                if (!ast_test_flag((&peer->flags[1]), SIP_PAGE2_SUBSCRIBEMWIONLY))
08606                   peer->lastmsgssent = -1;
08607                res = 0;
08608                break;
08609             }
08610          } 
08611       }
08612    }
08613    if (!peer && autocreatepeer) {
08614       /* Create peer if we have autocreate mode enabled */
08615       peer = temp_peer(name);
08616       if (peer) {
08617          ASTOBJ_CONTAINER_LINK(&peerl, peer);
08618          sip_cancel_destroy(p);
08619          switch (parse_register_contact(p, peer, req)) {
08620          case PARSE_REGISTER_FAILED:
08621             ast_log(LOG_WARNING, "Failed to parse contact info\n");
08622             transmit_response_with_date(p, "400 Bad Request", req);
08623             peer->lastmsgssent = -1;
08624             res = 0;
08625             break;
08626          case PARSE_REGISTER_QUERY:
08627             transmit_response_with_date(p, "200 OK", req);
08628             peer->lastmsgssent = -1;
08629             res = 0;
08630             break;
08631          case PARSE_REGISTER_UPDATE:
08632             /* Say OK and ask subsystem to retransmit msg counter */
08633             transmit_response_with_date(p, "200 OK", req);
08634             manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Registered\r\n", peer->name);
08635             peer->lastmsgssent = -1;
08636             res = 0;
08637             break;
08638          }
08639       }
08640    }
08641    if (!res) {
08642       ast_device_state_changed("SIP/%s", peer->name);
08643    }
08644    if (res < 0) {
08645       switch (res) {
08646       case AUTH_SECRET_FAILED:
08647          /* Wrong password in authentication. Go away, don't try again until you fixed it */
08648          transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq);
08649          break;
08650       case AUTH_USERNAME_MISMATCH:
08651          /* Username and digest username does not match. 
08652             Asterisk uses the From: username for authentication. We need the
08653             users to use the same authentication user name until we support
08654             proper authentication by digest auth name */
08655          transmit_response(p, "403 Authentication user name does not match account name", &p->initreq);
08656          break;
08657       case AUTH_NOT_FOUND:
08658       case AUTH_PEER_NOT_DYNAMIC:
08659       case AUTH_ACL_FAILED:
08660          if (global_alwaysauthreject) {
08661             transmit_fake_auth_response(p, &p->initreq, 1);
08662          } else {
08663             /* URI not found */
08664             if (res == AUTH_PEER_NOT_DYNAMIC)
08665                transmit_response(p, "403 Forbidden", &p->initreq);
08666             else
08667                transmit_response(p, "404 Not found", &p->initreq);
08668          }
08669          break;
08670       default:
08671          break;
08672       }
08673    }
08674    if (peer)
08675       ASTOBJ_UNREF(peer, sip_destroy_peer);
08676 
08677    return res;
08678 }

static char * regstate2str ( enum sipregistrystate  regstate  )  [static]

Convert registration state status to string.

Definition at line 7361 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.

07362 {
07363    switch(regstate) {
07364    case REG_STATE_FAILED:
07365       return "Failed";
07366    case REG_STATE_UNREGISTERED:
07367       return "Unregistered";
07368    case REG_STATE_REGSENT:
07369       return "Request Sent";
07370    case REG_STATE_AUTHSENT:
07371       return "Auth. Sent";
07372    case REG_STATE_REGISTERED:
07373       return "Registered";
07374    case REG_STATE_REJECTED:
07375       return "Rejected";
07376    case REG_STATE_TIMEOUT:
07377       return "Timeout";
07378    case REG_STATE_NOAUTH:
07379       return "No Authentication";
07380    default:
07381       return "Unknown";
07382    }
07383 }

static int reload ( void   )  [static]

Part of Asterisk module interface.

Definition at line 17785 of file chan_sip.c.

References sip_reload().

17786 {
17787    return sip_reload(0, 0, NULL);
17788 }

static int reload_config ( enum channelreloadreason  reason  )  [static]

Re-read SIP.conf config file.

Note:
This function reloads all config data, except for active peers (with registrations). They will only change configuration data at restart, not at reload. SIP debug and recordhistory state will not change

< Default DTMF setting: RFC2833

< NAT support if requested by device with rport

< Allow re-invites

Definition at line 16682 of file chan_sip.c.

References __ourip, add_realm_authentication(), add_sip_domain(), ast_append_ha(), ast_category_browse(), ast_clear_flag, ast_config_AST_SYSTEM_NAME, ast_config_destroy(), ast_config_load(), ast_context_create(), ast_context_find(), ast_copy_flags, ast_device_state_changed(), ast_enable_packet_fragmentation(), ast_find_ourip(), AST_FLAGS_ALL, ast_free_ha(), ast_get_ip_or_srv(), ast_gethostbyname(), ast_inet_ntoa(), ast_jb_read_conf(), AST_LIST_EMPTY, ast_log(), AST_MAX_CONTEXT, ast_mutex_lock(), ast_mutex_unlock(), ast_parse_allow_disallow(), ast_set2_flag, ast_set_flag, ast_str2tos(), ast_strdupa, ast_strlen_zero(), ast_tos2str(), ast_true(), ast_variable_browse(), ast_variable_retrieve(), ast_verbose(), ASTOBJ_CONTAINER_DESTROYALL, ASTOBJ_CONTAINER_LINK, ASTOBJ_CONTAINER_MARKALL, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, ASTOBJ_UNREF, authl, bindaddr, build_peer(), build_user(), channelreloadreason2txt(), cleanup_stale_contexts(), clear_realm_authentication(), clear_sip_domains(), context, DEFAULT_ALLOW_EXT_DOM, DEFAULT_ALLOWGUEST, DEFAULT_AUTOCREATEPEER, DEFAULT_CALLERID, DEFAULT_COMPACTHEADERS, DEFAULT_CONTEXT, DEFAULT_DEFAULT_EXPIRY, DEFAULT_EXPIRY, DEFAULT_MAX_CALL_BITRATE, DEFAULT_MAX_EXPIRY, DEFAULT_MAXMS, DEFAULT_MIN_EXPIRY, DEFAULT_MOHINTERPRET, DEFAULT_MOHSUGGEST, DEFAULT_MWITIME, DEFAULT_NOTIFYMIME, DEFAULT_NOTIFYRINGING, DEFAULT_PEDANTIC, default_prefs, DEFAULT_QUALIFY, DEFAULT_REALM, DEFAULT_REGISTRATION_TIMEOUT, DEFAULT_SRVLOOKUP, DEFAULT_T1MIN, DEFAULT_TOS_AUDIO, DEFAULT_TOS_SIP, DEFAULT_TOS_VIDEO, DEFAULT_USERAGENT, DEFAULT_VMEXTEN, errno, EVENT_FLAG_SYSTEM, externexpire, externhost, externip, externrefresh, FALSE, gen, global_jbconf, handle_common_options(), hp, ast_variable::lineno, localaddr, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, manager_event(), ast_variable::name, ast_variable::next, notify_types, option_debug, option_verbose, ourport, outboundproxyip, peerl, regl, secret, SIP_CAN_REINVITE, sip_destroy(), sip_destroy_peer(), sip_destroy_user(), SIP_DOMAIN_AUTO, SIP_DOMAIN_CONFIG, SIP_DTMF_RFC2833, SIP_NAT_RFC3581, SIP_PAGE2_ALLOWOVERLAP, SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PAGE2_DEBUG_CONFIG, SIP_PAGE2_DEBUG_CONSOLE, SIP_PAGE2_IGNOREREGEXPIRE, SIP_PAGE2_RTAUTOCLEAR, SIP_PAGE2_RTCACHEFRIENDS, SIP_PAGE2_RTSAVE_SYSNAME, SIP_PAGE2_RTUPDATE, SIP_PAGE2_VIDEOSUPPORT, sip_register(), sip_registry_destroy(), SIP_USEREQPHONE, sipsock, STANDARD_SIP_PORT, strsep(), TRANSFER_CLOSED, TRANSFER_OPENFORALL, userl, username, ast_variable::value, and VERBOSE_PREFIX_2.

16683 {
16684    struct ast_config *cfg, *ucfg;
16685    struct ast_variable *v;
16686    struct sip_peer *peer;
16687    struct sip_user *user;
16688    struct ast_hostent ahp;
16689    char *cat, *stringp, *context, *oldregcontext;
16690    char newcontexts[AST_MAX_CONTEXT], oldcontexts[AST_MAX_CONTEXT];
16691    struct hostent *hp;
16692    int format;
16693    struct ast_flags dummy[2];
16694    int auto_sip_domains = FALSE;
16695    struct sockaddr_in old_bindaddr = bindaddr;
16696    int registry_count = 0, peer_count = 0, user_count = 0;
16697    unsigned int temp_tos = 0;
16698    struct ast_flags debugflag = {0};
16699 
16700    cfg = ast_config_load(config);
16701 
16702    /* We *must* have a config file otherwise stop immediately */
16703    if (!cfg) {
16704       ast_log(LOG_NOTICE, "Unable to load config %s\n", config);
16705       return -1;
16706    }
16707    
16708    if (option_debug > 3)
16709       ast_log(LOG_DEBUG, "--------------- SIP reload started\n");
16710 
16711    clear_realm_authentication(authl);
16712    clear_sip_domains();
16713    authl = NULL;
16714 
16715    /* First, destroy all outstanding registry calls */
16716    /* This is needed, since otherwise active registry entries will not be destroyed */
16717    ASTOBJ_CONTAINER_TRAVERSE(&regl, 1, do {
16718       ASTOBJ_RDLOCK(iterator);
16719       if (iterator->call) {
16720          if (option_debug > 2)
16721             ast_log(LOG_DEBUG, "Destroying active SIP dialog for registry %s@%s\n", iterator->username, iterator->hostname);
16722          /* This will also remove references to the registry */
16723          sip_destroy(iterator->call);
16724       }
16725       ASTOBJ_UNLOCK(iterator);
16726    
16727    } while(0));
16728 
16729    /* Then, actually destroy users and registry */
16730    ASTOBJ_CONTAINER_DESTROYALL(&userl, sip_destroy_user);
16731    if (option_debug > 3)
16732       ast_log(LOG_DEBUG, "--------------- Done destroying user list\n");
16733    ASTOBJ_CONTAINER_DESTROYALL(&regl, sip_registry_destroy);
16734    if (option_debug > 3)
16735       ast_log(LOG_DEBUG, "--------------- Done destroying registry list\n");
16736    ASTOBJ_CONTAINER_MARKALL(&peerl);
16737 
16738    /* Initialize copy of current global_regcontext for later use in removing stale contexts */
16739    ast_copy_string(oldcontexts, global_regcontext, sizeof(oldcontexts));
16740    oldregcontext = oldcontexts;
16741 
16742    /* Clear all flags before setting default values */
16743    /* Preserve debugging settings for console */
16744    ast_copy_flags(&debugflag, &global_flags[1], SIP_PAGE2_DEBUG_CONSOLE);
16745    ast_clear_flag(&global_flags[0], AST_FLAGS_ALL);
16746    ast_clear_flag(&global_flags[1], AST_FLAGS_ALL);
16747    ast_copy_flags(&global_flags[1], &debugflag, SIP_PAGE2_DEBUG_CONSOLE);
16748 
16749    /* Reset IP addresses  */
16750    memset(&bindaddr, 0, sizeof(bindaddr));
16751    ast_free_ha(localaddr);
16752    memset(&localaddr, 0, sizeof(localaddr));
16753    memset(&externip, 0, sizeof(externip));
16754    memset(&default_prefs, 0 , sizeof(default_prefs));
16755    outboundproxyip.sin_port = htons(STANDARD_SIP_PORT);
16756    outboundproxyip.sin_family = AF_INET;  /* Type of address: IPv4 */
16757    ourport = STANDARD_SIP_PORT;
16758    srvlookup = DEFAULT_SRVLOOKUP;
16759    global_tos_sip = DEFAULT_TOS_SIP;
16760    global_tos_audio = DEFAULT_TOS_AUDIO;
16761    global_tos_video = DEFAULT_TOS_VIDEO;
16762    externhost[0] = '\0';         /* External host name (for behind NAT DynDNS support) */
16763    externexpire = 0;       /* Expiration for DNS re-issuing */
16764    externrefresh = 10;
16765    memset(&outboundproxyip, 0, sizeof(outboundproxyip));
16766 
16767    /* Reset channel settings to default before re-configuring */
16768    allow_external_domains = DEFAULT_ALLOW_EXT_DOM;          /* Allow external invites */
16769    global_regcontext[0] = '\0';
16770    expiry = DEFAULT_EXPIRY;
16771    global_notifyringing = DEFAULT_NOTIFYRINGING;
16772    global_limitonpeers = FALSE;
16773    global_directrtpsetup = FALSE;      /* Experimental feature, disabled by default */
16774    global_notifyhold = FALSE;
16775    global_alwaysauthreject = 0;
16776    global_allowsubscribe = FALSE;
16777    ast_copy_string(global_useragent, DEFAULT_USERAGENT, sizeof(global_useragent));
16778    ast_copy_string(default_notifymime, DEFAULT_NOTIFYMIME, sizeof(default_notifymime));
16779    if (ast_strlen_zero(ast_config_AST_SYSTEM_NAME))
16780       ast_copy_string(global_realm, DEFAULT_REALM, sizeof(global_realm));
16781    else
16782       ast_copy_string(global_realm, ast_config_AST_SYSTEM_NAME, sizeof(global_realm));
16783    ast_copy_string(default_callerid, DEFAULT_CALLERID, sizeof(default_callerid));
16784    compactheaders = DEFAULT_COMPACTHEADERS;
16785    global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT;
16786    global_regattempts_max = 0;
16787    pedanticsipchecking = DEFAULT_PEDANTIC;
16788    global_mwitime = DEFAULT_MWITIME;
16789    autocreatepeer = DEFAULT_AUTOCREATEPEER;
16790    global_autoframing = 0;
16791    global_allowguest = DEFAULT_ALLOWGUEST;
16792    global_rtptimeout = 0;
16793    global_rtpholdtimeout = 0;
16794    global_rtpkeepalive = 0;
16795    global_allowtransfer = TRANSFER_OPENFORALL;  /* Merrily accept all transfers by default */
16796    global_rtautoclear = 120;
16797    ast_set_flag(&global_flags[1], SIP_PAGE2_ALLOWSUBSCRIBE);   /* Default for peers, users: TRUE */
16798    ast_set_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP);     /* Default for peers, users: TRUE */
16799    ast_set_flag(&global_flags[1], SIP_PAGE2_RTUPDATE);
16800 
16801    /* Initialize some reasonable defaults at SIP reload (used both for channel and as default for peers and users */
16802    ast_copy_string(default_context, DEFAULT_CONTEXT, sizeof(default_context));
16803    default_subscribecontext[0] = '\0';
16804    default_language[0] = '\0';
16805    default_fromdomain[0] = '\0';
16806    default_qualify = DEFAULT_QUALIFY;
16807    default_maxcallbitrate = DEFAULT_MAX_CALL_BITRATE;
16808    ast_copy_string(default_mohinterpret, DEFAULT_MOHINTERPRET, sizeof(default_mohinterpret));
16809    ast_copy_string(default_mohsuggest, DEFAULT_MOHSUGGEST, sizeof(default_mohsuggest));
16810    ast_copy_string(default_vmexten, DEFAULT_VMEXTEN, sizeof(default_vmexten));
16811    ast_set_flag(&global_flags[0], SIP_DTMF_RFC2833);        /*!< Default DTMF setting: RFC2833 */
16812    ast_set_flag(&global_flags[0], SIP_NAT_RFC3581);         /*!< NAT support if requested by device with rport */
16813    ast_set_flag(&global_flags[0], SIP_CAN_REINVITE);        /*!< Allow re-invites */
16814 
16815    /* Debugging settings, always default to off */
16816    dumphistory = FALSE;
16817    recordhistory = FALSE;
16818    ast_clear_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONFIG);
16819 
16820    /* Misc settings for the channel */
16821    global_relaxdtmf = FALSE;
16822    global_callevents = FALSE;
16823    global_t1min = DEFAULT_T1MIN;    
16824 
16825    global_matchexterniplocally = FALSE;
16826 
16827    /* Copy the default jb config over global_jbconf */
16828    memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf));
16829 
16830    ast_clear_flag(&global_flags[1], SIP_PAGE2_VIDEOSUPPORT);
16831 
16832    /* Read the [general] config section of sip.conf (or from realtime config) */
16833    for (v = ast_variable_browse(cfg, "general"); v; v = v->next) {
16834       if (handle_common_options(&global_flags[0], &dummy[0], v))
16835          continue;
16836       /* handle jb conf */
16837       if (!ast_jb_read_conf(&global_jbconf, v->name, v->value))
16838          continue;
16839 
16840       /* Create the interface list */
16841       if (!strcasecmp(v->name, "context")) {
16842          ast_copy_string(default_context, v->value, sizeof(default_context));
16843       } else if (!strcasecmp(v->name, "subscribecontext")) {
16844          ast_copy_string(default_subscribecontext, v->value, sizeof(default_subscribecontext));
16845       } else if (!strcasecmp(v->name, "allowguest")) {
16846          global_allowguest = ast_true(v->value) ? 1 : 0;
16847       } else if (!strcasecmp(v->name, "realm")) {
16848          ast_copy_string(global_realm, v->value, sizeof(global_realm));
16849       } else if (!strcasecmp(v->name, "useragent")) {
16850          ast_copy_string(global_useragent, v->value, sizeof(global_useragent));
16851          if (option_debug)
16852             ast_log(LOG_DEBUG, "Setting SIP channel User-Agent Name to %s\n", global_useragent);
16853       } else if (!strcasecmp(v->name, "allowtransfer")) {
16854          global_allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED;
16855       } else if (!strcasecmp(v->name, "rtcachefriends")) {
16856          ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_RTCACHEFRIENDS);   
16857       } else if (!strcasecmp(v->name, "rtsavesysname")) {
16858          ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_RTSAVE_SYSNAME);   
16859       } else if (!strcasecmp(v->name, "rtupdate")) {
16860          ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_RTUPDATE);   
16861       } else if (!strcasecmp(v->name, "ignoreregexpire")) {
16862          ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_IGNOREREGEXPIRE);  
16863       } else if (!strcasecmp(v->name, "t1min")) {
16864          global_t1min = atoi(v->value);
16865       } else if (!strcasecmp(v->name, "rtautoclear")) {
16866          int i = atoi(v->value);
16867          if (i > 0)
16868             global_rtautoclear = i;
16869          else
16870             i = 0;
16871          ast_set2_flag(&global_flags[1], i || ast_true(v->value), SIP_PAGE2_RTAUTOCLEAR);
16872       } else if (!strcasecmp(v->name, "usereqphone")) {
16873          ast_set2_flag(&global_flags[0], ast_true(v->value), SIP_USEREQPHONE);   
16874       } else if (!strcasecmp(v->name, "relaxdtmf")) {
16875          global_relaxdtmf = ast_true(v->value);
16876       } else if (!strcasecmp(v->name, "checkmwi")) {
16877          if ((sscanf(v->value, "%d", &global_mwitime) != 1) || (global_mwitime < 0)) {
16878             ast_log(LOG_WARNING, "'%s' is not a valid MWI time setting at line %d.  Using default (10).\n", v->value, v->lineno);
16879             global_mwitime = DEFAULT_MWITIME;
16880          }
16881       } else if (!strcasecmp(v->name, "vmexten")) {
16882          ast_copy_string(default_vmexten, v->value, sizeof(default_vmexten));
16883       } else if (!strcasecmp(v->name, "rtptimeout")) {
16884          if ((sscanf(v->value, "%d", &global_rtptimeout) != 1) || (global_rtptimeout < 0)) {
16885             ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d.  Using default.\n", v->value, v->lineno);
16886             global_rtptimeout = 0;
16887          }
16888       } else if (!strcasecmp(v->name, "rtpholdtimeout")) {
16889          if ((sscanf(v->value, "%d", &global_rtpholdtimeout) != 1) || (global_rtpholdtimeout < 0)) {
16890             ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d.  Using default.\n", v->value, v->lineno);
16891             global_rtpholdtimeout = 0;
16892          }
16893       } else if (!strcasecmp(v->name, "rtpkeepalive")) {
16894          if ((sscanf(v->value, "%d", &global_rtpkeepalive) != 1) || (global_rtpkeepalive < 0)) {
16895             ast_log(LOG_WARNING, "'%s' is not a valid RTP keepalive time at line %d.  Using default.\n", v->value, v->lineno);
16896             global_rtpkeepalive = 0;
16897          }
16898       } else if (!strcasecmp(v->name, "compactheaders")) {
16899          compactheaders = ast_true(v->value);
16900       } else if (!strcasecmp(v->name, "notifymimetype")) {
16901          ast_copy_string(default_notifymime, v->value, sizeof(default_notifymime));
16902       } else if (!strncasecmp(v->name, "limitonpeer", 11)) {
16903          global_limitonpeers = ast_true(v->value);
16904       } else if (!strcasecmp(v->name, "directrtpsetup")) {
16905          global_directrtpsetup = ast_true(v->value);
16906       } else if (!strcasecmp(v->name, "notifyringing")) {
16907          global_notifyringing = ast_true(v->value);
16908       } else if (!strcasecmp(v->name, "notifyhold")) {
16909          global_notifyhold = ast_true(v->value);
16910       } else if (!strcasecmp(v->name, "alwaysauthreject")) {
16911          global_alwaysauthreject = ast_true(v->value);
16912       } else if (!strcasecmp(v->name, "mohinterpret") 
16913          || !strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) {
16914          ast_copy_string(default_mohinterpret, v->value, sizeof(default_mohinterpret));
16915       } else if (!strcasecmp(v->name, "mohsuggest")) {
16916          ast_copy_string(default_mohsuggest, v->value, sizeof(default_mohsuggest));
16917       } else if (!strcasecmp(v->name, "language")) {
16918          ast_copy_string(default_language, v->value, sizeof(default_language));
16919       } else if (!strcasecmp(v->name, "regcontext")) {
16920          ast_copy_string(newcontexts, v->value, sizeof(newcontexts));
16921          stringp = newcontexts;
16922          /* Let's remove any contexts that are no longer defined in regcontext */
16923          cleanup_stale_contexts(stringp, oldregcontext);
16924          /* Create contexts if they don't exist already */
16925          while ((context = strsep(&stringp, "&"))) {
16926             if (!ast_context_find(context))
16927                ast_context_create(NULL, context,"SIP");
16928          }
16929          ast_copy_string(global_regcontext, v->value, sizeof(global_regcontext));
16930       } else if (!strcasecmp(v->name, "callerid")) {
16931          ast_copy_string(default_callerid, v->value, sizeof(default_callerid));
16932       } else if (!strcasecmp(v->name, "fromdomain")) {
16933          ast_copy_string(default_fromdomain, v->value, sizeof(default_fromdomain));
16934       } else if (!strcasecmp(v->name, "outboundproxy")) {
16935          if (ast_get_ip_or_srv(&outboundproxyip, v->value, srvlookup ? "_sip._udp" : NULL) < 0)
16936             ast_log(LOG_WARNING, "Unable to locate host '%s'\n", v->value);
16937       } else if (!strcasecmp(v->name, "outboundproxyport")) {
16938          /* Port needs to be after IP */
16939          sscanf(v->value, "%d", &format);
16940          outboundproxyip.sin_port = htons(format);
16941       } else if (!strcasecmp(v->name, "autocreatepeer")) {
16942          autocreatepeer = ast_true(v->value);
16943       } else if (!strcasecmp(v->name, "srvlookup")) {
16944          srvlookup = ast_true(v->value);
16945       } else if (!strcasecmp(v->name, "pedantic")) {
16946          pedanticsipchecking = ast_true(v->value);
16947       } else if (!strcasecmp(v->name, "maxexpirey") || !strcasecmp(v->name, "maxexpiry")) {
16948          max_expiry = atoi(v->value);
16949          if (max_expiry < 1)
16950             max_expiry = DEFAULT_MAX_EXPIRY;
16951       } else if (!strcasecmp(v->name, "minexpirey") || !strcasecmp(v->name, "minexpiry")) {
16952          min_expiry = atoi(v->value);
16953          if (min_expiry < 1)
16954             min_expiry = DEFAULT_MIN_EXPIRY;
16955       } else if (!strcasecmp(v->name, "defaultexpiry") || !strcasecmp(v->name, "defaultexpirey")) {
16956          default_expiry = atoi(v->value);
16957          if (default_expiry < 1)
16958             default_expiry = DEFAULT_DEFAULT_EXPIRY;
16959       } else if (!strcasecmp(v->name, "sipdebug")) {  /* XXX maybe ast_set2_flags ? */
16960          if (ast_true(v->value))
16961             ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONFIG);
16962       } else if (!strcasecmp(v->name, "dumphistory")) {
16963          dumphistory = ast_true(v->value);
16964       } else if (!strcasecmp(v->name, "recordhistory")) {
16965          recordhistory = ast_true(v->value);
16966       } else if (!strcasecmp(v->name, "registertimeout")) {
16967          global_reg_timeout = atoi(v->value);
16968          if (global_reg_timeout < 1)
16969             global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT;
16970       } else if (!strcasecmp(v->name, "registerattempts")) {
16971          global_regattempts_max = atoi(v->value);
16972       } else if (!strcasecmp(v->name, "bindaddr")) {
16973          if (!(hp = ast_gethostbyname(v->value, &ahp))) {
16974             ast_log(LOG_WARNING, "Invalid address: %s\n", v->value);
16975          } else {
16976             memcpy(&bindaddr.sin_addr, hp->h_addr, sizeof(bindaddr.sin_addr));
16977          }
16978       } else if (!strcasecmp(v->name, "localnet")) {
16979          struct ast_ha *na;
16980          if (!(na = ast_append_ha("d", v->value, localaddr)))
16981             ast_log(LOG_WARNING, "Invalid localnet value: %s\n", v->value);
16982          else
16983             localaddr = na;
16984       } else if (!strcasecmp(v->name, "localmask")) {
16985          ast_log(LOG_WARNING, "Use of localmask is no long supported -- use localnet with mask syntax\n");
16986       } else if (!strcasecmp(v->name, "externip")) {
16987          if (!(hp = ast_gethostbyname(v->value, &ahp))) 
16988             ast_log(LOG_WARNING, "Invalid address for externip keyword: %s\n", v->value);
16989          else
16990             memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr));
16991          externexpire = 0;
16992       } else if (!strcasecmp(v->name, "externhost")) {
16993          ast_copy_string(externhost, v->value, sizeof(externhost));
16994          if (!(hp = ast_gethostbyname(externhost, &ahp))) 
16995             ast_log(LOG_WARNING, "Invalid address for externhost keyword: %s\n", externhost);
16996          else
16997             memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr));
16998          externexpire = time(NULL);
16999       } else if (!strcasecmp(v->name, "externrefresh")) {
17000          if (sscanf(v->value, "%d", &externrefresh) != 1) {
17001             ast_log(LOG_WARNING, "Invalid externrefresh value '%s', must be an integer >0 at line %d\n", v->value, v->lineno);
17002             externrefresh = 10;
17003          }
17004       } else if (!strcasecmp(v->name, "allow")) {
17005          ast_parse_allow_disallow(&default_prefs, &global_capability, v->value, 1);
17006       } else if (!strcasecmp(v->name, "disallow")) {
17007          ast_parse_allow_disallow(&default_prefs, &global_capability, v->value, 0);
17008       } else if (!strcasecmp(v->name, "autoframing")) {
17009          global_autoframing = ast_true(v->value);
17010       } else if (!strcasecmp(v->name, "allowexternaldomains")) {
17011          allow_external_domains = ast_true(v->value);
17012       } else if (!strcasecmp(v->name, "autodomain")) {
17013          auto_sip_domains = ast_true(v->value);
17014       } else if (!strcasecmp(v->name, "domain")) {
17015          char *domain = ast_strdupa(v->value);
17016          char *context = strchr(domain, ',');
17017 
17018          if (context)
17019             *context++ = '\0';
17020 
17021          if (option_debug && ast_strlen_zero(context))
17022             ast_log(LOG_DEBUG, "No context specified at line %d for domain '%s'\n", v->lineno, domain);
17023          if (ast_strlen_zero(domain))
17024             ast_log(LOG_WARNING, "Empty domain specified at line %d\n", v->lineno);
17025          else
17026             add_sip_domain(ast_strip(domain), SIP_DOMAIN_CONFIG, context ? ast_strip(context) : "");
17027       } else if (!strcasecmp(v->name, "register")) {
17028          if (sip_register(v->value, v->lineno) == 0)
17029             registry_count++;
17030       } else if (!strcasecmp(v->name, "tos")) {
17031          if (!ast_str2tos(v->value, &temp_tos)) {
17032             global_tos_sip = temp_tos;
17033             global_tos_audio = temp_tos;
17034             global_tos_video = temp_tos;
17035             ast_log(LOG_WARNING, "tos value at line %d is deprecated.  See doc/ip-tos.txt for more information.\n", v->lineno);
17036          } else
17037             ast_log(LOG_WARNING, "Invalid tos value at line %d, See doc/ip-tos.txt for more information.\n", v->lineno);
17038       } else if (!strcasecmp(v->name, "tos_sip")) {
17039          if (ast_str2tos(v->value, &global_tos_sip))
17040             ast_log(LOG_WARNING, "Invalid tos_sip value at line %d, recommended value is 'cs3'. See doc/ip-tos.txt.\n", v->lineno);
17041       } else if (!strcasecmp(v->name, "tos_audio")) {
17042          if (ast_str2tos(v->value, &global_tos_audio))
17043             ast_log(LOG_WARNING, "Invalid tos_audio value at line %d, recommended value is 'ef'. See doc/ip-tos.txt.\n", v->lineno);
17044       } else if (!strcasecmp(v->name, "tos_video")) {
17045          if (ast_str2tos(v->value, &global_tos_video))
17046             ast_log(LOG_WARNING, "Invalid tos_video value at line %d, recommended value is 'af41'. See doc/ip-tos.txt.\n", v->lineno);
17047       } else if (!strcasecmp(v->name, "bindport")) {
17048          if (sscanf(v->value, "%d", &ourport) == 1) {
17049             bindaddr.sin_port = htons(ourport);
17050          } else {
17051             ast_log(LOG_WARNING, "Invalid port number '%s' at line %d of %s\n", v->value, v->lineno, config);
17052          }
17053       } else if (!strcasecmp(v->name, "qualify")) {
17054          if (!strcasecmp(v->value, "no")) {
17055             default_qualify = 0;
17056          } else if (!strcasecmp(v->value, "yes")) {
17057             default_qualify = DEFAULT_MAXMS;
17058          } else if (sscanf(v->value, "%d", &default_qualify) != 1) {
17059             ast_log(LOG_WARNING, "Qualification default should be 'yes', 'no', or a number of milliseconds at line %d of sip.conf\n", v->lineno);
17060             default_qualify = 0;
17061          }
17062       } else if (!strcasecmp(v->name, "callevents")) {
17063          global_callevents = ast_true(v->value);
17064       } else if (!strcasecmp(v->name, "maxcallbitrate")) {
17065          default_maxcallbitrate = atoi(v->value);
17066          if (default_maxcallbitrate < 0)
17067             default_maxcallbitrate = DEFAULT_MAX_CALL_BITRATE;
17068       } else if (!strcasecmp(v->name, "matchexterniplocally")) {
17069          global_matchexterniplocally = ast_true(v->value);
17070       }
17071    }
17072 
17073    if (!allow_external_domains && AST_LIST_EMPTY(&domain_list)) {
17074       ast_log(LOG_WARNING, "To disallow external domains, you need to configure local SIP domains.\n");
17075       allow_external_domains = 1;
17076    }
17077    
17078    /* Build list of authentication to various SIP realms, i.e. service providers */
17079    for (v = ast_variable_browse(cfg, "authentication"); v ; v = v->next) {
17080       /* Format for authentication is auth = username:password@realm */
17081       if (!strcasecmp(v->name, "auth"))
17082          authl = add_realm_authentication(authl, v->value, v->lineno);
17083    }
17084    
17085    ucfg = ast_config_load("users.conf");
17086    if (ucfg) {
17087       struct ast_variable *gen;
17088       int genhassip, genregistersip;
17089       const char *hassip, *registersip;
17090       
17091       genhassip = ast_true(ast_variable_retrieve(ucfg, "general", "hassip"));
17092       genregistersip = ast_true(ast_variable_retrieve(ucfg, "general", "registersip"));
17093       gen = ast_variable_browse(ucfg, "general");
17094       cat = ast_category_browse(ucfg, NULL);
17095       while (cat) {
17096          if (strcasecmp(cat, "general")) {
17097             hassip = ast_variable_retrieve(ucfg, cat, "hassip");
17098             registersip = ast_variable_retrieve(ucfg, cat, "registersip");
17099             if (ast_true(hassip) || (!hassip && genhassip)) {
17100                peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0);
17101                if (peer) {
17102                   ast_device_state_changed("SIP/%s", peer->name);
17103                   ASTOBJ_CONTAINER_LINK(&peerl,peer);
17104                   ASTOBJ_UNREF(peer, sip_destroy_peer);
17105                   peer_count++;
17106                }
17107             }
17108             if (ast_true(registersip) || (!registersip && genregistersip)) {
17109                char tmp[256];
17110                const char *host = ast_variable_retrieve(ucfg, cat, "host");
17111                const char *username = ast_variable_retrieve(ucfg, cat, "username");
17112                const char *secret = ast_variable_retrieve(ucfg, cat, "secret");
17113                const char *contact = ast_variable_retrieve(ucfg, cat, "contact");
17114                if (!host)
17115                   host = ast_variable_retrieve(ucfg, "general", "host");
17116                if (!username)
17117                   username = ast_variable_retrieve(ucfg, "general", "username");
17118                if (!secret)
17119                   secret = ast_variable_retrieve(ucfg, "general", "secret");
17120                if (!contact)
17121                   contact = "s";
17122                if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) {
17123                   if (!ast_strlen_zero(secret))
17124                      snprintf(tmp, sizeof(tmp), "%s:%s@%s/%s", username, secret, host, contact);
17125                   else
17126                      snprintf(tmp, sizeof(tmp), "%s@%s/%s", username, host, contact);
17127                   if (sip_register(tmp, 0) == 0)
17128                      registry_count++;
17129                }
17130             }
17131          }
17132          cat = ast_category_browse(ucfg, cat);
17133       }
17134       ast_config_destroy(ucfg);
17135    }
17136    
17137 
17138    /* Load peers, users and friends */
17139    cat = NULL;
17140    while ( (cat = ast_category_browse(cfg, cat)) ) {
17141       const char *utype;
17142       if (!strcasecmp(cat, "general") || !strcasecmp(cat, "authentication"))
17143          continue;
17144       utype = ast_variable_retrieve(cfg, cat, "type");
17145       if (!utype) {
17146          ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat);
17147          continue;
17148       } else {
17149          int is_user = 0, is_peer = 0;
17150          if (!strcasecmp(utype, "user"))
17151             is_user = 1;
17152          else if (!strcasecmp(utype, "friend"))
17153             is_user = is_peer = 1;
17154          else if (!strcasecmp(utype, "peer"))
17155             is_peer = 1;
17156          else {
17157             ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, "sip.conf");
17158             continue;
17159          }
17160          if (is_user) {
17161             user = build_user(cat, ast_variable_browse(cfg, cat), 0);
17162             if (user) {
17163                ASTOBJ_CONTAINER_LINK(&userl,user);
17164                ASTOBJ_UNREF(user, sip_destroy_user);
17165                user_count++;
17166             }
17167          }
17168          if (is_peer) {
17169             peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0);
17170             if (peer) {
17171                ASTOBJ_CONTAINER_LINK(&peerl,peer);
17172                ASTOBJ_UNREF(peer, sip_destroy_peer);
17173                peer_count++;
17174             }
17175          }
17176       }
17177    }
17178    if (ast_find_ourip(&__ourip, bindaddr)) {
17179       ast_log(LOG_WARNING, "Unable to get own IP address, SIP disabled\n");
17180       ast_config_destroy(cfg);
17181       return 0;
17182    }
17183    if (!ntohs(bindaddr.sin_port))
17184       bindaddr.sin_port = ntohs(STANDARD_SIP_PORT);
17185    bindaddr.sin_family = AF_INET;
17186    ast_mutex_lock(&netlock);
17187    if ((sipsock > -1) && (memcmp(&old_bindaddr, &bindaddr, sizeof(struct sockaddr_in)))) {
17188       close(sipsock);
17189       sipsock = -1;
17190    }
17191    if (sipsock < 0) {
17192       sipsock = socket(AF_INET, SOCK_DGRAM, 0);
17193       if (sipsock < 0) {
17194          ast_log(LOG_WARNING, "Unable to create SIP socket: %s\n", strerror(errno));
17195          ast_config_destroy(cfg);
17196          return -1;
17197       } else {
17198          /* Allow SIP clients on the same host to access us: */
17199          const int reuseFlag = 1;
17200 
17201          setsockopt(sipsock, SOL_SOCKET, SO_REUSEADDR,
17202                (const char*)&reuseFlag,
17203                sizeof reuseFlag);
17204 
17205          ast_enable_packet_fragmentation(sipsock);
17206 
17207          if (bind(sipsock, (struct sockaddr *)&bindaddr, sizeof(bindaddr)) < 0) {
17208             ast_log(LOG_WARNING, "Failed to bind to %s:%d: %s\n",
17209             ast_inet_ntoa(bindaddr.sin_addr), ntohs(bindaddr.sin_port),
17210             strerror(errno));
17211             close(sipsock);
17212             sipsock = -1;
17213          } else {
17214             if (option_verbose > 1) { 
17215                ast_verbose(VERBOSE_PREFIX_2 "SIP Listening on %s:%d\n", 
17216                ast_inet_ntoa(bindaddr.sin_addr), ntohs(bindaddr.sin_port));
17217                ast_verbose(VERBOSE_PREFIX_2 "Using SIP TOS: %s\n", ast_tos2str(global_tos_sip));
17218             }
17219             if (setsockopt(sipsock, IPPROTO_IP, IP_TOS, &global_tos_sip, sizeof(global_tos_sip))) 
17220                ast_log(LOG_WARNING, "Unable to set SIP TOS to %s\n", ast_tos2str(global_tos_sip));
17221          }
17222       }
17223    }
17224    ast_mutex_unlock(&netlock);
17225 
17226    /* Add default domains - host name, IP address and IP:port */
17227    /* Only do this if user added any sip domain with "localdomains" */
17228    /* In order to *not* break backwards compatibility */
17229    /*    Some phones address us at IP only, some with additional port number */
17230    if (auto_sip_domains) {
17231       char temp[MAXHOSTNAMELEN];
17232 
17233       /* First our default IP address */
17234       if (bindaddr.sin_addr.s_addr)
17235          add_sip_domain(ast_inet_ntoa(bindaddr.sin_addr), SIP_DOMAIN_AUTO, NULL);
17236       else
17237          ast_log(LOG_NOTICE, "Can't add wildcard IP address to domain list, please add IP address to domain manually.\n");
17238 
17239       /* Our extern IP address, if configured */
17240       if (externip.sin_addr.s_addr)
17241          add_sip_domain(ast_inet_ntoa(externip.sin_addr), SIP_DOMAIN_AUTO, NULL);
17242 
17243       /* Extern host name (NAT traversal support) */
17244       if (!ast_strlen_zero(externhost))
17245          add_sip_domain(externhost, SIP_DOMAIN_AUTO, NULL);
17246       
17247       /* Our host name */
17248       if (!gethostname(temp, sizeof(temp)))
17249          add_sip_domain(temp, SIP_DOMAIN_AUTO, NULL);
17250    }
17251 
17252    /* Release configuration from memory */
17253    ast_config_destroy(cfg);
17254 
17255    /* Load the list of manual NOTIFY types to support */
17256    if (notify_types)
17257       ast_config_destroy(notify_types);
17258    notify_types = ast_config_load(notify_config);
17259 
17260    /* Done, tell the manager */
17261    manager_event(EVENT_FLAG_SYSTEM, "ChannelReload", "Channel: SIP\r\nReloadReason: %s\r\nRegistry_Count: %d\r\nPeer_Count: %d\r\nUser_Count: %d\r\n", channelreloadreason2txt(reason), registry_count, peer_count, user_count);
17262 
17263    return 0;
17264 }

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

reply to authentication for outbound registrations

Returns:
Returns -1 if we have no auth
Note:
This is used for register= servers in sip.conf, SIP proxies we register with for receiving calls from.

Definition at line 11384 of file chan_sip.c.

References ast_log(), ast_string_field_index, ast_string_field_index_set, ast_string_field_set, ast_strlen_zero(), build_reply_digest(), get_header(), key(), keys, LOG_WARNING, sip_registry::noncecount, sip_pvt::noncecount, sip_pvt::registry, and strsep().

Referenced by do_proxy_auth(), and do_register_auth().

11385 {
11386    char tmp[512];
11387    char *c;
11388    char oldnonce[256];
11389 
11390    /* table of recognised keywords, and places where they should be copied */
11391    const struct x {
11392       const char *key;
11393       int field_index;
11394    } *i, keys[] = {
11395       { "realm=", ast_string_field_index(p, realm) },
11396       { "nonce=", ast_string_field_index(p, nonce) },
11397       { "opaque=", ast_string_field_index(p, opaque) },
11398       { "qop=", ast_string_field_index(p, qop) },
11399       { "domain=", ast_string_field_index(p, domain) },
11400       { NULL, 0 },
11401    };
11402 
11403    ast_copy_string(tmp, get_header(req, header), sizeof(tmp));
11404    if (ast_strlen_zero(tmp)) 
11405       return -1;
11406    if (strncasecmp(tmp, "Digest ", strlen("Digest "))) {
11407       ast_log(LOG_WARNING, "missing Digest.\n");
11408       return -1;
11409    }
11410    c = tmp + strlen("Digest ");
11411    ast_copy_string(oldnonce, p->nonce, sizeof(oldnonce));
11412    while (c && *(c = ast_skip_blanks(c))) {  /* lookup for keys */
11413       for (i = keys; i->key != NULL; i++) {
11414          char *src, *separator;
11415          if (strncasecmp(c, i->key, strlen(i->key)) != 0)
11416             continue;
11417          /* Found. Skip keyword, take text in quotes or up to the separator. */
11418          c += strlen(i->key);
11419          if (*c == '"') {
11420             src = ++c;
11421             separator = "\"";
11422          } else {
11423             src = c;
11424             separator = ",";
11425          }
11426          strsep(&c, separator); /* clear separator and move ptr */
11427          ast_string_field_index_set(p, i->field_index, src);
11428          break;
11429       }
11430       if (i->key == NULL) /* not found, try ',' */
11431          strsep(&c, ",");
11432    }
11433    /* Reset nonce count */
11434    if (strcmp(p->nonce, oldnonce)) 
11435       p->noncecount = 0;
11436 
11437    /* Save auth data for following registrations */
11438    if (p->registry) {
11439       struct sip_registry *r = p->registry;
11440 
11441       if (strcmp(r->nonce, p->nonce)) {
11442          ast_string_field_set(r, realm, p->realm);
11443          ast_string_field_set(r, nonce, p->nonce);
11444          ast_string_field_set(r, domain, p->domain);
11445          ast_string_field_set(r, opaque, p->opaque);
11446          ast_string_field_set(r, qop, p->qop);
11447          r->noncecount = 0;
11448       }
11449    }
11450    return build_reply_digest(p, sipmethod, digest, digest_len); 
11451 }

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

Initialize a SIP request message (not the initial one in a dialog).

< Strict routing flag

Definition at line 5851 of file chan_sip.c.

References add_header(), add_route(), ast_log(), ast_random(), ast_strlen_zero(), ast_test_flag, sip_pvt::branch, build_via(), copy_header(), DEFAULT_MAX_FORWARDS, FALSE, sip_pvt::flags, get_header(), get_in_brackets(), sip_route::hop, init_req(), sip_pvt::initreq, sip_pvt::lastmsg, LOG_DEBUG, sip_route::next, sip_pvt::ocseq, sip_request::rlPart2, sip_pvt::route, set_destination(), SIP_ACK, SIP_BYE, SIP_CANCEL, SIP_MESSAGE, sip_methods, SIP_OUTGOING, sipdebug, strcasestr(), strsep(), sip_pvt::tag, text, cfsip_methods::text, and TRUE.

05852 {
05853    struct sip_request *orig = &p->initreq;
05854    char stripped[80];
05855    char tmp[80];
05856    char newto[256];
05857    const char *c;
05858    const char *ot, *of;
05859    int is_strict = FALSE;     /*!< Strict routing flag */
05860 
05861    memset(req, 0, sizeof(struct sip_request));
05862    
05863    snprintf(p->lastmsg, sizeof(p->lastmsg), "Tx: %s", sip_methods[sipmethod].text);
05864    
05865    if (!seqno) {
05866       p->ocseq++;
05867       seqno = p->ocseq;
05868    }
05869    
05870    if (newbranch) {
05871       p->branch ^= ast_random();
05872       build_via(p);
05873    }
05874 
05875    /* Check for strict or loose router */
05876    if (p->route && !ast_strlen_zero(p->route->hop) && strstr(p->route->hop,";lr") == NULL) {
05877       is_strict = TRUE;
05878       if (sipdebug)
05879          ast_log(LOG_DEBUG, "Strict routing enforced for session %s\n", p->callid);
05880    }
05881 
05882    if (sipmethod == SIP_CANCEL)
05883       c = p->initreq.rlPart2; /* Use original URI */
05884    else if (sipmethod == SIP_ACK) {
05885       /* Use URI from Contact: in 200 OK (if INVITE) 
05886       (we only have the contacturi on INVITEs) */
05887       if (!ast_strlen_zero(p->okcontacturi))
05888          c = is_strict ? p->route->hop : p->okcontacturi;
05889       else
05890          c = p->initreq.rlPart2;
05891    } else if (!ast_strlen_zero(p->okcontacturi)) 
05892       c = is_strict ? p->route->hop : p->okcontacturi; /* Use for BYE or REINVITE */
05893    else if (!ast_strlen_zero(p->uri)) 
05894       c = p->uri;
05895    else {
05896       char *n;
05897       /* We have no URI, use To: or From:  header as URI (depending on direction) */
05898       ast_copy_string(stripped, get_header(orig, (ast_test_flag(&p->flags[0], SIP_OUTGOING)) ? "To" : "From"),
05899             sizeof(stripped));
05900       n = get_in_brackets(stripped);
05901       c = strsep(&n, ";"); /* trim ; and beyond */
05902    }  
05903    init_req(req, sipmethod, c);
05904 
05905    snprintf(tmp, sizeof(tmp), "%d %s", seqno, sip_methods[sipmethod].text);
05906 
05907    add_header(req, "Via", p->via);
05908    if (p->route) {
05909       set_destination(p, p->route->hop);
05910       add_route(req, is_strict ? p->route->next : p->route);
05911    }
05912 
05913    ot = get_header(orig, "To");
05914    of = get_header(orig, "From");
05915 
05916    /* Add tag *unless* this is a CANCEL, in which case we need to send it exactly
05917       as our original request, including tag (or presumably lack thereof) */
05918    if (!strcasestr(ot, "tag=") && sipmethod != SIP_CANCEL) {
05919       /* Add the proper tag if we don't have it already.  If they have specified
05920          their tag, use it.  Otherwise, use our own tag */
05921       if (ast_test_flag(&p->flags[0], SIP_OUTGOING) && !ast_strlen_zero(p->theirtag))
05922          snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->theirtag);
05923       else if (!ast_test_flag(&p->flags[0], SIP_OUTGOING))
05924          snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->tag);
05925       else
05926          snprintf(newto, sizeof(newto), "%s", ot);
05927       ot = newto;
05928    }
05929 
05930    if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
05931       add_header(req, "From", of);
05932       add_header(req, "To", ot);
05933    } else {
05934       add_header(req, "From", ot);
05935       add_header(req, "To", of);
05936    }
05937    /* Do not add Contact for MESSAGE, BYE and Cancel requests */
05938    if (sipmethod != SIP_BYE && sipmethod != SIP_CANCEL && sipmethod != SIP_MESSAGE)
05939       add_header(req, "Contact", p->our_contact);
05940 
05941    copy_header(req, orig, "Call-ID");
05942    add_header(req, "CSeq", tmp);
05943 
05944    if (!ast_strlen_zero(global_useragent))
05945       add_header(req, "User-Agent", global_useragent);
05946    add_header(req, "Max-Forwards", DEFAULT_MAX_FORWARDS);
05947 
05948    if (!ast_strlen_zero(p->rpid))
05949       add_header(req, "Remote-Party-ID", p->rpid);
05950 
05951    return 0;
05952 }

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

Prepare SIP response packet.

Definition at line 5803 of file chan_sip.c.

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

05804 {
05805    char newto[256];
05806    const char *ot;
05807 
05808    init_resp(resp, msg);
05809    copy_via_headers(p, resp, req, "Via");
05810    if (msg[0] == '1' || msg[0] == '2')
05811       copy_all_header(resp, req, "Record-Route");
05812    copy_header(resp, req, "From");
05813    ot = get_header(req, "To");
05814    if (!strcasestr(ot, "tag=") && strncmp(msg, "100", 3)) {
05815       /* Add the proper tag if we don't have it already.  If they have specified
05816          their tag, use it.  Otherwise, use our own tag */
05817       if (!ast_strlen_zero(p->theirtag) && ast_test_flag(&p->flags[0], SIP_OUTGOING))
05818          snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->theirtag);
05819       else if (p->tag && !ast_test_flag(&p->flags[0], SIP_OUTGOING))
05820          snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->tag);
05821       else
05822          ast_copy_string(newto, ot, sizeof(newto));
05823       ot = newto;
05824    }
05825    add_header(resp, "To", ot);
05826    copy_header(resp, req, "Call-ID");
05827    copy_header(resp, req, "CSeq");
05828    if (!ast_strlen_zero(global_useragent))
05829       add_header(resp, "User-Agent", global_useragent);
05830    add_header(resp, "Allow", ALLOWED_METHODS);
05831    add_header(resp, "Supported", SUPPORTED_EXTENSIONS);
05832    if (msg[0] == '2' && (p->method == SIP_SUBSCRIBE || p->method == SIP_REGISTER)) {
05833       /* For registration responses, we also need expiry and
05834          contact info */
05835       char tmp[256];
05836 
05837       snprintf(tmp, sizeof(tmp), "%d", p->expiry);
05838       add_header(resp, "Expires", tmp);
05839       if (p->expiry) {  /* Only add contact if we have an expiry time */
05840          char contact[BUFSIZ];
05841          snprintf(contact, sizeof(contact), "%s;expires=%d", p->our_contact, p->expiry);
05842          add_header(resp, "Contact", contact);  /* Not when we unregister */
05843       }
05844    } else if (msg[0] != '4' && !ast_strlen_zero(p->our_contact)) {
05845       add_header(resp, "Contact", p->our_contact);
05846    }
05847    return 0;
05848 }

static int restart_monitor ( void   )  [static]

Start the channel monitor thread.

Definition at line 15628 of file chan_sip.c.

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

15629 {
15630    /* If we're supposed to be stopped -- stay stopped */
15631    if (monitor_thread == AST_PTHREADT_STOP)
15632       return 0;
15633    ast_mutex_lock(&monlock);
15634    if (monitor_thread == pthread_self()) {
15635       ast_mutex_unlock(&monlock);
15636       ast_log(LOG_WARNING, "Cannot kill myself\n");
15637       return -1;
15638    }
15639    if (monitor_thread != AST_PTHREADT_NULL) {
15640       /* Wake up the thread */
15641       pthread_kill(monitor_thread, SIGURG);
15642    } else {
15643       /* Start a new monitor */
15644       if (ast_pthread_create_background(&monitor_thread, NULL, do_monitor, NULL) < 0) {
15645          ast_mutex_unlock(&monlock);
15646          ast_log(LOG_ERROR, "Unable to start monitor thread.\n");
15647          return -1;
15648       }
15649    }
15650    ast_mutex_unlock(&monlock);
15651    return 0;
15652 }

static int retrans_pkt ( const void *  data  )  [static]

Retransmit SIP message if no answer (Called from scheduler).

Definition at line 1892 of file chan_sip.c.

References __sip_xmit(), append_history, AST_CAUSE_NO_USER_RESPONSE, ast_channel_trylock, ast_channel_unlock, ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_queue_hangup(), ast_set_flag, ast_test_flag, ast_verbose(), sip_pkt::data, DEFAULT_RETRANS, FLAG_FATAL, FLAG_RESPONSE, sip_pvt::flags, free, ast_channel::hangupcause, 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_pkt::retrans, sip_pkt::retransid, sip_pkt::seqno, sip_alreadygone(), SIP_BYE, sip_debug_test_pvt(), SIP_INVITE, sip_methods, sip_nat_mode(), SIP_NEEDDESTROY, SIP_OPTIONS, sip_real_dst(), sipdebug, cfsip_methods::text, sip_pkt::timer_a, sip_pkt::timer_t1, and XMIT_ERROR.

01893 {
01894    struct sip_pkt *pkt = (struct sip_pkt *)data, *prev, *cur = NULL;
01895    int reschedule = DEFAULT_RETRANS;
01896    int xmitres = 0;
01897 
01898    /* Lock channel PVT */
01899    ast_mutex_lock(&pkt->owner->lock);
01900 
01901    if (pkt->retrans < MAX_RETRANS) {
01902       pkt->retrans++;
01903       if (!pkt->timer_t1) {   /* Re-schedule using timer_a and timer_t1 */
01904          if (sipdebug && option_debug > 3)
01905             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);
01906       } else {
01907          int siptimer_a;
01908 
01909          if (sipdebug && option_debug > 3)
01910             ast_log(LOG_DEBUG, "SIP TIMER: Rescheduling retransmission #%d (%d) %s - %d\n", pkt->retransid, pkt->retrans, sip_methods[pkt->method].text, pkt->method);
01911          if (!pkt->timer_a)
01912             pkt->timer_a = 2 ;
01913          else
01914             pkt->timer_a = 2 * pkt->timer_a;
01915  
01916          /* For non-invites, a maximum of 4 secs */
01917          siptimer_a = pkt->timer_t1 * pkt->timer_a;   /* Double each time */
01918          if (pkt->method != SIP_INVITE && siptimer_a > 4000)
01919             siptimer_a = 4000;
01920       
01921          /* Reschedule re-transmit */
01922          reschedule = siptimer_a;
01923          if (option_debug > 3)
01924             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);
01925       } 
01926 
01927       if (sip_debug_test_pvt(pkt->owner)) {
01928          const struct sockaddr_in *dst = sip_real_dst(pkt->owner);
01929          ast_verbose("Retransmitting #%d (%s) to %s:%d:\n%s\n---\n",
01930             pkt->retrans, sip_nat_mode(pkt->owner),
01931             ast_inet_ntoa(dst->sin_addr),
01932             ntohs(dst->sin_port), pkt->data);
01933       }
01934 
01935       append_history(pkt->owner, "ReTx", "%d %s", reschedule, pkt->data);
01936       xmitres = __sip_xmit(pkt->owner, pkt->data, pkt->packetlen);
01937       ast_mutex_unlock(&pkt->owner->lock);
01938       if (xmitres == XMIT_ERROR)
01939          ast_log(LOG_WARNING, "Network error on retransmit in dialog %s\n", pkt->owner->callid);
01940       else
01941          return  reschedule;
01942    } 
01943    /* Too many retries */
01944    if (pkt->owner && pkt->method != SIP_OPTIONS && xmitres == 0) {
01945       if (ast_test_flag(pkt, FLAG_FATAL) || sipdebug) /* Tell us if it's critical or if we're debugging */
01946          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");
01947    } else if ((pkt->method == SIP_OPTIONS) && sipdebug) {
01948          ast_log(LOG_WARNING, "Cancelling retransmit of OPTIONs (call id %s) \n", pkt->owner->callid);
01949    }
01950    if (xmitres == XMIT_ERROR) {
01951       ast_log(LOG_WARNING, "Transmit error :: Cancelling transmission of transaction in call id %s \n", pkt->owner->callid);
01952       append_history(pkt->owner, "XmitErr", "%s", (ast_test_flag(pkt, FLAG_FATAL)) ? "(Critical)" : "(Non-critical)");
01953    } else
01954       append_history(pkt->owner, "MaxRetries", "%s", (ast_test_flag(pkt, FLAG_FATAL)) ? "(Critical)" : "(Non-critical)");
01955       
01956    pkt->retransid = -1;
01957 
01958    if (ast_test_flag(pkt, FLAG_FATAL)) {
01959       while(pkt->owner->owner && ast_channel_trylock(pkt->owner->owner)) {
01960          ast_mutex_unlock(&pkt->owner->lock);   /* SIP_PVT, not channel */
01961          usleep(1);
01962          ast_mutex_lock(&pkt->owner->lock);
01963       }
01964 
01965       if (pkt->owner->owner && !pkt->owner->owner->hangupcause) 
01966          pkt->owner->owner->hangupcause = AST_CAUSE_NO_USER_RESPONSE;
01967       
01968       if (pkt->owner->owner) {
01969          sip_alreadygone(pkt->owner);
01970          ast_log(LOG_WARNING, "Hanging up call %s - no reply to our critical packet.\n", pkt->owner->callid);
01971          ast_queue_hangup(pkt->owner->owner);
01972          ast_channel_unlock(pkt->owner->owner);
01973       } else {
01974          /* If no channel owner, destroy now */
01975 
01976          /* Let the peerpoke system expire packets when the timer expires for poke_noanswer */
01977          if (pkt->method != SIP_OPTIONS) {
01978             ast_set_flag(&pkt->owner->flags[0], SIP_NEEDDESTROY); 
01979             sip_alreadygone(pkt->owner);
01980             if (option_debug)
01981                append_history(pkt->owner, "DialogKill", "Killing this failed dialog immediately");
01982          }
01983       }
01984    }
01985 
01986    if (pkt->method == SIP_BYE) {
01987       /* We're not getting answers on SIP BYE's.  Tear down the call anyway. */
01988       if (pkt->owner->owner) 
01989          ast_channel_unlock(pkt->owner->owner);
01990       append_history(pkt->owner, "ByeFailure", "Remote peer doesn't respond to bye. Destroying call anyway.");
01991       ast_set_flag(&pkt->owner->flags[0], SIP_NEEDDESTROY);
01992    }
01993 
01994    /* In any case, go ahead and remove the packet */
01995    for (prev = NULL, cur = pkt->owner->packets; cur; prev = cur, cur = cur->next) {
01996       if (cur == pkt)
01997          break;
01998    }
01999    if (cur) {
02000       if (prev)
02001          prev->next = cur->next;
02002       else
02003          pkt->owner->packets = cur->next;
02004       ast_mutex_unlock(&pkt->owner->lock);
02005       free(cur);
02006       pkt = NULL;
02007    } else
02008       ast_log(LOG_WARNING, "Weird, couldn't find packet owner!\n");
02009    if (pkt)
02010       ast_mutex_unlock(&pkt->owner->lock);
02011    return 0;
02012 }

static int send_request ( struct sip_pvt p,
struct sip_request req,
enum xmittype  reliable,
int  seqno 
) [static]

Send SIP Request to the other part of the dialogue.

Definition at line 2267 of file chan_sip.c.

References __sip_reliable_xmit(), __sip_xmit(), add_blank(), append_history, ast_inet_ntoa(), ast_test_flag, ast_verbose(), sip_request::data, sip_pvt::flags, get_header(), sip_request::len, sip_request::method, parse_copy(), sip_pvt::recv, sip_pvt::sa, sip_debug_test_pvt(), sip_methods, SIP_NAT_ROUTE, SIP_NO_HISTORY, cfsip_methods::text, and XMIT_CRITICAL.

02268 {
02269    int res;
02270 
02271    add_blank(req);
02272    if (sip_debug_test_pvt(p)) {
02273       if (ast_test_flag(&p->flags[0], SIP_NAT_ROUTE))
02274          ast_verbose("%sTransmitting (NAT) to %s:%d:\n%s\n---\n", reliable ? "Reliably " : "", ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port), req->data);
02275       else
02276          ast_verbose("%sTransmitting (no NAT) to %s:%d:\n%s\n---\n", reliable ? "Reliably " : "", ast_inet_ntoa(p->sa.sin_addr), ntohs(p->sa.sin_port), req->data);
02277    }
02278    if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) {
02279       struct sip_request tmp;
02280       parse_copy(&tmp, req);
02281       append_history(p, reliable ? "TxReqRel" : "TxReq", "%s / %s - %s", tmp.data, get_header(&tmp, "CSeq"), sip_methods[tmp.method].text);
02282    }
02283    res = (reliable) ?
02284       __sip_reliable_xmit(p, seqno, 0, req->data, req->len, (reliable == XMIT_CRITICAL), req->method) :
02285       __sip_xmit(p, req->data, req->len);
02286    return res;
02287 }

static int send_response ( struct sip_pvt p,
struct sip_request req,
enum xmittype  reliable,
int  seqno 
) [static]

Transmit response on SIP request.

Definition at line 2239 of file chan_sip.c.

References __sip_reliable_xmit(), __sip_xmit(), add_blank(), append_history, ast_inet_ntoa(), ast_test_flag, ast_verbose(), sip_request::data, sip_pvt::flags, get_header(), sip_request::len, sip_request::method, parse_copy(), sip_request::rlPart2, sip_debug_test_pvt(), sip_methods, sip_nat_mode(), SIP_NO_HISTORY, sip_real_dst(), SIP_RESPONSE, SIP_UNKNOWN, cfsip_methods::text, and XMIT_CRITICAL.

02240 {
02241    int res;
02242 
02243    add_blank(req);
02244    if (sip_debug_test_pvt(p)) {
02245       const struct sockaddr_in *dst = sip_real_dst(p);
02246 
02247       ast_verbose("\n<--- %sTransmitting (%s) to %s:%d --->\n%s\n<------------>\n",
02248          reliable ? "Reliably " : "", sip_nat_mode(p),
02249          ast_inet_ntoa(dst->sin_addr),
02250          ntohs(dst->sin_port), req->data);
02251    }
02252    if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) {
02253       struct sip_request tmp;
02254       parse_copy(&tmp, req);
02255       append_history(p, reliable ? "TxRespRel" : "TxResp", "%s / %s - %s", tmp.data, get_header(&tmp, "CSeq"), 
02256          (tmp.method == SIP_RESPONSE || tmp.method == SIP_UNKNOWN) ? tmp.rlPart2 : sip_methods[tmp.method].text);
02257    }
02258    res = (reliable) ?
02259        __sip_reliable_xmit(p, seqno, 1, req->data, req->len, (reliable == XMIT_CRITICAL), req->method) :
02260       __sip_xmit(p, req->data, req->len);
02261    if (res > 0)
02262       return 0;
02263    return res;
02264 }

static int set_address_from_contact ( struct sip_pvt pvt  )  [static]

Change the other partys IP address based on given contact.

Definition at line 7944 of file chan_sip.c.

References ast_gethostbyname(), ast_log(), ast_strdupa, ast_test_flag, sip_pvt::flags, hp, LOG_NOTICE, LOG_WARNING, sip_pvt::recv, sip_pvt::sa, SIP_NAT_ROUTE, STANDARD_SIP_PORT, and strsep().

Referenced by handle_response_invite().

07945 {
07946    struct hostent *hp;
07947    struct ast_hostent ahp;
07948    int port;
07949    char *c, *host, *pt;
07950    char *contact;
07951 
07952 
07953    if (ast_test_flag(&pvt->flags[0], SIP_NAT_ROUTE)) {
07954       /* NAT: Don't trust the contact field.  Just use what they came to us
07955          with. */
07956       pvt->sa = pvt->recv;
07957       return 0;
07958    }
07959 
07960 
07961    /* Work on a copy */
07962    contact = ast_strdupa(pvt->fullcontact);
07963 
07964    /* Make sure it's a SIP URL */
07965    if (strncasecmp(contact, "sip:", 4)) {
07966       ast_log(LOG_NOTICE, "'%s' is not a valid SIP contact (missing sip:) trying to use anyway\n", contact);
07967    } else
07968       contact += 4;
07969 
07970    /* Ditch arguments */
07971    /* XXX this code is replicated also shortly below */
07972 
07973    /* Grab host */
07974    host = strchr(contact, '@');
07975    if (!host) {   /* No username part */
07976       host = contact;
07977       c = NULL;
07978    } else {
07979       *host++ = '\0';
07980    }
07981    pt = strchr(host, ':');
07982    if (pt) {
07983       *pt++ = '\0';
07984       port = atoi(pt);
07985    } else
07986       port = STANDARD_SIP_PORT;
07987 
07988    contact = strsep(&contact, ";"); /* trim ; and beyond in username part */
07989    host = strsep(&host, ";");    /* trim ; and beyond in host/domain part */
07990 
07991    /* XXX This could block for a long time XXX */
07992    /* We should only do this if it's a name, not an IP */
07993    hp = ast_gethostbyname(host, &ahp);
07994    if (!hp)  {
07995       ast_log(LOG_WARNING, "Invalid host name in Contact: (can't resolve in DNS) : '%s'\n", host);
07996       return -1;
07997    }
07998    pvt->sa.sin_family = AF_INET;
07999    memcpy(&pvt->sa.sin_addr, hp->h_addr, sizeof(pvt->sa.sin_addr));
08000    pvt->sa.sin_port = htons(port);
08001 
08002    return 0;
08003 }

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

Set destination from SIP URI.

Definition at line 5712 of file chan_sip.c.

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

Referenced by reqprep().

05713 {
05714    char *h, *maddr, hostname[256];
05715    int port, hn;
05716    struct hostent *hp;
05717    struct ast_hostent ahp;
05718    int debug=sip_debug_test_pvt(p);
05719 
05720    /* Parse uri to h (host) and port - uri is already just the part inside the <> */
05721    /* general form we are expecting is sip[s]:username[:password]@host[:port][;...] */
05722 
05723    if (debug)
05724       ast_verbose("set_destination: Parsing <%s> for address/port to send to\n", uri);
05725 
05726    /* Find and parse hostname */
05727    h = strchr(uri, '@');
05728    if (h)
05729       ++h;
05730    else {
05731       h = uri;
05732       if (strncasecmp(h, "sip:", 4) == 0)
05733          h += 4;
05734       else if (strncasecmp(h, "sips:", 5) == 0)
05735          h += 5;
05736    }
05737    hn = strcspn(h, ":;>") + 1;
05738    if (hn > sizeof(hostname)) 
05739       hn = sizeof(hostname);
05740    ast_copy_string(hostname, h, hn);
05741    /* XXX bug here if string has been trimmed to sizeof(hostname) */
05742    h += hn - 1;
05743 
05744    /* Is "port" present? if not default to STANDARD_SIP_PORT */
05745    if (*h == ':') {
05746       /* Parse port */
05747       ++h;
05748       port = strtol(h, &h, 10);
05749    }
05750    else
05751       port = STANDARD_SIP_PORT;
05752 
05753    /* Got the hostname:port - but maybe there's a "maddr=" to override address? */
05754    maddr = strstr(h, "maddr=");
05755    if (maddr) {
05756       maddr += 6;
05757       hn = strspn(maddr, "0123456789.") + 1;
05758       if (hn > sizeof(hostname))
05759          hn = sizeof(hostname);
05760       ast_copy_string(hostname, maddr, hn);
05761    }
05762    
05763    hp = ast_gethostbyname(hostname, &ahp);
05764    if (hp == NULL)  {
05765       ast_log(LOG_WARNING, "Can't find address for host '%s'\n", hostname);
05766       return;
05767    }
05768    p->sa.sin_family = AF_INET;
05769    memcpy(&p->sa.sin_addr, hp->h_addr, sizeof(p->sa.sin_addr));
05770    p->sa.sin_port = htons(port);
05771    if (debug)
05772       ast_verbose("set_destination: set destination to %s, port %d\n", ast_inet_ntoa(p->sa.sin_addr), port);
05773 }

static void set_insecure_flags ( struct ast_flags flags,
const char *  value,
int  lineno 
) [static]

Parse the "insecure" setting from sip.conf or from realtime.

Parameters:
flags a pointer to an ast_flags structure
value the value of the SIP insecure setting
lineno linenumber in sip.conf or -1 for realtime

Definition at line 15935 of file chan_sip.c.

References ast_false(), ast_log(), ast_set_flag, ast_strlen_zero(), ast_true(), LOG_WARNING, SIP_INSECURE_INVITE, SIP_INSECURE_PORT, and strsep().

Referenced by handle_common_options(), and realtime_peer().

15936 {
15937    static int dep_insecure_very = 0;
15938    static int dep_insecure_yes = 0;
15939 
15940    if (ast_strlen_zero(value))
15941       return;
15942 
15943    if (!strcasecmp(value, "very")) {
15944       ast_set_flag(flags, SIP_INSECURE_PORT | SIP_INSECURE_INVITE);
15945       if(!dep_insecure_very) {
15946          if(lineno != -1)
15947             ast_log(LOG_WARNING, "insecure=very at line %d is deprecated; use insecure=port,invite instead\n", lineno);
15948          else
15949             ast_log(LOG_WARNING, "insecure=very is deprecated; use insecure=port,invite instead\n");
15950          dep_insecure_very = 1;
15951       }
15952    }
15953    else if (ast_true(value)) {
15954       ast_set_flag(flags, SIP_INSECURE_PORT);
15955       if(!dep_insecure_yes) {
15956          if(lineno != -1)
15957             ast_log(LOG_WARNING, "insecure=%s at line %d is deprecated; use insecure=port instead\n", value, lineno);
15958          else
15959             ast_log(LOG_WARNING, "insecure=%s is deprecated; use insecure=port instead\n", value);
15960          dep_insecure_yes = 1;
15961       }
15962    }
15963    else if (!ast_false(value)) {
15964       char buf[64];
15965       char *word, *next;
15966       ast_copy_string(buf, value, sizeof(buf));
15967       next = buf;
15968       while ((word = strsep(&next, ","))) {
15969          if (!strcasecmp(word, "port"))
15970             ast_set_flag(flags, SIP_INSECURE_PORT);
15971          else if (!strcasecmp(word, "invite"))
15972             ast_set_flag(flags, SIP_INSECURE_INVITE);
15973          else
15974             ast_log(LOG_WARNING, "Unknown insecure mode '%s' on line %d\n", value, lineno);
15975       }
15976    }
15977 }

static void set_peer_defaults ( struct sip_peer peer  )  [static]

Set peer defaults before configuring specific configurations.

Definition at line 16362 of file chan_sip.c.

References sip_peer::addr, sip_peer::allowtransfer, ast_copy_flags, sip_peer::autoframing, sip_peer::callgroup, sip_peer::capability, sip_peer::cid_name, sip_peer::cid_num, sip_peer::context, sip_peer::defaddr, default_prefs, sip_peer::expire, sip_peer::flags, sip_peer::fromdomain, sip_peer::fromuser, sip_peer::language, sip_peer::mailbox, sip_peer::maxcallbitrate, sip_peer::maxms, sip_peer::md5secret, sip_peer::mohinterpret, sip_peer::mohsuggest, sip_peer::pickupgroup, sip_peer::pokeexpire, sip_peer::prefs, sip_peer::regexten, sip_peer::rtpholdtimeout, sip_peer::rtpkeepalive, sip_peer::rtptimeout, sip_peer::secret, SIP_FLAGS_TO_COPY, SIP_PAGE2_FLAGS_TO_COPY, STANDARD_SIP_PORT, sip_peer::subscribecontext, and sip_peer::vmexten.

Referenced by build_peer(), and temp_peer().

16363 {
16364    if (peer->expire == 0) {
16365       /* Don't reset expire or port time during reload 
16366          if we have an active registration 
16367       */
16368       peer->expire = -1;
16369       peer->pokeexpire = -1;
16370       peer->addr.sin_port = htons(STANDARD_SIP_PORT);
16371    }
16372    ast_copy_flags(&peer->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY);
16373    ast_copy_flags(&peer->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY);
16374    strcpy(peer->context, default_context);
16375    strcpy(peer->subscribecontext, default_subscribecontext);
16376    strcpy(peer->language, default_language);
16377    strcpy(peer->mohinterpret, default_mohinterpret);
16378    strcpy(peer->mohsuggest, default_mohsuggest);
16379    peer->addr.sin_family = AF_INET;
16380    peer->defaddr.sin_family = AF_INET;
16381    peer->capability = global_capability;
16382    peer->maxcallbitrate = default_maxcallbitrate;
16383    peer->rtptimeout = global_rtptimeout;
16384    peer->rtpholdtimeout = global_rtpholdtimeout;
16385    peer->rtpkeepalive = global_rtpkeepalive;
16386    peer->allowtransfer = global_allowtransfer;
16387    peer->autoframing = global_autoframing;
16388    strcpy(peer->vmexten, default_vmexten);
16389    peer->secret[0] = '\0';
16390    peer->md5secret[0] = '\0';
16391    peer->cid_num[0] = '\0';
16392    peer->cid_name[0] = '\0';
16393    peer->fromdomain[0] = '\0';
16394    peer->fromuser[0] = '\0';
16395    peer->regexten[0] = '\0';
16396    peer->mailbox[0] = '\0';
16397    peer->callgroup = 0;
16398    peer->pickupgroup = 0;
16399    peer->maxms = default_qualify;
16400    peer->prefs = default_prefs;
16401 }

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

Add a SIP header to an outbound INVITE.

Definition at line 17603 of file chan_sip.c.

References ast_channel_lock, ast_channel_unlock, ast_log(), ast_strlen_zero(), FALSE, inbuf(), LOG_DEBUG, LOG_WARNING, pbx_builtin_getvar_helper(), pbx_builtin_setvar_helper(), sipdebug, and TRUE.

Referenced by load_module().

17604 {
17605    int no = 0;
17606    int ok = FALSE;
17607    char varbuf[30];
17608    char *inbuf = (char *) data;
17609    
17610    if (ast_strlen_zero(inbuf)) {
17611       ast_log(LOG_WARNING, "This application requires the argument: Header\n");
17612       return 0;
17613    }
17614    ast_channel_lock(chan);
17615 
17616    /* Check for headers */
17617    while (!ok && no <= 50) {
17618       no++;
17619       snprintf(varbuf, sizeof(varbuf), "_SIPADDHEADER%.2d", no);
17620 
17621       /* Compare without the leading underscore */
17622       if( (pbx_builtin_getvar_helper(chan, (const char *) varbuf + 1) == (const char *) NULL) )
17623          ok = TRUE;
17624    }
17625    if (ok) {
17626       pbx_builtin_setvar_helper (chan, varbuf, inbuf);
17627       if (sipdebug)
17628          ast_log(LOG_DEBUG,"SIP Header added \"%s\" as %s\n", inbuf, varbuf);
17629    } else {
17630       ast_log(LOG_WARNING, "Too many SIP headers added, max 50\n");
17631    }
17632    ast_channel_unlock(chan);
17633    return 0;
17634 }

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

Support routine for find_peer.

Definition at line 2629 of file chan_sip.c.

References sip_peer::addr, ast_test_flag, sip_peer::flags, inaddrcmp(), and SIP_INSECURE_PORT.

Referenced by find_peer().

02630 {
02631    /* We know name is the first field, so we can cast */
02632    struct sip_peer *p = (struct sip_peer *) name;
02633    return   !(!inaddrcmp(&p->addr, sin) || 
02634                (ast_test_flag(&p->flags[0], SIP_INSECURE_PORT) &&
02635                (p->addr.sin_addr.s_addr == sin->sin_addr.s_addr)));
02636 }

static struct sip_pvt * sip_alloc ( ast_string_field  callid,
struct sockaddr_in *  sin,
int  useglobal_nat,
const int  intended_method 
) [static, read]

Allocate SIP_PVT structure and set defaults.

Definition at line 4390 of file chan_sip.c.

References __ourip, sip_pvt::allowtransfer, ast_calloc, ast_copy_flags, ast_log(), ast_mutex_destroy(), ast_mutex_init(), ast_mutex_lock(), ast_mutex_unlock(), ast_random(), AST_RTP_DTMF, ast_rtp_new_with_bindaddr(), ast_rtp_set_rtpholdtimeout(), ast_rtp_set_rtpkeepalive(), ast_rtp_set_rtptimeout(), ast_rtp_setdtmf(), ast_rtp_setdtmfcompensate(), ast_rtp_settos(), ast_set2_flag, ast_sip_ouraddrfor(), ast_string_field_init, ast_string_field_set, ast_test_flag, ast_udptl_get_error_correction_scheme(), ast_udptl_new_with_bindaddr(), ast_udptl_settos(), ast_variables_destroy(), sip_pvt::autokillid, bindaddr, sip_pvt::branch, build_callid_pvt(), build_via(), t38properties::capability, sip_pvt::capability, sip_pvt::chanvars, domain::context, default_prefs, do_setnat(), errno, sip_pvt::flags, free, global_t38_capability, iflist, INITIAL_CSEQ, sip_pvt::initid, t38properties::jointcapability, sip_pvt::lock, LOG_DEBUG, LOG_WARNING, make_our_tag(), sip_pvt::maxcallbitrate, sip_pvt::method, mohinterpret, mohsuggest, sip_pvt::next, sip_pvt::noncodeccapability, NONE, sip_pvt::ocseq, option_debug, sip_pvt::ourip, sip_pvt::prefs, sip_pvt::recv, sip_pvt::rtp, sip_pvt::sa, SIP_DTMF, SIP_DTMF_AUTO, SIP_DTMF_RFC2833, SIP_FLAGS_TO_COPY, sip_methods, SIP_NAT, SIP_NAT_ROUTE, SIP_NO_HISTORY, SIP_OPTIONS, SIP_PAGE2_FLAGS_TO_COPY, SIP_PAGE2_RFC2833_COMPENSATE, SIP_PAGE2_T38SUPPORT, SIP_PAGE2_VIDEOSUPPORT, SIP_REGISTER, sip_pvt::stateid, sip_pvt::subscribed, sip_pvt::t38, T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF, T38FAX_UDP_EC_FEC, T38FAX_UDP_EC_NONE, T38FAX_UDP_EC_REDUNDANCY, sip_pvt::tag, text, sip_pvt::timer_t1, sip_pvt::udptl, UDPTL_ERROR_CORRECTION_FEC, UDPTL_ERROR_CORRECTION_NONE, UDPTL_ERROR_CORRECTION_REDUNDANCY, sip_pvt::vrtp, and sip_pvt::waitid.

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

04392 {
04393    struct sip_pvt *p;
04394 
04395    if (!(p = ast_calloc(1, sizeof(*p))))
04396       return NULL;
04397 
04398    if (ast_string_field_init(p, 512)) {
04399       free(p);
04400       return NULL;
04401    }
04402 
04403    ast_mutex_init(&p->lock);
04404 
04405    p->method = intended_method;
04406    p->initid = -1;
04407    p->waitid = -1;
04408    p->autokillid = -1;
04409    p->subscribed = NONE;
04410    p->stateid = -1;
04411    p->prefs = default_prefs;     /* Set default codecs for this call */
04412 
04413    if (intended_method != SIP_OPTIONS) /* Peerpoke has it's own system */
04414       p->timer_t1 = 500;   /* Default SIP retransmission timer T1 (RFC 3261) */
04415 
04416    if (sin) {
04417       p->sa = *sin;
04418       if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
04419          p->ourip = __ourip;
04420    } else
04421       p->ourip = __ourip;
04422 
04423    /* Copy global flags to this PVT at setup. */
04424    ast_copy_flags(&p->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY);
04425    ast_copy_flags(&p->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY);
04426 
04427    ast_set2_flag(&p->flags[0], !recordhistory, SIP_NO_HISTORY);
04428 
04429    p->branch = ast_random();  
04430    make_our_tag(p->tag, sizeof(p->tag));
04431    p->ocseq = INITIAL_CSEQ;
04432 
04433    if (sip_methods[intended_method].need_rtp) {
04434       p->rtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr.sin_addr);
04435       /* If the global videosupport flag is on, we always create a RTP interface for video */
04436       if (ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT))
04437          p->vrtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr.sin_addr);
04438       if (ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT))
04439          p->udptl = ast_udptl_new_with_bindaddr(sched, io, 0, bindaddr.sin_addr);
04440       if (!p->rtp || (ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) && !p->vrtp)) {
04441          ast_log(LOG_WARNING, "Unable to create RTP audio %s session: %s\n",
04442             ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) ? "and video" : "", strerror(errno));
04443          ast_mutex_destroy(&p->lock);
04444          if (p->chanvars) {
04445             ast_variables_destroy(p->chanvars);
04446             p->chanvars = NULL;
04447          }
04448          free(p);
04449          return NULL;
04450       }
04451       ast_rtp_setdtmf(p->rtp, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833);
04452       ast_rtp_setdtmfcompensate(p->rtp, ast_test_flag(&p->flags[1], SIP_PAGE2_RFC2833_COMPENSATE));
04453       ast_rtp_settos(p->rtp, global_tos_audio);
04454       ast_rtp_set_rtptimeout(p->rtp, global_rtptimeout);
04455       ast_rtp_set_rtpholdtimeout(p->rtp, global_rtpholdtimeout);
04456       ast_rtp_set_rtpkeepalive(p->rtp, global_rtpkeepalive);
04457       if (p->vrtp) {
04458          ast_rtp_settos(p->vrtp, global_tos_video);
04459          ast_rtp_setdtmf(p->vrtp, 0);
04460          ast_rtp_setdtmfcompensate(p->vrtp, 0);
04461          ast_rtp_set_rtptimeout(p->vrtp, global_rtptimeout);
04462          ast_rtp_set_rtpholdtimeout(p->vrtp, global_rtpholdtimeout);
04463          ast_rtp_set_rtpkeepalive(p->vrtp, global_rtpkeepalive);
04464       }
04465       if (p->udptl)
04466          ast_udptl_settos(p->udptl, global_tos_audio);
04467       p->maxcallbitrate = default_maxcallbitrate;
04468    }
04469 
04470    if (useglobal_nat && sin) {
04471       /* Setup NAT structure according to global settings if we have an address */
04472       ast_copy_flags(&p->flags[0], &global_flags[0], SIP_NAT);
04473       p->recv = *sin;
04474       do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE);
04475    }
04476 
04477    if (p->method != SIP_REGISTER)
04478       ast_string_field_set(p, fromdomain, default_fromdomain);
04479    build_via(p);
04480    if (!callid)
04481       build_callid_pvt(p);
04482    else
04483       ast_string_field_set(p, callid, callid);
04484    /* Assign default music on hold class */
04485    ast_string_field_set(p, mohinterpret, default_mohinterpret);
04486    ast_string_field_set(p, mohsuggest, default_mohsuggest);
04487    p->capability = global_capability;
04488    p->allowtransfer = global_allowtransfer;
04489    if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) ||
04490        (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO))
04491       p->noncodeccapability |= AST_RTP_DTMF;
04492    if (p->udptl) {
04493       p->t38.capability = global_t38_capability;
04494       if (ast_udptl_get_error_correction_scheme(p->udptl) == UDPTL_ERROR_CORRECTION_REDUNDANCY)
04495          p->t38.capability |= T38FAX_UDP_EC_REDUNDANCY;
04496       else if (ast_udptl_get_error_correction_scheme(p->udptl) == UDPTL_ERROR_CORRECTION_FEC)
04497          p->t38.capability |= T38FAX_UDP_EC_FEC;
04498       else if (ast_udptl_get_error_correction_scheme(p->udptl) == UDPTL_ERROR_CORRECTION_NONE)
04499          p->t38.capability |= T38FAX_UDP_EC_NONE;
04500       p->t38.capability |= T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF;
04501       p->t38.jointcapability = p->t38.capability;
04502    }
04503    ast_string_field_set(p, context, default_context);
04504 
04505    /* Add to active dialog list */
04506    ast_mutex_lock(&iflock);
04507    p->next = iflist;
04508    iflist = p;
04509    ast_mutex_unlock(&iflock);
04510    if (option_debug)
04511       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");
04512    return p;
04513 }

static void sip_alreadygone ( struct sip_pvt dialog  )  [static]

Definition at line 1651 of file chan_sip.c.

References ast_log(), ast_set_flag, sip_pvt::flags, LOG_DEBUG, option_debug, and SIP_ALREADYGONE.

Referenced by handle_request_bye(), handle_request_cancel(), handle_request_invite(), handle_request_refer(), handle_response(), handle_response_invite(), retrans_pkt(), sip_indicate(), and sip_sipredirect().

01652 {
01653    if (option_debug > 2)
01654       ast_log(LOG_DEBUG, "Setting SIP_ALREADYGONE on dialog %s\n", dialog->callid);
01655    ast_set_flag(&dialog->flags[0], SIP_ALREADYGONE);
01656 }

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 3638 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, option_debug, t38properties::state, sip_pvt::t38, T38_ENABLED, T38_PEER_DIRECT, ast_channel::tech_pvt, transmit_response_with_sdp(), transmit_response_with_t38_sdp(), try_suggested_sip_codec(), and XMIT_CRITICAL.

03639 {
03640    int res = 0;
03641    struct sip_pvt *p = ast->tech_pvt;
03642 
03643    ast_mutex_lock(&p->lock);
03644    if (ast->_state != AST_STATE_UP) {
03645       try_suggested_sip_codec(p);   
03646 
03647       ast_setstate(ast, AST_STATE_UP);
03648       if (option_debug)
03649          ast_log(LOG_DEBUG, "SIP answering channel: %s\n", ast->name);
03650       if (p->t38.state == T38_PEER_DIRECT) {
03651          p->t38.state = T38_ENABLED;
03652          if (option_debug > 1)
03653             ast_log(LOG_DEBUG,"T38State change to %d on channel %s\n", p->t38.state, ast->name);
03654          res = transmit_response_with_t38_sdp(p, "200 OK", &p->initreq, XMIT_CRITICAL);
03655       } else 
03656          res = transmit_response_with_sdp(p, "200 OK", &p->initreq, XMIT_CRITICAL);
03657    }
03658    ast_mutex_unlock(&p->lock);
03659    return res;
03660 }

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

Initiate SIP call from PBX used from the dial() application.

Definition at line 2933 of file chan_sip.c.

References ast_channel::_state, sip_invite_param::addsipheaders, AST_FORMAT_AUDIO_MASK, AST_LIST_TRAVERSE, ast_log(), ast_sched_add(), ast_sched_del(), ast_set_flag, AST_STATE_DOWN, AST_STATE_RESERVED, ast_string_field_set, ast_translate_available_formats(), ast_var_name(), ast_var_value(), auto_congest(), sip_pvt::callingpres, t38properties::capability, sip_pvt::capability, ast_channel::cid, cid_name, ast_callerid::cid_pres, sip_invite_param::distinctive_ring, sip_pvt::flags, INC_CALL_RINGING, sip_pvt::initid, INV_CALLING, sip_pvt::invitestate, t38properties::jointcapability, sip_pvt::jointcapability, sip_pvt::jointnoncodeccapability, LOG_DEBUG, LOG_WARNING, sip_pvt::maxtime, sip_pvt::noncodeccapability, option_debug, sip_pvt::options, sip_pvt::prefcodec, sip_invite_param::replaces, SIP_INVITE, SIP_OUTGOING, SIP_TRANS_TIMEOUT, sipdebug, t38properties::state, sip_pvt::t38, T38_LOCAL_DIRECT, ast_channel::tech_pvt, sip_invite_param::transfer, transmit_invite(), update_call_counter(), sip_invite_param::uri_options, ast_channel::varshead, sip_invite_param::vxml_url, and XMIT_ERROR.

02934 {
02935    int res, xmitres = 0;
02936    struct sip_pvt *p;
02937    struct varshead *headp;
02938    struct ast_var_t *current;
02939    const char *referer = NULL;   /* SIP refererer */  
02940 
02941    p = ast->tech_pvt;
02942    if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) {
02943       ast_log(LOG_WARNING, "sip_call called on %s, neither down nor reserved\n", ast->name);
02944       return -1;
02945    }
02946 
02947    /* Check whether there is vxml_url, distinctive ring variables */
02948    headp=&ast->varshead;
02949    AST_LIST_TRAVERSE(headp,current,entries) {
02950       /* Check whether there is a VXML_URL variable */
02951       if (!p->options->vxml_url && !strcasecmp(ast_var_name(current), "VXML_URL")) {
02952          p->options->vxml_url = ast_var_value(current);
02953       } else if (!p->options->uri_options && !strcasecmp(ast_var_name(current), "SIP_URI_OPTIONS")) {
02954          p->options->uri_options = ast_var_value(current);
02955       } else if (!p->options->distinctive_ring && !strcasecmp(ast_var_name(current), "ALERT_INFO")) {
02956          /* Check whether there is a ALERT_INFO variable */
02957          p->options->distinctive_ring = ast_var_value(current);
02958       } else if (!p->options->addsipheaders && !strncasecmp(ast_var_name(current), "SIPADDHEADER", strlen("SIPADDHEADER"))) {
02959          /* Check whether there is a variable with a name starting with SIPADDHEADER */
02960          p->options->addsipheaders = 1;
02961       } else if (!strcasecmp(ast_var_name(current), "SIPTRANSFER")) {
02962          /* This is a transfered call */
02963          p->options->transfer = 1;
02964       } else if (!strcasecmp(ast_var_name(current), "SIPTRANSFER_REFERER")) {
02965          /* This is the referer */
02966          referer = ast_var_value(current);
02967       } else if (!strcasecmp(ast_var_name(current), "SIPTRANSFER_REPLACES")) {
02968          /* We're replacing a call. */
02969          p->options->replaces = ast_var_value(current);
02970       } else if (!strcasecmp(ast_var_name(current), "T38CALL")) {
02971          p->t38.state = T38_LOCAL_DIRECT;
02972          if (option_debug)
02973             ast_log(LOG_DEBUG,"T38State change to %d on channel %s\n", p->t38.state, ast->name);
02974       }
02975 
02976    }
02977    
02978    res = 0;
02979    ast_set_flag(&p->flags[0], SIP_OUTGOING);
02980 
02981    if (p->options->transfer) {
02982       char buf[BUFSIZ/2];
02983 
02984       if (referer) {
02985          if (sipdebug && option_debug > 2)
02986             ast_log(LOG_DEBUG, "Call for %s transfered by %s\n", p->username, referer);
02987          snprintf(buf, sizeof(buf)-1, "-> %s (via %s)", p->cid_name, referer);
02988       } else 
02989          snprintf(buf, sizeof(buf)-1, "-> %s", p->cid_name);
02990       ast_string_field_set(p, cid_name, buf);
02991    } 
02992    if (option_debug)
02993       ast_log(LOG_DEBUG, "Outgoing Call for %s\n", p->username);
02994 
02995    res = update_call_counter(p, INC_CALL_RINGING);
02996    if ( res != -1 ) {
02997       p->callingpres = ast->cid.cid_pres;
02998       p->jointcapability = ast_translate_available_formats(p->capability, p->prefcodec);
02999       p->jointnoncodeccapability = p->noncodeccapability;
03000 
03001       /* If there are no audio formats left to offer, punt */
03002       if (!(p->jointcapability & AST_FORMAT_AUDIO_MASK)) {
03003          ast_log(LOG_WARNING, "No audio format found to offer. Cancelling call to %s\n", p->username);
03004          res = -1;
03005       } else {
03006          p->t38.jointcapability = p->t38.capability;
03007          if (option_debug > 1)
03008             ast_log(LOG_DEBUG,"Our T38 capability (%d), joint T38 capability (%d)\n", p->t38.capability, p->t38.jointcapability);
03009          xmitres = transmit_invite(p, SIP_INVITE, 1, 2);
03010          if (xmitres == XMIT_ERROR)
03011             return -1;  /* Transmission error */
03012 
03013          p->invitestate = INV_CALLING;
03014 
03015          /* Initialize auto-congest time */
03016          if (p->initid > -1)
03017             ast_sched_del(sched, p->initid);
03018          p->initid = ast_sched_add(sched, p->maxtime ? (p->maxtime * 4) : SIP_TRANS_TIMEOUT, auto_congest, p);
03019       }
03020    }
03021    return res;
03022 }

static void sip_cancel_destroy ( struct sip_pvt p  )  [static]

Cancel destruction of SIP dialog.

Definition at line 2127 of file chan_sip.c.

References append_history, ast_sched_del(), and sip_pvt::autokillid.

Referenced by cb_extensionstate(), check_user_full(), handle_request_invite(), handle_request_subscribe(), handle_response(), handle_response_invite(), register_verify(), and sip_hangup().

02128 {
02129    if (p->autokillid > -1) {
02130       ast_sched_del(sched, p->autokillid);
02131       append_history(p, "CancelDestroy", "");
02132       p->autokillid = -1;
02133    }
02134 }

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

See if we pass debug IP filter.

Definition at line 1733 of file chan_sip.c.

References debugaddr, and sipdebug.

Referenced by check_user_full(), sip_debug_test_pvt(), and sipsock_read().

01734 {
01735    if (!sipdebug)
01736       return 0;
01737    if (debugaddr.sin_addr.s_addr) {
01738       if (((ntohs(debugaddr.sin_port) != 0)
01739          && (debugaddr.sin_port != addr->sin_port))
01740          || (debugaddr.sin_addr.s_addr != addr->sin_addr.s_addr))
01741          return 0;
01742    }
01743    return 1;
01744 }

static int sip_debug_test_pvt ( struct sip_pvt p  )  [inline, static]

static void sip_destroy ( struct sip_pvt p  )  [static]

Destroy SIP call structure.

Definition at line 3280 of file chan_sip.c.

References __sip_destroy(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), LOG_DEBUG, and option_debug.

Referenced by __sip_autodestruct(), handle_request_subscribe(), reload_config(), sip_destroy_peer(), sip_notify(), sip_poke_noanswer(), sip_poke_peer(), sip_registry_destroy(), sip_request_call(), sip_send_mwi_to_peer(), and transmit_register().

03281 {
03282    ast_mutex_lock(&iflock);
03283    if (option_debug > 2)
03284       ast_log(LOG_DEBUG, "Destroying SIP dialog %s\n", p->callid);
03285    __sip_destroy(p, 1);
03286    ast_mutex_unlock(&iflock);
03287 }

static void sip_destroy_peer ( struct sip_peer peer  )  [static]

Destroy peer object from memory.

Definition at line 2439 of file chan_sip.c.

References ast_free_ha(), ast_log(), ast_sched_del(), ast_test_flag, ast_variables_destroy(), sip_peer::auth, sip_peer::call, sip_peer::chanvars, clear_realm_authentication(), sip_peer::expire, FALSE, sip_peer::flags, free, sip_peer::ha, LOG_DEBUG, sip_peer::mwipvt, option_debug, sip_peer::pokeexpire, register_peer_exten(), sip_destroy(), SIP_PAGE2_SELFDESTRUCT, and SIP_REALTIME.

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

02440 {
02441    if (option_debug > 2)
02442       ast_log(LOG_DEBUG, "Destroying SIP peer %s\n", peer->name);
02443 
02444    /* Delete it, it needs to disappear */
02445    if (peer->call)
02446       sip_destroy(peer->call);
02447 
02448    if (peer->mwipvt)    /* We have an active subscription, delete it */
02449       sip_destroy(peer->mwipvt);
02450 
02451    if (peer->chanvars) {
02452       ast_variables_destroy(peer->chanvars);
02453       peer->chanvars = NULL;
02454    }
02455    if (peer->expire > -1)
02456       ast_sched_del(sched, peer->expire);
02457 
02458    if (peer->pokeexpire > -1)
02459       ast_sched_del(sched, peer->pokeexpire);
02460    register_peer_exten(peer, FALSE);
02461    ast_free_ha(peer->ha);
02462    if (ast_test_flag(&peer->flags[1], SIP_PAGE2_SELFDESTRUCT))
02463       apeerobjs--;
02464    else if (ast_test_flag(&peer->flags[0], SIP_REALTIME))
02465       rpeerobjs--;
02466    else
02467       speerobjs--;
02468    clear_realm_authentication(peer->auth);
02469    peer->auth = NULL;
02470    free(peer);
02471 }

static void sip_destroy_user ( struct sip_user user  )  [static]

Remove user object from in-memory storage.

Definition at line 2657 of file chan_sip.c.

References ast_free_ha(), ast_log(), ast_test_flag, ast_variables_destroy(), sip_user::chanvars, sip_user::flags, free, sip_user::ha, LOG_DEBUG, option_debug, and SIP_REALTIME.

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

02658 {
02659    if (option_debug > 2)
02660       ast_log(LOG_DEBUG, "Destroying user object from memory: %s\n", user->name);
02661    ast_free_ha(user->ha);
02662    if (user->chanvars) {
02663       ast_variables_destroy(user->chanvars);
02664       user->chanvars = NULL;
02665    }
02666    if (ast_test_flag(&user->flags[0], SIP_REALTIME))
02667       ruserobjs--;
02668    else
02669       suserobjs--;
02670    free(user);
02671 }

static int sip_devicestate ( void *  data  )  [static]

Part of PBX channel interface.

Note:
Return values:---
If we have qualify on and the device is not reachable, regardless of registration state we return AST_DEVICE_UNAVAILABLE

For peers with call limit:

  • not registered AST_DEVICE_UNAVAILABLE
  • registered, no call AST_DEVICE_NOT_INUSE
  • registered, active calls AST_DEVICE_INUSE
  • registered, call limit reached AST_DEVICE_BUSY
  • registered, onhold AST_DEVICE_ONHOLD
  • registered, ringing AST_DEVICE_RINGING

For peers without call limit:

  • not registered AST_DEVICE_UNAVAILABLE
  • registered AST_DEVICE_NOT_INUSE
  • fixed IP (!dynamic) AST_DEVICE_NOT_INUSE

Peers that does not have a known call and can't be reached by OPTIONS

  • unreachable AST_DEVICE_UNAVAILABLE

If we return AST_DEVICE_UNKNOWN, the device state engine will try to find out a state by walking the channel list.

The queue system (app_queue.c) treats a member as "active" if devicestate is != AST_DEVICE_UNAVAILBALE && != AST_DEVICE_INVALID

When placing a call to the queue member, queue system sets a member to busy if != AST_DEVICE_NOT_INUSE and != AST_DEVICE_UNKNOWN

Definition at line 15777 of file chan_sip.c.

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

15778 {
15779    char *host;
15780    char *tmp;
15781 
15782    struct hostent *hp;
15783    struct ast_hostent ahp;
15784    struct sip_peer *p;
15785 
15786    int res = AST_DEVICE_INVALID;
15787 
15788    /* make sure data is not null. Maybe unnecessary, but better be safe */
15789    host = ast_strdupa(data ? data : "");
15790    if ((tmp = strchr(host, '@')))
15791       host = tmp + 1;
15792 
15793    if (option_debug > 2) 
15794       ast_log(LOG_DEBUG, "Checking device state for peer %s\n", host);
15795 
15796    if ((p = find_peer(host, NULL, 1))) {
15797       if (p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) {
15798          /* we have an address for the peer */
15799       
15800          /* Check status in this order
15801             - Hold
15802             - Ringing
15803             - Busy (enforced only by call limit)
15804             - Inuse (we have a call)
15805             - Unreachable (qualify)
15806             If we don't find any of these state, report AST_DEVICE_NOT_INUSE
15807             for registered devices */
15808 
15809          if (p->onHold)
15810             /* First check for hold or ring states */
15811             res = AST_DEVICE_ONHOLD;
15812          else if (p->inRinging) {
15813             if (p->inRinging == p->inUse)
15814                res = AST_DEVICE_RINGING;
15815             else
15816                res = AST_DEVICE_RINGINUSE;
15817          } else if (p->call_limit && (p->inUse == p->call_limit))
15818             /* check call limit */
15819             res = AST_DEVICE_BUSY;
15820          else if (p->call_limit && p->inUse)
15821             /* Not busy, but we do have a call */
15822             res = AST_DEVICE_INUSE;
15823          else if (p->maxms && ((p->lastms > p->maxms) || (p->lastms < 0))) 
15824             /* We don't have a call. Are we reachable at all? Requires qualify= */
15825             res = AST_DEVICE_UNAVAILABLE;
15826          else  /* Default reply if we're registered and have no other data */
15827             res = AST_DEVICE_NOT_INUSE;
15828       } else {
15829          /* there is no address, it's unavailable */
15830          res = AST_DEVICE_UNAVAILABLE;
15831       }
15832       ASTOBJ_UNREF(p,sip_destroy_peer);
15833    } else {
15834       char *port = strchr(host, ':');
15835       if (port)
15836          *port = '\0';
15837       hp = ast_gethostbyname(host, &ahp);
15838       if (hp)
15839          res = AST_DEVICE_UNKNOWN;
15840    }
15841 
15842    return res;
15843 }

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

Turn on SIP debugging (CLI command).

Definition at line 11197 of file chan_sip.c.

References ast_cli(), ast_set_flag, debugaddr, RESULT_SHOWUSAGE, RESULT_SUCCESS, sip_do_debug_ip(), sip_do_debug_peer(), SIP_PAGE2_DEBUG_CONSOLE, and sipdebug_console.

11198 {
11199    int oldsipdebug = sipdebug_console;
11200    if (argc != 3) {
11201       if (argc != 5) 
11202          return RESULT_SHOWUSAGE;
11203       else if (strcmp(argv[3], "ip") == 0)
11204          return sip_do_debug_ip(fd, argc, argv);
11205       else if (strcmp(argv[3], "peer") == 0)
11206          return sip_do_debug_peer(fd, argc, argv);
11207       else
11208          return RESULT_SHOWUSAGE;
11209    }
11210    ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE);
11211    memset(&debugaddr, 0, sizeof(debugaddr));
11212    ast_cli(fd, "SIP Debugging %senabled\n", oldsipdebug ? "re-" : "");
11213    return RESULT_SUCCESS;
11214 }

static int sip_do_debug_deprecated ( int  fd,
int  argc,
char *  argv[] 
) [static]

Definition at line 11216 of file chan_sip.c.

References ast_cli(), ast_set_flag, debugaddr, RESULT_SHOWUSAGE, RESULT_SUCCESS, sip_do_debug_ip(), sip_do_debug_peer(), SIP_PAGE2_DEBUG_CONSOLE, and sipdebug_console.

11217 {
11218    int oldsipdebug = sipdebug_console;
11219    char *newargv[6] = { "sip", "set", "debug", NULL };
11220    if (argc != 2) {
11221       if (argc != 4) 
11222          return RESULT_SHOWUSAGE;
11223       else if (strcmp(argv[2], "ip") == 0) {
11224          newargv[3] = argv[2];
11225          newargv[4] = argv[3];
11226          return sip_do_debug_ip(fd, argc + 1, newargv);
11227       } else if (strcmp(argv[2], "peer") == 0) {
11228          newargv[3] = argv[2];
11229          newargv[4] = argv[3];
11230          return sip_do_debug_peer(fd, argc + 1, newargv);
11231       } else
11232          return RESULT_SHOWUSAGE;
11233    }
11234    ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE);
11235    memset(&debugaddr, 0, sizeof(debugaddr));
11236    ast_cli(fd, "SIP Debugging %senabled\n", oldsipdebug ? "re-" : "");
11237    return RESULT_SUCCESS;
11238 }

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

Enable SIP Debugging in CLI.

Definition at line 11143 of file chan_sip.c.

References ast_cli(), ast_gethostbyname(), ast_inet_ntoa(), ast_set_flag, debugaddr, hp, RESULT_SHOWUSAGE, RESULT_SUCCESS, SIP_PAGE2_DEBUG_CONSOLE, and strsep().

Referenced by sip_do_debug(), and sip_do_debug_deprecated().

11144 {
11145    struct hostent *hp;
11146    struct ast_hostent ahp;
11147    int port = 0;
11148    char *p, *arg;
11149 
11150    /* sip set debug ip <ip> */
11151    if (argc != 5)
11152       return RESULT_SHOWUSAGE;
11153    p = arg = argv[4];
11154    strsep(&p, ":");
11155    if (p)
11156       port = atoi(p);
11157    hp = ast_gethostbyname(arg, &ahp);
11158    if (hp == NULL)
11159       return RESULT_SHOWUSAGE;
11160 
11161    debugaddr.sin_family = AF_INET;
11162    memcpy(&debugaddr.sin_addr, hp->h_addr, sizeof(debugaddr.sin_addr));
11163    debugaddr.sin_port = htons(port);
11164    if (port == 0)
11165       ast_cli(fd, "SIP Debugging Enabled for IP: %s\n", ast_inet_ntoa(debugaddr.sin_addr));
11166    else
11167       ast_cli(fd, "SIP Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(debugaddr.sin_addr), port);
11168 
11169    ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE);
11170 
11171    return RESULT_SUCCESS;
11172 }

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

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

Referenced by sip_do_debug(), and sip_do_debug_deprecated().

11176 {
11177    struct sip_peer *peer;
11178    if (argc != 5)
11179       return RESULT_SHOWUSAGE;
11180    peer = find_peer(argv[4], NULL, 1);
11181    if (peer) {
11182       if (peer->addr.sin_addr.s_addr) {
11183          debugaddr.sin_family = AF_INET;
11184          debugaddr.sin_addr = peer->addr.sin_addr;
11185          debugaddr.sin_port = peer->addr.sin_port;
11186          ast_cli(fd, "SIP Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(debugaddr.sin_addr), ntohs(debugaddr.sin_port));
11187          ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE);
11188       } else
11189          ast_cli(fd, "Unable to get IP address of peer '%s'\n", argv[4]);
11190       ASTOBJ_UNREF(peer,sip_destroy_peer);
11191    } else
11192       ast_cli(fd, "No such peer '%s'\n", argv[4]);
11193    return RESULT_SUCCESS;
11194 }

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

Enable SIP History logging (CLI).

Definition at line 11316 of file chan_sip.c.

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

11317 {
11318    if (argc != 2) {
11319       return RESULT_SHOWUSAGE;
11320    }
11321    recordhistory = TRUE;
11322    ast_cli(fd, "SIP History Recording Enabled (use 'sip show history')\n");
11323    return RESULT_SUCCESS;
11324 }

static int sip_do_reload ( enum channelreloadreason  reason  )  [static]

Reload module.

Definition at line 17744 of file chan_sip.c.

References ast_log(), ASTOBJ_CONTAINER_PRUNE_MARKED, LOG_DEBUG, option_debug, peerl, reload_config(), sip_destroy_peer(), sip_poke_all_peers(), and sip_send_all_registers().

Referenced by do_monitor().

17745 {
17746    reload_config(reason);
17747 
17748    /* Prune peers who still are supposed to be deleted */
17749    ASTOBJ_CONTAINER_PRUNE_MARKED(&peerl, sip_destroy_peer);
17750    if (option_debug > 3)
17751       ast_log(LOG_DEBUG, "--------------- Done destroying pruned peers\n");
17752 
17753    /* Send qualify (OPTIONS) to all peers */
17754    sip_poke_all_peers();
17755 
17756    /* Register with all services */
17757    sip_send_all_registers();
17758 
17759    if (option_debug > 3)
17760       ast_log(LOG_DEBUG, "--------------- SIP reload done\n");
17761 
17762    return 0;
17763 }

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

Set the DTMFmode for an outbound SIP call (application).

Definition at line 17548 of file chan_sip.c.

References ast_channel_lock, ast_channel_unlock, ast_clear_flag, ast_dsp_free(), ast_dsp_new(), ast_dsp_set_features(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_RTP_DTMF, ast_rtp_setdtmf(), ast_set_flag, ast_test_flag, DSP_FEATURE_DTMF_DETECT, sip_pvt::flags, sip_pvt::jointnoncodeccapability, sip_pvt::lock, LOG_WARNING, sip_pvt::rtp, SIP_DTMF, SIP_DTMF_INBAND, SIP_DTMF_INFO, SIP_DTMF_RFC2833, sip_tech, sip_tech_info, ast_channel::tech, ast_channel::tech_pvt, and sip_pvt::vad.

Referenced by load_module().

17549 {
17550    struct sip_pvt *p;
17551    char *mode;
17552    if (data)
17553       mode = (char *)data;
17554    else {
17555       ast_log(LOG_WARNING, "This application requires the argument: info, inband, rfc2833\n");
17556       return 0;
17557    }
17558    ast_channel_lock(chan);
17559    if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) {
17560       ast_log(LOG_WARNING, "Call this application only on SIP incoming calls\n");
17561       ast_channel_unlock(chan);
17562       return 0;
17563    }
17564    p = chan->tech_pvt;
17565    if (!p) {
17566       ast_channel_unlock(chan);
17567       return 0;
17568    }
17569    ast_mutex_lock(&p->lock);
17570    if (!strcasecmp(mode,"info")) {
17571       ast_clear_flag(&p->flags[0], SIP_DTMF);
17572       ast_set_flag(&p->flags[0], SIP_DTMF_INFO);
17573       p->jointnoncodeccapability &= ~AST_RTP_DTMF;
17574    } else if (!strcasecmp(mode,"rfc2833")) {
17575       ast_clear_flag(&p->flags[0], SIP_DTMF);
17576       ast_set_flag(&p->flags[0], SIP_DTMF_RFC2833);
17577       p->jointnoncodeccapability |= AST_RTP_DTMF;
17578    } else if (!strcasecmp(mode,"inband")) { 
17579       ast_clear_flag(&p->flags[0], SIP_DTMF);
17580       ast_set_flag(&p->flags[0], SIP_DTMF_INBAND);
17581       p->jointnoncodeccapability &= ~AST_RTP_DTMF;
17582    } else
17583       ast_log(LOG_WARNING, "I don't know about this dtmf mode: %s\n",mode);
17584    if (p->rtp)
17585       ast_rtp_setdtmf(p->rtp, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833);
17586    if (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) {
17587       if (!p->vad) {
17588          p->vad = ast_dsp_new();
17589          ast_dsp_set_features(p->vad, DSP_FEATURE_DTMF_DETECT);
17590       }
17591    } else {
17592       if (p->vad) {
17593          ast_dsp_free(p->vad);
17594          p->vad = NULL;
17595       }
17596    }
17597    ast_mutex_unlock(&p->lock);
17598    ast_channel_unlock(chan);
17599    return 0;
17600 }

static void sip_dump_history ( struct sip_pvt dialog  )  [static]

Dump SIP history to debug log file at end of lifespan for SIP dialog.

Definition at line 11008 of file chan_sip.c.

References AST_LIST_TRAVERSE, ast_log(), sip_pvt::history, LOG_DEBUG, LOG_NOTICE, option_debug, sipdebug, and sip_pvt::subscribed.

Referenced by __sip_destroy().

11009 {
11010    int x = 0;
11011    struct sip_history *hist;
11012    static int errmsg = 0;
11013 
11014    if (!dialog)
11015       return;
11016 
11017    if (!option_debug && !sipdebug) {
11018       if (!errmsg) {
11019          ast_log(LOG_NOTICE, "You must have debugging enabled (SIP or Asterisk) in order to dump SIP history.\n");
11020          errmsg = 1;
11021       }
11022       return;
11023    }
11024 
11025    ast_log(LOG_DEBUG, "\n---------- SIP HISTORY for '%s' \n", dialog->callid);
11026    if (dialog->subscribed)
11027       ast_log(LOG_DEBUG, "  * Subscription\n");
11028    else
11029       ast_log(LOG_DEBUG, "  * SIP Call\n");
11030    if (dialog->history)
11031       AST_LIST_TRAVERSE(dialog->history, hist, list)
11032          ast_log(LOG_DEBUG, "  %-3.3d. %s\n", ++x, hist->event);
11033    if (!x)
11034       ast_log(LOG_DEBUG, "Call '%s' has no history\n", dialog->callid);
11035    ast_log(LOG_DEBUG, "\n---------- END SIP HISTORY for '%s' \n", dialog->callid);
11036 }

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

References append_history, AST_FLAG_ZOMBIE, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, sip_pvt::lock, LOG_DEBUG, LOG_WARNING, option_debug, sip_pvt::owner, and ast_channel::tech_pvt.

03741 {
03742    int ret = -1;
03743    struct sip_pvt *p;
03744 
03745    if (newchan && ast_test_flag(newchan, AST_FLAG_ZOMBIE) && option_debug)
03746       ast_log(LOG_DEBUG, "New channel is zombie\n");
03747    if (oldchan && ast_test_flag(oldchan, AST_FLAG_ZOMBIE) && option_debug)
03748       ast_log(LOG_DEBUG, "Old channel is zombie\n");
03749 
03750    if (!newchan || !newchan->tech_pvt) {
03751       if (!newchan)
03752          ast_log(LOG_WARNING, "No new channel! Fixup of %s failed.\n", oldchan->name);
03753       else
03754          ast_log(LOG_WARNING, "No SIP tech_pvt! Fixup of %s failed.\n", oldchan->name);
03755       return -1;
03756    }
03757    p = newchan->tech_pvt;
03758 
03759    if (!p) {
03760       ast_log(LOG_WARNING, "No pvt after masquerade. Strange things may happen\n");
03761       return -1;
03762    }
03763 
03764    ast_mutex_lock(&p->lock);
03765    append_history(p, "Masq", "Old channel: %s\n", oldchan->name);
03766    append_history(p, "Masq (cont)", "...new owner: %s\n", newchan->name);
03767    if (p->owner != oldchan)
03768       ast_log(LOG_WARNING, "old channel wasn't %p but was %p\n", oldchan, p->owner);
03769    else {
03770       p->owner = newchan;
03771       ret = 0;
03772    }
03773    if (option_debug > 2)
03774       ast_log(LOG_DEBUG, "SIP Fixup: New owner for dialogue %s: %s (Old parent: %s)\n", p->callid, p->owner->name, oldchan->name);
03775 
03776    ast_mutex_unlock(&p->lock);
03777    return ret;
03778 }

static int sip_get_codec ( struct ast_channel chan  )  [static]

Return SIP UA's codec (part of the RTP interface).

Definition at line 17693 of file chan_sip.c.

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

17694 {
17695    struct sip_pvt *p = chan->tech_pvt;
17696    return p->peercapability ? p->peercapability : p->capability;  
17697 }

static enum ast_rtp_get_result sip_get_rtp_peer ( struct ast_channel chan,
struct ast_rtp **  rtp 
) [static]

Returns null if we can't reinvite audio (part of RTP interface).

Definition at line 17401 of file chan_sip.c.

References AST_JB_FORCED, ast_mutex_lock(), ast_mutex_unlock(), AST_RTP_GET_FAILED, ast_rtp_getnat(), AST_RTP_TRY_NATIVE, AST_RTP_TRY_PARTIAL, ast_test_flag, sip_pvt::flags, global_jbconf, sip_pvt::lock, sip_pvt::rtp, SIP_CAN_REINVITE, SIP_CAN_REINVITE_NAT, and ast_channel::tech_pvt.

17402 {
17403    struct sip_pvt *p = NULL;
17404    enum ast_rtp_get_result res = AST_RTP_TRY_PARTIAL;
17405 
17406    if (!(p = chan->tech_pvt))
17407       return AST_RTP_GET_FAILED;
17408 
17409    ast_mutex_lock(&p->lock);
17410    if (!(p->rtp)) {
17411       ast_mutex_unlock(&p->lock);
17412       return AST_RTP_GET_FAILED;
17413    }
17414 
17415    *rtp = p->rtp;
17416 
17417    if (ast_rtp_getnat(*rtp) && !ast_test_flag(&p->flags[0], SIP_CAN_REINVITE_NAT))
17418       res = AST_RTP_TRY_PARTIAL;
17419    else if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE))
17420       res = AST_RTP_TRY_NATIVE;
17421    else if (ast_test_flag(&global_jbconf, AST_JB_FORCED))
17422       res = AST_RTP_GET_FAILED;
17423 
17424    ast_mutex_unlock(&p->lock);
17425 
17426    return res;
17427 }

static struct ast_udptl * sip_get_udptl_peer ( struct ast_channel chan  )  [static, read]

Definition at line 17266 of file chan_sip.c.

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

17267 {
17268    struct sip_pvt *p;
17269    struct ast_udptl *udptl = NULL;
17270    
17271    p = chan->tech_pvt;
17272    if (!p)
17273       return NULL;
17274    
17275    ast_mutex_lock(&p->lock);
17276    if (p->udptl && ast_test_flag(&p->flags[0], SIP_CAN_REINVITE))
17277       udptl = p->udptl;
17278    ast_mutex_unlock(&p->lock);
17279    return udptl;
17280 }

static enum ast_rtp_get_result sip_get_vrtp_peer ( struct ast_channel chan,
struct ast_rtp **  rtp 
) [static]

Returns null if we can't reinvite video (part of RTP interface).

Definition at line 17430 of file chan_sip.c.

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

17431 {
17432    struct sip_pvt *p = NULL;
17433    enum ast_rtp_get_result res = AST_RTP_TRY_PARTIAL;
17434    
17435    if (!(p = chan->tech_pvt))
17436       return AST_RTP_GET_FAILED;
17437 
17438    ast_mutex_lock(&p->lock);
17439    if (!(p->vrtp)) {
17440       ast_mutex_unlock(&p->lock);
17441       return AST_RTP_GET_FAILED;
17442    }
17443 
17444    *rtp = p->vrtp;
17445 
17446    if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE))
17447       res = AST_RTP_TRY_NATIVE;
17448 
17449    ast_mutex_unlock(&p->lock);
17450 
17451    return res;
17452 }

static int sip_handle_t38_reinvite ( struct ast_channel chan,
struct sip_pvt pvt,
int  reinvite 
) [static]

Handle T38 reinvite.

T38 negotiation helper function

Todo:
Make sure we don't destroy the call if we can't handle the re-invite. Nothing should be changed until we have processed the SDP and know that we can handle it.

Todo:
check if this is not set earlier when setting up the PVT. If not maybe it should move there.

Note:
The SIP_CAN_REINVITE flag is for RTP media redirects, not really T38 re-invites which are different. In this case it's used properly, to see if we can reinvite over NAT

Definition at line 17318 of file chan_sip.c.

References ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_test_flag, ast_udptl_get_error_correction_scheme(), ast_udptl_get_local_max_datagram(), ast_udptl_get_peer(), ast_udptl_set_error_correction_scheme(), ast_udptl_set_far_max_datagram(), ast_udptl_set_local_max_datagram(), sip_pvt::flags, sip_pvt::initreq, t38properties::jointcapability, sip_pvt::lastrtprx, sip_pvt::lastrtptx, sip_pvt::lock, LOG_DEBUG, option_debug, sip_pvt::ourip, sip_pvt::owner, t38properties::peercapability, sip_pvt::pendinginvite, SIP_CAN_REINVITE, SIP_GOTREFER, SIP_NEEDREINVITE, SIP_PENDINGBYE, t38properties::state, sip_pvt::t38, T38_ENABLED, ast_channel::tech_pvt, transmit_reinvite_with_t38_sdp(), transmit_response_with_t38_sdp(), sip_pvt::udptl, sip_pvt::udptlredirip, and XMIT_CRITICAL.

Referenced by handle_request_invite(), and handle_response_invite().

17319 {
17320    struct sip_pvt *p;
17321    int flag = 0;
17322    
17323    p = chan->tech_pvt;
17324    if (!p || !pvt->udptl)
17325       return -1;
17326    
17327    /* Setup everything on the other side like offered/responded from first side */
17328    ast_mutex_lock(&p->lock);
17329 
17330    /*! \todo check if this is not set earlier when setting up the PVT. If not
17331       maybe it should move there. */
17332    p->t38.jointcapability = p->t38.peercapability = pvt->t38.jointcapability;
17333 
17334    ast_udptl_set_far_max_datagram(p->udptl, ast_udptl_get_local_max_datagram(pvt->udptl));
17335    ast_udptl_set_local_max_datagram(p->udptl, ast_udptl_get_local_max_datagram(pvt->udptl));
17336    ast_udptl_set_error_correction_scheme(p->udptl, ast_udptl_get_error_correction_scheme(pvt->udptl));
17337    
17338    if (reinvite) {      /* If we are handling sending re-invite to the other side of the bridge */
17339       /*! \note The SIP_CAN_REINVITE flag is for RTP media redirects,
17340          not really T38 re-invites which are different. In this
17341          case it's used properly, to see if we can reinvite over
17342          NAT 
17343       */
17344       if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE) && ast_test_flag(&pvt->flags[0], SIP_CAN_REINVITE)) {
17345          ast_udptl_get_peer(pvt->udptl, &p->udptlredirip);
17346          flag =1;
17347       } else {
17348          memset(&p->udptlredirip, 0, sizeof(p->udptlredirip));
17349       }
17350       if (!ast_test_flag(&p->flags[0], SIP_GOTREFER)) {
17351          if (!p->pendinginvite) {
17352             if (option_debug > 2) {
17353                if (flag)
17354                   ast_log(LOG_DEBUG, "Sending reinvite on SIP '%s' - It's UDPTL soon redirected to IP %s:%d\n", p->callid, ast_inet_ntoa(p->udptlredirip.sin_addr), ntohs(p->udptlredirip.sin_port));
17355                else
17356                   ast_log(LOG_DEBUG, "Sending reinvite on SIP '%s' - It's UDPTL soon redirected to us (IP %s)\n", p->callid, ast_inet_ntoa(p->ourip));
17357             }
17358             transmit_reinvite_with_t38_sdp(p);
17359          } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) {
17360             if (option_debug > 2) {
17361                if (flag)
17362                   ast_log(LOG_DEBUG, "Deferring reinvite on SIP '%s' - It's UDPTL will be redirected to IP %s:%d\n", p->callid, ast_inet_ntoa(p->udptlredirip.sin_addr), ntohs(p->udptlredirip.sin_port));
17363                else
17364                   ast_log(LOG_DEBUG, "Deferring reinvite on SIP '%s' - It's UDPTL will be redirected to us (IP %s)\n", p->callid, ast_inet_ntoa(p->ourip));
17365             }
17366             ast_set_flag(&p->flags[0], SIP_NEEDREINVITE);
17367          }
17368       }
17369       /* Reset lastrtprx timer */
17370       p->lastrtprx = p->lastrtptx = time(NULL);
17371       ast_mutex_unlock(&p->lock);
17372       return 0;
17373    } else { /* If we are handling sending 200 OK to the other side of the bridge */
17374       if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE) && ast_test_flag(&pvt->flags[0], SIP_CAN_REINVITE)) {
17375          ast_udptl_get_peer(pvt->udptl, &p->udptlredirip);
17376          flag = 1;
17377       } else {
17378          memset(&p->udptlredirip, 0, sizeof(p->udptlredirip));
17379       }
17380       if (option_debug > 2) {
17381          if (flag)
17382             ast_log(LOG_DEBUG, "Responding 200 OK on SIP '%s' - It's UDPTL soon redirected to IP %s:%d\n", p->callid, ast_inet_ntoa(p->udptlredirip.sin_addr), ntohs(p->udptlredirip.sin_port));
17383          else
17384             ast_log(LOG_DEBUG, "Responding 200 OK on SIP '%s' - It's UDPTL soon redirected to us (IP %s)\n", p->callid, ast_inet_ntoa(p->ourip));
17385       }
17386       pvt->t38.state = T38_ENABLED;
17387       p->t38.state = T38_ENABLED;
17388       if (option_debug > 1) {
17389          ast_log(LOG_DEBUG, "T38 changed state to %d on channel %s\n", pvt->t38.state, pvt->owner ? pvt->owner->name : "<none>");
17390          ast_log(LOG_DEBUG, "T38 changed state to %d on channel %s\n", p->t38.state, chan ? chan->name : "<none>");
17391       }
17392       transmit_response_with_t38_sdp(p, "200 OK", &p->initreq, XMIT_CRITICAL);
17393       p->lastrtprx = p->lastrtptx = time(NULL);
17394       ast_mutex_unlock(&p->lock);
17395       return 0;
17396    }
17397 }

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

References __sip_pretend_ack(), ast_channel::_state, append_history, ast_cause2str(), ast_clear_flag, ast_dsp_free(), AST_FLAG_ZOMBIE, ast_log(), ast_module_unref(), ast_mutex_lock(), ast_mutex_unlock(), ast_rtp_get_quality(), ast_sched_del(), ast_set_flag, ast_state2str(), AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, ast_strlen_zero(), ast_test_flag, sip_pvt::autokillid, sip_request::data, DEC_CALL_LIMIT, DEFAULT_TRANS_TIMEOUT, FALSE, sip_pvt::flags, hangup_cause2sip(), ast_channel::hangupcause, INC_CALL_LIMIT, sip_pvt::initid, sip_pvt::initreq, INV_CALLING, INV_CANCELLED, INV_COMPLETED, INV_TERMINATED, sip_pvt::invitestate, sip_pvt::lock, LOG_DEBUG, LOG_WARNING, sip_pvt::ocseq, option_debug, sip_pvt::owner, pbx_builtin_setvar_helper(), sip_pvt::pendinginvite, sip_pvt::refer, sip_pvt::rtp, SIP_ALREADYGONE, SIP_BYE, SIP_CANCEL, sip_cancel_destroy(), SIP_DEFER_BYE_ON_TRANSFER, SIP_INC_COUNT, SIP_NEEDDESTROY, SIP_NEEDREINVITE, SIP_NO_HISTORY, SIP_OUTGOING, SIP_PAGE2_CALL_ONHOLD, SIP_PENDINGBYE, sip_scheddestroy(), sipdebug, stop_media_flows(), ast_channel::tech_pvt, transmit_request(), transmit_request_with_auth(), transmit_response_reliable(), TRUE, update_call_counter(), sip_pvt::vad, sip_pvt::vrtp, sip_pvt::waitid, and XMIT_RELIABLE.

03453 {
03454    struct sip_pvt *p = ast->tech_pvt;
03455    int needcancel = FALSE;
03456    int needdestroy = 0;
03457    struct ast_channel *oldowner = ast;
03458 
03459    if (!p) {
03460       if (option_debug)
03461          ast_log(LOG_DEBUG, "Asked to hangup channel that was not connected\n");
03462       return 0;
03463    }
03464 
03465    if (ast_test_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER)) {
03466       if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) {
03467          if (option_debug && sipdebug)
03468             ast_log(LOG_DEBUG, "update_call_counter(%s) - decrement call limit counter on hangup\n", p->username);
03469          update_call_counter(p, DEC_CALL_LIMIT);
03470       }
03471       if (option_debug >3)
03472          ast_log(LOG_DEBUG, "SIP Transfer: Not hanging up right now... Rescheduling hangup for %s.\n", p->callid);
03473       if (p->autokillid > -1)
03474          sip_cancel_destroy(p);
03475       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
03476       ast_clear_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Really hang up next time */
03477       ast_clear_flag(&p->flags[0], SIP_NEEDDESTROY);
03478       p->owner->tech_pvt = NULL;
03479       p->owner = NULL;  /* Owner will be gone after we return, so take it away */
03480       return 0;
03481    }
03482    if (option_debug) {
03483       if (ast_test_flag(ast, AST_FLAG_ZOMBIE) && p->refer && option_debug)
03484                ast_log(LOG_DEBUG, "SIP Transfer: Hanging up Zombie channel %s after transfer ... Call-ID: %s\n", ast->name, p->callid);
03485       else  {
03486          if (option_debug)
03487             ast_log(LOG_DEBUG, "Hangup call %s, SIP callid %s)\n", ast->name, p->callid);
03488       }
03489    }
03490    if (option_debug && ast_test_flag(ast, AST_FLAG_ZOMBIE)) 
03491       ast_log(LOG_DEBUG, "Hanging up zombie call. Be scared.\n");
03492 
03493    ast_mutex_lock(&p->lock);
03494    if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) {
03495       if (option_debug && sipdebug)
03496          ast_log(LOG_DEBUG, "update_call_counter(%s) - decrement call limit counter on hangup\n", p->username);
03497       update_call_counter(p, DEC_CALL_LIMIT);
03498    }
03499 
03500    /* Determine how to disconnect */
03501    if (p->owner != ast) {
03502       ast_log(LOG_WARNING, "Huh?  We aren't the owner? Can't hangup call.\n");
03503       ast_mutex_unlock(&p->lock);
03504       return 0;
03505    }
03506    /* If the call is not UP, we need to send CANCEL instead of BYE */
03507    if (ast->_state == AST_STATE_RING || ast->_state == AST_STATE_RINGING || (p->invitestate < INV_COMPLETED && ast->_state != AST_STATE_UP)) {
03508       needcancel = TRUE;
03509       if (option_debug > 3)
03510          ast_log(LOG_DEBUG, "Hanging up channel in state %s (not UP)\n", ast_state2str(ast->_state));
03511    }
03512 
03513    stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */
03514 
03515    append_history(p, needcancel ? "Cancel" : "Hangup", "Cause %s", p->owner ? ast_cause2str(p->owner->hangupcause) : "Unknown");
03516 
03517    /* Disconnect */
03518    if (p->vad)
03519       ast_dsp_free(p->vad);
03520 
03521    p->owner = NULL;
03522    ast->tech_pvt = NULL;
03523 
03524    ast_module_unref(ast_module_info->self);
03525 
03526    /* Do not destroy this pvt until we have timeout or
03527       get an answer to the BYE or INVITE/CANCEL 
03528       If we get no answer during retransmit period, drop the call anyway.
03529       (Sorry, mother-in-law, you can't deny a hangup by sending
03530       603 declined to BYE...)
03531    */
03532    if (ast_test_flag(&p->flags[0], SIP_ALREADYGONE))
03533       needdestroy = 1;  /* Set destroy flag at end of this function */
03534    else if (p->invitestate != INV_CALLING)
03535       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
03536 
03537    /* Start the process if it's not already started */
03538    if (!ast_test_flag(&p->flags[0], SIP_ALREADYGONE) && !ast_strlen_zero(p->initreq.data)) {
03539       if (needcancel) { /* Outgoing call, not up */
03540          if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
03541             /* stop retransmitting an INVITE that has not received a response */
03542             __sip_pretend_ack(p);
03543 
03544             /* if we can't send right now, mark it pending */
03545             if (p->invitestate == INV_CALLING) {
03546                /* We can't send anything in CALLING state */
03547                ast_set_flag(&p->flags[0], SIP_PENDINGBYE);
03548                /* Do we need a timer here if we don't hear from them at all? Yes we do or else we will get hung dialogs and those are no fun. */
03549                sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
03550                append_history(p, "DELAY", "Not sending cancel, waiting for timeout");
03551             } else {
03552                /* Send a new request: CANCEL */
03553                transmit_request(p, SIP_CANCEL, p->ocseq, XMIT_RELIABLE, FALSE);
03554                /* Actually don't destroy us yet, wait for the 487 on our original 
03555                   INVITE, but do set an autodestruct just in case we never get it. */
03556                needdestroy = 0;
03557                sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
03558                p->invitestate = INV_CANCELLED;
03559             }
03560             if ( p->initid != -1 ) {
03561                /* channel still up - reverse dec of inUse counter
03562                   only if the channel is not auto-congested */
03563                update_call_counter(p, INC_CALL_LIMIT);
03564             }
03565          } else { /* Incoming call, not up */
03566             const char *res;
03567             if (ast->hangupcause && (res = hangup_cause2sip(ast->hangupcause)))
03568                transmit_response_reliable(p, res, &p->initreq);
03569             else 
03570                transmit_response_reliable(p, "603 Declined", &p->initreq);
03571             p->invitestate = INV_TERMINATED;
03572          }
03573       } else { /* Call is in UP state, send BYE */
03574          if (!p->pendinginvite) {
03575             char *audioqos = "";
03576             char *videoqos = "";
03577             if (p->rtp)
03578                audioqos = ast_rtp_get_quality(p->rtp, NULL);
03579             if (p->vrtp)
03580                videoqos = ast_rtp_get_quality(p->vrtp, NULL);
03581             /* Send a hangup */
03582             transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, 1);
03583 
03584             /* Get RTCP quality before end of call */
03585             if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) {
03586                if (p->rtp)
03587                   append_history(p, "RTCPaudio", "Quality:%s", audioqos);
03588                if (p->vrtp)
03589                   append_history(p, "RTCPvideo", "Quality:%s", videoqos);
03590             }
03591             if (p->rtp && oldowner)
03592                pbx_builtin_setvar_helper(oldowner, "RTPAUDIOQOS", audioqos);
03593             if (p->vrtp && oldowner)
03594                pbx_builtin_setvar_helper(oldowner, "RTPVIDEOQOS", videoqos);
03595          } else {
03596             /* Note we will need a BYE when this all settles out
03597                but we can't send one while we have "INVITE" outstanding. */
03598             ast_set_flag(&p->flags[0], SIP_PENDINGBYE);  
03599             ast_clear_flag(&p->flags[0], SIP_NEEDREINVITE); 
03600             if (p->waitid)
03601                ast_sched_del(sched, p->waitid);
03602             p->waitid = -1;
03603             sip_cancel_destroy(p);
03604          }
03605       }
03606    }
03607    if (needdestroy)
03608       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
03609    ast_mutex_unlock(&p->lock);
03610    return 0;
03611 }

static int sip_indicate ( struct ast_channel ast,
int  condition,
const void *  data,
size_t  datalen 
) [static]

Play indication to user With SIP a lot of indications is sent as messages, letting the device play the indication - busy signal, congestion etc.

Returns:
-1 to force ast_indicate to send indication in audio, 0 if SIP can handle the indication by sending a message

Definition at line 3849 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_moh_start(), ast_moh_stop(), 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::flags, sip_pvt::initreq, INV_COMPLETED, INV_EARLY_MEDIA, INV_PROCEEDING, sip_pvt::invitestate, sip_pvt::lock, 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(), sip_pvt::vrtp, and XMIT_UNRELIABLE.

03850 {
03851    struct sip_pvt *p = ast->tech_pvt;
03852    int res = 0;
03853 
03854    ast_mutex_lock(&p->lock);
03855    switch(condition) {
03856    case AST_CONTROL_RINGING:
03857       if (ast->_state == AST_STATE_RING) {
03858          p->invitestate = INV_EARLY_MEDIA;
03859          if (!ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) ||
03860              (ast_test_flag(&p->flags[0], SIP_PROG_INBAND) == SIP_PROG_INBAND_NEVER)) {            
03861             /* Send 180 ringing if out-of-band seems reasonable */
03862             transmit_response(p, "180 Ringing", &p->initreq);
03863             ast_set_flag(&p->flags[0], SIP_RINGING);
03864             if (ast_test_flag(&p->flags[0], SIP_PROG_INBAND) != SIP_PROG_INBAND_YES)
03865                break;
03866          } else {
03867             /* Well, if it's not reasonable, just send in-band */
03868          }
03869       }
03870       res = -1;
03871       break;
03872    case AST_CONTROL_BUSY:
03873       if (ast->_state != AST_STATE_UP) {
03874          transmit_response(p, "486 Busy Here", &p->initreq);
03875          p->invitestate = INV_COMPLETED;
03876          sip_alreadygone(p);
03877          ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV);
03878          break;
03879       }
03880       res = -1;
03881       break;
03882    case AST_CONTROL_CONGESTION:
03883       if (ast->_state != AST_STATE_UP) {
03884          transmit_response(p, "503 Service Unavailable", &p->initreq);
03885          p->invitestate = INV_COMPLETED;
03886          sip_alreadygone(p);
03887          ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV);
03888          break;
03889       }
03890       res = -1;
03891       break;
03892    case AST_CONTROL_PROCEEDING:
03893       if ((ast->_state != AST_STATE_UP) &&
03894           !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) &&
03895           !ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
03896          transmit_response(p, "100 Trying", &p->initreq);
03897          p->invitestate = INV_PROCEEDING;  
03898          break;
03899       }
03900       res = -1;
03901       break;
03902    case AST_CONTROL_PROGRESS:
03903       if ((ast->_state != AST_STATE_UP) &&
03904           !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) &&
03905           !ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
03906          p->invitestate = INV_EARLY_MEDIA;
03907          transmit_response_with_sdp(p, "183 Session Progress", &p->initreq, XMIT_UNRELIABLE);
03908          ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT);  
03909          break;
03910       }
03911       res = -1;
03912       break;
03913    case AST_CONTROL_HOLD:
03914       ast_moh_start(ast, data, p->mohinterpret);
03915       break;
03916    case AST_CONTROL_UNHOLD:
03917       ast_moh_stop(ast);
03918       break;
03919    case AST_CONTROL_VIDUPDATE:   /* Request a video frame update */
03920       if (p->vrtp && !ast_test_flag(&p->flags[0], SIP_NOVIDEO)) {
03921          transmit_info_with_vidupdate(p);
03922          /* ast_rtcp_send_h261fur(p->vrtp); */
03923       } else
03924          res = -1;
03925       break;
03926    case -1:
03927       res = -1;
03928       break;
03929    default:
03930       ast_log(LOG_WARNING, "Don't know how to indicate condition %d\n", condition);
03931       res = -1;
03932       break;
03933    }
03934    ast_mutex_unlock(&p->lock);
03935    return res;
03936 }

static const char * sip_nat_mode ( const struct sip_pvt p  )  [static]

Display SIP nat mode.

Definition at line 1753 of file chan_sip.c.

References ast_test_flag, sip_pvt::flags, SIP_NAT, and SIP_NAT_ROUTE.

Referenced by check_via(), retrans_pkt(), and send_response().

01754 {
01755    return ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE ? "NAT" : "no NAT";
01756 }

static struct ast_channel* sip_new ( struct sip_pvt i,
int  state,
const char *  title 
) [static, read]

Initiate a call in the SIP channel called from sip_request_call (calls from the pbx ) for outbound channels and from handle_request_invite for inbound channels.

Definition at line 3944 of file chan_sip.c.

References accountcode, ast_channel::adsicpe, ast_channel::amaflags, sip_pvt::amaflags, append_history, AST_ADSI_UNAVAILABLE, ast_best_codec(), AST_CAUSE_SWITCH_CONGESTION, ast_channel_alloc(), ast_codec_choose(), ast_dsp_digitmode(), ast_dsp_new(), ast_dsp_set_features(), AST_FORMAT_VIDEO_MASK, ast_getformatname_multiple(), ast_hangup(), ast_jb_configure(), ast_log(), ast_module_ref(), ast_mutex_lock(), ast_mutex_unlock(), ast_pbx_start(), ast_rtcp_fd(), ast_rtp_fd(), AST_STATE_DOWN, AST_STATE_RING, ast_strdup, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_udptl_fd(), ast_uri_decode(), sip_pvt::callgroup, ast_channel::callgroup, sip_pvt::callingpres, sip_pvt::capability, sip_pvt::chanvars, ast_channel::cid, ast_callerid::cid_ani, ast_callerid::cid_dnid, 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, sip_pvt::flags, fmt, global_jbconf, ast_channel::hangupcause, sip_pvt::jointcapability, language, sip_pvt::lock, LOG_DEBUG, LOG_WARNING, ast_variable::name, ast_channel::nativeformats, ast_variable::next, option_debug, sip_pvt::owner, pbx_builtin_setvar_helper(), sip_pvt::pickupgroup, ast_channel::pickupgroup, sip_pvt::prefcodec, sip_pvt::prefs, ast_channel::priority, ast_channel::rawreadformat, ast_channel::rawwriteformat, ast_channel::readformat, ast_channel::rings, sip_pvt::rtp, SIP_DTMF, SIP_DTMF_INBAND, SIP_DTMF_INFO, SIP_NO_HISTORY, sip_tech, sip_tech_info, t38properties::state, sip_pvt::t38, T38_PEER_DIRECT, ast_channel::tech, ast_channel::tech_pvt, sip_pvt::udptl, sip_pvt::vad, ast_variable::value, sip_pvt::vrtp, and ast_channel::writeformat.

Referenced by handle_request_invite(), and sip_request_call().

03945 {
03946    struct ast_channel *tmp;
03947    struct ast_variable *v = NULL;
03948    int fmt;
03949    int what;
03950    int needvideo = 0, video = 0;
03951    char *decoded_exten;
03952    {
03953       const char *my_name;    /* pick a good name */
03954 
03955       if (title)
03956          my_name = title;
03957       else if ( (my_name = strchr(i->fromdomain,':')) )
03958          my_name++;      /* skip ':' */
03959       else
03960          my_name = i->fromdomain;
03961 
03962       ast_mutex_unlock(&i->lock);
03963       /* Don't hold a sip pvt lock while we allocate a channel */
03964       tmp = ast_channel_alloc(1, state, i->cid_num, i->cid_name, i->accountcode, i->exten, i->context, i->amaflags, "SIP/%s-%08x", my_name, (int)(long) i);
03965 
03966    }
03967    if (!tmp) {
03968       ast_log(LOG_WARNING, "Unable to allocate AST channel structure for SIP channel\n");
03969       return NULL;
03970    }
03971    ast_mutex_lock(&i->lock);
03972 
03973    if (ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_INFO)
03974       tmp->tech = &sip_tech_info;
03975    else
03976       tmp->tech = &sip_tech;
03977 
03978    /* Select our native format based on codec preference until we receive
03979       something from another device to the contrary. */
03980    if (i->jointcapability) {     /* The joint capabilities of us and peer */
03981       what = i->jointcapability;
03982       video = i->jointcapability & AST_FORMAT_VIDEO_MASK;
03983    } else if (i->capability)  {  /* Our configured capability for this peer */
03984       what = i->capability;
03985       video = i->capability & AST_FORMAT_VIDEO_MASK;
03986    } else {
03987       what = global_capability;  /* Global codec support */
03988       video = global_capability & AST_FORMAT_VIDEO_MASK;
03989    }
03990 
03991    /* Set the native formats for audio  and merge in video */
03992    tmp->nativeformats = ast_codec_choose(&i->prefs, what, 1) | video;
03993    if (option_debug > 2) {
03994       char buf[BUFSIZ];
03995       ast_log(LOG_DEBUG, "*** Our native formats are %s \n", ast_getformatname_multiple(buf, BUFSIZ, tmp->nativeformats));
03996       ast_log(LOG_DEBUG, "*** Joint capabilities are %s \n", ast_getformatname_multiple(buf, BUFSIZ, i->jointcapability));
03997       ast_log(LOG_DEBUG, "*** Our capabilities are %s \n", ast_getformatname_multiple(buf, BUFSIZ, i->capability));
03998       ast_log(LOG_DEBUG, "*** AST_CODEC_CHOOSE formats are %s \n", ast_getformatname_multiple(buf, BUFSIZ, ast_codec_choose(&i->prefs, what, 1)));
03999       if (i->prefcodec)
04000          ast_log(LOG_DEBUG, "*** Our preferred formats from the incoming channel are %s \n", ast_getformatname_multiple(buf, BUFSIZ, i->prefcodec));
04001    }
04002 
04003    /* XXX Why are we choosing a codec from the native formats?? */
04004    fmt = ast_best_codec(tmp->nativeformats);
04005 
04006    /* If we have a prefcodec setting, we have an inbound channel that set a 
04007       preferred format for this call. Otherwise, we check the jointcapability
04008       We also check for vrtp. If it's not there, we are not allowed do any video anyway.
04009     */
04010    if (i->vrtp) {
04011       if (i->prefcodec)
04012          needvideo = i->prefcodec & AST_FORMAT_VIDEO_MASK;  /* Outbound call */
04013       else
04014          needvideo = i->jointcapability & AST_FORMAT_VIDEO_MASK;  /* Inbound call */
04015    }
04016 
04017    if (option_debug > 2) {
04018       if (needvideo) 
04019          ast_log(LOG_DEBUG, "This channel can handle video! HOLLYWOOD next!\n");
04020       else
04021          ast_log(LOG_DEBUG, "This channel will not be able to handle video.\n");
04022    }
04023 
04024 
04025 
04026    if (ast_test_flag(&i->flags[0], SIP_DTMF) ==  SIP_DTMF_INBAND) {
04027       i->vad = ast_dsp_new();
04028       ast_dsp_set_features(i->vad, DSP_FEATURE_DTMF_DETECT);
04029       if (global_relaxdtmf)
04030          ast_dsp_digitmode(i->vad, DSP_DIGITMODE_DTMF | DSP_DIGITMODE_RELAXDTMF);
04031    }
04032    if (i->rtp) {
04033       tmp->fds[0] = ast_rtp_fd(i->rtp);
04034       tmp->fds[1] = ast_rtcp_fd(i->rtp);
04035    }
04036    if (needvideo && i->vrtp) {
04037       tmp->fds[2] = ast_rtp_fd(i->vrtp);
04038       tmp->fds[3] = ast_rtcp_fd(i->vrtp);
04039    }
04040    if (i->udptl) {
04041       tmp->fds[5] = ast_udptl_fd(i->udptl);
04042    }
04043    if (state == AST_STATE_RING)
04044       tmp->rings = 1;
04045    tmp->adsicpe = AST_ADSI_UNAVAILABLE;
04046    tmp->writeformat = fmt;
04047    tmp->rawwriteformat = fmt;
04048    tmp->readformat = fmt;
04049    tmp->rawreadformat = fmt;
04050    tmp->tech_pvt = i;
04051 
04052    tmp->callgroup = i->callgroup;
04053    tmp->pickupgroup = i->pickupgroup;
04054    tmp->cid.cid_pres = i->callingpres;
04055    if (!ast_strlen_zero(i->accountcode))
04056       ast_string_field_set(tmp, accountcode, i->accountcode);
04057    if (i->amaflags)
04058       tmp->amaflags = i->amaflags;
04059    if (!ast_strlen_zero(i->language))
04060       ast_string_field_set(tmp, language, i->language);
04061    i->owner = tmp;
04062    ast_module_ref(ast_module_info->self);
04063    ast_copy_string(tmp->context, i->context, sizeof(tmp->context));
04064    /*Since it is valid to have extensions in the dialplan that have unescaped characters in them
04065     * we should decode the uri before storing it in the channel, but leave it encoded in the sip_pvt
04066     * structure so that there aren't issues when forming URI's
04067     */
04068    decoded_exten = ast_strdupa(i->exten);
04069    ast_uri_decode(decoded_exten);
04070    ast_copy_string(tmp->exten, decoded_exten, sizeof(tmp->exten));
04071 
04072    /* Don't use ast_set_callerid() here because it will
04073     * generate an unnecessary NewCallerID event  */
04074    tmp->cid.cid_ani = ast_strdup(i->cid_num);
04075    if (!ast_strlen_zero(i->rdnis))
04076       tmp->cid.cid_rdnis = ast_strdup(i->rdnis);
04077    
04078    if (!ast_strlen_zero(i->exten) && strcmp(i->exten, "s"))
04079       tmp->cid.cid_dnid = ast_strdup(i->exten);
04080 
04081    tmp->priority = 1;
04082    if (!ast_strlen_zero(i->uri))
04083       pbx_builtin_setvar_helper(tmp, "SIPURI", i->uri);
04084    if (!ast_strlen_zero(i->domain))
04085       pbx_builtin_setvar_helper(tmp, "SIPDOMAIN", i->domain);
04086    if (!ast_strlen_zero(i->useragent))
04087       pbx_builtin_setvar_helper(tmp, "SIPUSERAGENT", i->useragent);
04088    if (!ast_strlen_zero(i->callid))
04089       pbx_builtin_setvar_helper(tmp, "SIPCALLID", i->callid);
04090    if (i->rtp)
04091       ast_jb_configure(tmp, &global_jbconf);
04092 
04093    /* If the INVITE contains T.38 SDP information set the proper channel variable so a created outgoing call will also have T.38 */
04094    if (i->udptl && i->t38.state == T38_PEER_DIRECT)
04095       pbx_builtin_setvar_helper(tmp, "_T38CALL", "1");
04096 
04097    /* Set channel variables for this call from configuration */
04098    for (v = i->chanvars ; v ; v = v->next)
04099       pbx_builtin_setvar_helper(tmp, v->name, v->value);
04100 
04101    if (state != AST_STATE_DOWN && ast_pbx_start(tmp)) {
04102       ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
04103       tmp->hangupcause = AST_CAUSE_SWITCH_CONGESTION;
04104       ast_hangup(tmp);
04105       tmp = NULL;
04106    }
04107 
04108    if (!ast_test_flag(&i->flags[0], SIP_NO_HISTORY))
04109       append_history(i, "NewChan", "Channel %s - from %s", tmp->name, i->callid);
04110 
04111    return tmp;
04112 }

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

Disable SIP Debugging in CLI.

Definition at line 11297 of file chan_sip.c.

References ast_clear_flag, ast_cli(), RESULT_SHOWUSAGE, RESULT_SUCCESS, and SIP_PAGE2_DEBUG_CONSOLE.

11298 {
11299    if (argc != 4)
11300       return RESULT_SHOWUSAGE;
11301    ast_clear_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE);
11302    ast_cli(fd, "SIP Debugging Disabled\n");
11303    return RESULT_SUCCESS;
11304 }

static int sip_no_debug_deprecated ( int  fd,
int  argc,
char *  argv[] 
) [static]

Definition at line 11306 of file chan_sip.c.

References ast_clear_flag, ast_cli(), RESULT_SHOWUSAGE, RESULT_SUCCESS, and SIP_PAGE2_DEBUG_CONSOLE.

11307 {
11308    if (argc != 3)
11309       return RESULT_SHOWUSAGE;
11310    ast_clear_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE);
11311    ast_cli(fd, "SIP Debugging Disabled\n");
11312    return RESULT_SUCCESS;
11313 }

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

Disable SIP History logging (CLI).

Definition at line 11327 of file chan_sip.c.

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

11328 {
11329    if (argc != 3) {
11330       return RESULT_SHOWUSAGE;
11331    }
11332    recordhistory = FALSE;
11333    ast_cli(fd, "SIP History Recording Disabled\n");
11334    return RESULT_SUCCESS;
11335 }

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

Cli command to send SIP notify to peer.

Definition at line 11241 of file chan_sip.c.

References __ourip, add_header(), ast_cli(), ast_log(), ast_sip_ouraddrfor(), ast_unescape_semicolon(), ast_variable_browse(), build_callid_pvt(), build_via(), create_addr(), DEFAULT_TRANS_TIMEOUT, initreqprep(), LOG_WARNING, ast_variable::name, ast_variable::next, notify_types, sip_pvt::ourip, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, sip_pvt::sa, sip_alloc(), sip_destroy(), SIP_NOTIFY, sip_scheddestroy(), transmit_sip_request(), ast_variable::value, and var.

11242 {
11243    struct ast_variable *varlist;
11244    int i;
11245 
11246    if (argc < 4)
11247       return RESULT_SHOWUSAGE;
11248 
11249    if (!notify_types) {
11250       ast_cli(fd, "No %s file found, or no types listed there\n", notify_config);
11251       return RESULT_FAILURE;
11252    }
11253 
11254    varlist = ast_variable_browse(notify_types, argv[2]);
11255 
11256    if (!varlist) {
11257       ast_cli(fd, "Unable to find notify type '%s'\n", argv[2]);
11258       return RESULT_FAILURE;
11259    }
11260 
11261    for (i = 3; i < argc; i++) {
11262       struct sip_pvt *p;
11263       struct sip_request req;
11264       struct ast_variable *var;
11265 
11266       if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY))) {
11267          ast_log(LOG_WARNING, "Unable to build sip pvt data for notify (memory/socket error)\n");
11268          return RESULT_FAILURE;
11269       }
11270 
11271       if (create_addr(p, argv[i])) {
11272          /* Maybe they're not registered, etc. */
11273          sip_destroy(p);
11274          ast_cli(fd, "Could not create address for '%s'\n", argv[i]);
11275          continue;
11276       }
11277 
11278       initreqprep(&req, p, SIP_NOTIFY);
11279 
11280       for (var = varlist; var; var = var->next)
11281          add_header(&req, var->name, ast_unescape_semicolon(var->value));
11282 
11283       /* Recalculate our side, and recalculate Call ID */
11284       if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
11285          p->ourip = __ourip;
11286       build_via(p);
11287       build_callid_pvt(p);
11288       ast_cli(fd, "Sending NOTIFY of type '%s' to '%s'\n", argv[2], argv[i]);
11289       transmit_sip_request(p, &req);
11290       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
11291    }
11292 
11293    return RESULT_SUCCESS;
11294 }

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

Park a call using the subsystem in res_features.c This is executed in a separate thread.

Definition at line 13032 of file chan_sip.c.

References ast_channel::amaflags, ast_calloc, AST_CAUSE_SWITCH_CONGESTION, ast_channel_alloc(), ast_channel_lock, ast_channel_masquerade(), ast_channel_trylock, ast_channel_unlock, ast_do_masquerade(), ast_hangup(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_pthread_create_background, AST_STATE_DOWN, sip_dual::chan1, sip_dual::chan2, ast_channel::context, copy_request(), ast_channel::exten, free, ast_channel::hangupcause, sip_pvt::lock, LOG_DEBUG, LOG_WARNING, option_debug, ast_channel::priority, ast_channel::readformat, sip_dual::req, sip_dual::seqno, sip_park_thread(), ast_channel::tech_pvt, and ast_channel::writeformat.

Referenced by handle_request_refer().

13033 {
13034    struct sip_dual *d;
13035    struct ast_channel *transferee, *transferer;
13036       /* Chan2m: The transferer, chan1m: The transferee */
13037    pthread_t th;
13038 
13039    transferee = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan1->accountcode, chan1->exten, chan1->context, chan1->amaflags, "Parking/%s", chan1->name);
13040    transferer = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->amaflags, "SIPPeer/%s", chan2->name);
13041    if ((!transferer) || (!transferee)) {
13042       if (transferee) {
13043          transferee->hangupcause = AST_CAUSE_SWITCH_CONGESTION;
13044          ast_hangup(transferee);
13045       }
13046       if (transferer) {
13047          transferer->hangupcause = AST_CAUSE_SWITCH_CONGESTION;
13048          ast_hangup(transferer);
13049       }
13050       return -1;
13051    }
13052 
13053    /* Make formats okay */
13054    transferee->readformat = chan1->readformat;
13055    transferee->writeformat = chan1->writeformat;
13056 
13057    /* Prepare for taking over the channel */
13058    ast_channel_masquerade(transferee, chan1);
13059 
13060    /* Setup the extensions and such */
13061    ast_copy_string(transferee->context, chan1->context, sizeof(transferee->context));
13062    ast_copy_string(transferee->exten, chan1->exten, sizeof(transferee->exten));
13063    transferee->priority = chan1->priority;
13064       
13065    /* We make a clone of the peer channel too, so we can play
13066       back the announcement */
13067 
13068    /* Make formats okay */
13069    transferer->readformat = chan2->readformat;
13070    transferer->writeformat = chan2->writeformat;
13071 
13072    /* Prepare for taking over the channel.  Go ahead and grab this channel
13073     * lock here to avoid a deadlock with callbacks into the channel driver
13074     * that hold the channel lock and want the pvt lock.  */
13075    while (ast_channel_trylock(chan2)) {
13076       struct sip_pvt *pvt = chan2->tech_pvt;
13077       ast_mutex_unlock(&pvt->lock);
13078       usleep(1);
13079       ast_mutex_lock(&pvt->lock);
13080    }
13081    ast_channel_masquerade(transferer, chan2);
13082    ast_channel_unlock(chan2);
13083 
13084    /* Setup the extensions and such */
13085    ast_copy_string(transferer->context, chan2->context, sizeof(transferer->context));
13086    ast_copy_string(transferer->exten, chan2->exten, sizeof(transferer->exten));
13087    transferer->priority = chan2->priority;
13088 
13089    ast_channel_lock(transferer);
13090    if (ast_do_masquerade(transferer)) {
13091       ast_log(LOG_WARNING, "Masquerade failed :(\n");
13092       ast_channel_unlock(transferer);
13093       transferer->hangupcause = AST_CAUSE_SWITCH_CONGESTION;
13094       ast_hangup(transferer);
13095       return -1;
13096    }
13097    ast_channel_unlock(transferer);
13098    if (!transferer || !transferee) {
13099       if (!transferer) { 
13100          if (option_debug)
13101             ast_log(LOG_DEBUG, "No transferer channel, giving up parking\n");
13102       }
13103       if (!transferee) {
13104          if (option_debug)
13105             ast_log(LOG_DEBUG, "No transferee channel, giving up parking\n");
13106       }
13107       return -1;
13108    }
13109    if ((d = ast_calloc(1, sizeof(*d)))) {
13110       pthread_attr_t attr;
13111 
13112       pthread_attr_init(&attr);
13113       pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);   
13114 
13115       /* Save original request for followup */
13116       copy_request(&d->req, req);
13117       d->chan1 = transferee;  /* Transferee */
13118       d->chan2 = transferer;  /* Transferer */
13119       d->seqno = seqno;
13120       if (ast_pthread_create_background(&th, &attr, sip_park_thread, d) < 0) {
13121          /* Could not start thread */
13122          free(d); /* We don't need it anymore. If thread is created, d will be free'd
13123                   by sip_park_thread() */
13124          pthread_attr_destroy(&attr);
13125          return 0;
13126       }
13127       pthread_attr_destroy(&attr);
13128    } 
13129    return -1;
13130 }

static void * sip_park_thread ( void *  stuff  )  [static]

Park SIP call support function Starts in a new thread, then parks the call XXX Should we add a wait period after streaming audio and before hangup?? Sometimes the audio can't be heard before hangup.

Definition at line 12965 of file chan_sip.c.

References append_history, AST_CAUSE_NORMAL_CLEARING, ast_channel_lock, ast_channel_unlock, ast_do_masquerade(), ast_hangup(), ast_log(), ast_park_call(), sip_dual::chan1, sip_dual::chan2, copy_request(), ext, free, ast_channel::hangupcause, LOG_DEBUG, LOG_ERROR, LOG_WARNING, option_debug, sip_dual::req, sip_dual::seqno, ast_channel::tech_pvt, transmit_message_with_text(), transmit_notify_with_sipfrag(), transmit_response(), and TRUE.

Referenced by sip_park().

12966 {
12967    struct ast_channel *transferee, *transferer; /* Chan1: The transferee, Chan2: The transferer */
12968    struct sip_dual *d;
12969    struct sip_request req;
12970    int ext;
12971    int res;
12972 
12973    d = stuff;
12974    transferee = d->chan1;
12975    transferer = d->chan2;
12976    copy_request(&req, &d->req);
12977    free(d);
12978 
12979    if (!transferee || !transferer) {
12980       ast_log(LOG_ERROR, "Missing channels for parking! Transferer %s Transferee %s\n", transferer ? "<available>" : "<missing>", transferee ? "<available>" : "<missing>" );
12981       return NULL;
12982    }
12983    if (option_debug > 3) 
12984       ast_log(LOG_DEBUG, "SIP Park: Transferer channel %s, Transferee %s\n", transferer->name, transferee->name);
12985 
12986    ast_channel_lock(transferee);
12987    if (ast_do_masquerade(transferee)) {
12988       ast_log(LOG_WARNING, "Masquerade failed.\n");
12989       transmit_response(transferer->tech_pvt, "503 Internal error", &req);
12990       ast_channel_unlock(transferee);
12991       return NULL;
12992    } 
12993    ast_channel_unlock(transferee);
12994 
12995    res = ast_park_call(transferee, transferer, 0, &ext);
12996    
12997 
12998 #ifdef WHEN_WE_KNOW_THAT_THE_CLIENT_SUPPORTS_MESSAGE
12999    if (!res) {
13000       transmit_message_with_text(transferer->tech_pvt, "Unable to park call.\n");
13001    } else {
13002       /* Then tell the transferer what happened */
13003       sprintf(buf, "Call parked on extension '%d'", ext);
13004       transmit_message_with_text(transferer->tech_pvt, buf);
13005    }
13006 #endif
13007 
13008    /* Any way back to the current call??? */
13009    /* Transmit response to the REFER request */
13010    transmit_response(transferer->tech_pvt, "202 Accepted", &req);
13011    if (!res)   {
13012       /* Transfer succeeded */
13013       append_history(transferer->tech_pvt, "SIPpark","Parked call on %d", ext);
13014       transmit_notify_with_sipfrag(transferer->tech_pvt, d->seqno, "200 OK", TRUE);
13015       transferer->hangupcause = AST_CAUSE_NORMAL_CLEARING;
13016       ast_hangup(transferer); /* This will cause a BYE */
13017       if (option_debug)
13018          ast_log(LOG_DEBUG, "SIP Call parked on extension '%d'\n", ext);
13019    } else {
13020       transmit_notify_with_sipfrag(transferer->tech_pvt, d->seqno, "503 Service Unavailable", TRUE);
13021       append_history(transferer->tech_pvt, "SIPpark","Parking failed\n");
13022       if (option_debug)
13023          ast_log(LOG_DEBUG, "SIP Call parked failed \n");
13024       /* Do not hangup call */
13025    }
13026    return NULL;
13027 }

static void sip_peer_hold ( struct sip_pvt p,
int  hold 
) [static]

Change onhold state of a peer using a pvt structure.

Definition at line 8448 of file chan_sip.c.

References ast_device_state_changed(), find_peer(), and sip_peer::onHold.

Referenced by change_hold_state(), and update_call_counter().

08449 {
08450    struct sip_peer *peer = find_peer(p->peername, NULL, 1);
08451 
08452    if (!peer)
08453       return;
08454 
08455    /* If they put someone on hold, increment the value... otherwise decrement it */
08456    if (hold)
08457       peer->onHold++;
08458    else
08459       peer->onHold--;
08460 
08461    /* Request device state update */
08462    ast_device_state_changed("SIP/%s", peer->name);
08463 
08464    return;
08465 }

static void sip_poke_all_peers ( void   )  [static]

Send a poke to all known peers Space them out 100 ms apart XXX We might have a cool algorithm for this or use random - any suggestions?

Definition at line 17703 of file chan_sip.c.

References ast_sched_add(), ast_sched_del(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_UNLOCK, ASTOBJ_WRLOCK, peerl, and sip_poke_peer_s().

Referenced by load_module(), and sip_do_reload().

17704 {
17705    int ms = 0;
17706    
17707    if (!speerobjs)   /* No peers, just give up */
17708       return;
17709 
17710    ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do {
17711       ASTOBJ_WRLOCK(iterator);
17712       if (iterator->pokeexpire > -1)
17713          ast_sched_del(sched, iterator->pokeexpire);
17714       ms += 100;
17715       iterator->pokeexpire = ast_sched_add(sched, ms, sip_poke_peer_s, iterator);
17716       ASTOBJ_UNLOCK(iterator);
17717    } while (0)
17718    );
17719 }

static int sip_poke_noanswer ( const void *  data  )  [static]

React to lack of answer to Qualify poke.

Definition at line 15655 of file chan_sip.c.

References ast_device_state_changed(), ast_log(), ast_sched_add(), ast_sched_del(), 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().

15656 {
15657    struct sip_peer *peer = (struct sip_peer *)data;
15658    
15659    peer->pokeexpire = -1;
15660    if (peer->lastms > -1) {
15661       ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE!  Last qualify: %d\n", peer->name, peer->lastms);
15662       manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, -1);
15663    }
15664    if (peer->call)
15665       sip_destroy(peer->call);
15666    peer->call = NULL;
15667    peer->lastms = -1;
15668    ast_device_state_changed("SIP/%s", peer->name);
15669    /* Try again quickly */
15670    if (peer->pokeexpire > -1)
15671       ast_sched_del(sched, peer->pokeexpire);
15672    peer->pokeexpire = ast_sched_add(sched, DEFAULT_FREQ_NOTOK, sip_poke_peer_s, peer);
15673    return 0;
15674 }

static int sip_poke_peer ( struct sip_peer peer  )  [static]

Check availability of peer, also keep NAT open.

Note:
This is done with the interval in qualify= configuration option Default is 2 seconds

Definition at line 15679 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_string_field_set, ast_strlen_zero(), build_callid_pvt(), build_via(), sip_peer::call, sip_peer::flags, sip_pvt::flags, sip_peer::fullcontact, sip_peer::lastms, LOG_NOTICE, sip_peer::maxms, sip_pvt::ourip, sip_peer::pokeexpire, sip_peer::ps, sip_pvt::recv, sip_pvt::relatedpeer, sip_pvt::sa, sip_alloc(), sip_destroy(), SIP_FLAGS_TO_COPY, SIP_INVITE, SIP_OPTIONS, SIP_OUTGOING, SIP_PAGE2_FLAGS_TO_COPY, sip_poke_noanswer(), sipdebug, sip_peer::tohost, transmit_invite(), and XMIT_ERROR.

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

15680 {
15681    struct sip_pvt *p;
15682    int xmitres = 0;
15683 
15684    if (!peer->maxms || !peer->addr.sin_addr.s_addr) {
15685       /* IF we have no IP, or this isn't to be monitored, return
15686         imeediately after clearing things out */
15687       if (peer->pokeexpire > -1)
15688          ast_sched_del(sched, peer->pokeexpire);
15689       peer->lastms = 0;
15690       peer->pokeexpire = -1;
15691       peer->call = NULL;
15692       return 0;
15693    }
15694    if (peer->call) {
15695       if (sipdebug)
15696          ast_log(LOG_NOTICE, "Still have a QUALIFY dialog active, deleting\n");
15697       sip_destroy(peer->call);
15698    }
15699    if (!(p = peer->call = sip_alloc(NULL, NULL, 0, SIP_OPTIONS)))
15700       return -1;
15701    
15702    p->sa = peer->addr;
15703    p->recv = peer->addr;
15704    ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY);
15705    ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY);
15706 
15707    /* Send OPTIONs to peer's fullcontact */
15708    if (!ast_strlen_zero(peer->fullcontact))
15709       ast_string_field_set(p, fullcontact, peer->fullcontact);
15710 
15711    if (!ast_strlen_zero(peer->tohost))
15712       ast_string_field_set(p, tohost, peer->tohost);
15713    else
15714       ast_string_field_set(p, tohost, ast_inet_ntoa(peer->addr.sin_addr));
15715 
15716    /* Recalculate our side, and recalculate Call ID */
15717    if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
15718       p->ourip = __ourip;
15719    build_via(p);
15720    build_callid_pvt(p);
15721 
15722    if (peer->pokeexpire > -1)
15723       ast_sched_del(sched, peer->pokeexpire);
15724    p->relatedpeer = peer;
15725    ast_set_flag(&p->flags[0], SIP_OUTGOING);
15726 #ifdef VOCAL_DATA_HACK
15727    ast_copy_string(p->username, "__VOCAL_DATA_SHOULD_READ_THE_SIP_SPEC__", sizeof(p->username));
15728    xmitres = transmit_invite(p, SIP_INVITE, 0, 2);
15729 #else
15730    xmitres = transmit_invite(p, SIP_OPTIONS, 0, 2);
15731 #endif
15732    gettimeofday(&peer->ps, NULL);
15733    if (xmitres == XMIT_ERROR)
15734       sip_poke_noanswer(peer);   /* Immediately unreachable, network problems */
15735    else {
15736       if (peer->pokeexpire > -1)
15737          ast_sched_del(sched, peer->pokeexpire);
15738       peer->pokeexpire = ast_sched_add(sched, peer->maxms * 2, sip_poke_noanswer, peer);
15739    }
15740 
15741    return 0;
15742 }

static int sip_poke_peer_s ( const void *  data  )  [static]

Poke peer (send qualify to check if peer is alive and well).

Definition at line 7853 of file chan_sip.c.

References sip_peer::pokeexpire, and sip_poke_peer().

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

07854 {
07855    struct sip_peer *peer = (struct sip_peer *)data;
07856 
07857    peer->pokeexpire = -1;
07858    sip_poke_peer(peer);
07859    return 0;
07860 }

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

Remove temporary realtime objects from memory (CLI).

Definition at line 10034 of file chan_sip.c.

References ast_cli(), ast_test_flag, ASTOBJ_CONTAINER_FIND_UNLINK, ASTOBJ_CONTAINER_LINK, ASTOBJ_CONTAINER_PRUNE_MARKED, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_CONTAINER_UNLOCK, ASTOBJ_CONTAINER_WRLOCK, ASTOBJ_MARK, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, ASTOBJ_UNREF, FALSE, sip_user::flags, sip_peer::flags, name, peerl, RESULT_SHOWUSAGE, RESULT_SUCCESS, sip_destroy_peer(), sip_destroy_user(), SIP_PAGE2_RTCACHEFRIENDS, TRUE, and userl.

10035 {
10036    struct sip_peer *peer;
10037    struct sip_user *user;
10038    int pruneuser = FALSE;
10039    int prunepeer = FALSE;
10040    int multi = FALSE;
10041    char *name = NULL;
10042    regex_t regexbuf;
10043 
10044    switch (argc) {
10045    case 4:
10046       if (!strcasecmp(argv[3], "user"))
10047          return RESULT_SHOWUSAGE;
10048       if (!strcasecmp(argv[3], "peer"))
10049          return RESULT_SHOWUSAGE;
10050       if (!strcasecmp(argv[3], "like"))
10051          return RESULT_SHOWUSAGE;
10052       if (!strcasecmp(argv[3], "all")) {
10053          multi = TRUE;
10054          pruneuser = prunepeer = TRUE;
10055       } else {
10056          pruneuser = prunepeer = TRUE;
10057          name = argv[3];
10058       }
10059       break;
10060    case 5:
10061       if (!strcasecmp(argv[4], "like"))
10062          return RESULT_SHOWUSAGE;
10063       if (!strcasecmp(argv[3], "all"))
10064          return RESULT_SHOWUSAGE;
10065       if (!strcasecmp(argv[3], "like")) {
10066          multi = TRUE;
10067          name = argv[4];
10068          pruneuser = prunepeer = TRUE;
10069       } else if (!strcasecmp(argv[3], "user")) {
10070          pruneuser = TRUE;
10071          if (!strcasecmp(argv[4], "all"))
10072             multi = TRUE;
10073          else
10074             name = argv[4];
10075       } else if (!strcasecmp(argv[3], "peer")) {
10076          prunepeer = TRUE;
10077          if (!strcasecmp(argv[4], "all"))
10078             multi = TRUE;
10079          else
10080             name = argv[4];
10081       } else
10082          return RESULT_SHOWUSAGE;
10083       break;
10084    case 6:
10085       if (strcasecmp(argv[4], "like"))
10086          return RESULT_SHOWUSAGE;
10087       if (!strcasecmp(argv[3], "user")) {
10088          pruneuser = TRUE;
10089          name = argv[5];
10090       } else if (!strcasecmp(argv[3], "peer")) {
10091          prunepeer = TRUE;
10092          name = argv[5];
10093       } else
10094          return RESULT_SHOWUSAGE;
10095       break;
10096    default:
10097       return RESULT_SHOWUSAGE;
10098    }
10099 
10100    if (multi && name) {
10101       if (regcomp(&regexbuf, name, REG_EXTENDED | REG_NOSUB))
10102          return RESULT_SHOWUSAGE;
10103    }
10104 
10105    if (multi) {
10106       if (prunepeer) {
10107          int pruned = 0;
10108 
10109          ASTOBJ_CONTAINER_WRLOCK(&peerl);
10110          ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do {
10111             ASTOBJ_RDLOCK(iterator);
10112             if (name && regexec(&regexbuf, iterator->name, 0, NULL, 0)) {
10113                ASTOBJ_UNLOCK(iterator);
10114                continue;
10115             };
10116             if (ast_test_flag(&iterator->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) {
10117                ASTOBJ_MARK(iterator);
10118                pruned++;
10119             }
10120             ASTOBJ_UNLOCK(iterator);
10121          } while (0) );
10122          if (pruned) {
10123             ASTOBJ_CONTAINER_PRUNE_MARKED(&peerl, sip_destroy_peer);
10124             ast_cli(fd, "%d peers pruned.\n", pruned);
10125          } else
10126             ast_cli(fd, "No peers found to prune.\n");
10127          ASTOBJ_CONTAINER_UNLOCK(&peerl);
10128       }
10129       if (pruneuser) {
10130          int pruned = 0;
10131 
10132          ASTOBJ_CONTAINER_WRLOCK(&userl);
10133          ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do {
10134             ASTOBJ_RDLOCK(iterator);
10135             if (name && regexec(&regexbuf, iterator->name, 0, NULL, 0)) {
10136                ASTOBJ_UNLOCK(iterator);
10137                continue;
10138             };
10139             if (ast_test_flag(&iterator->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) {
10140                ASTOBJ_MARK(iterator);
10141                pruned++;
10142             }
10143             ASTOBJ_UNLOCK(iterator);
10144          } while (0) );
10145          if (pruned) {
10146             ASTOBJ_CONTAINER_PRUNE_MARKED(&userl, sip_destroy_user);
10147             ast_cli(fd, "%d users pruned.\n", pruned);
10148          } else
10149             ast_cli(fd, "No users found to prune.\n");
10150          ASTOBJ_CONTAINER_UNLOCK(&userl);
10151       }
10152    } else {
10153       if (prunepeer) {
10154          if ((peer = ASTOBJ_CONTAINER_FIND_UNLINK(&peerl, name))) {
10155             if (!ast_test_flag(&peer->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) {
10156                ast_cli(fd, "Peer '%s' is not a Realtime peer, cannot be pruned.\n", name);
10157                ASTOBJ_CONTAINER_LINK(&peerl, peer);
10158             } else
10159                ast_cli(fd, "Peer '%s' pruned.\n", name);
10160             ASTOBJ_UNREF(peer, sip_destroy_peer);
10161          } else
10162             ast_cli(fd, "Peer '%s' not found.\n", name);
10163       }
10164       if (pruneuser) {
10165          if ((user = ASTOBJ_CONTAINER_FIND_UNLINK(&userl, name))) {
10166             if (!ast_test_flag(&user->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) {
10167                ast_cli(fd, "User '%s' is not a Realtime user, cannot be pruned.\n", name);
10168                ASTOBJ_CONTAINER_LINK(&userl, user);
10169             } else
10170                ast_cli(fd, "User '%s' pruned.\n", name);
10171             ASTOBJ_UNREF(user, sip_destroy_user);
10172          } else
10173             ast_cli(fd, "User '%s' not found.\n", name);
10174       }
10175    }
10176 
10177    return RESULT_SUCCESS;
10178 }

static struct ast_frame * sip_read ( struct ast_channel ast  )  [static, read]

Read SIP RTP from channel.

Definition at line 4315 of file chan_sip.c.

References ast_bridged_channel(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_test_flag, FALSE, sip_pvt::flags, sip_pvt::lastrtprx, sip_pvt::lock, LOG_DEBUG, option_debug, sip_pvt::pendinginvite, SIP_GOTREFER, SIP_NEEDREINVITE, SIP_PAGE2_T38SUPPORT_UDPTL, SIP_PENDINGBYE, sip_rtp_read(), t38properties::state, sip_pvt::t38, T38_DISABLED, T38_LOCAL_REINVITE, t38properties::t38support, ast_channel::tech_pvt, and transmit_reinvite_with_t38_sdp().

04316 {
04317    struct ast_frame *fr;
04318    struct sip_pvt *p = ast->tech_pvt;
04319    int faxdetected = FALSE;
04320 
04321    ast_mutex_lock(&p->lock);
04322    fr = sip_rtp_read(ast, p, &faxdetected);
04323    p->lastrtprx = time(NULL);
04324 
04325    /* If we are NOT bridged to another channel, and we have detected fax tone we issue T38 re-invite to a peer */
04326    /* If we are bridged then it is the responsibility of the SIP device to issue T38 re-invite if it detects CNG or fax preamble */
04327    if (faxdetected && ast_test_flag(&p->t38.t38support, SIP_PAGE2_T38SUPPORT_UDPTL) && (p->t38.state == T38_DISABLED) && !(ast_bridged_channel(ast))) {
04328       if (!ast_test_flag(&p->flags[0], SIP_GOTREFER)) {
04329          if (!p->pendinginvite) {
04330             if (option_debug > 2)
04331                ast_log(LOG_DEBUG, "Sending reinvite on SIP (%s) for T.38 negotiation.\n",ast->name);
04332             p->t38.state = T38_LOCAL_REINVITE;
04333             transmit_reinvite_with_t38_sdp(p);
04334             if (option_debug > 1)
04335                ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, ast->name);
04336          }
04337       } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) {
04338          if (option_debug > 2)
04339             ast_log(LOG_DEBUG, "Deferring reinvite on SIP (%s) - it will be re-negotiated for T.38\n", ast->name);
04340          ast_set_flag(&p->flags[0], SIP_NEEDREINVITE);
04341       }
04342    }
04343 
04344    ast_mutex_unlock(&p->lock);
04345    return fr;
04346 }

static struct sockaddr_in * sip_real_dst ( const struct sip_pvt p  )  [static, read]

The real destination address for a write.

Definition at line 1747 of file chan_sip.c.

References ast_test_flag, sip_pvt::flags, sip_pvt::recv, sip_pvt::sa, SIP_NAT, and SIP_NAT_ROUTE.

Referenced by __sip_xmit(), check_via(), retrans_pkt(), send_response(), and sip_debug_test_pvt().

01748 {
01749    return ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE ? &p->recv : &p->sa;
01750 }

static int sip_refer_allocate ( struct sip_pvt p  )  [static]

Allocate SIP refer structure.

Definition at line 7662 of file chan_sip.c.

References ast_calloc, and sip_pvt::refer.

Referenced by get_also_info(), handle_request_invite(), handle_request_refer(), and transmit_refer().

07663 {
07664    p->refer = ast_calloc(1, sizeof(struct sip_refer)); 
07665    return p->refer ? 1 : 0;
07666 }

static int sip_reg_timeout ( const void *  data  )  [static]

Registration timeout, register again.

Definition at line 7418 of file chan_sip.c.

References __sip_pretend_ack(), ast_log(), ast_set_flag, ASTOBJ_REF, ASTOBJ_UNREF, sip_registry::call, EVENT_FLAG_SYSTEM, sip_pvt::flags, 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, and transmit_register().

Referenced by transmit_register().

07419 {
07420 
07421    /* if we are here, our registration timed out, so we'll just do it over */
07422    struct sip_registry *r = ASTOBJ_REF((struct sip_registry *) data);
07423    struct sip_pvt *p;
07424    int res;
07425 
07426    /* if we couldn't get a reference to the registry object, punt */
07427    if (!r)
07428       return 0;
07429 
07430    ast_log(LOG_NOTICE, "   -- Registration for '%s@%s' timed out, trying again (Attempt #%d)\n", r->username, r->hostname, r->regattempts); 
07431    if (r->call) {
07432       /* Unlink us, destroy old call.  Locking is not relevant here because all this happens
07433          in the single SIP manager thread. */
07434       p = r->call;
07435       if (p->registry)
07436          ASTOBJ_UNREF(p->registry, sip_registry_destroy);
07437       r->call = NULL;
07438       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
07439       /* Pretend to ACK anything just in case */
07440       __sip_pretend_ack(p); /* XXX we need p locked, not sure we have */
07441    }
07442    /* If we have a limit, stop registration and give up */
07443    if (global_regattempts_max && (r->regattempts > global_regattempts_max)) {
07444       /* Ok, enough is enough. Don't try any more */
07445       /* We could add an external notification here... 
07446          steal it from app_voicemail :-) */
07447       ast_log(LOG_NOTICE, "   -- Giving up forever trying to register '%s@%s'\n", r->username, r->hostname);
07448       r->regstate = REG_STATE_FAILED;
07449    } else {
07450       r->regstate = REG_STATE_UNREGISTERED;
07451       r->timeout = -1;
07452       res=transmit_register(r, SIP_REGISTER, NULL, NULL);
07453    }
07454    manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelDriver: SIP\r\nUsername: %s\r\nDomain: %s\r\nStatus: %s\r\n", r->username, r->hostname, regstate2str(r->regstate));
07455    ASTOBJ_UNREF(r, sip_registry_destroy);
07456    return 0;
07457 }

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

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

Definition at line 4635 of file chan_sip.c.

References ast_calloc, ast_log(), ast_string_field_init, ast_string_field_set, ast_strlen_zero(), ASTOBJ_CONTAINER_LINK, ASTOBJ_INIT, ASTOBJ_UNREF, sip_registry::callid_valid, sip_registry::expire, FALSE, free, hostname, INITIAL_CSEQ, LOG_ERROR, LOG_WARNING, sip_registry::ocseq, sip_registry::portno, sip_registry::refresh, regl, secret, sip_registry_destroy(), sip_registry::timeout, and username.

Referenced by reload_config().

04636 {
04637    struct sip_registry *reg;
04638    int portnum = 0;
04639    char username[256] = "";
04640    char *hostname=NULL, *secret=NULL, *authuser=NULL;
04641    char *porta=NULL;
04642    char *contact=NULL;
04643 
04644    if (!value)
04645       return -1;
04646    ast_copy_string(username, value, sizeof(username));
04647    /* First split around the last '@' then parse the two components. */
04648    hostname = strrchr(username, '@'); /* allow @ in the first part */
04649    if (hostname)
04650       *hostname++ = '\0';
04651    if (ast_strlen_zero(username) || ast_strlen_zero(hostname)) {
04652       ast_log(LOG_WARNING, "Format for registration is user[:secret[:authuser]]@host[:port][/contact] at line %d\n", lineno);
04653       return -1;
04654    }
04655    /* split user[:secret[:authuser]] */
04656    secret = strchr(username, ':');
04657    if (secret) {
04658       *secret++ = '\0';
04659       authuser = strchr(secret, ':');
04660       if (authuser)
04661          *authuser++ = '\0';
04662    }
04663    /* split host[:port][/contact] */
04664    contact = strchr(hostname, '/');
04665    if (contact)
04666       *contact++ = '\0';
04667    if (ast_strlen_zero(contact))
04668       contact = "s";
04669    porta = strchr(hostname, ':');
04670    if (porta) {
04671       *porta++ = '\0';
04672       portnum = atoi(porta);
04673       if (portnum == 0) {
04674          ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno);
04675          return -1;
04676       }
04677    }
04678    if (!(reg = ast_calloc(1, sizeof(*reg)))) {
04679       ast_log(LOG_ERROR, "Out of memory. Can't allocate SIP registry entry\n");
04680       return -1;
04681    }
04682 
04683    if (ast_string_field_init(reg, 256)) {
04684       ast_log(LOG_ERROR, "Out of memory. Can't allocate SIP registry strings\n");
04685       free(reg);
04686       return -1;
04687    }
04688 
04689    regobjs++;
04690    ASTOBJ_INIT(reg);
04691    ast_string_field_set(reg, contact, contact);
04692    if (!ast_strlen_zero(username))
04693       ast_string_field_set(reg, username, username);
04694    if (hostname)
04695       ast_string_field_set(reg, hostname, hostname);
04696    if (authuser)
04697       ast_string_field_set(reg, authuser, authuser);
04698    if (secret)
04699       ast_string_field_set(reg, secret, secret);
04700    reg->expire = -1;
04701    reg->timeout =  -1;
04702    reg->refresh = default_expiry;
04703    reg->portno = portnum;
04704    reg->callid_valid = FALSE;
04705    reg->ocseq = INITIAL_CSEQ;
04706    ASTOBJ_CONTAINER_LINK(&regl, reg);  /* Add the new registry entry to the list */
04707    ASTOBJ_UNREF(reg,sip_registry_destroy);
04708    return 0;
04709 }

static void sip_registry_destroy ( struct sip_registry reg  )  [static]

Destroy registry object Objects created with the register= statement in static configuration.

Definition at line 3026 of file chan_sip.c.

References ast_log(), ast_sched_del(), ast_string_field_free_memory, sip_registry::call, sip_registry::expire, free, LOG_DEBUG, option_debug, sip_pvt::registry, sip_destroy(), and sip_registry::timeout.

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

03027 {
03028    /* Really delete */
03029    if (option_debug > 2)
03030       ast_log(LOG_DEBUG, "Destroying registry entry for %s@%s\n", reg->username, reg->hostname);
03031 
03032    if (reg->call) {
03033       /* Clear registry before destroying to ensure
03034          we don't get reentered trying to grab the registry lock */
03035       reg->call->registry = NULL;
03036       if (option_debug > 2)
03037          ast_log(LOG_DEBUG, "Destroying active SIP dialog for registry %s@%s\n", reg->username, reg->hostname);
03038       sip_destroy(reg->call);
03039    }
03040    if (reg->expire > -1)
03041       ast_sched_del(sched, reg->expire);
03042    if (reg->timeout > -1)
03043       ast_sched_del(sched, reg->timeout);
03044    ast_string_field_free_memory(reg);
03045    regobjs--;
03046    free(reg);
03047    
03048 }

static int sip_reinvite_retry ( const void *  data  )  [static]

Reset the NEEDREINVITE flag after waiting when we get 491 on a Re-invite to avoid race conditions between asterisk servers. Called from the scheduler.

Definition at line 11957 of file chan_sip.c.

References ast_set_flag, sip_pvt::flags, SIP_NEEDREINVITE, and sip_pvt::waitid.

Referenced by handle_response_invite().

11958 {
11959    struct sip_pvt *p = (struct sip_pvt *) data;
11960 
11961    ast_set_flag(&p->flags[0], SIP_NEEDREINVITE);   
11962    p->waitid = -1;
11963    return 0;
11964 }

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

Force reload of module from cli.

Definition at line 17766 of file chan_sip.c.

References ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), CHANNEL_CLI_RELOAD, CHANNEL_MODULE_RELOAD, restart_monitor(), and TRUE.

Referenced by reload().

17767 {
17768    ast_mutex_lock(&sip_reload_lock);
17769    if (sip_reloading) 
17770       ast_verbose("Previous SIP reload not yet done\n");
17771    else {
17772       sip_reloading = TRUE;
17773       if (fd)
17774          sip_reloadreason = CHANNEL_CLI_RELOAD;
17775       else
17776          sip_reloadreason = CHANNEL_MODULE_RELOAD;
17777    }
17778    ast_mutex_unlock(&sip_reload_lock);
17779    restart_monitor();
17780 
17781    return 0;
17782 }

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

PBX interface function -build SIP pvt structure SIP calls initiated by the PBX arrive here.

Note:
This is added to help splitting up chan_sip.c into several files in coming releases

Definition at line 15847 of file chan_sip.c.

References __ourip, ast_calloc, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_SWITCH_CONGESTION, AST_CAUSE_UNREGISTERED, AST_FORMAT_MAX_AUDIO, ast_getformatname(), ast_getformatname_multiple(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_sip_ouraddrfor(), AST_STATE_DOWN, ast_string_field_free, ast_string_field_set, ast_strlen_zero(), ast_update_use_count(), build_callid_pvt(), build_via(), create_addr(), ext, sip_pvt::flags, sip_pvt::lock, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, option_debug, sip_pvt::options, sip_pvt::ourip, sip_pvt::prefcodec, restart_monitor(), sip_pvt::sa, sip_alloc(), sip_destroy(), SIP_INVITE, sip_new(), SIP_PAGE2_OUTGOING_CALL, and username.

15848 {
15849    int oldformat;
15850    struct sip_pvt *p;
15851    struct ast_channel *tmpc = NULL;
15852    char *ext, *host;
15853    char tmp[256];
15854    char *dest = data;
15855 
15856    oldformat = format;
15857    if (!(format &= ((AST_FORMAT_MAX_AUDIO << 1) - 1))) {
15858       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));
15859       *cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;   /* Can't find codec to connect to host */
15860       return NULL;
15861    }
15862    if (option_debug)
15863       ast_log(LOG_DEBUG, "Asked to create a SIP channel with formats: %s\n", ast_getformatname_multiple(tmp, sizeof(tmp), oldformat));
15864 
15865    if (!(p = sip_alloc(NULL, NULL, 0, SIP_INVITE))) {
15866       ast_log(LOG_ERROR, "Unable to build sip pvt data for '%s' (Out of memory or socket error)\n", (char *)data);
15867       *cause = AST_CAUSE_SWITCH_CONGESTION;
15868       return NULL;
15869    }
15870 
15871    ast_set_flag(&p->flags[1], SIP_PAGE2_OUTGOING_CALL);
15872 
15873    if (!(p->options = ast_calloc(1, sizeof(*p->options)))) {
15874       sip_destroy(p);
15875       ast_log(LOG_ERROR, "Unable to build option SIP data structure - Out of memory\n");
15876       *cause = AST_CAUSE_SWITCH_CONGESTION;
15877       return NULL;
15878    }
15879 
15880    ast_copy_string(tmp, dest, sizeof(tmp));
15881    host = strchr(tmp, '@');
15882    if (host) {
15883       *host++ = '\0';
15884       ext = tmp;
15885    } else {
15886       ext = strchr(tmp, '/');
15887       if (ext) 
15888          *ext++ = '\0';
15889       host = tmp;
15890    }
15891 
15892    if (create_addr(p, host)) {
15893       *cause = AST_CAUSE_UNREGISTERED;
15894       if (option_debug > 2)
15895          ast_log(LOG_DEBUG, "Cant create SIP call - target device not registred\n");
15896       sip_destroy(p);
15897       return NULL;
15898    }
15899    if (ast_strlen_zero(p->peername) && ext)
15900       ast_string_field_set(p, peername, ext);
15901    /* Recalculate our side, and recalculate Call ID */
15902    if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
15903       p->ourip = __ourip;
15904    build_via(p);
15905    build_callid_pvt(p);
15906    
15907    /* We have an extension to call, don't use the full contact here */
15908    /* This to enable dialing registered peers with extension dialling,
15909       like SIP/peername/extension   
15910       SIP/peername will still use the full contact */
15911    if (ext) {
15912       ast_string_field_set(p, username, ext);
15913       ast_string_field_free(p, fullcontact);
15914    }
15915 #if 0
15916    printf("Setting up to call extension '%s' at '%s'\n", ext ? ext : "<none>", host);
15917 #endif
15918    p->prefcodec = oldformat;           /* Format for this call */
15919    ast_mutex_lock(&p->lock);
15920    tmpc = sip_new(p, AST_STATE_DOWN, host);  /* Place the call */
15921    ast_mutex_unlock(&p->lock);
15922    if (!tmpc)
15923       sip_destroy(p);
15924    ast_update_use_count();
15925    restart_monitor();
15926    return tmpc;
15927 }

static int sip_reregister ( const void *  data  )  [static]

Update registration with SIP Proxy.

Definition at line 7386 of file chan_sip.c.

References __sip_do_register(), append_history, ast_log(), ast_test_flag, ASTOBJ_REF, ASTOBJ_UNREF, sip_registry::call, sip_registry::expire, sip_pvt::flags, LOG_NOTICE, SIP_NO_HISTORY, sip_registry_destroy(), and sipdebug.

Referenced by handle_response_register(), and sip_send_all_registers().

07387 {
07388    /* if we are here, we know that we need to reregister. */
07389    struct sip_registry *r= ASTOBJ_REF((struct sip_registry *) data);
07390 
07391    /* if we couldn't get a reference to the registry object, punt */
07392    if (!r)
07393       return 0;
07394 
07395    if (r->call && !ast_test_flag(&r->call->flags[0], SIP_NO_HISTORY))
07396       append_history(r->call, "RegistryRenew", "Account: %s@%s", r->username, r->hostname);
07397    /* Since registry's are only added/removed by the the monitor thread, this
07398       may be overkill to reference/dereference at all here */
07399    if (sipdebug)
07400       ast_log(LOG_NOTICE, "   -- Re-registration for  %s@%s\n", r->username, r->hostname);
07401 
07402    r->expire = -1;
07403    __sip_do_register(r);
07404    ASTOBJ_UNREF(r, sip_registry_destroy);
07405    return 0;
07406 }

static struct ast_frame * sip_rtp_read ( struct ast_channel ast,
struct sip_pvt p,
int *  faxdetect 
) [static, read]

Read RTP from network.

Definition at line 4245 of file chan_sip.c.

References ast_dsp_process(), AST_FORMAT_AUDIO_MASK, AST_FORMAT_VIDEO_MASK, AST_FRAME_DTMF, AST_FRAME_VOICE, ast_getformatname(), ast_log(), ast_null_frame, ast_rtcp_read(), ast_rtp_read(), ast_set_read_format(), ast_set_write_format(), ast_test_flag, ast_udptl_read(), f, ast_channel::fdno, sip_pvt::flags, ast_frame::frametype, sip_pvt::jointcapability, LOG_DEBUG, ast_channel::nativeformats, option_debug, sip_pvt::owner, ast_channel::readformat, sip_pvt::rtp, SIP_DTMF, SIP_DTMF_INBAND, SIP_DTMF_RFC2833, SIP_PAGE2_T38SUPPORT_UDPTL, ast_frame::subclass, sip_pvt::t38, t38properties::t38support, sip_pvt::udptl, sip_pvt::vad, sip_pvt::vrtp, and ast_channel::writeformat.

Referenced by sip_read().

04246 {
04247    /* Retrieve audio/etc from channel.  Assumes p->lock is already held. */
04248    struct ast_frame *f;
04249    
04250    if (!p->rtp) {
04251       /* We have no RTP allocated for this channel */
04252       return &ast_null_frame;
04253    }
04254 
04255    switch(ast->fdno) {
04256    case 0:
04257       f = ast_rtp_read(p->rtp);  /* RTP Audio */
04258       break;
04259    case 1:
04260       f = ast_rtcp_read(p->rtp); /* RTCP Control Channel */
04261       break;
04262    case 2:
04263       f = ast_rtp_read(p->vrtp); /* RTP Video */
04264       break;
04265    case 3:
04266       f = ast_rtcp_read(p->vrtp);   /* RTCP Control Channel for video */
04267       break;
04268    case 5:
04269       f = ast_udptl_read(p->udptl); /* UDPTL for T.38 */
04270       break;
04271    default:
04272       f = &ast_null_frame;
04273    }
04274    /* Don't forward RFC2833 if we're not supposed to */
04275    if (f && (f->frametype == AST_FRAME_DTMF) &&
04276        (ast_test_flag(&p->flags[0], SIP_DTMF) != SIP_DTMF_RFC2833))
04277       return &ast_null_frame;
04278 
04279       /* We already hold the channel lock */
04280    if (!p->owner || (f && f->frametype != AST_FRAME_VOICE))
04281       return f;
04282 
04283    if (f && f->subclass != (p->owner->nativeformats & AST_FORMAT_AUDIO_MASK)) {
04284       if (!(f->subclass & p->jointcapability)) {
04285          if (option_debug) {
04286             ast_log(LOG_DEBUG, "Bogus frame of format '%s' received from '%s'!\n",
04287                ast_getformatname(f->subclass), p->owner->name);
04288          }
04289          return &ast_null_frame;
04290       }
04291       if (option_debug)
04292          ast_log(LOG_DEBUG, "Oooh, format changed to %d\n", f->subclass);
04293       p->owner->nativeformats = (p->owner->nativeformats & AST_FORMAT_VIDEO_MASK) | f->subclass;
04294       ast_set_read_format(p->owner, p->owner->readformat);
04295       ast_set_write_format(p->owner, p->owner->writeformat);
04296    }
04297 
04298    if (f && (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) && p->vad) {
04299       f = ast_dsp_process(p->owner, p->vad, f);
04300       if (f && f->frametype == AST_FRAME_DTMF) {
04301          if (ast_test_flag(&p->t38.t38support, SIP_PAGE2_T38SUPPORT_UDPTL) && f->subclass == 'f') {
04302             if (option_debug)
04303                ast_log(LOG_DEBUG, "Fax CNG detected on %s\n", ast->name);
04304             *faxdetect = 1;
04305          } else if (option_debug) {
04306             ast_log(LOG_DEBUG, "* Detected inband DTMF '%c'\n", f->subclass);
04307          }
04308       }
04309    }
04310    
04311    return f;
04312 }

static void sip_scheddestroy ( struct sip_pvt p,
int  ms 
) [static]

static void sip_send_all_registers ( void   )  [static]

Send all known registrations.

Definition at line 17722 of file chan_sip.c.

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

Referenced by load_module(), and sip_do_reload().

17723 {
17724    int ms;
17725    int regspacing;
17726    if (!regobjs)
17727       return;
17728    regspacing = default_expiry * 1000/regobjs;
17729    if (regspacing > 100)
17730       regspacing = 100;
17731    ms = regspacing;
17732    ASTOBJ_CONTAINER_TRAVERSE(&regl, 1, do {
17733       ASTOBJ_WRLOCK(iterator);
17734       if (iterator->expire > -1)
17735          ast_sched_del(sched, iterator->expire);
17736       ms += regspacing;
17737       iterator->expire = ast_sched_add(sched, ms, sip_reregister, iterator);
17738       ASTOBJ_UNLOCK(iterator);
17739    } while (0)
17740    );
17741 }

static int sip_send_mwi_to_peer ( struct sip_peer peer  )  [static]

Send message waiting indication to alert peer that they've got voicemail.

Definition at line 15392 of file chan_sip.c.

References __ourip, sip_peer::addr, ast_app_inboxcount(), ast_set_flag, ast_sip_ouraddrfor(), build_callid_pvt(), build_via(), create_addr_from_peer(), sip_peer::defaddr, DEFAULT_TRANS_TIMEOUT, sip_pvt::flags, sip_peer::lastmsgcheck, sip_peer::lastmsgssent, sip_peer::mailbox, sip_peer::mwipvt, sip_pvt::ourip, sip_pvt::sa, sip_alloc(), sip_destroy(), SIP_NOTIFY, SIP_OUTGOING, sip_scheddestroy(), transmit_notify_with_mwi(), and sip_peer::vmexten.

Referenced by do_monitor(), and handle_request_subscribe().

15393 {
15394    /* Called with peerl lock, but releases it */
15395    struct sip_pvt *p;
15396    int newmsgs, oldmsgs;
15397 
15398    /* Do we have an IP address? If not, skip this peer */
15399    if (!peer->addr.sin_addr.s_addr && !peer->defaddr.sin_addr.s_addr) 
15400       return 0;
15401 
15402    /* Check for messages */
15403    ast_app_inboxcount(peer->mailbox, &newmsgs, &oldmsgs);
15404    
15405    peer->lastmsgcheck = time(NULL);
15406    
15407    /* Return now if it's the same thing we told them last time */
15408    if (((newmsgs > 0x7fff ? 0x7fff0000 : (newmsgs << 16)) | (oldmsgs > 0xffff ? 0xffff : oldmsgs)) == peer->lastmsgssent) {
15409       return 0;
15410    }
15411    
15412    
15413    peer->lastmsgssent = ((newmsgs > 0x7fff ? 0x7fff0000 : (newmsgs << 16)) | (oldmsgs > 0xffff ? 0xffff : oldmsgs));
15414 
15415    if (peer->mwipvt) {
15416       /* Base message on subscription */
15417       p = peer->mwipvt;
15418    } else {
15419       /* Build temporary dialog for this message */
15420       if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY))) 
15421          return -1;
15422       if (create_addr_from_peer(p, peer)) {
15423          /* Maybe they're not registered, etc. */
15424          sip_destroy(p);
15425          return 0;
15426       }
15427       /* Recalculate our side, and recalculate Call ID */
15428       if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
15429          p->ourip = __ourip;
15430       build_via(p);
15431       build_callid_pvt(p);
15432       /* Destroy this session after 32 secs */
15433       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
15434    }
15435    /* Send MWI */
15436    ast_set_flag(&p->flags[0], SIP_OUTGOING);
15437    transmit_notify_with_mwi(p, newmsgs, oldmsgs, peer->vmexten);
15438    return 0;
15439 }

static int sip_senddigit_begin ( struct ast_channel ast,
char  digit 
) [static]

Definition at line 3780 of file chan_sip.c.

References ast_mutex_lock(), ast_mutex_unlock(), ast_rtp_senddigit_begin(), ast_test_flag, sip_pvt::flags, sip_pvt::lock, sip_pvt::rtp, SIP_DTMF, SIP_DTMF_INBAND, SIP_DTMF_RFC2833, and ast_channel::tech_pvt.

03781 {
03782    struct sip_pvt *p = ast->tech_pvt;
03783    int res = 0;
03784 
03785    ast_mutex_lock(&p->lock);
03786    switch (ast_test_flag(&p->flags[0], SIP_DTMF)) {
03787    case SIP_DTMF_INBAND:
03788       res = -1; /* Tell Asterisk to generate inband indications */
03789       break;
03790    case SIP_DTMF_RFC2833:
03791       if (p->rtp)
03792          ast_rtp_senddigit_begin(p->rtp, digit);
03793       break;
03794    default:
03795       break;
03796    }
03797    ast_mutex_unlock(&p->lock);
03798 
03799    return res;
03800 }

static int sip_senddigit_end ( struct ast_channel ast,
char  digit,
unsigned int  duration 
) [static]

Send DTMF character on SIP channel within one call, we're able to transmit in many methods simultaneously.

Definition at line 3804 of file chan_sip.c.

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

03805 {
03806    struct sip_pvt *p = ast->tech_pvt;
03807    int res = 0;
03808 
03809    ast_mutex_lock(&p->lock);
03810    switch (ast_test_flag(&p->flags[0], SIP_DTMF)) {
03811    case SIP_DTMF_INFO:
03812       transmit_info_with_digit(p, digit, duration);
03813       break;
03814    case SIP_DTMF_RFC2833:
03815       if (p->rtp)
03816          ast_rtp_senddigit_end(p->rtp, digit);
03817       break;
03818    case SIP_DTMF_INBAND:
03819       res = -1; /* Tell Asterisk to stop inband indications */
03820       break;
03821    }
03822    ast_mutex_unlock(&p->lock);
03823 
03824    return res;
03825 }

static int sip_sendtext ( struct ast_channel ast,
const char *  dest,
const char *  text,
int  ispdu 
) [static]

Send SIP MESSAGE text within a call Called from PBX core sendtext() application.

Definition at line 2352 of file chan_sip.c.

References ast_strlen_zero(), ast_verbose(), debug, sip_debug_test_pvt(), ast_channel::tech_pvt, and transmit_message_with_text().

02353 {
02354    struct sip_pvt *p = ast->tech_pvt;
02355    int debug = sip_debug_test_pvt(p);
02356 
02357    if (debug)
02358       ast_verbose("Sending text %s on %s\n", text, ast->name);
02359    if (!p)
02360       return -1;
02361    if (ast_strlen_zero(text))
02362       return 0;
02363    if (debug)
02364       ast_verbose("Really sending text %s on %s\n", text, ast->name);
02365    transmit_message_with_text(p, text);
02366    return 0;   
02367 }

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

Set the RTP peer for this call.

Definition at line 17455 of file chan_sip.c.

References ast_channel::_state, append_history, ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_rtp_get_peer(), ast_set_flag, AST_STATE_UP, ast_test_flag, sip_pvt::capability, sip_pvt::flags, sip_pvt::jointcapability, 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_ALREADYGONE, SIP_CAN_REINVITE_NAT, SIP_DEFER_BYE_ON_TRANSFER, SIP_GOTREFER, SIP_NEEDREINVITE, SIP_NO_HISTORY, SIP_PENDINGBYE, ast_channel::tech_pvt, transmit_reinvite_with_sdp(), and sip_pvt::vredirip.

17456 {
17457    struct sip_pvt *p;
17458    int changed = 0;
17459 
17460    p = chan->tech_pvt;
17461    if (!p) 
17462       return -1;
17463 
17464    /* Disable early RTP bridge  */
17465    if (chan->_state != AST_STATE_UP && !global_directrtpsetup)    /* We are in early state */
17466       return 0;
17467 
17468    ast_mutex_lock(&p->lock);
17469    if (ast_test_flag(&p->flags[0], SIP_ALREADYGONE)) {
17470       /* If we're destroyed, don't bother */
17471       ast_mutex_unlock(&p->lock);
17472       return 0;
17473    }
17474 
17475    /* if this peer cannot handle reinvites of the media stream to devices
17476       that are known to be behind a NAT, then stop the process now
17477    */
17478    if (nat_active && !ast_test_flag(&p->flags[0], SIP_CAN_REINVITE_NAT)) {
17479       ast_mutex_unlock(&p->lock);
17480       return 0;
17481    }
17482 
17483    if (rtp) {
17484       changed |= ast_rtp_get_peer(rtp, &p->redirip);
17485    } else if (p->redirip.sin_addr.s_addr || ntohs(p->redirip.sin_port) != 0) {
17486       memset(&p->redirip, 0, sizeof(p->redirip));
17487       changed = 1;
17488    }
17489    if (vrtp) {
17490       changed |= ast_rtp_get_peer(vrtp, &p->vredirip);
17491    } else if (p->vredirip.sin_addr.s_addr || ntohs(p->vredirip.sin_port) != 0) {
17492       memset(&p->vredirip, 0, sizeof(p->vredirip));
17493       changed = 1;
17494    }
17495    if (codecs) {
17496       if ((p->redircodecs != codecs)) {
17497          p->redircodecs = codecs;
17498          changed = 1;
17499       }
17500       if ((p->capability & codecs) != p->capability) {
17501          p->jointcapability &= codecs;
17502          p->capability &= codecs;
17503          changed = 1;
17504       }
17505    }
17506    if (changed && !ast_test_flag(&p->flags[0], SIP_GOTREFER) && !ast_test_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER)) {
17507       if (chan->_state != AST_STATE_UP) { /* We are in early state */
17508          if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY))
17509             append_history(p, "ExtInv", "Initial invite sent with remote bridge proposal.");
17510          if (option_debug)
17511             ast_log(LOG_DEBUG, "Early remote bridge setting SIP '%s' - Sending media to %s\n", p->callid, ast_inet_ntoa(rtp ? p->redirip.sin_addr : p->ourip));
17512       } else if (!p->pendinginvite) {     /* We are up, and have no outstanding invite */
17513          if (option_debug > 2) {
17514             ast_log(LOG_DEBUG, "Sending reinvite on SIP '%s' - It's audio soon redirected to IP %s\n", p->callid, ast_inet_ntoa(rtp ? p->redirip.sin_addr : p->ourip));
17515          }
17516          transmit_reinvite_with_sdp(p);
17517       } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) {
17518          if (option_debug > 2) {
17519             ast_log(LOG_DEBUG, "Deferring reinvite on SIP '%s' - It's audio will be redirected to IP %s\n", p->callid, ast_inet_ntoa(rtp ? p->redirip.sin_addr : p->ourip));
17520          }
17521          /* We have a pending Invite. Send re-invite when we're done with the invite */
17522          ast_set_flag(&p->flags[0], SIP_NEEDREINVITE);   
17523       }
17524    }
17525    /* Reset lastrtprx timer */
17526    p->lastrtprx = p->lastrtptx = time(NULL);
17527    ast_mutex_unlock(&p->lock);
17528    return 0;
17529 }

static int sip_set_udptl_peer ( struct ast_channel chan,
struct ast_udptl udptl 
) [static]

Definition at line 17282 of file chan_sip.c.

References ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_test_flag, ast_udptl_get_peer(), sip_pvt::flags, sip_pvt::lastrtprx, sip_pvt::lastrtptx, sip_pvt::lock, LOG_DEBUG, option_debug, sip_pvt::ourip, sip_pvt::pendinginvite, SIP_GOTREFER, SIP_NEEDREINVITE, SIP_PENDINGBYE, ast_channel::tech_pvt, transmit_reinvite_with_t38_sdp(), and sip_pvt::udptlredirip.

17283 {
17284    struct sip_pvt *p;
17285    
17286    p = chan->tech_pvt;
17287    if (!p)
17288       return -1;
17289    ast_mutex_lock(&p->lock);
17290    if (udptl)
17291       ast_udptl_get_peer(udptl, &p->udptlredirip);
17292    else
17293       memset(&p->udptlredirip, 0, sizeof(p->udptlredirip));
17294    if (!ast_test_flag(&p->flags[0], SIP_GOTREFER)) {
17295       if (!p->pendinginvite) {
17296          if (option_debug > 2) {
17297             ast_log(LOG_DEBUG, "Sending reinvite on SIP '%s' - It's UDPTL soon redirected to IP %s:%d\n", p->callid, ast_inet_ntoa(udptl ? p->udptlredirip.sin_addr : p->ourip), udptl ? ntohs(p->udptlredirip.sin_port) : 0);
17298          }
17299          transmit_reinvite_with_t38_sdp(p);
17300       } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) {
17301          if (option_debug > 2) {
17302             ast_log(LOG_DEBUG, "Deferring reinvite on SIP '%s' - It's UDPTL will be redirected to IP %s:%d\n", p->callid, ast_inet_ntoa(udptl ? p->udptlredirip.sin_addr : p->ourip), udptl ? ntohs(p->udptlredirip.sin_port) : 0);
17303          }
17304          ast_set_flag(&p->flags[0], SIP_NEEDREINVITE);
17305       }
17306    }
17307    /* Reset lastrtprx timer */
17308    p->lastrtprx = p->lastrtptx = time(NULL);
17309    ast_mutex_unlock(&p->lock);
17310    return 0;
17311 }

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

Show details of one active dialog.

Definition at line 10903 of file chan_sip.c.

References sip_pvt::allowtransfer, ast_cli(), ast_getformatname_multiple(), ast_inet_ntoa(), ast_mutex_lock(), ast_mutex_unlock(), ast_strlen_zero(), ast_test_flag, sip_pvt::capability, dtmfmode2str(), sip_pvt::flags, sip_route::hop, cfsip_options::id, iflist, sip_pvt::jointcapability, sip_pvt::lastmsg, len, sip_pvt::maxcallbitrate, nat2str(), ast_channel::nativeformats, sip_pvt::next, sip_pvt::noncodeccapability, NONE, sip_pvt::ourip, sip_pvt::owner, sip_pvt::peercapability, sip_pvt::recv, sip_pvt::redirip, RESULT_SHOWUSAGE, RESULT_SUCCESS, 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, and transfermode2str().

10904 {
10905    struct sip_pvt *cur;
10906    size_t len;
10907    int found = 0;
10908 
10909    if (argc != 4)
10910       return RESULT_SHOWUSAGE;
10911    len = strlen(argv[3]);
10912    ast_mutex_lock(&iflock);
10913    for (cur = iflist; cur; cur = cur->next) {
10914       if (!strncasecmp(cur->callid, argv[3], len)) {
10915          char formatbuf[BUFSIZ/2];
10916          ast_cli(fd,"\n");
10917          if (cur->subscribed != NONE)
10918             ast_cli(fd, "  * Subscription (type: %s)\n", subscription_type2str(cur->subscribed));
10919          else
10920             ast_cli(fd, "  * SIP Call\n");
10921          ast_cli(fd, "  Curr. trans. direction:  %s\n", ast_test_flag(&cur->flags[0], SIP_OUTGOING) ? "Outgoing" : "Incoming");
10922          ast_cli(fd, "  Call-ID:                %s\n", cur->callid);
10923          ast_cli(fd, "  Owner channel ID:       %s\n", cur->owner ? cur->owner->name : "<none>");
10924          ast_cli(fd, "  Our Codec Capability:   %d\n", cur->capability);
10925          ast_cli(fd, "  Non-Codec Capability (DTMF):   %d\n", cur->noncodeccapability);
10926          ast_cli(fd, "  Their Codec Capability:   %d\n", cur->peercapability);
10927          ast_cli(fd, "  Joint Codec Capability:   %d\n", cur->jointcapability);
10928          ast_cli(fd, "  Format:                 %s\n", ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->owner ? cur->owner->nativeformats : 0) );
10929          ast_cli(fd, "  MaxCallBR:              %d kbps\n", cur->maxcallbitrate);
10930          ast_cli(fd, "  Theoretical Address:    %s:%d\n", ast_inet_ntoa(cur->sa.sin_addr), ntohs(cur->sa.sin_port));
10931          ast_cli(fd, "  Received Address:       %s:%d\n", ast_inet_ntoa(cur->recv.sin_addr), ntohs(cur->recv.sin_port));
10932          ast_cli(fd, "  SIP Transfer mode:      %s\n", transfermode2str(cur->allowtransfer));
10933          ast_cli(fd, "  NAT Support:            %s\n", nat2str(ast_test_flag(&cur->flags[0], SIP_NAT)));
10934          ast_cli(fd, "  Audio IP:               %s %s\n", ast_inet_ntoa(cur->redirip.sin_addr.s_addr ? cur->redirip.sin_addr : cur->ourip), cur->redirip.sin_addr.s_addr ? "(Outside bridge)" : "(local)" );
10935          ast_cli(fd, "  Our Tag:                %s\n", cur->tag);
10936          ast_cli(fd, "  Their Tag:              %s\n", cur->theirtag);
10937          ast_cli(fd, "  SIP User agent:         %s\n", cur->useragent);
10938          if (!ast_strlen_zero(cur->username))
10939             ast_cli(fd, "  Username:               %s\n", cur->username);
10940          if (!ast_strlen_zero(cur->peername))
10941             ast_cli(fd, "  Peername:               %s\n", cur->peername);
10942          if (!ast_strlen_zero(cur->uri))
10943             ast_cli(fd, "  Original uri:           %s\n", cur->uri);
10944          if (!ast_strlen_zero(cur->cid_num))
10945             ast_cli(fd, "  Caller-ID:              %s\n", cur->cid_num);
10946          ast_cli(fd, "  Need Destroy:           %d\n", ast_test_flag(&cur->flags[0], SIP_NEEDDESTROY));
10947          ast_cli(fd, "  Last Message:           %s\n", cur->lastmsg);
10948          ast_cli(fd, "  Promiscuous Redir:      %s\n", ast_test_flag(&cur->flags[0], SIP_PROMISCREDIR) ? "Yes" : "No");
10949          ast_cli(fd, "  Route:                  %s\n", cur->route ? cur->route->hop : "N/A");
10950          ast_cli(fd, "  DTMF Mode:              %s\n", dtmfmode2str(ast_test_flag(&cur->flags[0], SIP_DTMF)));
10951          ast_cli(fd, "  SIP Options:            ");
10952          if (cur->sipoptions) {
10953             int x;
10954             for (x=0 ; (x < (sizeof(sip_options) / sizeof(sip_options[0]))); x++) {
10955                if (cur->sipoptions & sip_options[x].id)
10956                   ast_cli(fd, "%s ", sip_options[x].text);
10957             }
10958          } else
10959             ast_cli(fd, "(none)\n");
10960          ast_cli(fd, "\n\n");
10961          found++;
10962       }
10963    }
10964    ast_mutex_unlock(&iflock);
10965    if (!found) 
10966       ast_cli(fd, "No such SIP Call ID starting with '%s'\n", argv[3]);
10967    return RESULT_SUCCESS;
10968 }

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

Show active SIP channels.

Definition at line 10700 of file chan_sip.c.

References __sip_show_channels().

10701 {
10702         return __sip_show_channels(fd, argc, argv, 0);
10703 }

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

CLI command to list local domains.

Definition at line 10212 of file chan_sip.c.

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

10213 {
10214    struct domain *d;
10215 #define FORMAT "%-40.40s %-20.20s %-16.16s\n"
10216 
10217    if (AST_LIST_EMPTY(&domain_list)) {
10218       ast_cli(fd, "SIP Domain support not enabled.\n\n");
10219       return RESULT_SUCCESS;
10220    } else {
10221       ast_cli(fd, FORMAT, "Our local SIP domains:", "Context", "Set by");
10222       AST_LIST_LOCK(&domain_list);
10223       AST_LIST_TRAVERSE(&domain_list, d, list)
10224          ast_cli(fd, FORMAT, d->domain, S_OR(d->context, "(default)"),
10225             domain_mode_to_text(d->mode));
10226       AST_LIST_UNLOCK(&domain_list);
10227       ast_cli(fd, "\n");
10228       return RESULT_SUCCESS;
10229    }
10230 }

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

Show history details of one dialog.

Definition at line 10971 of file chan_sip.c.

References ast_cli(), AST_LIST_TRAVERSE, ast_mutex_lock(), ast_mutex_unlock(), sip_pvt::history, iflist, len, sip_pvt::next, NONE, RESULT_SHOWUSAGE, RESULT_SUCCESS, and sip_pvt::subscribed.

10972 {
10973    struct sip_pvt *cur;
10974    size_t len;
10975    int found = 0;
10976 
10977    if (argc != 4)
10978       return RESULT_SHOWUSAGE;
10979    if (!recordhistory)
10980       ast_cli(fd, "\n***Note: History recording is currently DISABLED.  Use 'sip history' to ENABLE.\n");
10981    len = strlen(argv[3]);
10982    ast_mutex_lock(&iflock);
10983    for (cur = iflist; cur; cur = cur->next) {
10984       if (!strncasecmp(cur->callid, argv[3], len)) {
10985          struct sip_history *hist;
10986          int x = 0;
10987 
10988          ast_cli(fd,"\n");
10989          if (cur->subscribed != NONE)
10990             ast_cli(fd, "  * Subscription\n");
10991          else
10992             ast_cli(fd, "  * SIP Call\n");
10993          if (cur->history)
10994             AST_LIST_TRAVERSE(cur->history, hist, list)
10995                ast_cli(fd, "%d. %s\n", ++x, hist->event);
10996          if (x == 0)
10997             ast_cli(fd, "Call '%s' has no history\n", cur->callid);
10998          found++;
10999       }
11000    }
11001    ast_mutex_unlock(&iflock);
11002    if (!found) 
11003       ast_cli(fd, "No such SIP Call ID starting with '%s'\n", argv[3]);
11004    return RESULT_SUCCESS;
11005 }

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

CLI Command to show calls within limits set by call_limit.

Definition at line 9637 of file chan_sip.c.

References ast_cli(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, FALSE, FORMAT, FORMAT2, peerl, RESULT_SHOWUSAGE, RESULT_SUCCESS, TRUE, and userl.

09638 {
09639 #define FORMAT  "%-25.25s %-15.15s %-15.15s \n"
09640 #define FORMAT2 "%-25.25s %-15.15s %-15.15s \n"
09641    char ilimits[40];
09642    char iused[40];
09643    int showall = FALSE;
09644 
09645    if (argc < 3) 
09646       return RESULT_SHOWUSAGE;
09647 
09648    if (argc == 4 && !strcmp(argv[3],"all")) 
09649          showall = TRUE;
09650    
09651    ast_cli(fd, FORMAT, "* User name", "In use", "Limit");
09652    ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do {
09653       ASTOBJ_RDLOCK(iterator);
09654       if (iterator->call_limit)
09655          snprintf(ilimits, sizeof(ilimits), "%d", iterator->call_limit);
09656       else 
09657          ast_copy_string(ilimits, "N/A", sizeof(ilimits));
09658       snprintf(iused, sizeof(iused), "%d", iterator->inUse);
09659       if (showall || iterator->call_limit)
09660          ast_cli(fd, FORMAT2, iterator->name, iused, ilimits);
09661       ASTOBJ_UNLOCK(iterator);
09662    } while (0) );
09663 
09664    ast_cli(fd, FORMAT, "* Peer name", "In use", "Limit");
09665 
09666    ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do {
09667       ASTOBJ_RDLOCK(iterator);
09668       if (iterator->call_limit)
09669          snprintf(ilimits, sizeof(ilimits), "%d", iterator->call_limit);
09670       else 
09671          ast_copy_string(ilimits, "N/A", sizeof(ilimits));
09672       snprintf(iused, sizeof(iused), "%d/%d", iterator->inUse, iterator->inRinging);
09673       if (showall || iterator->call_limit)
09674          ast_cli(fd, FORMAT2, iterator->name, iused, ilimits);
09675       ASTOBJ_UNLOCK(iterator);
09676    } while (0) );
09677 
09678    return RESULT_SUCCESS;
09679 #undef FORMAT
09680 #undef FORMAT2
09681 }

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

List all allocated SIP Objects (realtime or static).

Definition at line 9958 of file chan_sip.c.

References ast_cli(), ASTOBJ_CONTAINER_DUMP, peerl, regl, RESULT_SHOWUSAGE, RESULT_SUCCESS, and userl.

09959 {
09960    char tmp[256];
09961    if (argc != 3)
09962       return RESULT_SHOWUSAGE;
09963    ast_cli(fd, "-= User objects: %d static, %d realtime =-\n\n", suserobjs, ruserobjs);
09964    ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), &userl);
09965    ast_cli(fd, "-= Peer objects: %d static, %d realtime, %d autocreate =-\n\n", speerobjs, rpeerobjs, apeerobjs);
09966    ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), &peerl);
09967    ast_cli(fd, "-= Registry objects: %d =-\n\n", regobjs);
09968    ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), &regl);
09969    return RESULT_SUCCESS;
09970 }

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

Show one peer in detail.

Definition at line 10264 of file chan_sip.c.

References _sip_show_peer().

10265 {
10266    return _sip_show_peer(0, fd, NULL, NULL, argc, (const char **) argv);
10267 }

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

CLI Show Peers command.

Definition at line 9814 of file chan_sip.c.

References _sip_show_peers().

09815 {
09816    return _sip_show_peers(fd, NULL, NULL, NULL, argc, (const char **) argv);
09817 }

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

Show SIP Registry (registrations with other SIP proxies.

Definition at line 10537 of file chan_sip.c.

References ast_cli(), ast_localtime(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, FORMAT, FORMAT2, regl, regstate2str(), RESULT_SHOWUSAGE, RESULT_SUCCESS, and STANDARD_SIP_PORT.

10538 {
10539 #define FORMAT2 "%-30.30s  %-12.12s  %8.8s %-20.20s %-25.25s\n"
10540 #define FORMAT  "%-30.30s  %-12.12s  %8d %-20.20s %-25.25s\n"
10541    char host[80];
10542    char tmpdat[256];
10543    struct tm tm;
10544 
10545 
10546    if (argc != 3)
10547       return RESULT_SHOWUSAGE;
10548    ast_cli(fd, FORMAT2, "Host", "Username", "Refresh", "State", "Reg.Time");
10549    ASTOBJ_CONTAINER_TRAVERSE(&regl, 1, do {
10550       ASTOBJ_RDLOCK(iterator);
10551       snprintf(host, sizeof(host), "%s:%d", iterator->hostname, iterator->portno ? iterator->portno : STANDARD_SIP_PORT);
10552       if (iterator->regtime) {
10553          ast_localtime(&iterator->regtime, &tm, NULL);
10554          strftime(tmpdat, sizeof(tmpdat), "%a, %d %b %Y %T", &tm);
10555       } else {
10556          tmpdat[0] = 0;
10557       }
10558       ast_cli(fd, FORMAT, host, iterator->username, iterator->refresh, regstate2str(iterator->regstate), tmpdat);
10559       ASTOBJ_UNLOCK(iterator);
10560    } while(0));
10561    return RESULT_SUCCESS;
10562 #undef FORMAT
10563 #undef FORMAT2
10564 }

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

List global settings for the SIP channel.

Definition at line 10567 of file chan_sip.c.

References ast_check_realtime(), ast_cli(), ast_getformatname_multiple(), ast_inet_ntoa(), AST_LIST_EMPTY, ast_test_flag, ast_tos2str(), authl, bindaddr, default_prefs, dtmfmode2str(), nat2str(), print_codec_to_cli(), RESULT_SHOWUSAGE, RESULT_SUCCESS, S_OR, SIP_DTMF, SIP_NAT, SIP_PAGE2_ALLOWOVERLAP, SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PAGE2_IGNOREREGEXPIRE, SIP_PAGE2_RFC2833_COMPENSATE, SIP_PAGE2_RTCACHEFRIENDS, SIP_PAGE2_RTSAVE_SYSNAME, SIP_PAGE2_RTUPDATE, SIP_PAGE2_T38SUPPORT_RTP, SIP_PAGE2_T38SUPPORT_TCP, SIP_PAGE2_T38SUPPORT_UDPTL, SIP_PAGE2_VIDEOSUPPORT, SIP_PROG_INBAND, SIP_PROG_INBAND_NEVER, SIP_PROG_INBAND_NO, SIP_PROMISCREDIR, SIP_USECLIENTCODE, SIP_USEREQPHONE, and transfermode2str().

10568 {
10569    int realtimepeers;
10570    int realtimeusers;
10571    char codec_buf[BUFSIZ];
10572 
10573    realtimepeers = ast_check_realtime("sippeers");
10574    realtimeusers = ast_check_realtime("sipusers");
10575 
10576    if (argc != 3)
10577       return RESULT_SHOWUSAGE;
10578    ast_cli(fd, "\n\nGlobal Settings:\n");
10579    ast_cli(fd, "----------------\n");
10580    ast_cli(fd, "  SIP Port:               %d\n", ntohs(bindaddr.sin_port));
10581    ast_cli(fd, "  Bindaddress:            %s\n", ast_inet_ntoa(bindaddr.sin_addr));
10582    ast_cli(fd, "  Videosupport:           %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_VIDEOSUPPORT) ? "Yes" : "No");
10583    ast_cli(fd, "  AutoCreatePeer:         %s\n", autocreatepeer ? "Yes" : "No");
10584    ast_cli(fd, "  Allow unknown access:   %s\n", global_allowguest ? "Yes" : "No");
10585    ast_cli(fd, "  Allow subscriptions:    %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWSUBSCRIBE) ? "Yes" : "No");
10586    ast_cli(fd, "  Allow overlap dialing:  %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP) ? "Yes" : "No");
10587    ast_cli(fd, "  Promsic. redir:         %s\n", ast_test_flag(&global_flags[0], SIP_PROMISCREDIR) ? "Yes" : "No");
10588    ast_cli(fd, "  SIP domain support:     %s\n", AST_LIST_EMPTY(&domain_list) ? "No" : "Yes");
10589    ast_cli(fd, "  Call to non-local dom.: %s\n", allow_external_domains ? "Yes" : "No");
10590    ast_cli(fd, "  URI user is phone no:   %s\n", ast_test_flag(&global_flags[0], SIP_USEREQPHONE) ? "Yes" : "No");
10591    ast_cli(fd, "  Our auth realm          %s\n", global_realm);
10592    ast_cli(fd, "  Realm. auth:            %s\n", authl ? "Yes": "No");
10593    ast_cli(fd, "  Always auth rejects:    %s\n", global_alwaysauthreject ? "Yes" : "No");
10594    ast_cli(fd, "  Call limit peers only:  %s\n", global_limitonpeers ? "Yes" : "No");
10595    ast_cli(fd, "  Direct RTP setup:       %s\n", global_directrtpsetup ? "Yes" : "No");
10596    ast_cli(fd, "  User Agent:             %s\n", global_useragent);
10597    ast_cli(fd, "  MWI checking interval:  %d secs\n", global_mwitime);
10598    ast_cli(fd, "  Reg. context:           %s\n", S_OR(global_regcontext, "(not set)"));
10599    ast_cli(fd, "  Caller ID:              %s\n", default_callerid);
10600    ast_cli(fd, "  From: Domain:           %s\n", default_fromdomain);
10601    ast_cli(fd, "  Record SIP history:     %s\n", recordhistory ? "On" : "Off");
10602    ast_cli(fd, "  Call Events:            %s\n", global_callevents ? "On" : "Off");
10603    ast_cli(fd, "  IP ToS SIP:             %s\n", ast_tos2str(global_tos_sip));
10604    ast_cli(fd, "  IP ToS RTP audio:       %s\n", ast_tos2str(global_tos_audio));
10605    ast_cli(fd, "  IP ToS RTP video:       %s\n", ast_tos2str(global_tos_video));
10606    ast_cli(fd, "  T38 fax pt UDPTL:       %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT_UDPTL) ? "Yes" : "No");
10607 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS
10608    ast_cli(fd, "  T38 fax pt RTP:         %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT_RTP) ? "Yes" : "No");
10609    ast_cli(fd, "  T38 fax pt TCP:         %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT_TCP) ? "Yes" : "No");
10610 #endif
10611    ast_cli(fd, "  RFC2833 Compensation:   %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RFC2833_COMPENSATE) ? "Yes" : "No");
10612    if (!realtimepeers && !realtimeusers)
10613       ast_cli(fd, "  SIP realtime:           Disabled\n" );
10614    else
10615       ast_cli(fd, "  SIP realtime:           Enabled\n" );
10616 
10617    ast_cli(fd, "\nGlobal Signalling Settings:\n");
10618    ast_cli(fd, "---------------------------\n");
10619    ast_cli(fd, "  Codecs:                 ");
10620    ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, global_capability);
10621    ast_cli(fd, "%s\n", codec_buf);
10622    ast_cli(fd, "  Codec Order:            ");
10623    print_codec_to_cli(fd, &default_prefs);
10624    ast_cli(fd, "\n");
10625    ast_cli(fd, "  T1 minimum:             %d\n", global_t1min);
10626    ast_cli(fd, "  Relax DTMF:             %s\n", global_relaxdtmf ? "Yes" : "No");
10627    ast_cli(fd, "  Compact SIP headers:    %s\n", compactheaders ? "Yes" : "No");
10628    ast_cli(fd, "  RTP Keepalive:          %d %s\n", global_rtpkeepalive, global_rtpkeepalive ? "" : "(Disabled)" );
10629    ast_cli(fd, "  RTP Timeout:            %d %s\n", global_rtptimeout, global_rtptimeout ? "" : "(Disabled)" );
10630    ast_cli(fd, "  RTP Hold Timeout:       %d %s\n", global_rtpholdtimeout, global_rtpholdtimeout ? "" : "(Disabled)");
10631    ast_cli(fd, "  MWI NOTIFY mime type:   %s\n", default_notifymime);
10632    ast_cli(fd, "  DNS SRV lookup:         %s\n", srvlookup ? "Yes" : "No");
10633    ast_cli(fd, "  Pedantic SIP support:   %s\n", pedanticsipchecking ? "Yes" : "No");
10634    ast_cli(fd, "  Reg. min duration       %d secs\n", min_expiry);
10635    ast_cli(fd, "  Reg. max duration:      %d secs\n", max_expiry);
10636    ast_cli(fd, "  Reg. default duration:  %d secs\n", default_expiry);
10637    ast_cli(fd, "  Outbound reg. timeout:  %d secs\n", global_reg_timeout);
10638    ast_cli(fd, "  Outbound reg. attempts: %d\n", global_regattempts_max);
10639    ast_cli(fd, "  Notify ringing state:   %s\n", global_notifyringing ? "Yes" : "No");
10640    ast_cli(fd, "  Notify hold state:      %s\n", global_notifyhold ? "Yes" : "No");
10641    ast_cli(fd, "  SIP Transfer mode:      %s\n", transfermode2str(global_allowtransfer));
10642    ast_cli(fd, "  Max Call Bitrate:       %d kbps\r\n", default_maxcallbitrate);
10643    ast_cli(fd, "  Auto-Framing:           %s \r\n", global_autoframing ? "Yes" : "No");
10644    ast_cli(fd, "\nDefault Settings:\n");
10645    ast_cli(fd, "-----------------\n");
10646    ast_cli(fd, "  Context:                %s\n", default_context);
10647    ast_cli(fd, "  Nat:                    %s\n", nat2str(ast_test_flag(&global_flags[0], SIP_NAT)));
10648    ast_cli(fd, "  DTMF:                   %s\n", dtmfmode2str(ast_test_flag(&global_flags[0], SIP_DTMF)));
10649    ast_cli(fd, "  Qualify:                %d\n", default_qualify);
10650    ast_cli(fd, "  Use ClientCode:         %s\n", ast_test_flag(&global_flags[0], SIP_USECLIENTCODE) ? "Yes" : "No");
10651    ast_cli(fd, "  Progress inband:        %s\n", (ast_test_flag(&global_flags[0], SIP_PROG_INBAND) == SIP_PROG_INBAND_NEVER) ? "Never" : (ast_test_flag(&global_flags[0], SIP_PROG_INBAND) == SIP_PROG_INBAND_NO) ? "No" : "Yes" );
10652    ast_cli(fd, "  Language:               %s\n", S_OR(default_language, "(Defaults to English)"));
10653    ast_cli(fd, "  MOH Interpret:          %s\n", default_mohinterpret);
10654    ast_cli(fd, "  MOH Suggest:            %s\n", default_mohsuggest);
10655    ast_cli(fd, "  Voice Mail Extension:   %s\n", default_vmexten);
10656 
10657    
10658    if (realtimepeers || realtimeusers) {
10659       ast_cli(fd, "\nRealtime SIP Settings:\n");
10660       ast_cli(fd, "----------------------\n");
10661       ast_cli(fd, "  Realtime Peers:         %s\n", realtimepeers ? "Yes" : "No");
10662       ast_cli(fd, "  Realtime Users:         %s\n", realtimeusers ? "Yes" : "No");
10663       ast_cli(fd, "  Cache Friends:          %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS) ? "Yes" : "No");
10664       ast_cli(fd, "  Update:                 %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RTUPDATE) ? "Yes" : "No");
10665       ast_cli(fd, "  Ignore Reg. Expire:     %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_IGNOREREGEXPIRE) ? "Yes" : "No");
10666       ast_cli(fd, "  Save sys. name:         %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RTSAVE_SYSNAME) ? "Yes" : "No");
10667       ast_cli(fd, "  Auto Clear:             %d\n", global_rtautoclear);
10668    }
10669    ast_cli(fd, "\n----\n");
10670    return RESULT_SUCCESS;
10671 }

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

Show active SIP subscriptions.

Definition at line 10706 of file chan_sip.c.

References __sip_show_channels().

10707 {
10708         return __sip_show_channels(fd, argc, argv, 1);
10709 }

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

Show one user in detail.

Definition at line 10482 of file chan_sip.c.

References sip_user::accountcode, sip_user::allowtransfer, sip_user::amaflags, ast_callerid_merge(), ast_cdr_flags2str(), ast_cli(), ast_describe_caller_presentation(), ast_strlen_zero(), ASTOBJ_UNREF, sip_user::autoframing, sip_user::call_limit, sip_user::callgroup, sip_user::callingpres, sip_user::chanvars, sip_user::cid_name, sip_user::cid_num, sip_user::context, FALSE, find_user(), sip_user::ha, sip_user::language, sip_user::maxcallbitrate, sip_user::md5secret, ast_variable::name, ast_variable::next, sip_user::pickupgroup, sip_user::prefs, print_codec_to_cli(), print_group(), RESULT_SHOWUSAGE, RESULT_SUCCESS, sip_user::secret, sip_destroy_user(), transfermode2str(), TRUE, and ast_variable::value.

10483 {
10484    char cbuf[256];
10485    struct sip_user *user;
10486    struct ast_variable *v;
10487    int load_realtime;
10488 
10489    if (argc < 4)
10490       return RESULT_SHOWUSAGE;
10491 
10492    /* Load from realtime storage? */
10493    load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? TRUE : FALSE;
10494 
10495    user = find_user(argv[3], load_realtime);
10496    if (user) {
10497       ast_cli(fd,"\n\n");
10498       ast_cli(fd, "  * Name       : %s\n", user->name);
10499       ast_cli(fd, "  Secret       : %s\n", ast_strlen_zero(user->secret)?"<Not set>":"<Set>");
10500       ast_cli(fd, "  MD5Secret    : %s\n", ast_strlen_zero(user->md5secret)?"<Not set>":"<Set>");
10501       ast_cli(fd, "  Context      : %s\n", user->context);
10502       ast_cli(fd, "  Language     : %s\n", user->language);
10503       if (!ast_strlen_zero(user->accountcode))
10504          ast_cli(fd, "  Accountcode  : %s\n", user->accountcode);
10505       ast_cli(fd, "  AMA flags    : %s\n", ast_cdr_flags2str(user->amaflags));
10506       ast_cli(fd, "  Transfer mode: %s\n", transfermode2str(user->allowtransfer));
10507       ast_cli(fd, "  MaxCallBR    : %d kbps\n", user->maxcallbitrate);
10508       ast_cli(fd, "  CallingPres  : %s\n", ast_describe_caller_presentation(user->callingpres));
10509       ast_cli(fd, "  Call limit   : %d\n", user->call_limit);
10510       ast_cli(fd, "  Callgroup    : ");
10511       print_group(fd, user->callgroup, 0);
10512       ast_cli(fd, "  Pickupgroup  : ");
10513       print_group(fd, user->pickupgroup, 0);
10514       ast_cli(fd, "  Callerid     : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), user->cid_name, user->cid_num, "<unspecified>"));
10515       ast_cli(fd, "  ACL          : %s\n", (user->ha?"Yes":"No"));
10516       ast_cli(fd, "  Codec Order  : (");
10517       print_codec_to_cli(fd, &user->prefs);
10518       ast_cli(fd, ")\n");
10519 
10520       ast_cli(fd, "  Auto-Framing:  %s \n", user->autoframing ? "Yes" : "No");
10521       if (user->chanvars) {
10522          ast_cli(fd, "  Variables    :\n");
10523          for (v = user->chanvars ; v ; v = v->next)
10524             ast_cli(fd, "                 %s = %s\n", v->name, v->value);
10525       }
10526       ast_cli(fd,"\n");
10527       ASTOBJ_UNREF(user,sip_destroy_user);
10528    } else {
10529       ast_cli(fd,"User %s not found.\n", argv[3]);
10530       ast_cli(fd,"\n");
10531    }
10532 
10533    return RESULT_SUCCESS;
10534 }

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

CLI Command 'SIP Show Users'.

Definition at line 9737 of file chan_sip.c.

References ast_cli(), ast_test_flag, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, FALSE, FORMAT, nat2str(), RESULT_SHOWUSAGE, RESULT_SUCCESS, SIP_NAT, TRUE, and userl.

09738 {
09739    regex_t regexbuf;
09740    int havepattern = FALSE;
09741 
09742 #define FORMAT  "%-25.25s  %-15.15s  %-15.15s  %-15.15s  %-5.5s%-10.10s\n"
09743 
09744    switch (argc) {
09745    case 5:
09746       if (!strcasecmp(argv[3], "like")) {
09747          if (regcomp(&regexbuf, argv[4], REG_EXTENDED | REG_NOSUB))
09748             return RESULT_SHOWUSAGE;
09749          havepattern = TRUE;
09750       } else
09751          return RESULT_SHOWUSAGE;
09752    case 3:
09753       break;
09754    default:
09755       return RESULT_SHOWUSAGE;
09756    }
09757 
09758    ast_cli(fd, FORMAT, "Username", "Secret", "Accountcode", "Def.Context", "ACL", "NAT");
09759    ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do {
09760       ASTOBJ_RDLOCK(iterator);
09761 
09762       if (havepattern && regexec(&regexbuf, iterator->name, 0, NULL, 0)) {
09763          ASTOBJ_UNLOCK(iterator);
09764          continue;
09765       }
09766 
09767       ast_cli(fd, FORMAT, iterator->name, 
09768          iterator->secret, 
09769          iterator->accountcode,
09770          iterator->context,
09771          iterator->ha ? "Yes" : "No",
09772          nat2str(ast_test_flag(&iterator->flags[0], SIP_NAT)));
09773       ASTOBJ_UNLOCK(iterator);
09774    } while (0)
09775    );
09776 
09777    if (havepattern)
09778       regfree(&regexbuf);
09779 
09780    return RESULT_SUCCESS;
09781 #undef FORMAT
09782 }

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

Transfer call before connect with a 302 redirect.

Note:
Called by the transfer() dialplan application through the sip_transfer() pbx interface function if the call is in ringing state
Todo:
Fix this function so that we wait for reply to the REFER and react to errors, denials or other issues the other end might have.

Definition at line 17642 of file chan_sip.c.

References ast_log(), ast_strdupa, ast_string_field_build, ast_strlen_zero(), get_header(), sip_pvt::initreq, LOG_ERROR, sip_alreadygone(), sip_scheddestroy(), SIP_TRANS_TIMEOUT, strcasestr(), strsep(), and transmit_response_reliable().

Referenced by sip_transfer().

17643 {
17644    char *cdest;
17645    char *extension, *host, *port;
17646    char tmp[80];
17647    
17648    cdest = ast_strdupa(dest);
17649    
17650    extension = strsep(&cdest, "@");
17651    host = strsep(&cdest, ":");
17652    port = strsep(&cdest, ":");
17653    if (ast_strlen_zero(extension)) {
17654       ast_log(LOG_ERROR, "Missing mandatory argument: extension\n");
17655       return 0;
17656    }
17657 
17658    /* we'll issue the redirect message here */
17659    if (!host) {
17660       char *localtmp;
17661       ast_copy_string(tmp, get_header(&p->initreq, "To"), sizeof(tmp));
17662       if (ast_strlen_zero(tmp)) {
17663          ast_log(LOG_ERROR, "Cannot retrieve the 'To' header from the original SIP request!\n");
17664          return 0;
17665       }
17666       if ((localtmp = strcasestr(tmp, "sip:")) && (localtmp = strchr(localtmp, '@'))) {
17667          char lhost[80], lport[80];
17668          memset(lhost, 0, sizeof(lhost));
17669          memset(lport, 0, sizeof(lport));
17670          localtmp++;
17671          /* This is okey because lhost and lport are as big as tmp */
17672          sscanf(localtmp, "%[^<>:; ]:%[^<>:; ]", lhost, lport);
17673          if (ast_strlen_zero(lhost)) {
17674             ast_log(LOG_ERROR, "Can't find the host address\n");
17675             return 0;
17676          }
17677          host = ast_strdupa(lhost);
17678          if (!ast_strlen_zero(lport)) {
17679             port = ast_strdupa(lport);
17680          }
17681       }
17682    }
17683 
17684    ast_string_field_build(p, our_contact, "Transfer <sip:%s@%s%s%s>", extension, host, port ? ":" : "", port ? port : "");
17685    transmit_response_reliable(p, "302 Moved Temporarily", &p->initreq);
17686 
17687    sip_scheddestroy(p, SIP_TRANS_TIMEOUT);   /* Make sure we stop send this reply. */
17688    sip_alreadygone(p);
17689    return 0;
17690 }

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

Transfer SIP call.

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

03829 {
03830    struct sip_pvt *p = ast->tech_pvt;
03831    int res;
03832 
03833    if (dest == NULL) /* functions below do not take a NULL */
03834       dest = "";
03835    ast_mutex_lock(&p->lock);
03836    if (ast->_state == AST_STATE_RING)
03837       res = sip_sipredirect(p, dest);
03838    else
03839       res = transmit_refer(p, dest);
03840    ast_mutex_unlock(&p->lock);
03841    return res;
03842 }

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

Send frame to media channel (rtp).

Definition at line 3663 of file chan_sip.c.

References ast_channel::_state, AST_FORMAT_AUDIO_MASK, AST_FRAME_IMAGE, AST_FRAME_MODEM, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_getformatname_multiple(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_rtp_write(), ast_set_flag, AST_STATE_UP, ast_test_flag, ast_udptl_write(), sip_pvt::flags, 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::udptl, sip_pvt::vrtp, ast_channel::writeformat, and XMIT_UNRELIABLE.

03664 {
03665    struct sip_pvt *p = ast->tech_pvt;
03666    int res = 0;
03667 
03668    switch (frame->frametype) {
03669    case AST_FRAME_VOICE:
03670       if (!(frame->subclass & ast->nativeformats)) {
03671          char s1[512], s2[512], s3[512];
03672          ast_log(LOG_WARNING, "Asked to transmit frame type %d, while native formats is %s(%d) read/write = %s(%d)/%s(%d)\n",
03673             frame->subclass, 
03674             ast_getformatname_multiple(s1, sizeof(s1) - 1, ast->nativeformats & AST_FORMAT_AUDIO_MASK),
03675             ast->nativeformats & AST_FORMAT_AUDIO_MASK,
03676             ast_getformatname_multiple(s2, sizeof(s2) - 1, ast->readformat),
03677             ast->readformat,
03678             ast_getformatname_multiple(s3, sizeof(s3) - 1, ast->writeformat),
03679             ast->writeformat);
03680          return 0;
03681       }
03682       if (p) {
03683          ast_mutex_lock(&p->lock);
03684          if (p->rtp) {
03685             /* If channel is not up, activate early media session */
03686             if ((ast->_state != AST_STATE_UP) &&
03687                 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) &&
03688                 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
03689                transmit_response_with_sdp(p, "183 Session Progress", &p->initreq, XMIT_UNRELIABLE);
03690                ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT);  
03691             }
03692             p->lastrtptx = time(NULL);
03693             res = ast_rtp_write(p->rtp, frame);
03694          }
03695          ast_mutex_unlock(&p->lock);
03696       }
03697       break;
03698    case AST_FRAME_VIDEO:
03699       if (p) {
03700          ast_mutex_lock(&p->lock);
03701          if (p->vrtp) {
03702             /* Activate video early media */
03703             if ((ast->_state != AST_STATE_UP) &&
03704                 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) &&
03705                 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
03706                transmit_response_with_sdp(p, "183 Session Progress", &p->initreq, XMIT_UNRELIABLE);
03707                ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT);  
03708             }
03709             p->lastrtptx = time(NULL);
03710             res = ast_rtp_write(p->vrtp, frame);
03711          }
03712          ast_mutex_unlock(&p->lock);
03713       }
03714       break;
03715    case AST_FRAME_IMAGE:
03716       return 0;
03717       break;
03718    case AST_FRAME_MODEM:
03719       if (p) {
03720          ast_mutex_lock(&p->lock);
03721          /* UDPTL requires two-way communication, so early media is not needed here.
03722             we simply forget the frames if we get modem frames before the bridge is up.
03723             Fax will re-transmit.
03724          */
03725          if (p->udptl && ast->_state == AST_STATE_UP) 
03726             res = ast_udptl_write(p->udptl, frame);
03727          ast_mutex_unlock(&p->lock);
03728       }
03729       break;
03730    default: 
03731       ast_log(LOG_WARNING, "Can't send %d type frames with SIP write\n", frame->frametype);
03732       return 0;
03733    }
03734 
03735    return res;
03736 }

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

Read data from SIP socket.

Note:
sipsock_read locks the owner channel while we are processing the SIP message
Returns:
1 on error, 0 on success
Note:
Successful messages is connected to SIP call and forwarded to handle_request()

Definition at line 15291 of file chan_sip.c.

References append_history, ast_channel_trylock, ast_channel_unlock, ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_test_flag, ast_update_use_count(), ast_verbose(), sip_request::data, errno, find_call(), find_sip_method(), sip_pvt::flags, get_header(), handle_request(), sip_request::headers, sip_request::len, len, sip_request::lines, sip_pvt::lock, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, LOG_WARNING, lws2sws(), sip_request::method, option_debug, sip_pvt::owner, parse_request(), sip_pvt::recv, sip_request::rlPart1, sip_request::rlPart2, S_OR, SIP_ACK, sip_debug_test_addr(), SIP_NO_HISTORY, SIP_PKT_DEBUG, sipsock, and transmit_response().

Referenced by do_monitor().

15292 {
15293    struct sip_request req;
15294    struct sockaddr_in sin = { 0, };
15295    struct sip_pvt *p;
15296    int res;
15297    socklen_t len = sizeof(sin);
15298    int nounlock;
15299    int recount = 0;
15300    int lockretry;
15301 
15302    memset(&req, 0, sizeof(req));
15303    res = recvfrom(sipsock, req.data, sizeof(req.data) - 1, 0, (struct sockaddr *)&sin, &len);
15304    if (res < 0) {
15305 #if !defined(__FreeBSD__)
15306       if (errno == EAGAIN)
15307          ast_log(LOG_NOTICE, "SIP: Received packet with bad UDP checksum\n");
15308       else 
15309 #endif
15310       if (errno != ECONNREFUSED)
15311          ast_log(LOG_WARNING, "Recv error: %s\n", strerror(errno));
15312       return 1;
15313    }
15314    if (option_debug && res == sizeof(req.data)) {
15315       ast_log(LOG_DEBUG, "Received packet exceeds buffer. Data is possibly lost\n");
15316       req.data[sizeof(req.data) - 1] = '\0';
15317    } else
15318       req.data[res] = '\0';
15319    req.len = res;
15320    if(sip_debug_test_addr(&sin)) /* Set the debug flag early on packet level */
15321       ast_set_flag(&req, SIP_PKT_DEBUG);
15322    if (pedanticsipchecking)
15323       req.len = lws2sws(req.data, req.len);  /* Fix multiline headers */
15324    if (ast_test_flag(&req, SIP_PKT_DEBUG))
15325       ast_verbose("\n<--- SIP read from %s:%d --->\n%s\n<------------->\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port), req.data);
15326 
15327    parse_request(&req);
15328    req.method = find_sip_method(req.rlPart1);
15329 
15330    if (ast_test_flag(&req, SIP_PKT_DEBUG))
15331       ast_verbose("--- (%d headers %d lines)%s ---\n", req.headers, req.lines, (req.headers + req.lines == 0) ? " Nat keepalive" : "");
15332 
15333    if (req.headers < 2) /* Must have at least two headers */
15334       return 1;
15335 
15336    /* Process request, with netlock held, and with usual deadlock avoidance */
15337    for (lockretry = 100; lockretry > 0; lockretry--) {
15338       ast_mutex_lock(&netlock);
15339 
15340       /* Find the active SIP dialog or create a new one */
15341       p = find_call(&req, &sin, req.method); /* returns p locked */
15342       if (p == NULL) {
15343          if (option_debug)
15344             ast_log(LOG_DEBUG, "Invalid SIP message - rejected , no callid, len %d\n", req.len);
15345          ast_mutex_unlock(&netlock);
15346          return 1;
15347       }
15348       /* Go ahead and lock the owner if it has one -- we may need it */
15349       /* becaues this is deadlock-prone, we need to try and unlock if failed */
15350       if (!p->owner || !ast_channel_trylock(p->owner))
15351          break;   /* locking succeeded */
15352       if (option_debug)
15353          ast_log(LOG_DEBUG, "Failed to grab owner channel lock, trying again. (SIP call %s)\n", p->callid);
15354       ast_mutex_unlock(&p->lock);
15355       ast_mutex_unlock(&netlock);
15356       /* Sleep for a very short amount of time */
15357       usleep(1);
15358    }
15359    p->recv = sin;
15360 
15361    if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) /* This is a request or response, note what it was for */
15362       append_history(p, "Rx", "%s / %s / %s", req.data, get_header(&req, "CSeq"), req.rlPart2);
15363 
15364    if (!lockretry) {
15365       if (p->owner)
15366          ast_log(LOG_ERROR, "We could NOT get the channel lock for %s! \n", S_OR(p->owner->name, "- no channel name ??? - "));
15367       ast_log(LOG_ERROR, "SIP transaction failed: %s \n", p->callid);
15368       if (req.method != SIP_ACK)
15369          transmit_response(p, "503 Server error", &req); /* We must respond according to RFC 3261 sec 12.2 */
15370       /* XXX We could add retry-after to make sure they come back */
15371       append_history(p, "LockFail", "Owner lock failed, transaction failed.");
15372       return 1;
15373    }
15374    nounlock = 0;
15375    if (handle_request(p, &req, &sin, &recount, &nounlock) == -1) {
15376       /* Request failed */
15377       if (option_debug)
15378          ast_log(LOG_DEBUG, "SIP message could not be handled, bad request: %-70.70s\n", p->callid[0] ? p->callid : "<no callid>");
15379    }
15380       
15381    if (p->owner && !nounlock)
15382       ast_channel_unlock(p->owner);
15383    ast_mutex_unlock(&p->lock);
15384    ast_mutex_unlock(&netlock);
15385    if (recount)
15386       ast_update_use_count();
15387 
15388    return 1;
15389 }

static void stop_media_flows ( struct sip_pvt p  )  [static]

Immediately stop RTP, VRTP and UDPTL as applicable.

Definition at line 12542 of file chan_sip.c.

References ast_rtp_stop(), ast_udptl_stop(), sip_pvt::rtp, sip_pvt::udptl, and sip_pvt::vrtp.

Referenced by handle_request_bye(), handle_request_cancel(), handle_response(), and sip_hangup().

12543 {
12544    /* Immediately stop RTP, VRTP and UDPTL as applicable */
12545    if (p->rtp)
12546       ast_rtp_stop(p->rtp);
12547    if (p->vrtp)
12548       ast_rtp_stop(p->vrtp);
12549    if (p->udptl)
12550       ast_udptl_stop(p->udptl);
12551 }

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

Show subscription type in string format.

Definition at line 10674 of file chan_sip.c.

References subscription_types, cfsubscription_types::text, and type.

Referenced by __sip_show_channels(), and sip_show_channel().

10675 {
10676    int i;
10677 
10678    for (i = 1; (i < (sizeof(subscription_types) / sizeof(subscription_types[0]))); i++) {
10679       if (subscription_types[i].type == subtype) {
10680          return subscription_types[i].text;
10681       }
10682    }
10683    return subscription_types[0].text;
10684 }

static int t38_get_rate ( int  t38cap  )  [static]

Get Max T.38 Transmission rate from T38 capabilities.

Definition at line 6202 of file chan_sip.c.

References ast_log(), LOG_DEBUG, option_debug, T38FAX_RATE_12000, T38FAX_RATE_14400, T38FAX_RATE_2400, T38FAX_RATE_4800, T38FAX_RATE_7200, and T38FAX_RATE_9600.

Referenced by add_t38_sdp().

06203 {
06204    int maxrate = (t38cap & (T38FAX_RATE_14400 | T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400));
06205    
06206    if (maxrate & T38FAX_RATE_14400) {
06207       if (option_debug > 1)
06208          ast_log(LOG_DEBUG, "T38MaxFaxRate 14400 found\n");
06209       return 14400;
06210    } else if (maxrate & T38FAX_RATE_12000) {
06211       if (option_debug > 1)
06212          ast_log(LOG_DEBUG, "T38MaxFaxRate 12000 found\n");
06213       return 12000;
06214    } else if (maxrate & T38FAX_RATE_9600) {
06215       if (option_debug > 1)
06216          ast_log(LOG_DEBUG, "T38MaxFaxRate 9600 found\n");
06217       return 9600;
06218    } else if (maxrate & T38FAX_RATE_7200) {
06219       if (option_debug > 1)
06220          ast_log(LOG_DEBUG, "T38MaxFaxRate 7200 found\n");
06221       return 7200;
06222    } else if (maxrate & T38FAX_RATE_4800) {
06223       if (option_debug > 1)
06224          ast_log(LOG_DEBUG, "T38MaxFaxRate 4800 found\n");
06225       return 4800;
06226    } else if (maxrate & T38FAX_RATE_2400) {
06227       if (option_debug > 1)
06228          ast_log(LOG_DEBUG, "T38MaxFaxRate 2400 found\n");
06229       return 2400;
06230    } else {
06231       if (option_debug > 1)
06232          ast_log(LOG_DEBUG, "Strange, T38MaxFaxRate NOT found in peers T38 SDP.\n");
06233       return 0;
06234    }
06235 }

static struct sip_peer * temp_peer ( const char *  name  )  [static, read]

Create temporary peer (used in autocreatepeer mode).

Definition at line 16404 of file chan_sip.c.

References ast_calloc, ast_set_flag, ASTOBJ_INIT, default_prefs, sip_peer::flags, sip_peer::prefs, reg_source_db(), set_peer_defaults(), SIP_PAGE2_DYNAMIC, and SIP_PAGE2_SELFDESTRUCT.

Referenced by register_verify().

16405 {
16406    struct sip_peer *peer;
16407 
16408    if (!(peer = ast_calloc(1, sizeof(*peer))))
16409       return NULL;
16410 
16411    apeerobjs++;
16412    ASTOBJ_INIT(peer);
16413    set_peer_defaults(peer);
16414 
16415    ast_copy_string(peer->name, name, sizeof(peer->name));
16416 
16417    ast_set_flag(&peer->flags[1], SIP_PAGE2_SELFDESTRUCT);
16418    ast_set_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC);
16419    peer->prefs = default_prefs;
16420    reg_source_db(peer);
16421 
16422    return peer;
16423 }

static void temp_pvt_cleanup ( void *  data  )  [static]

Definition at line 5978 of file chan_sip.c.

References ast_string_field_free_memory, and free.

05979 {
05980    struct sip_pvt *p = data;
05981 
05982    ast_string_field_free_memory(p);
05983 
05984    free(data);
05985 }

static char * transfermode2str ( enum transfermodes  mode  )  [static]

Convert transfer mode to text string.

Definition at line 9684 of file chan_sip.c.

References TRANSFER_CLOSED, and TRANSFER_OPENFORALL.

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

09685 {
09686    if (mode == TRANSFER_OPENFORALL)
09687       return "open";
09688    else if (mode == TRANSFER_CLOSED)
09689       return "closed";
09690    return "strict";
09691 }

static void transmit_fake_auth_response ( struct sip_pvt p,
struct sip_request req,
int  reliable 
) [static]

Send a fake 401 Unauthorized response when the administrator wants to hide the names of local users/peers from fishers.

Definition at line 8505 of file chan_sip.c.

References ast_random(), ast_string_field_build, and transmit_response_with_auth().

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

08506 {
08507    ast_string_field_build(p, randdata, "%08lx", ast_random()); /* Create nonce for challenge */
08508    transmit_response_with_auth(p, "401 Unauthorized", req, p->randdata, reliable, "WWW-Authenticate", 0);
08509 }

static int transmit_info_with_digit ( struct sip_pvt p,
const char  digit,
unsigned int  duration 
) [static]

Send SIP INFO dtmf message, see Cisco documentation on cisco.com.

Definition at line 7744 of file chan_sip.c.

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

Referenced by sip_senddigit_end().

07745 {
07746    struct sip_request req;
07747 
07748    reqprep(&req, p, SIP_INFO, 0, 1);
07749    add_digit(&req, digit, duration);
07750    return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
07751 }

static int transmit_info_with_vidupdate ( struct sip_pvt p  )  [static]

Send SIP INFO with video update request.

Definition at line 7754 of file chan_sip.c.

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

Referenced by sip_indicate().

07755 {
07756    struct sip_request req;
07757 
07758    reqprep(&req, p, SIP_INFO, 0, 1);
07759    add_vidupdate(&req);
07760    return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
07761 }

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

Build REFER/INVITE/OPTIONS message and transmit it.

Definition at line 7004 of file chan_sip.c.

References add_header(), add_header_contentLength(), add_sdp(), add_t38_sdp(), sip_invite_param::addsipheaders, ALLOWED_METHODS, append_date(), ast_channel_lock, ast_channel_unlock, AST_LIST_TRAVERSE, ast_log(), ast_random(), ast_strdupa, ast_strlen_zero(), ast_udptl_offered_from_local(), ast_var_name(), ast_var_value(), sip_invite_param::auth, sip_invite_param::authheader, sip_pvt::branch, build_via(), sip_request::headers, initialize_initreq(), sip_pvt::initreq, initreqprep(), sip_pvt::lastinvite, LOG_DEBUG, LOG_WARNING, sip_request::method, sip_pvt::ocseq, option_debug, sip_pvt::options, sip_pvt::owner, sip_pvt::refer, sip_refer::refer_to, sip_refer::referred_by, sip_refer::referred_by_name, sip_invite_param::replaces, reqprep(), sip_pvt::rtp, send_request(), SIP_REFER, sipdebug, t38properties::state, SUPPORTED_EXTENSIONS, sip_pvt::t38, T38_LOCAL_DIRECT, sip_pvt::udptl, ast_channel::varshead, XMIT_CRITICAL, and XMIT_RELIABLE.

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

07005 {
07006    struct sip_request req;
07007    
07008    req.method = sipmethod;
07009    if (init) {    /* Seems like init always is 2 */
07010       /* Bump branch even on initial requests */
07011       p->branch ^= ast_random();
07012       build_via(p);
07013       if (init > 1)
07014          initreqprep(&req, p, sipmethod);
07015       else
07016          reqprep(&req, p, sipmethod, 0, 1);
07017    } else
07018       reqprep(&req, p, sipmethod, 0, 1);
07019       
07020    if (p->options && p->options->auth)
07021       add_header(&req, p->options->authheader, p->options->auth);
07022    append_date(&req);
07023    if (sipmethod == SIP_REFER) { /* Call transfer */
07024       if (p->refer) {
07025          char buf[BUFSIZ];
07026          if (!ast_strlen_zero(p->refer->refer_to))
07027             add_header(&req, "Refer-To", p->refer->refer_to);
07028          if (!ast_strlen_zero(p->refer->referred_by)) {
07029             snprintf(buf, sizeof(buf), "%s <%s>", p->refer->referred_by_name, p->refer->referred_by);
07030             add_header(&req, "Referred-By", buf);
07031          }
07032       }
07033    }
07034    /* This new INVITE is part of an attended transfer. Make sure that the
07035    other end knows and replace the current call with this new call */
07036    if (p->options && p->options->replaces && !ast_strlen_zero(p->options->replaces)) {
07037       add_header(&req, "Replaces", p->options->replaces);
07038       add_header(&req, "Require", "replaces");
07039    }
07040 
07041    add_header(&req, "Allow", ALLOWED_METHODS);
07042    add_header(&req, "Supported", SUPPORTED_EXTENSIONS);
07043    if (p->options && p->options->addsipheaders && p->owner) {
07044       struct ast_channel *chan = p->owner; /* The owner channel */
07045       struct varshead *headp;
07046    
07047       ast_channel_lock(chan);
07048 
07049       headp = &chan->varshead;
07050 
07051       if (!headp)
07052          ast_log(LOG_WARNING,"No Headp for the channel...ooops!\n");
07053       else {
07054          const struct ast_var_t *current;
07055          AST_LIST_TRAVERSE(headp, current, entries) {  
07056             /* SIPADDHEADER: Add SIP header to outgoing call */
07057             if (!strncasecmp(ast_var_name(current), "SIPADDHEADER", strlen("SIPADDHEADER"))) {
07058                char *content, *end;
07059                const char *header = ast_var_value(current);
07060                char *headdup = ast_strdupa(header);
07061 
07062                /* Strip of the starting " (if it's there) */
07063                if (*headdup == '"')
07064                   headdup++;
07065                if ((content = strchr(headdup, ':'))) {
07066                   *content++ = '\0';
07067                   content = ast_skip_blanks(content); /* Skip white space */
07068                   /* Strip the ending " (if it's there) */
07069                   end = content + strlen(content) -1; 
07070                   if (*end == '"')
07071                      *end = '\0';
07072                
07073                   add_header(&req, headdup, content);
07074                   if (sipdebug)
07075                      ast_log(LOG_DEBUG, "Adding SIP Header \"%s\" with content :%s: \n", headdup, content);
07076                }
07077             }
07078          }
07079       }
07080 
07081       ast_channel_unlock(chan);
07082    }
07083    if (sdp) {
07084       if (p->udptl && p->t38.state == T38_LOCAL_DIRECT) {
07085          ast_udptl_offered_from_local(p->udptl, 1);
07086          if (option_debug)
07087             ast_log(LOG_DEBUG, "T38 is in state %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>");
07088          add_t38_sdp(&req, p);
07089       } else if (p->rtp) 
07090          add_sdp(&req, p);
07091    } else {
07092       add_header_contentLength(&req, 0);
07093    }
07094 
07095    if (!p->initreq.headers)
07096       initialize_initreq(p, &req);
07097    p->lastinvite = p->ocseq;
07098    return send_request(p, &req, init ? XMIT_CRITICAL : XMIT_RELIABLE, p->ocseq);
07099 }

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

Transmit text with SIP MESSAGE method.

Definition at line 7652 of file chan_sip.c.

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

Referenced by sip_park_thread(), and sip_sendtext().

07653 {
07654    struct sip_request req;
07655 
07656    reqprep(&req, p, SIP_MESSAGE, 0, 1);
07657    add_text(&req, text);
07658    return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
07659 }

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

Notify user of messages waiting in voicemail.

Note:
- Notification only works for registered peers with mailbox= definitions in sip.conf
  • We use the SIP Event package message-summary MIME type defaults to "application/simple-message-summary";

Definition at line 7289 of file chan_sip.c.

References add_header(), add_header_contentLength(), add_line(), ast_build_string(), ast_inet_ntoa(), ast_log(), ast_test_flag, sip_pvt::expiry, sip_pvt::flags, sip_request::headers, initialize_initreq(), sip_pvt::initreq, initreqprep(), LOG_WARNING, sip_pvt::ocseq, sip_pvt::ourip, S_OR, send_request(), SIP_NOTIFY, SIP_PAGE2_BUGGY_MWI, sip_pvt::subscribed, t, and XMIT_RELIABLE.

Referenced by sip_send_mwi_to_peer().

07290 {
07291    struct sip_request req;
07292    char tmp[500];
07293    char *t = tmp;
07294    size_t maxbytes = sizeof(tmp);
07295 
07296    initreqprep(&req, p, SIP_NOTIFY);
07297    add_header(&req, "Event", "message-summary");
07298    add_header(&req, "Content-Type", default_notifymime);
07299 
07300    ast_build_string(&t, &maxbytes, "Messages-Waiting: %s\r\n", newmsgs ? "yes" : "no");
07301    ast_build_string(&t, &maxbytes, "Message-Account: sip:%s@%s\r\n",
07302       S_OR(vmexten, default_vmexten), S_OR(p->fromdomain, ast_inet_ntoa(p->ourip)));
07303    /* Cisco has a bug in the SIP stack where it can't accept the
07304       (0/0) notification. This can temporarily be disabled in
07305       sip.conf with the "buggymwi" option */
07306    ast_build_string(&t, &maxbytes, "Voice-Message: %d/%d%s\r\n", newmsgs, oldmsgs, (ast_test_flag(&p->flags[1], SIP_PAGE2_BUGGY_MWI) ? "" : " (0/0)"));
07307 
07308    if (p->subscribed) {
07309       if (p->expiry)
07310          add_header(&req, "Subscription-State", "active");
07311       else  /* Expired */
07312          add_header(&req, "Subscription-State", "terminated;reason=timeout");
07313    }
07314 
07315    if (t > tmp + sizeof(tmp))
07316       ast_log(LOG_WARNING, "Buffer overflow detected!!  (Please file a bug report)\n");
07317 
07318    add_header_contentLength(&req, strlen(tmp));
07319    add_line(&req, tmp);
07320 
07321    if (!p->initreq.headers) 
07322       initialize_initreq(p, &req);
07323    return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
07324 }

static int transmit_notify_with_sipfrag ( struct sip_pvt p,
int  cseq,
char *  message,
int  terminate 
) [static]

Notify a transferring party of the status of transfer.

Definition at line 7335 of file chan_sip.c.

References add_header(), add_header_contentLength(), add_line(), ALLOWED_METHODS, sip_request::headers, initialize_initreq(), sip_pvt::initreq, sip_pvt::lastnoninvite, sip_pvt::ocseq, reqprep(), send_request(), SIP_NOTIFY, SUPPORTED_EXTENSIONS, and XMIT_RELIABLE.

Referenced by handle_request_refer(), local_attended_transfer(), and sip_park_thread().

07336 {
07337    struct sip_request req;
07338    char tmp[BUFSIZ/2];
07339 
07340    reqprep(&req, p, SIP_NOTIFY, 0, 1);
07341    snprintf(tmp, sizeof(tmp), "refer;id=%d", cseq);
07342    add_header(&req, "Event", tmp);
07343    add_header(&req, "Subscription-state", terminate ? "terminated;reason=noresource" : "active");
07344    add_header(&req, "Content-Type", "message/sipfrag;version=2.0");
07345    add_header(&req, "Allow", ALLOWED_METHODS);
07346    add_header(&req, "Supported", SUPPORTED_EXTENSIONS);
07347 
07348    snprintf(tmp, sizeof(tmp), "SIP/2.0 %s\r\n", message);
07349    add_header_contentLength(&req, strlen(tmp));
07350    add_line(&req, tmp);
07351 
07352    if (!p->initreq.headers)
07353       initialize_initreq(p, &req);
07354 
07355    p->lastnoninvite = p->ocseq;
07356 
07357    return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
07358 }

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

Transmit SIP REFER message (initiated by the transfer() dialplan application.

Note:
this is currently broken as we have no way of telling the dialplan engine whether a transfer succeeds or fails.
Todo:
Fix the transfer() dialplan function so that a transfer may fail

Todo:
In theory, we should hang around and wait for a reply, before returning to the dial plan here. Don't know really how that would affect the transfer() app or the pbx, but, well, to make this useful we should have a STATUS code on transfer().

Definition at line 7673 of file chan_sip.c.

References add_header(), ALLOWED_METHODS, ast_log(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, DEFAULT_MAX_FORWARDS, sip_pvt::flags, get_header(), get_in_brackets(), sip_request::headers, sip_pvt::initreq, LOG_DEBUG, LOG_NOTICE, sip_pvt::ocseq, option_debug, sip_pvt::refer, REFER_SENT, sip_refer::refer_to, sip_refer::referred_by, reqprep(), send_request(), SIP_OUTGOING, SIP_REFER, sip_refer_allocate(), sipdebug, sip_refer::status, SUPPORTED_EXTENSIONS, sip_pvt::tag, and XMIT_RELIABLE.

Referenced by sip_transfer().

07674 {
07675    struct sip_request req = { 
07676       .headers = 0,  
07677    };
07678    char from[256];
07679    const char *of;
07680    char *c;
07681    char referto[256];
07682    char *ttag, *ftag;
07683    char *theirtag = ast_strdupa(p->theirtag);
07684 
07685    if (option_debug || sipdebug)
07686       ast_log(LOG_DEBUG, "SIP transfer of %s to %s\n", p->callid, dest);
07687 
07688    /* Are we transfering an inbound or outbound call ? */
07689    if (ast_test_flag(&p->flags[0], SIP_OUTGOING))  {
07690       of = get_header(&p->initreq, "To");
07691       ttag = theirtag;
07692       ftag = p->tag;
07693    } else {
07694       of = get_header(&p->initreq, "From");
07695       ftag = theirtag;
07696       ttag = p->tag;
07697    }
07698 
07699    ast_copy_string(from, of, sizeof(from));
07700    of = get_in_brackets(from);
07701    ast_string_field_set(p, from, of);
07702    if (strncasecmp(of, "sip:", 4))
07703       ast_log(LOG_NOTICE, "From address missing 'sip:', using it anyway\n");
07704    else
07705       of += 4;
07706    /* Get just the username part */
07707    if ((c = strchr(dest, '@')))
07708       c = NULL;
07709    else if ((c = strchr(of, '@')))
07710       *c++ = '\0';
07711    if (c) 
07712       snprintf(referto, sizeof(referto), "<sip:%s@%s>", dest, c);
07713    else
07714       snprintf(referto, sizeof(referto), "<sip:%s>", dest);
07715 
07716    /* save in case we get 407 challenge */
07717    sip_refer_allocate(p);
07718    ast_copy_string(p->refer->refer_to, referto, sizeof(p->refer->refer_to));
07719    ast_copy_string(p->refer->referred_by, p->our_contact, sizeof(p->refer->referred_by));
07720    p->refer->status = REFER_SENT;   /* Set refer status */
07721 
07722    reqprep(&req, p, SIP_REFER, 0, 1);
07723    add_header(&req, "Max-Forwards", DEFAULT_MAX_FORWARDS);
07724 
07725    add_header(&req, "Refer-To", referto);
07726    add_header(&req, "Allow", ALLOWED_METHODS);
07727    add_header(&req, "Supported", SUPPORTED_EXTENSIONS);
07728    if (!ast_strlen_zero(p->our_contact))
07729       add_header(&req, "Referred-By", p->our_contact);
07730 
07731    return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
07732    /* We should propably wait for a NOTIFY here until we ack the transfer */
07733    /* Maybe fork a new thread and wait for a STATUS of REFER_200OK on the refer status before returning to app_transfer */
07734 
07735    /*! \todo In theory, we should hang around and wait for a reply, before
07736    returning to the dial plan here. Don't know really how that would
07737    affect the transfer() app or the pbx, but, well, to make this
07738    useful we should have a STATUS code on transfer().
07739    */
07740 }

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

Transmit register to SIP proxy or UA.

Definition at line 7460 of file chan_sip.c.

References __ourip, add_header(), add_header_contentLength(), append_history, ast_log(), ast_random(), ast_sched_add(), ast_sched_del(), ast_set_flag, ast_sip_ouraddrfor(), ast_string_field_free, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_verbose(), ASTOBJ_REF, bindaddr, sip_pvt::branch, build_callid_registry(), build_contact(), build_reply_digest(), build_via(), sip_registry::call, sip_registry::callid_valid, create_addr(), DEFAULT_MAX_FORWARDS, exten, sip_pvt::flags, sip_request::headers, init_req(), initialize_initreq(), sip_pvt::initreq, sip_request::lines, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, make_our_tag(), sip_pvt::noncecount, sip_registry::noncecount, sip_pvt::ocseq, sip_registry::ocseq, option_debug, sip_pvt::ourip, sip_registry::portno, sip_pvt::recv, REG_STATE_AUTHSENT, REG_STATE_REGSENT, sip_registry::regattempts, sip_pvt::registry, sip_registry::regstate, sip_pvt::sa, send_request(), sip_alloc(), sip_debug_test_pvt(), sip_destroy(), sip_methods, SIP_NO_HISTORY, SIP_OUTGOING, sip_reg_timeout(), SIP_REGISTER, sipdebug, STANDARD_SIP_PORT, sip_pvt::tag, cfsip_methods::text, sip_registry::timeout, TRUE, username, and XMIT_CRITICAL.

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

07461 {
07462    struct sip_request req;
07463    char from[256];
07464    char to[256];
07465    char tmp[80];
07466    char addr[80];
07467    struct sip_pvt *p;
07468 
07469    /* exit if we are already in process with this registrar ?*/
07470    if ( r == NULL || ((auth==NULL) && (r->regstate==REG_STATE_REGSENT || r->regstate==REG_STATE_AUTHSENT))) {
07471       ast_log(LOG_NOTICE, "Strange, trying to register %s@%s when registration already pending\n", r->username, r->hostname);
07472       return 0;
07473    }
07474 
07475    if (r->call) { /* We have a registration */
07476       if (!auth) {
07477          ast_log(LOG_WARNING, "Already have a REGISTER going on to %s@%s?? \n", r->username, r->hostname);
07478          return 0;
07479       } else {
07480          p = r->call;
07481          make_our_tag(p->tag, sizeof(p->tag));  /* create a new local tag for every register attempt */
07482          ast_string_field_free(p, theirtag); /* forget their old tag, so we don't match tags when getting response */
07483       }
07484    } else {
07485       /* Build callid for registration if we haven't registered before */
07486       if (!r->callid_valid) {
07487          build_callid_registry(r, __ourip, default_fromdomain);
07488          r->callid_valid = TRUE;
07489       }
07490       /* Allocate SIP packet for registration */
07491       if (!(p = sip_alloc( r->callid, NULL, 0, SIP_REGISTER))) {
07492          ast_log(LOG_WARNING, "Unable to allocate registration transaction (memory or socket error)\n");
07493          return 0;
07494       }
07495       if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY))
07496          append_history(p, "RegistryInit", "Account: %s@%s", r->username, r->hostname);
07497       /* Find address to hostname */
07498       if (create_addr(p, r->hostname)) {
07499          /* we have what we hope is a temporary network error,
07500           * probably DNS.  We need to reschedule a registration try */
07501          sip_destroy(p);
07502          if (r->timeout > -1) {
07503             ast_sched_del(sched, r->timeout);
07504             r->timeout = ast_sched_add(sched, global_reg_timeout*1000, sip_reg_timeout, r);
07505             ast_log(LOG_WARNING, "Still have a registration timeout for %s@%s (create_addr() error), %d\n", r->username, r->hostname, r->timeout);
07506          } else {
07507             r->timeout = ast_sched_add(sched, global_reg_timeout*1000, sip_reg_timeout, r);
07508             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);
07509          }
07510          r->regattempts++;
07511          return 0;
07512       }
07513       /* Copy back Call-ID in case create_addr changed it */
07514       ast_string_field_set(r, callid, p->callid);
07515       if (r->portno) {
07516          p->sa.sin_port = htons(r->portno);
07517          p->recv.sin_port = htons(r->portno);
07518       } else   /* Set registry port to the port set from the peer definition/srv or default */
07519          r->portno = ntohs(p->sa.sin_port);
07520       ast_set_flag(&p->flags[0], SIP_OUTGOING); /* Registration is outgoing call */
07521       r->call=p;        /* Save pointer to SIP packet */
07522       p->registry = ASTOBJ_REF(r);  /* Add pointer to registry in packet */
07523       if (!ast_strlen_zero(r->secret)) /* Secret (password) */
07524          ast_string_field_set(p, peersecret, r->secret);
07525       if (!ast_strlen_zero(r->md5secret))
07526          ast_string_field_set(p, peermd5secret, r->md5secret);
07527       /* User name in this realm  
07528       - if authuser is set, use that, otherwise use username */
07529       if (!ast_strlen_zero(r->authuser)) {   
07530          ast_string_field_set(p, peername, r->authuser);
07531          ast_string_field_set(p, authname, r->authuser);
07532       } else if (!ast_strlen_zero(r->username)) {
07533          ast_string_field_set(p, peername, r->username);
07534          ast_string_field_set(p, authname, r->username);
07535          ast_string_field_set(p, fromuser, r->username);
07536       }
07537       if (!ast_strlen_zero(r->username))
07538          ast_string_field_set(p, username, r->username);
07539       /* Save extension in packet */
07540       ast_string_field_set(p, exten, r->contact);
07541 
07542       /*
07543         check which address we should use in our contact header 
07544         based on whether the remote host is on the external or
07545         internal network so we can register through nat
07546        */
07547       if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
07548          p->ourip = bindaddr.sin_addr;
07549       build_contact(p);
07550    }
07551 
07552    /* set up a timeout */
07553    if (auth == NULL)  {
07554       if (r->timeout > -1) {
07555          ast_log(LOG_WARNING, "Still have a registration timeout, #%d - deleting it\n", r->timeout);
07556          ast_sched_del(sched, r->timeout);
07557       }
07558       r->timeout = ast_sched_add(sched, global_reg_timeout * 1000, sip_reg_timeout, r);
07559       if (option_debug)
07560          ast_log(LOG_DEBUG, "Scheduled a registration timeout for %s id  #%d \n", r->hostname, r->timeout);
07561    }
07562 
07563    if (strchr(r->username, '@')) {
07564       snprintf(from, sizeof(from), "<sip:%s>;tag=%s", r->username, p->tag);
07565       if (!ast_strlen_zero(p->theirtag))
07566          snprintf(to, sizeof(to), "<sip:%s>;tag=%s", r->username, p->theirtag);
07567       else
07568          snprintf(to, sizeof(to), "<sip:%s>", r->username);
07569    } else {
07570       snprintf(from, sizeof(from), "<sip:%s@%s>;tag=%s", r->username, p->tohost, p->tag);
07571       if (!ast_strlen_zero(p->theirtag))
07572          snprintf(to, sizeof(to), "<sip:%s@%s>;tag=%s", r->username, p->tohost, p->theirtag);
07573       else
07574          snprintf(to, sizeof(to), "<sip:%s@%s>", r->username, p->tohost);
07575    }
07576    
07577    /* Fromdomain is what we are registering to, regardless of actual
07578       host name from SRV */
07579    if (!ast_strlen_zero(p->fromdomain)) {
07580       if (r->portno && r->portno != STANDARD_SIP_PORT)
07581          snprintf(addr, sizeof(addr), "sip:%s:%d", p->fromdomain, r->portno);
07582       else
07583          snprintf(addr, sizeof(addr), "sip:%s", p->fromdomain);
07584    } else {
07585       if (r->portno && r->portno != STANDARD_SIP_PORT)
07586          snprintf(addr, sizeof(addr), "sip:%s:%d", r->hostname, r->portno);
07587       else
07588          snprintf(addr, sizeof(addr), "sip:%s", r->hostname);
07589    }
07590    ast_string_field_set(p, uri, addr);
07591 
07592    p->branch ^= ast_random();
07593 
07594    init_req(&req, sipmethod, addr);
07595 
07596    /* Add to CSEQ */
07597    snprintf(tmp, sizeof(tmp), "%u %s", ++r->ocseq, sip_methods[sipmethod].text);
07598    p->ocseq = r->ocseq;
07599 
07600    build_via(p);
07601    add_header(&req, "Via", p->via);
07602    add_header(&req, "From", from);
07603    add_header(&req, "To", to);
07604    add_header(&req, "Call-ID", p->callid);
07605    add_header(&req, "CSeq", tmp);
07606    if (!ast_strlen_zero(global_useragent))
07607       add_header(&req, "User-Agent", global_useragent);
07608    add_header(&req, "Max-Forwards", DEFAULT_MAX_FORWARDS);
07609 
07610    
07611    if (auth)   /* Add auth header */
07612       add_header(&req, authheader, auth);
07613    else if (!ast_strlen_zero(r->nonce)) {
07614       char digest[1024];
07615 
07616       /* We have auth data to reuse, build a digest header! */
07617       if (sipdebug)
07618          ast_log(LOG_DEBUG, "   >>> Re-using Auth data for %s@%s\n", r->username, r->hostname);
07619       ast_string_field_set(p, realm, r->realm);
07620       ast_string_field_set(p, nonce, r->nonce);
07621       ast_string_field_set(p, domain, r->domain);
07622       ast_string_field_set(p, opaque, r->opaque);
07623       ast_string_field_set(p, qop, r->qop);
07624       r->noncecount++;
07625       p->noncecount = r->noncecount;
07626 
07627       memset(digest,0,sizeof(digest));
07628       if(!build_reply_digest(p, sipmethod, digest, sizeof(digest)))
07629          add_header(&req, "Authorization", digest);
07630       else
07631          ast_log(LOG_NOTICE, "No authorization available for authentication of registration to %s@%s\n", r->username, r->hostname);
07632    
07633    }
07634 
07635    snprintf(tmp, sizeof(tmp), "%d", default_expiry);
07636    add_header(&req, "Expires", tmp);
07637    add_header(&req, "Contact", p->our_contact);
07638    add_header(&req, "Event", "registration");
07639    add_header_contentLength(&req, 0);
07640 
07641    initialize_initreq(p, &req);
07642    if (sip_debug_test_pvt(p))
07643       ast_verbose("REGISTER %d headers, %d lines\n", p->initreq.headers, p->initreq.lines);
07644    r->regstate = auth ? REG_STATE_AUTHSENT : REG_STATE_REGSENT;
07645    r->regattempts++; /* Another attempt */
07646    if (option_debug > 3)
07647       ast_verbose("REGISTER attempt %d to %s@%s\n", r->regattempts, r->username, r->hostname);
07648    return send_request(p, &req, XMIT_CRITICAL, p->ocseq);
07649 }

static int transmit_reinvite_with_sdp ( struct sip_pvt p  )  [static]

Transmit reinvite with SDP.

Note:
A re-invite is basically a new INVITE with the same CALL-ID and TAG as the INVITE that opened the SIP dialogue We reinvite so that the audio stream (RTP) go directly between the SIP UAs. SIP Signalling stays with * in the path.

Definition at line 6724 of file chan_sip.c.

References add_header(), add_sdp(), ALLOWED_METHODS, append_history, ast_set_flag, ast_test_flag, sip_pvt::flags, initialize_initreq(), sip_pvt::lastinvite, sip_pvt::ocseq, reqprep(), send_request(), SIP_INVITE, SIP_NO_HISTORY, SIP_OUTGOING, SIP_REINVITE_UPDATE, SIP_UPDATE, sipdebug, SUPPORTED_EXTENSIONS, and XMIT_CRITICAL.

Referenced by check_pendings(), and sip_set_rtp_peer().

06725 {
06726    struct sip_request req;
06727 
06728    reqprep(&req, p, ast_test_flag(&p->flags[0], SIP_REINVITE_UPDATE) ?  SIP_UPDATE : SIP_INVITE, 0, 1);
06729    
06730    add_header(&req, "Allow", ALLOWED_METHODS);
06731    add_header(&req, "Supported", SUPPORTED_EXTENSIONS);
06732    if (sipdebug)
06733       add_header(&req, "X-asterisk-Info", "SIP re-invite (External RTP bridge)");
06734    if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY))
06735       append_history(p, "ReInv", "Re-invite sent");
06736    add_sdp(&req, p);
06737    /* Use this as the basis */
06738    initialize_initreq(p, &req);
06739    p->lastinvite = p->ocseq;
06740    ast_set_flag(&p->flags[0], SIP_OUTGOING);    /* Change direction of this dialog */
06741    return send_request(p, &req, XMIT_CRITICAL, p->ocseq);
06742 }

static int transmit_reinvite_with_t38_sdp ( struct sip_pvt p  )  [static]

Transmit reinvite with T38 SDP We reinvite so that the T38 processing can take place. SIP Signalling stays with * in the path.

Definition at line 6748 of file chan_sip.c.

References add_header(), add_t38_sdp(), ALLOWED_METHODS, ast_set_flag, ast_test_flag, ast_udptl_offered_from_local(), sip_pvt::flags, initialize_initreq(), sip_pvt::lastinvite, sip_pvt::ocseq, reqprep(), send_request(), SIP_INVITE, SIP_OUTGOING, SIP_REINVITE_UPDATE, SIP_UPDATE, sipdebug, SUPPORTED_EXTENSIONS, sip_pvt::udptl, and XMIT_CRITICAL.

Referenced by sip_handle_t38_reinvite(), sip_read(), and sip_set_udptl_peer().

06749 {
06750    struct sip_request req;
06751 
06752    reqprep(&req, p, ast_test_flag(&p->flags[0], SIP_REINVITE_UPDATE) ?  SIP_UPDATE : SIP_INVITE, 0, 1);
06753    
06754    add_header(&req, "Allow", ALLOWED_METHODS);
06755    add_header(&req, "Supported", SUPPORTED_EXTENSIONS);
06756    if (sipdebug)
06757       add_header(&req, "X-asterisk-info", "SIP re-invite (T38 switchover)");
06758    ast_udptl_offered_from_local(p->udptl, 1);
06759    add_t38_sdp(&req, p);
06760    /* Use this as the basis */
06761    initialize_initreq(p, &req);
06762    ast_set_flag(&p->flags[0], SIP_OUTGOING);    /* Change direction of this dialog */
06763    p->lastinvite = p->ocseq;
06764    return send_request(p, &req, XMIT_CRITICAL, p->ocseq);
06765 }

static int transmit_request ( struct sip_pvt p,
int  sipmethod,
int  inc,
enum xmittype  reliable,
int  newbranch 
) [static]

Transmit generic SIP request returns XMIT_ERROR if transmit failed with a critical error (don't retry).

Definition at line 7766 of file chan_sip.c.

References add_header_contentLength(), INV_CONFIRMED, sip_pvt::invitestate, sip_pvt::ocseq, reqprep(), send_request(), and SIP_ACK.

Referenced by check_pendings(), handle_response(), handle_response_invite(), and sip_hangup().

07767 {
07768    struct sip_request resp;
07769 
07770    if (sipmethod == SIP_ACK)
07771       p->invitestate = INV_CONFIRMED;
07772 
07773    reqprep(&resp, p, sipmethod, seqno, newbranch);
07774    add_header_contentLength(&resp, 0);
07775    return send_request(p, &resp, reliable, seqno ? seqno : p->ocseq);
07776 }

static int transmit_request_with_auth ( struct sip_pvt p,
int  sipmethod,
int  seqno,
enum xmittype  reliable,
int  newbranch 
) [static]

Transmit SIP request, auth added.

Definition at line 7779 of file chan_sip.c.

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

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

07780 {
07781    struct sip_request resp;
07782 
07783    reqprep(&resp, p, sipmethod, seqno, newbranch);
07784    if (!ast_strlen_zero(p->realm)) {
07785       char digest[1024];
07786 
07787       memset(digest, 0, sizeof(digest));
07788       if(!build_reply_digest(p, sipmethod, digest, sizeof(digest))) {
07789          if (p->options && p->options->auth_type == PROXY_AUTH)
07790             add_header(&resp, "Proxy-Authorization", digest);
07791          else if (p->options && p->options->auth_type == WWW_AUTH)
07792             add_header(&resp, "Authorization", digest);
07793          else  /* Default, to be backwards compatible (maybe being too careful, but leaving it for now) */
07794             add_header(&resp, "Proxy-Authorization", digest);
07795       } else
07796          ast_log(LOG_WARNING, "No authentication available for call %s\n", p->callid);
07797    }
07798    /* If we are hanging up and know a cause for that, send it in clear text to make
07799       debugging easier. */
07800    if (sipmethod == SIP_BYE && p->owner && p->owner->hangupcause) {
07801       char buf[10];
07802 
07803       add_header(&resp, "X-Asterisk-HangupCause", ast_cause2str(p->owner->hangupcause));
07804       snprintf(buf, sizeof(buf), "%d", p->owner->hangupcause);
07805       add_header(&resp, "X-Asterisk-HangupCauseCode", buf);
07806    }
07807 
07808    add_header_contentLength(&resp, 0);
07809    return send_request(p, &resp, reliable, seqno ? seqno : p->ocseq);   
07810 }

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

Transmit response, no retransmits.

Definition at line 6038 of file chan_sip.c.

References __transmit_response(), and XMIT_UNRELIABLE.

06039 {
06040    return __transmit_response(p, msg, req, XMIT_UNRELIABLE);
06041 }

static int transmit_response_reliable ( struct sip_pvt p,
const char *  msg,
const struct sip_request req 
) [static]

Transmit response, Make sure you get an ACK This is only used for responses to INVITEs, where we need to make sure we get an ACK.

Definition at line 6057 of file chan_sip.c.

References __transmit_response(), and XMIT_CRITICAL.

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

06058 {
06059    return __transmit_response(p, msg, req, XMIT_CRITICAL);
06060 }

static int transmit_response_using_temp ( ast_string_field  callid,
struct sockaddr_in *  sin,
int  useglobal_nat,
const int  intended_method,
const struct sip_request req,
const char *  msg 
) [static]

Transmit response, no retransmits, using a temporary pvt structure.

Definition at line 5988 of file chan_sip.c.

References __ourip, __transmit_response(), ast_copy_flags, ast_log(), ast_random(), ast_set_flag, ast_sip_ouraddrfor(), ast_string_field_init, ast_string_field_reset_all, ast_string_field_set, ast_test_flag, sip_pvt::branch, build_via(), do_setnat(), sip_pvt::flags, INITIAL_CSEQ, LOG_NOTICE, make_our_tag(), sip_pvt::method, sip_pvt::ocseq, sip_pvt::ourip, sip_pvt::recv, sip_pvt::sa, SIP_NAT, SIP_NAT_ROUTE, SIP_NO_HISTORY, sip_pvt::tag, and XMIT_UNRELIABLE.

Referenced by find_call().

05989 {
05990    struct sip_pvt *p = NULL;
05991 
05992    if (!(p = ast_threadstorage_get(&ts_temp_pvt, sizeof(*p)))) {
05993       ast_log(LOG_NOTICE, "Failed to get temporary pvt\n");
05994       return -1;
05995    }
05996 
05997    /* if the structure was just allocated, initialize it */
05998    if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) {
05999       ast_set_flag(&p->flags[0], SIP_NO_HISTORY);
06000       if (ast_string_field_init(p, 512))
06001          return -1;
06002    }
06003 
06004    /* Initialize the bare minimum */
06005    p->method = intended_method;
06006 
06007    if (sin) {
06008       p->sa = *sin;
06009       if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
06010          p->ourip = __ourip;
06011    } else
06012       p->ourip = __ourip;
06013 
06014    p->branch = ast_random();
06015    make_our_tag(p->tag, sizeof(p->tag));
06016    p->ocseq = INITIAL_CSEQ;
06017 
06018    if (useglobal_nat && sin) {
06019       ast_copy_flags(&p->flags[0], &global_flags[0], SIP_NAT);
06020       p->recv = *sin;
06021       do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE);
06022    }
06023 
06024    ast_string_field_set(p, fromdomain, default_fromdomain);
06025    build_via(p);
06026    ast_string_field_set(p, callid, callid);
06027 
06028    /* Use this temporary pvt structure to send the message */
06029    __transmit_response(p, msg, req, XMIT_UNRELIABLE);
06030 
06031    /* Free the string fields, but not the pool space */
06032    ast_string_field_reset_all(p);
06033 
06034    return 0;
06035 }

static int transmit_response_with_allow ( struct sip_pvt p,
const char *  msg,
const struct sip_request req,
enum xmittype  reliable 
) [static]

Append Accept header, content length before transmitting response.

Definition at line 6085 of file chan_sip.c.

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

Referenced by handle_request(), and handle_request_options().

06086 {
06087    struct sip_request resp;
06088    respprep(&resp, p, msg, req);
06089    add_header(&resp, "Accept", "application/sdp");
06090    add_header_contentLength(&resp, 0);
06091    return send_response(p, &resp, reliable, 0);
06092 }

static int transmit_response_with_auth ( struct sip_pvt p,
const char *  msg,
const struct sip_request req,
const char *  rand,
enum xmittype  reliable,
const char *  header,
int  stale 
) [static]

Respond with authorization request.

Definition at line 6095 of file chan_sip.c.

References add_header(), add_header_contentLength(), append_history, ast_log(), get_header(), LOG_WARNING, sip_pvt::noncecount, respprep(), and send_response().

Referenced by check_auth(), and transmit_fake_auth_response().

06096 {
06097    struct sip_request resp;
06098    char tmp[512];
06099    int seqno = 0;
06100 
06101    if (reliable && (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1)) {
06102       ast_log(LOG_WARNING, "Unable to determine sequence number from '%s'\n", get_header(req, "CSeq"));
06103       return -1;
06104    }
06105    /* Stale means that they sent us correct authentication, but 
06106       based it on an old challenge (nonce) */
06107    snprintf(tmp, sizeof(tmp), "Digest algorithm=MD5, realm=\"%s\", nonce=\"%s\"%s", global_realm, randdata, stale ? ", stale=true" : "");
06108    respprep(&resp, p, msg, req);
06109    add_header(&resp, header, tmp);
06110    add_header_contentLength(&resp, 0);
06111    append_history(p, "AuthChal", "Auth challenge sent for %s - nc %d", p->username, p->noncecount);
06112    return send_response(p, &resp, reliable, seqno);
06113 }

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

Append date and content length before transmitting response.

Definition at line 6075 of file chan_sip.c.

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

Referenced by register_verify().

06076 {
06077    struct sip_request resp;
06078    respprep(&resp, p, msg, req);
06079    append_date(&resp);
06080    add_header_contentLength(&resp, 0);
06081    return send_response(p, &resp, XMIT_UNRELIABLE, 0);
06082 }

static int transmit_response_with_sdp ( struct sip_pvt p,
const char *  msg,
const struct sip_request req,
enum xmittype  reliable 
) [static]

Used for 200 OK and 183 early media.

Returns:
Will return XMIT_ERROR for network errors.

Definition at line 6653 of file chan_sip.c.

References add_sdp(), ast_log(), ast_rtp_codec_setpref(), ast_test_flag, sip_pvt::autoframing, sip_pvt::flags, get_header(), LOG_DEBUG, LOG_ERROR, LOG_WARNING, option_debug, sip_pvt::pendinginvite, sip_pvt::prefs, respprep(), sip_pvt::rtp, send_response(), SIP_OUTGOING, and try_suggested_sip_codec().

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

06654 {
06655    struct sip_request resp;
06656    int seqno;
06657    if (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1) {
06658       ast_log(LOG_WARNING, "Unable to get seqno from '%s'\n", get_header(req, "CSeq"));
06659       return -1;
06660    }
06661    respprep(&resp, p, msg, req);
06662    if (p->rtp) {
06663       if (!p->autoframing && !ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
06664          if (option_debug)
06665             ast_log(LOG_DEBUG, "Setting framing from config on incoming call\n");
06666          ast_rtp_codec_setpref(p->rtp, &p->prefs);
06667       }
06668       try_suggested_sip_codec(p);   
06669       add_sdp(&resp, p);
06670    } else 
06671       ast_log(LOG_ERROR, "Can't add SDP to response, since we have no RTP session allocated. Call-ID %s\n", p->callid);
06672    if (reliable && !p->pendinginvite)
06673       p->pendinginvite = seqno;     /* Buggy clients sends ACK on RINGING too */
06674    return send_response(p, &resp, reliable, seqno);
06675 }

static int transmit_response_with_t38_sdp ( struct sip_pvt p,
char *  msg,
struct sip_request req,
int  retrans 
) [static]

Used for 200 OK and 183 early media.

Definition at line 6613 of file chan_sip.c.

References add_t38_sdp(), ast_log(), ast_udptl_offered_from_local(), get_header(), LOG_ERROR, LOG_WARNING, sip_pvt::pendinginvite, respprep(), send_response(), and sip_pvt::udptl.

Referenced by handle_request_invite(), sip_answer(), and sip_handle_t38_reinvite().

06614 {
06615    struct sip_request resp;
06616    int seqno;
06617    
06618    if (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1) {
06619       ast_log(LOG_WARNING, "Unable to get seqno from '%s'\n", get_header(req, "CSeq"));
06620       return -1;
06621    }
06622    respprep(&resp, p, msg, req);
06623    if (p->udptl) {
06624       ast_udptl_offered_from_local(p->udptl, 0);
06625       add_t38_sdp(&resp, p);
06626    } else 
06627       ast_log(LOG_ERROR, "Can't add SDP to response, since we have no UDPTL session allocated. Call-ID %s\n", p->callid);
06628    if (retrans && !p->pendinginvite)
06629       p->pendinginvite = seqno;     /* Buggy clients sends ACK on RINGING too */
06630    return send_response(p, &resp, retrans, seqno);
06631 }

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

Transmit response, no retransmits.

Definition at line 6044 of file chan_sip.c.

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

Referenced by handle_request_invite().

06045 {
06046    struct sip_request resp;
06047    respprep(&resp, p, msg, req);
06048    append_date(&resp);
06049    add_header(&resp, "Unsupported", unsupported);
06050    add_header_contentLength(&resp, 0);
06051    return send_response(p, &resp, XMIT_UNRELIABLE, 0);
06052 }

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

Transmit SIP request unreliably (only used in sip_notify subsystem).

Definition at line 7327 of file chan_sip.c.

References sip_request::headers, initialize_initreq(), sip_pvt::initreq, sip_pvt::ocseq, send_request(), and XMIT_UNRELIABLE.

Referenced by sip_notify().

07328 {
07329    if (!p->initreq.headers)   /* Initialize first request before sending */
07330       initialize_initreq(p, req);
07331    return send_request(p, req, XMIT_UNRELIABLE, p->ocseq);
07332 }

static int transmit_state_notify ( struct sip_pvt p,
int  state,
int  full,
int  timeout 
) [static]

Used in the SUBSCRIBE notification subsystem.

Definition at line 7102 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_ONHOLD, AST_EXTENSION_REMOVED, AST_EXTENSION_RINGING, AST_EXTENSION_UNAVAILABLE, ast_get_hint(), ast_log(), AST_MAX_EXTENSION, CPIM_PIDF_XML, DIALOG_INFO_XML, sip_pvt::dialogver, cfsubscription_types::event, sip_pvt::expiry, find_subscription_type(), get_header(), get_in_brackets(), sip_pvt::initreq, LOG_WARNING, cfsubscription_types::mediatype, NONE, sip_pvt::ocseq, PIDF_XML, reqprep(), send_request(), SIP_NOTIFY, strsep(), sip_pvt::subscribed, t, XMIT_RELIABLE, and XPIDF_XML.

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

07103 {
07104    char tmp[4000], from[256], to[256];
07105    char *t = tmp, *c, *mfrom, *mto;
07106    size_t maxbytes = sizeof(tmp);
07107    struct sip_request req;
07108    char hint[AST_MAX_EXTENSION];
07109    char *statestring = "terminated";
07110    const struct cfsubscription_types *subscriptiontype;
07111    enum state { NOTIFY_OPEN, NOTIFY_INUSE, NOTIFY_CLOSED } local_state = NOTIFY_OPEN;
07112    char *pidfstate = "--";
07113    char *pidfnote= "Ready";
07114 
07115    memset(from, 0, sizeof(from));
07116    memset(to, 0, sizeof(to));
07117    memset(tmp, 0, sizeof(tmp));
07118 
07119    switch (state) {
07120    case (AST_EXTENSION_RINGING | AST_EXTENSION_INUSE):
07121       statestring = (global_notifyringing) ? "early" : "confirmed";
07122       local_state = NOTIFY_INUSE;
07123       pidfstate = "busy";
07124       pidfnote = "Ringing";
07125       break;
07126    case AST_EXTENSION_RINGING:
07127       statestring = "early";
07128       local_state = NOTIFY_INUSE;
07129       pidfstate = "busy";
07130       pidfnote = "Ringing";
07131       break;
07132    case AST_EXTENSION_INUSE:
07133       statestring = "confirmed";
07134       local_state = NOTIFY_INUSE;
07135       pidfstate = "busy";
07136       pidfnote = "On the phone";
07137       break;
07138    case AST_EXTENSION_BUSY:
07139       statestring = "confirmed";
07140       local_state = NOTIFY_CLOSED;
07141       pidfstate = "busy";
07142       pidfnote = "On the phone";
07143       break;
07144    case AST_EXTENSION_UNAVAILABLE:
07145       statestring = "terminated";
07146       local_state = NOTIFY_CLOSED;
07147       pidfstate = "away";
07148       pidfnote = "Unavailable";
07149       break;
07150    case AST_EXTENSION_ONHOLD:
07151       statestring = "confirmed";
07152       local_state = NOTIFY_INUSE;
07153       pidfstate = "busy";
07154       pidfnote = "On Hold";
07155       break;
07156    case AST_EXTENSION_NOT_INUSE:
07157    default:
07158       /* Default setting */
07159       break;
07160    }
07161 
07162    subscriptiontype = find_subscription_type(p->subscribed);
07163    
07164    /* Check which device/devices we are watching  and if they are registered */
07165    if (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, p->context, p->exten)) {
07166       char *hint2 = hint, *individual_hint = NULL;
07167       int hint_count = 0, unavailable_count = 0;
07168 
07169       while ((individual_hint = strsep(&hint2, "&"))) {
07170          hint_count++;
07171 
07172          if (ast_device_state(individual_hint) == AST_DEVICE_UNAVAILABLE)
07173             unavailable_count++;
07174       }
07175 
07176       /* If none of the hinted devices are registered, we will
07177        * override notification and show no availability.
07178        */
07179       if (hint_count > 0 && hint_count == unavailable_count) {
07180          local_state = NOTIFY_CLOSED;
07181          pidfstate = "away";
07182          pidfnote = "Not online";
07183       }
07184    }
07185 
07186    ast_copy_string(from, get_header(&p->initreq, "From"), sizeof(from));
07187    c = get_in_brackets(from);
07188    if (strncasecmp(c, "sip:", 4)) {
07189       ast_log(LOG_WARNING, "Huh?  Not a SIP header (%s)?\n", c);
07190       return -1;
07191    }
07192    mfrom = strsep(&c, ";");   /* trim ; and beyond */
07193 
07194    ast_copy_string(to, get_header(&p->initreq, "To"), sizeof(to));
07195    c = get_in_brackets(to);
07196    if (strncasecmp(c, "sip:", 4)) {
07197       ast_log(LOG_WARNING, "Huh?  Not a SIP header (%s)?\n", c);
07198       return -1;
07199    }
07200    mto = strsep(&c, ";");  /* trim ; and beyond */
07201 
07202    reqprep(&req, p, SIP_NOTIFY, 0, 1);
07203 
07204    
07205    add_header(&req, "Event", subscriptiontype->event);
07206    add_header(&req, "Content-Type", subscriptiontype->mediatype);
07207    switch(state) {
07208    case AST_EXTENSION_DEACTIVATED:
07209       if (timeout)
07210          add_header(&req, "Subscription-State", "terminated;reason=timeout");
07211       else {
07212          add_header(&req, "Subscription-State", "terminated;reason=probation");
07213          add_header(&req, "Retry-After", "60");
07214       }
07215       break;
07216    case AST_EXTENSION_REMOVED:
07217       add_header(&req, "Subscription-State", "terminated;reason=noresource");
07218       break;
07219    default:
07220       if (p->expiry)
07221          add_header(&req, "Subscription-State", "active");
07222       else  /* Expired */
07223          add_header(&req, "Subscription-State", "terminated;reason=timeout");
07224    }
07225    switch (p->subscribed) {
07226    case XPIDF_XML:
07227    case CPIM_PIDF_XML:
07228       ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\"?>\n");
07229       ast_build_string(&t, &maxbytes, "<!DOCTYPE presence PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n");
07230       ast_build_string(&t, &maxbytes, "<presence>\n");
07231       ast_build_string(&t, &maxbytes, "<presentity uri=\"%s;method=SUBSCRIBE\" />\n", mfrom);
07232       ast_build_string(&t, &maxbytes, "<atom id=\"%s\">\n", p->exten);
07233       ast_build_string(&t, &maxbytes, "<address uri=\"%s;user=ip\" priority=\"0.800000\">\n", mto);
07234       ast_build_string(&t, &maxbytes, "<status status=\"%s\" />\n", (local_state ==  NOTIFY_OPEN) ? "open" : (local_state == NOTIFY_INUSE) ? "inuse" : "closed");
07235       ast_build_string(&t, &maxbytes, "<msnsubstatus substatus=\"%s\" />\n", (local_state == NOTIFY_OPEN) ? "online" : (local_state == NOTIFY_INUSE) ? "onthephone" : "offline");
07236       ast_build_string(&t, &maxbytes, "</address>\n</atom>\n</presence>\n");
07237       break;
07238    case PIDF_XML: /* Eyebeam supports this format */
07239       ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n");
07240       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);
07241       ast_build_string(&t, &maxbytes, "<pp:person><status>\n");
07242       if (pidfstate[0] != '-')
07243          ast_build_string(&t, &maxbytes, "<ep:activities><ep:%s/></ep:activities>\n", pidfstate);
07244       ast_build_string(&t, &maxbytes, "</status></pp:person>\n");
07245       ast_build_string(&t, &maxbytes, "<note>%s</note>\n", pidfnote); /* Note */
07246       ast_build_string(&t, &maxbytes, "<tuple id=\"%s\">\n", p->exten); /* Tuple start */
07247       ast_build_string(&t, &maxbytes, "<contact priority=\"1\">%s</contact>\n", mto);
07248       if (pidfstate[0] == 'b') /* Busy? Still open ... */
07249          ast_build_string(&t, &maxbytes, "<status><basic>open</basic></status>\n");
07250       else
07251          ast_build_string(&t, &maxbytes, "<status><basic>%s</basic></status>\n", (local_state != NOTIFY_CLOSED) ? "open" : "closed");
07252       ast_build_string(&t, &maxbytes, "</tuple>\n</presence>\n");
07253       break;
07254    case DIALOG_INFO_XML: /* SNOM subscribes in this format */
07255       ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\"?>\n");
07256       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);
07257       if ((state & AST_EXTENSION_RINGING) && global_notifyringing)
07258          ast_build_string(&t, &maxbytes, "<dialog id=\"%s\" direction=\"recipient\">\n", p->exten);
07259       else
07260          ast_build_string(&t, &maxbytes, "<dialog id=\"%s\">\n", p->exten);
07261       ast_build_string(&t, &maxbytes, "<state>%s</state>\n", statestring);
07262       if (state == AST_EXTENSION_ONHOLD) {
07263          ast_build_string(&t, &maxbytes, "<local>\n<target uri=\"%s\">\n"
07264                                          "<param pname=\"+sip.rendering\" pvalue=\"no\">\n"
07265                                          "</target>\n</local>\n", mto);
07266       }
07267       ast_build_string(&t, &maxbytes, "</dialog>\n</dialog-info>\n");
07268       break;
07269    case NONE:
07270    default:
07271       break;
07272    }
07273 
07274    if (t > tmp + sizeof(tmp))
07275       ast_log(LOG_WARNING, "Buffer overflow detected!!  (Please file a bug report)\n");
07276 
07277    add_header_contentLength(&req, strlen(tmp));
07278    add_line(&req, tmp);
07279 
07280    return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
07281 }

static void try_suggested_sip_codec ( struct sip_pvt p  )  [static]

Try setting codec suggested by the SIP_CODEC channel variable.

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

03615 {
03616    int fmt;
03617    const char *codec;
03618 
03619    codec = pbx_builtin_getvar_helper(p->owner, "SIP_CODEC");
03620    if (!codec) 
03621       return;
03622 
03623    fmt = ast_getformatbyname(codec);
03624    if (fmt) {
03625       ast_log(LOG_NOTICE, "Changing codec to '%s' for this call because of ${SIP_CODEC} variable\n", codec);
03626       if (p->jointcapability & fmt) {
03627          p->jointcapability &= fmt;
03628          p->capability &= fmt;
03629       } else
03630          ast_log(LOG_NOTICE, "Ignoring ${SIP_CODEC} variable because it is not shared by both ends.\n");
03631    } else
03632       ast_log(LOG_NOTICE, "Ignoring ${SIP_CODEC} variable because of unrecognized/not configured codec (check allow/disallow in sip.conf): %s\n", codec);
03633    return;  
03634 }

static int unload_module ( void   )  [static]

PBX unload module API.

Definition at line 17964 of file chan_sip.c.

References __sip_destroy(), ast_channel_unregister(), ast_cli_unregister_multiple(), ast_custom_function_unregister(), ast_free_ha(), ast_manager_unregister(), ast_mutex_lock(), ast_mutex_unlock(), AST_PTHREADT_NULL, AST_PTHREADT_STOP, ast_rtp_proto_unregister(), ast_softhangup(), AST_SOFTHANGUP_APPUNLOAD, ast_udptl_proto_unregister(), ast_unregister_application(), ASTOBJ_CONTAINER_DESTROY, ASTOBJ_CONTAINER_DESTROYALL, authl, clear_realm_authentication(), clear_sip_domains(), iflist, localaddr, sip_pvt::next, sip_pvt::owner, peerl, regl, sched_context_destroy(), sip_destroy_peer(), sip_destroy_user(), sip_registry_destroy(), sip_rtp, sip_tech, sip_udptl, sipsock, TRUE, and userl.

17965 {
17966    struct sip_pvt *p, *pl;
17967    
17968    /* First, take us out of the channel type list */
17969    ast_channel_unregister(&sip_tech);
17970 
17971    /* Unregister dial plan functions */
17972    ast_custom_function_unregister(&sipchaninfo_function);
17973    ast_custom_function_unregister(&sippeer_function);
17974    ast_custom_function_unregister(&sip_header_function);
17975    ast_custom_function_unregister(&checksipdomain_function);
17976 
17977    /* Unregister dial plan applications */
17978    ast_unregister_application(app_dtmfmode);
17979    ast_unregister_application(app_sipaddheader);
17980 
17981    /* Unregister CLI commands */
17982    ast_cli_unregister_multiple(cli_sip, sizeof(cli_sip) / sizeof(struct ast_cli_entry));
17983 
17984    /* Disconnect from the RTP subsystem */
17985    ast_rtp_proto_unregister(&sip_rtp);
17986 
17987    /* Disconnect from UDPTL */
17988    ast_udptl_proto_unregister(&sip_udptl);
17989 
17990    /* Unregister AMI actions */
17991    ast_manager_unregister("SIPpeers");
17992    ast_manager_unregister("SIPshowpeer");
17993 
17994    ast_mutex_lock(&iflock);
17995    /* Hangup all interfaces if they have an owner */
17996    for (p = iflist; p ; p = p->next) {
17997       if (p->owner)
17998          ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD);
17999    }
18000    ast_mutex_unlock(&iflock);
18001 
18002    ast_mutex_lock(&monlock);
18003    if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP) && (monitor_thread != AST_PTHREADT_NULL)) {
18004       pthread_cancel(monitor_thread);
18005       pthread_kill(monitor_thread, SIGURG);
18006       pthread_join(monitor_thread, NULL);
18007    }
18008    monitor_thread = AST_PTHREADT_STOP;
18009    ast_mutex_unlock(&monlock);
18010 
18011    ast_mutex_lock(&iflock);
18012    /* Destroy all the interfaces and free their memory */
18013    p = iflist;
18014    while (p) {
18015       pl = p;
18016       p = p->next;
18017       __sip_destroy(pl, TRUE);
18018    }
18019    iflist = NULL;
18020    ast_mutex_unlock(&iflock);
18021 
18022    /* Free memory for local network address mask */
18023    ast_free_ha(localaddr);
18024 
18025    ASTOBJ_CONTAINER_DESTROYALL(&userl, sip_destroy_user);
18026    ASTOBJ_CONTAINER_DESTROY(&userl);
18027    ASTOBJ_CONTAINER_DESTROYALL(&peerl, sip_destroy_peer);
18028    ASTOBJ_CONTAINER_DESTROY(&peerl);
18029    ASTOBJ_CONTAINER_DESTROYALL(&regl, sip_registry_destroy);
18030    ASTOBJ_CONTAINER_DESTROY(&regl);
18031 
18032    clear_realm_authentication(authl);
18033    clear_sip_domains();
18034    close(sipsock);
18035    sched_context_destroy(sched);
18036       
18037    return 0;
18038 }

static int update_call_counter ( struct sip_pvt fup,
int  event 
) [static]

update_call_counter: Handle call_limit for SIP users Setting a call-limit will cause calls above the limit not to be accepted.

Remember that for a type=friend, there's one limit for the user and another for the peer, not a combined call limit. This will cause unexpected behaviour in subscriptions, since a "friend" is *two* devices in Asterisk, not one.

Thought: For realtime, we should propably update storage with inuse counter...

Returns:
0 if call is ok (no call limit, below treshold) -1 on rejection of call

Definition at line 3166 of file chan_sip.c.

References ast_clear_flag, ast_device_state_changed(), ast_log(), ast_set_flag, ast_strlen_zero(), ast_test_flag, ASTOBJ_UNREF, sip_peer::call_limit, sip_user::call_limit, DEC_CALL_LIMIT, DEC_CALL_RINGING, FALSE, find_peer(), find_user(), sip_pvt::flags, INC_CALL_LIMIT, INC_CALL_RINGING, sip_peer::inRinging, sip_peer::inUse, sip_user::inUse, inuse, LOG_DEBUG, LOG_ERROR, LOG_WARNING, name, option_debug, SIP_CALL_LIMIT, sip_destroy_peer(), sip_destroy_user(), SIP_INC_COUNT, SIP_PAGE2_CALL_ONHOLD, SIP_PAGE2_INC_RINGING, SIP_PAGE2_OUTGOING_CALL, SIP_PAGE2_RTCACHEFRIENDS, sip_peer_hold(), SIP_REALTIME, and sipdebug.

Referenced by __sip_destroy(), handle_request_cancel(), handle_request_invite(), handle_response_invite(), sip_call(), and sip_hangup().

03167 {
03168    char name[256];
03169    int *inuse = NULL, *call_limit = NULL, *inringing = NULL;
03170    int outgoing = ast_test_flag(&fup->flags[1], SIP_PAGE2_OUTGOING_CALL);
03171    struct sip_user *u = NULL;
03172    struct sip_peer *p = NULL;
03173 
03174    if (option_debug > 2)
03175       ast_log(LOG_DEBUG, "Updating call counter for %s call\n", outgoing ? "outgoing" : "incoming");
03176 
03177    /* Test if we need to check call limits, in order to avoid 
03178       realtime lookups if we do not need it */
03179    if (!ast_test_flag(&fup->flags[0], SIP_CALL_LIMIT) && !ast_test_flag(&fup->flags[1], SIP_PAGE2_CALL_ONHOLD))
03180       return 0;
03181 
03182    ast_copy_string(name, fup->username, sizeof(name));
03183 
03184    /* Check the list of users only for incoming calls */
03185    if (global_limitonpeers == FALSE && !outgoing && (u = find_user(name, 1)))  {
03186       inuse = &u->inUse;
03187       call_limit = &u->call_limit;
03188       inringing = NULL;
03189    } else if ( (p = find_peer(ast_strlen_zero(fup->peername) ? name : fup->peername, NULL, 1) ) ) { /* Try to find peer */
03190       inuse = &p->inUse;
03191       call_limit = &p->call_limit;
03192       inringing = &p->inRinging;
03193       ast_copy_string(name, fup->peername, sizeof(name));
03194    } 
03195    if (!p && !u) {
03196       if (option_debug > 1)
03197          ast_log(LOG_DEBUG, "%s is not a local device, no call limit\n", name);
03198       return 0;
03199    }
03200 
03201    switch(event) {
03202    /* incoming and outgoing affects the inUse counter */
03203    case DEC_CALL_LIMIT:
03204       if ( *inuse > 0 ) {
03205          if (ast_test_flag(&fup->flags[0], SIP_INC_COUNT)) {
03206             (*inuse)--;
03207             ast_clear_flag(&fup->flags[0], SIP_INC_COUNT);
03208          }
03209       } else {
03210          *inuse = 0;
03211       }
03212       if (inringing) {
03213          if (ast_test_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING)) {
03214             if (*inringing > 0)
03215                (*inringing)--;
03216             else if (!ast_test_flag(&fup->flags[0], SIP_REALTIME) || ast_test_flag(&fup->flags[1], SIP_PAGE2_RTCACHEFRIENDS))
03217                ast_log(LOG_WARNING, "Inringing for peer '%s' < 0?\n", fup->peername);
03218             ast_clear_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING);
03219          }
03220       }
03221       if (ast_test_flag(&fup->flags[1], SIP_PAGE2_CALL_ONHOLD) && global_notifyhold) {
03222          ast_clear_flag(&fup->flags[1], SIP_PAGE2_CALL_ONHOLD);
03223          sip_peer_hold(fup, 0);
03224       }
03225       if (option_debug > 1 || sipdebug) {
03226          ast_log(LOG_DEBUG, "Call %s %s '%s' removed from call limit %d\n", outgoing ? "to" : "from", u ? "user":"peer", name, *call_limit);
03227       }
03228       break;
03229 
03230    case INC_CALL_RINGING:
03231    case INC_CALL_LIMIT:
03232       if (*call_limit > 0 ) {
03233          if (*inuse >= *call_limit) {
03234             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);
03235             if (u)
03236                ASTOBJ_UNREF(u, sip_destroy_user);
03237             else
03238                ASTOBJ_UNREF(p, sip_destroy_peer);
03239             return -1; 
03240          }
03241       }
03242       if (inringing && (event == INC_CALL_RINGING)) {
03243          if (!ast_test_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING)) {
03244             (*inringing)++;
03245             ast_set_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING);
03246          }
03247       }
03248       /* Continue */
03249       (*inuse)++;
03250       ast_set_flag(&fup->flags[0], SIP_INC_COUNT);
03251       if (option_debug > 1 || sipdebug) {
03252          ast_log(LOG_DEBUG, "Call %s %s '%s' is %d out of %d\n", outgoing ? "to" : "from", u ? "user":"peer", name, *inuse, *call_limit);
03253       }
03254       break;
03255 
03256    case DEC_CALL_RINGING:
03257       if (inringing) {
03258          if (ast_test_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING)) {
03259             if (*inringing > 0)
03260                (*inringing)--;
03261             else if (!ast_test_flag(&fup->flags[0], SIP_REALTIME) || ast_test_flag(&fup->flags[1], SIP_PAGE2_RTCACHEFRIENDS))
03262                ast_log(LOG_WARNING, "Inringing for peer '%s' < 0?\n", p->name);
03263             ast_clear_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING);
03264          }
03265       }
03266       break;
03267 
03268    default:
03269       ast_log(LOG_ERROR, "update_call_counter(%s, %d) called with no event!\n", name, event);
03270    }
03271    if (p) {
03272       ast_device_state_changed("SIP/%s", p->name);
03273       ASTOBJ_UNREF(p, sip_destroy_peer);
03274    } else /* u must be set */
03275       ASTOBJ_UNREF(u, sip_destroy_user);
03276    return 0;
03277 }

static void update_peer ( struct sip_peer p,
int  expiry 
) [static]

Update peer data in database (if used).

Definition at line 2474 of file chan_sip.c.

References sip_peer::addr, ast_test_flag, sip_peer::flags, sip_peer::fullcontact, realtime_update_peer(), SIP_PAGE2_RTCACHEFRIENDS, SIP_PAGE2_RTUPDATE, SIP_REALTIME, and sip_peer::username.

Referenced by register_verify().

02475 {
02476    int rtcachefriends = ast_test_flag(&p->flags[1], SIP_PAGE2_RTCACHEFRIENDS);
02477    if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTUPDATE) &&
02478        (ast_test_flag(&p->flags[0], SIP_REALTIME) || rtcachefriends)) {
02479       realtime_update_peer(p->name, &p->addr, p->username, rtcachefriends ? p->fullcontact : NULL, expiry);
02480    }
02481 }


Variable Documentation

struct in_addr __ourip [static]

Definition at line 1206 of file chan_sip.c.

int allow_external_domains [static]

Accept calls to external SIP domains?

Definition at line 565 of file chan_sip.c.

int apeerobjs = 0 [static]

Autocreated peer objects

Definition at line 581 of file chan_sip.c.

char* app_dtmfmode = "SIPDtmfMode" [static]

Definition at line 17533 of file chan_sip.c.

char* app_sipaddheader = "SIPAddHeader" [static]

Definition at line 17535 of file chan_sip.c.

struct sip_auth* authl = NULL [static]

Todo:
Move the sip_auth list to AST_LIST
Authentication list for realm authentication

Definition at line 1195 of file chan_sip.c.

Referenced by build_reply_digest(), reload_config(), sip_show_settings(), and unload_module().

int autocreatepeer [static]

Auto creation of peers at registration? Default off.

Definition at line 545 of file chan_sip.c.

struct sockaddr_in bindaddr = { 0, } [static]

The address we bind to

Definition at line 1200 of file chan_sip.c.

Definition at line 11698 of file chan_sip.c.

struct ast_cli_entry cli_sip[] [static]

Definition at line 17800 of file chan_sip.c.

Initial value:

   { { "sip", "debug", NULL },
   sip_do_debug_deprecated, "Enable SIP debugging",
   debug_usage }

Definition at line 17790 of file chan_sip.c.

Initial value:

   { { "sip", "no", "debug", NULL },
   sip_no_debug_deprecated, "Disable SIP debugging",
   debug_usage }

Definition at line 17795 of file chan_sip.c.

int compactheaders [static]

send compact sip headers

Definition at line 559 of file chan_sip.c.

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

Definition at line 231 of file chan_sip.c.

char debug_usage[] [static]

Definition at line 11582 of file chan_sip.c.

struct sockaddr_in debugaddr [static]

char default_callerid[AST_MAX_EXTENSION] [static]

Definition at line 525 of file chan_sip.c.

char default_context[AST_MAX_CONTEXT] [static]

Definition at line 522 of file chan_sip.c.

int default_expiry = DEFAULT_DEFAULT_EXPIRY [static]

Definition at line 192 of file chan_sip.c.

char default_fromdomain[AST_MAX_EXTENSION] [static]

Definition at line 526 of file chan_sip.c.

struct ast_jb_conf default_jbconf [static]

Global jitterbuffer configuration - by default, jb is disabled.

Definition at line 222 of file chan_sip.c.

char default_language[MAX_LANGUAGE] [static]

Definition at line 524 of file chan_sip.c.

int default_maxcallbitrate [static]

Maximum bitrate for call

Definition at line 533 of file chan_sip.c.

char default_mohinterpret[MAX_MUSICCLASS] [static]

Global setting for moh class to use when put on hold

Definition at line 530 of file chan_sip.c.

char default_mohsuggest[MAX_MUSICCLASS] [static]

Global setting for moh class to suggest when putting a bridged channel on hold

Definition at line 531 of file chan_sip.c.

char default_notifymime[AST_MAX_EXTENSION] [static]

Definition at line 527 of file chan_sip.c.

struct ast_codec_pref default_prefs [static]

Default codec prefs

Definition at line 534 of file chan_sip.c.

Referenced by build_device(), build_user(), reload_config(), set_peer_defaults(), sip_alloc(), sip_show_settings(), and temp_peer().

int default_qualify [static]

Default Qualify= setting

Definition at line 528 of file chan_sip.c.

char default_subscribecontext[AST_MAX_CONTEXT] [static]

Definition at line 523 of file chan_sip.c.

char default_vmexten[AST_MAX_EXTENSION] [static]

Definition at line 529 of file chan_sip.c.

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

Definition at line 17532 of file chan_sip.c.

char* descrip_sipaddheader [static]

Definition at line 17538 of file chan_sip.c.

int dumphistory [static]

Dump history to verbose before destroying SIP dialog

Definition at line 561 of file chan_sip.c.

int expiry = DEFAULT_EXPIRY [static]

Definition at line 193 of file chan_sip.c.

Referenced by complete_dpreply(), and register_verify().

time_t externexpire = 0 [static]

Expiration counter for re-resolving external host name in dynamic DNS

Definition at line 1203 of file chan_sip.c.

Referenced by ast_sip_ouraddrfor(), and reload_config().

char externhost[MAXHOSTNAMELEN] [static]

External host name (possibly with dynamic DNS and DHCP

Definition at line 1202 of file chan_sip.c.

Referenced by ast_sip_ouraddrfor(), and reload_config().

struct sockaddr_in externip [static]

External IP address if we are behind NAT

Definition at line 1201 of file chan_sip.c.

int externrefresh = 10 [static]

Definition at line 1204 of file chan_sip.c.

Referenced by ast_sip_ouraddrfor(), and reload_config().

int global_allowguest [static]

allow unauthenticated users/peers to connect?

Definition at line 552 of file chan_sip.c.

int global_allowsubscribe [static]

Flag for disabling ALL subscriptions, this is FALSE only if all peers are FALSE the global setting is in globals_flags[1]

Definition at line 553 of file chan_sip.c.

SIP Refer restriction scheme

Definition at line 569 of file chan_sip.c.

Send 401 Unauthorized for all failing requests

Definition at line 542 of file chan_sip.c.

int global_autoframing [static]

Turn autoframing on or off.

Definition at line 568 of file chan_sip.c.

int global_callevents [static]

Whether we send manager events or not

Definition at line 566 of file chan_sip.c.

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

int global_directrtpsetup [static]

Enable support for Direct RTP setup (no re-invites)

Definition at line 537 of file chan_sip.c.

struct ast_flags global_flags[2] = {{0}} [static]

global SIP_ flags

Definition at line 584 of file chan_sip.c.

struct ast_jb_conf global_jbconf [static]

Definition at line 229 of file chan_sip.c.

int global_limitonpeers [static]

Match call limit on peers only

Definition at line 538 of file chan_sip.c.

Match externip/externhost setting against localnet setting

Definition at line 571 of file chan_sip.c.

int global_mwitime [static]

Time between MWI checks for peers

Definition at line 555 of file chan_sip.c.

int global_notifyhold [static]

Send notifications on hold

Definition at line 541 of file chan_sip.c.

int global_notifyringing [static]

Send notifications on ringing

Definition at line 540 of file chan_sip.c.

char global_realm[MAXHOSTNAMELEN] [static]

Default realm

Definition at line 562 of file chan_sip.c.

int global_reg_timeout [static]

Definition at line 550 of file chan_sip.c.

int global_regattempts_max [static]

Registration attempts before giving up

Definition at line 551 of file chan_sip.c.

char global_regcontext[AST_MAX_CONTEXT] [static]

Context for auto-extensions

Definition at line 563 of file chan_sip.c.

int global_relaxdtmf [static]

Relax DTMF

Definition at line 546 of file chan_sip.c.

int global_rtautoclear [static]

Definition at line 539 of file chan_sip.c.

int global_rtpholdtimeout [static]

Definition at line 548 of file chan_sip.c.

int global_rtpkeepalive [static]

Send RTP keepalives

Definition at line 549 of file chan_sip.c.

int global_rtptimeout [static]

Time out call if no RTP

Definition at line 547 of file chan_sip.c.

int global_t1min [static]

T1 roundtrip time minimum

Definition at line 567 of file chan_sip.c.

int global_t38_capability = T38FAX_VERSION_0 | T38FAX_RATE_2400 | T38FAX_RATE_4800 | T38FAX_RATE_7200 | T38FAX_RATE_9600 [static]

Definition at line 832 of file chan_sip.c.

Referenced by create_addr_from_peer(), and sip_alloc().

unsigned int global_tos_audio [static]

IP type of service for audio RTP packets

Definition at line 557 of file chan_sip.c.

unsigned int global_tos_sip [static]

IP type of service for SIP packets

Definition at line 556 of file chan_sip.c.

unsigned int global_tos_video [static]

IP type of service for video RTP packets

Definition at line 558 of file chan_sip.c.

char global_useragent[AST_MAX_EXTENSION] [static]

Useragent for the SIP channel

Definition at line 564 of file chan_sip.c.

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

struct sip_pvt * iflist [static]

struct io_context* io [static]

The IO context

Definition at line 605 of file chan_sip.c.

struct ast_ha* localaddr [static]

List of local networks, on the same side of NAT as this Asterisk

Definition at line 1205 of file chan_sip.c.

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

char mandescr_show_peer[] [static]

Initial value:

 
"Description: Show one SIP peer with details on current status.\n"
"Variables: \n"
"  Peer: <name>           The peer name you want to check.\n"
"  ActionID: <id>   Optional action ID for this AMI transaction.\n"

Definition at line 10233 of file chan_sip.c.

Referenced by load_module().

char mandescr_show_peers[] [static]

Initial value:

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

Definition at line 9784 of file chan_sip.c.

Referenced by load_module().

int max_expiry = DEFAULT_MAX_EXPIRY [static]

Maximum accepted registration time

Definition at line 191 of file chan_sip.c.

int min_expiry = DEFAULT_MIN_EXPIRY [static]

Minimum accepted registration time

Definition at line 190 of file chan_sip.c.

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

char no_debug_usage[] [static]

Initial value:

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

Definition at line 11591 of file chan_sip.c.

char no_history_usage[] [static]

Initial value:

 
"Usage: sip history off\n"
"       Disables recording of SIP dialog history for debugging purposes\n"

Definition at line 11595 of file chan_sip.c.

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

Definition at line 232 of file chan_sip.c.

struct ast_config* notify_types [static]

The list of manual NOTIFY types we know how to send

Definition at line 1211 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 11531 of file chan_sip.c.

int ourport [static]

Definition at line 1208 of file chan_sip.c.

struct sockaddr_in outboundproxyip [static]

Definition at line 1207 of file chan_sip.c.

Referenced by reload_config().

int pedanticsipchecking [static]

Extra checking ? Default off

Definition at line 544 of file chan_sip.c.

struct ast_peer_list peerl [static]

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

int recordhistory [static]

Record SIP history. Off by default

Definition at line 560 of file chan_sip.c.

Referenced by referstatus2str().

struct ast_register_list regl [static]

int regobjs = 0 [static]

Registry objects

Definition at line 582 of file chan_sip.c.

int rpeerobjs = 0 [static]

Realtime peers

Definition at line 580 of file chan_sip.c.

int ruserobjs = 0 [static]

Realtime users

Definition at line 578 of file chan_sip.c.

struct sched_context* sched [static]

The scheduling context

Definition at line 604 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 11555 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 11551 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 11526 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 11559 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 11546 of file chan_sip.c.

char show_objects_usage[] [static]

Initial value:

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

Definition at line 11612 of file chan_sip.c.

char show_peer_usage[] [static]

Initial value:

"Usage: sip show peer <name> [load]\n"
"       Shows all details on one SIP peer and the current status.\n"
"       Option \"load\" forces lookup of peer in realtime storage.\n"

Definition at line 11568 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 11563 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 11578 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 11616 of file chan_sip.c.

char show_subscriptions_usage[] [static]

Initial value:

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

Definition at line 11608 of file chan_sip.c.

char show_user_usage[] [static]

Initial value:

"Usage: sip show user <name> [load]\n"
"       Shows all details on one SIP user and the current status.\n"
"       Option \"load\" forces lookup of peer in realtime storage.\n"

Definition at line 11541 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 11536 of file chan_sip.c.

Definition at line 11674 of file chan_sip.c.

struct cfsip_methods sip_methods[] [static]

struct cfsip_options sip_options[] [static]

char sip_reload_usage[] [static]

Initial value:

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

Definition at line 11604 of file chan_sip.c.

int sip_reloading = FALSE [static]

Flag for avoiding multiple reloads at the same time

Definition at line 601 of file chan_sip.c.

Reason for last reload/load of configuration

Definition at line 602 of file chan_sip.c.

struct ast_rtp_protocol sip_rtp [static]

Interface structure with callbacks used to connect to RTP module.

Definition at line 1608 of file chan_sip.c.

Referenced by load_module(), and unload_module().

struct ast_channel_tech sip_tech [static]

Definition of this channel for PBX channel registration.

Definition at line 1550 of file chan_sip.c.

Referenced by acf_channel_read(), func_header_read(), function_sipchaninfo_read(), handle_request_invite(), handle_response_invite(), load_module(), sip_dtmfmode(), sip_new(), and unload_module().

This version of the sip channel tech has no send_digit_begin callback. This is for use with channels using SIP INFO DTMF so that the core knows that the channel doesn't want DTMF BEGIN frames.

Definition at line 1576 of file chan_sip.c.

Referenced by acf_channel_read(), func_header_read(), function_sipchaninfo_read(), handle_request_invite(), handle_response_invite(), sip_dtmfmode(), and sip_new().

struct ast_udptl_protocol sip_udptl [static]

Initial value:

 {
   type: "SIP",
   get_udptl_info: sip_get_udptl_peer,
   set_udptl_peer: sip_set_udptl_peer,
}
Interface structure with callbacks used to connect to UDPTL module.

Definition at line 1617 of file chan_sip.c.

Referenced by load_module(), and unload_module().

Structure to declare a dialplan function: SIPCHANINFO.

Definition at line 11853 of file chan_sip.c.

Structure to declare a dialplan function: SIPPEER.

Definition at line 11773 of file chan_sip.c.

int sipsock = -1 [static]

Main socket for SIP network communication

Definition at line 1199 of file chan_sip.c.

Referenced by __sip_xmit(), do_monitor(), reg_source_db(), reload_config(), sipsock_read(), and unload_module().

int* sipsock_read_id [static]

ID of IO entry for sipsock FD

Definition at line 606 of file chan_sip.c.

int speerobjs = 0 [static]

Statis peers

Definition at line 579 of file chan_sip.c.

int srvlookup [static]

SRV Lookup on or off. Default is on

Definition at line 543 of file chan_sip.c.

int suserobjs = 0 [static]

Static users

Definition at line 577 of file chan_sip.c.

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

Definition at line 17531 of file chan_sip.c.

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

Definition at line 17536 of file chan_sip.c.

struct ast_user_list userl [static]


Generated on Sat Apr 12 07:12:42 2008 for Asterisk - the Open Source PBX by  doxygen 1.5.5