Sun Dec 18 20:55:46 2011

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"

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 CHECK_AUTH_BUF_INITLEN   256
#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)   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_STATECHANGEQUEUE   (1 << 9)
#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_UDPTL_DESTINATION   (1 << 28)
#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 SIPBUFSIZE   512
#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 called with p locked.
static int __sip_autodestruct (const void *data)
 Kill a SIP dialog (called by scheduler).
static int __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 called with p locked.
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 (check_auth_buf, check_auth_buf_init)
 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, struct ast_variable *alt, 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, const 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 display_nat_warning (const char *cat, int reason, struct ast_flags *flags)
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 int 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 int 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 *text)
 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_uri_cmp (const char *input1, const char *input2)
static int sip_uri_headers_cmp (const char *input1, const char *input2)
 helper routine for sip_uri_cmp
static int sip_uri_params_cmp (const char *input1, const char *input2)
 helper routine for sip_uri_cmp
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, int sipmethod, struct sip_request *req, enum xmittype 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
 sip_pvt: PVT structures are used for each SIP dialog, ie. a call, a registration, a subscribe
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
 The peer list: Peers and Friends.
static char prune_realtime_usage []
static int recordhistory
static struct c_referstatusstring referstatusstrings []
static struct ast_register_list regl
 The register list: Other SIP proxys we register with and place calls to.
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 []
 List of well-known SIP options. If we get this in a require, we should check the list and answer accordingly.
static char sip_reload_usage []
static int sip_reloading = 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
 The user list: Users and friends.


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

Referenced by initreqprep().

#define CAN_CREATE_DIALOG   1

Definition at line 369 of file chan_sip.c.

Referenced by find_call().

#define CAN_CREATE_DIALOG_UNSUPPORTED_METHOD   2

Definition at line 370 of file chan_sip.c.

Referenced by find_call().

#define CAN_NOT_CREATE_DIALOG   0

Definition at line 368 of file chan_sip.c.

#define CHECK_AUTH_BUF_INITLEN   256

Definition at line 8398 of file chan_sip.c.

Referenced by check_auth(), and transmit_fake_auth_response().

#define DEC_CALL_LIMIT   0

#define DEC_CALL_RINGING   2

Definition at line 611 of file chan_sip.c.

Referenced by handle_response_invite(), and update_call_counter().

#define DEFAULT_ALLOW_EXT_DOM   TRUE

Definition at line 508 of file chan_sip.c.

Referenced by reload_config().

#define DEFAULT_ALLOWGUEST   TRUE

Definition at line 502 of file chan_sip.c.

Referenced by reload_config().

#define DEFAULT_AUTOCREATEPEER   FALSE

Definition at line 512 of file chan_sip.c.

Referenced by reload_config().

#define DEFAULT_CALLERID   "asterisk"

Definition at line 499 of file chan_sip.c.

Referenced by reload_config().

#define DEFAULT_COMPACTHEADERS   FALSE

Definition at line 504 of file chan_sip.c.

Referenced by reload_config().

#define DEFAULT_CONTEXT   "default"

Definition at line 495 of file chan_sip.c.

Referenced by reload_config().

#define DEFAULT_DEFAULT_EXPIRY   120

Definition at line 172 of file chan_sip.c.

Referenced by reload_config().

#define DEFAULT_EXPIRY   900

Expire slowly

Definition at line 189 of file chan_sip.c.

#define DEFAULT_FREQ_NOTOK   10 * 1000

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

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

#define DEFAULT_MAX_CALL_BITRATE   (384)

Max bitrate for video

Definition at line 515 of file chan_sip.c.

Referenced by reload_config().

#define DEFAULT_MAX_EXPIRY   3600

Definition at line 174 of file chan_sip.c.

Referenced by reload_config().

#define DEFAULT_MAX_FORWARDS   "70"

Definition at line 176 of file chan_sip.c.

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

#define DEFAULT_MAXMS   2000

Qualification: Must be faster than 2 seconds by default

Definition at line 202 of file chan_sip.c.

#define DEFAULT_MIN_EXPIRY   60

Definition at line 173 of file chan_sip.c.

Referenced by reload_config().

#define DEFAULT_MOHINTERPRET   "default"

Definition at line 496 of file chan_sip.c.

Referenced by reload_config().

#define DEFAULT_MOHSUGGEST   ""

Definition at line 497 of file chan_sip.c.

Referenced by reload_config().

#define DEFAULT_MWITIME   10

Definition at line 501 of file chan_sip.c.

Referenced by reload_config().

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

Definition at line 500 of file chan_sip.c.

Referenced by reload_config().

#define DEFAULT_NOTIFYRINGING   TRUE

Definition at line 510 of file chan_sip.c.

Referenced by reload_config().

#define DEFAULT_PEDANTIC   FALSE

Definition at line 511 of file chan_sip.c.

Referenced by reload_config().

#define DEFAULT_QUALIFY   FALSE

Definition at line 513 of file chan_sip.c.

Referenced by reload_config().

#define DEFAULT_REALM   "asterisk"

Definition at line 509 of file chan_sip.c.

Referenced by reload_config().

#define DEFAULT_REGISTRATION_TIMEOUT   20

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

#define DEFAULT_SRVLOOKUP   TRUE

Recommended setting is ON

Definition at line 503 of file chan_sip.c.

Referenced by reload_config().

#define DEFAULT_T1MIN   100

100 MS for minimal roundtrip time

Definition at line 514 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 506 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 505 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 507 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 517 of file chan_sip.c.

Referenced by reload_config().

#define DEFAULT_VMEXTEN   "asterisk"

Definition at line 498 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 181 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 183 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 187 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 180 of file chan_sip.c.

Referenced by handle_response_register().

#define FALSE   0

Definition at line 154 of file chan_sip.c.

#define FLAG_FATAL   (1 << 1)

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

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

#define INC_CALL_RINGING   3

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

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

#define IPTOS_MINCOST   0x02

Definition at line 167 of file chan_sip.c.

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

Definition at line 197 of file chan_sip.c.

#define MAX_AUTHTRIES   3

Try authentication three times, then fail

Definition at line 212 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 1025 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 207 of file chan_sip.c.

#define NO_RTP   0

Definition at line 236 of file chan_sip.c.

#define NOT_SUPPORTED   0

Definition at line 409 of file chan_sip.c.

#define RTP   1

Definition at line 235 of file chan_sip.c.

#define SDP_MAX_RTPMAP_CODECS   32

Maximum number of codecs allowed in received SDP

Definition at line 218 of file chan_sip.c.

Referenced by process_sdp().

#define SDP_SAMPLE_RATE (  )     8000

Note:
G.722 actually is supposed to specified as 8 kHz, even though it is really 16 kHz. Update this macro for other formats as they are added in the future.

Definition at line 6439 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 716 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 757 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 745 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 746 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 731 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 736 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 734 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 735 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 730 of file chan_sip.c.

#define SIP_G726_NONSTANDARD   (1 << 31)

Use non-standard packing for G726-32 data

Definition at line 760 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 759 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 750 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 749 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 214 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 215 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 216 of file chan_sip.c.

#define SIP_NAT   (3 << 18)

#define SIP_NAT_ALWAYS   (3 << 18)

NAT Both ROUTE and RFC3581

Definition at line 742 of file chan_sip.c.

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

#define SIP_NAT_NEVER   (0 << 18)

No nat support

Definition at line 739 of file chan_sip.c.

Referenced by handle_common_options(), and nat2str().

#define SIP_NAT_RFC3581   (1 << 18)

NAT RFC3581

Definition at line 740 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 721 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 718 of file chan_sip.c.

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

#define SIP_OPT_100REL   (1 << 1)

Definition at line 412 of file chan_sip.c.

#define SIP_OPT_EARLY_SESSION   (1 << 3)

Definition at line 414 of file chan_sip.c.

#define SIP_OPT_EVENTLIST   (1 << 11)

Definition at line 422 of file chan_sip.c.

#define SIP_OPT_GRUU   (1 << 12)

Definition at line 423 of file chan_sip.c.

#define SIP_OPT_HISTINFO   (1 << 15)

Definition at line 426 of file chan_sip.c.

#define SIP_OPT_JOIN   (1 << 4)

Definition at line 415 of file chan_sip.c.

#define SIP_OPT_NOREFERSUB   (1 << 14)

Definition at line 425 of file chan_sip.c.

#define SIP_OPT_PATH   (1 << 5)

Definition at line 416 of file chan_sip.c.

#define SIP_OPT_PRECONDITION   (1 << 7)

Definition at line 418 of file chan_sip.c.

#define SIP_OPT_PREF   (1 << 6)

Definition at line 417 of file chan_sip.c.

#define SIP_OPT_PRIVACY   (1 << 8)

Definition at line 419 of file chan_sip.c.

#define SIP_OPT_REPLACES   (1 << 0)

Definition at line 411 of file chan_sip.c.

Referenced by handle_request_invite().

#define SIP_OPT_RESPRIORITY   (1 << 16)

Definition at line 427 of file chan_sip.c.

#define SIP_OPT_SDP_ANAT   (1 << 9)

Definition at line 420 of file chan_sip.c.

#define SIP_OPT_SEC_AGREE   (1 << 10)

Definition at line 421 of file chan_sip.c.

#define SIP_OPT_TARGET_DIALOG   (1 << 13)

Definition at line 424 of file chan_sip.c.

#define SIP_OPT_TIMER   (1 << 2)

Definition at line 413 of file chan_sip.c.

#define SIP_OUTGOING   (1 << 13)

#define SIP_PAGE2_ALLOWOVERLAP   (1 << 17)

Allow overlap dialing ?

Definition at line 784 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 783 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 796 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 792 of file chan_sip.c.

Referenced by change_hold_state().

#define SIP_PAGE2_CALL_ONHOLD_INACTIVE   (3 << 23)

23: Inactive hold

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

Referenced by add_sdp(), and change_hold_state().

#define SIP_PAGE2_DEBUG   (3 << 11)

Definition at line 777 of file chan_sip.c.

#define SIP_PAGE2_DEBUG_CONFIG   (1 << 11)

Definition at line 778 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 780 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 776 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 786 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 797 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 772 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 771 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 773 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 770 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 781 of file chan_sip.c.

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

#define SIP_PAGE2_STATECHANGEQUEUE   (1 << 9)

D: Unsent state pending change exists

Definition at line 775 of file chan_sip.c.

Referenced by cb_extensionstate(), and handle_response().

#define SIP_PAGE2_SUBSCRIBEMWIONLY   (1 << 18)

Only issue MWI notification if subscribed to

Definition at line 785 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 787 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 789 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 790 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 788 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_UDPTL_DESTINATION   (1 << 28)

28: Use source IP of RTP as destination if NAT is enabled

Definition at line 798 of file chan_sip.c.

Referenced by handle_common_options(), and process_sdp().

#define SIP_PAGE2_VIDEOSUPPORT   (1 << 15)

#define SIP_PENDINGBYE   (1 << 6)

Need to send bye after we ack?

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

Referenced by handle_request().

#define SIP_PKT_IGNORE_RESP   (1 << 3)

Resp ignore - ???

Definition at line 808 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 806 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 752 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 753 of file chan_sip.c.

Referenced by sip_indicate(), and sip_show_settings().

#define SIP_PROG_INBAND_NO   (1 << 25)

Definition at line 754 of file chan_sip.c.

Referenced by handle_common_options(), and sip_show_settings().

#define SIP_PROG_INBAND_YES   (2 << 25)

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

Referenced by sip_indicate(), and sip_write().

#define SIP_PROMISCREDIR   (1 << 8)

Promiscuous redirection

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

Referenced by sip_indicate().

#define SIP_SENDRPID   (1 << 29)

Remote Party-ID Support

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

Referenced by sip_call(), and sip_sipredirect().

#define SIP_TRUSTRPID   (1 << 9)

Trust RPID headers?

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

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

#define SIPBUFSIZE   512

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

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

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

#define SUPPORTED_EXTENSIONS   "replaces"

#define T38FAX_FILL_BIT_REMOVAL   (1 << 0)

Default: 0 (unset)

Definition at line 812 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 831 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 832 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 827 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 828 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 829 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 830 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 817 of file chan_sip.c.

Referenced by add_t38_sdp(), and process_sdp().

#define T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF   (0 << 3)

Definition at line 816 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 814 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 813 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 820 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 819 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 821 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 823 of file chan_sip.c.

Referenced by add_t38_sdp().

#define T38FAX_VERSION_0   (0 << 6)

Version 0

Definition at line 824 of file chan_sip.c.

Referenced by add_t38_sdp(), and process_sdp().

#define T38FAX_VERSION_1   (1 << 6)

Version 1

Definition at line 825 of file chan_sip.c.

Referenced by add_t38_sdp(), and process_sdp().

#define TRUE   1

Definition at line 158 of file chan_sip.c.

#define UNLINK ( element,
head,
prev   ) 

--- some list management macros.

Definition at line 1603 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 165 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 344 of file chan_sip.c.

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

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

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

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

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

Enumerator:
PARSE_REGISTER_FAILED 
PARSE_REGISTER_UPDATE 
PARSE_REGISTER_QUERY 

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

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

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

00338                    {
00339    PROXY_AUTH,
00340    WWW_AUTH,
00341 };

enum sip_result

Enumerator:
AST_SUCCESS 
AST_FAILURE 

Definition at line 247 of file chan_sip.c.

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

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

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

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

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

Enumerator:
NONE 
XPIDF_XML 
DIALOG_INFO_XML 
CPIM_PIDF_XML 
PIDF_XML 
MWI_NOTIFICATION 

Definition at line 288 of file chan_sip.c.

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

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

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

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

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

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

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


Function Documentation

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

Definition at line 4251 of file chan_sip.c.

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

04252 {
04253    int pass;
04254 
04255    /*
04256     * Technically you can place arbitrary whitespace both before and after the ':' in
04257     * a header, although RFC3261 clearly says you shouldn't before, and place just
04258     * one afterwards.  If you shouldn't do it, what absolute idiot decided it was 
04259     * a good idea to say you can do it, and if you can do it, why in the hell would.
04260     * you say you shouldn't.
04261     * Anyways, pedanticsipchecking controls whether we allow spaces before ':',
04262     * and we always allow spaces after that for compatibility.
04263     */
04264    for (pass = 0; name && pass < 2;pass++) {
04265       int x, len = strlen(name);
04266       for (x=*start; x<req->headers; x++) {
04267          if (!strncasecmp(req->header[x], name, len)) {
04268             char *r = req->header[x] + len;  /* skip name */
04269             if (pedanticsipchecking)
04270                r = ast_skip_blanks(r);
04271 
04272             if (*r == ':') {
04273                *start = x+1;
04274                return ast_skip_blanks(r+1);
04275             }
04276          }
04277       }
04278       if (pass == 0) /* Try aliases */
04279          name = find_alias(name, NULL);
04280    }
04281 
04282    /* Don't return NULL, so get_header is always a valid pointer */
04283    return "";
04284 }

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

Acknowledges receipt of a packet and stops retransmission called with p locked.

Definition at line 2143 of file chan_sip.c.

References ast_log(), ast_sched_del(), ast_test_flag, sip_pkt::data, DEADLOCK_AVOIDANCE, 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().

02144 {
02145    struct sip_pkt *cur, *prev = NULL;
02146 
02147    /* Just in case... */
02148    char *msg;
02149    int res = FALSE;
02150 
02151    msg = sip_methods[sipmethod].text;
02152 
02153    for (cur = p->packets; cur; prev = cur, cur = cur->next) {
02154       if ((cur->seqno == seqno) && ((ast_test_flag(cur, FLAG_RESPONSE)) == resp) &&
02155          ((ast_test_flag(cur, FLAG_RESPONSE)) || 
02156           (!strncasecmp(msg, cur->data, strlen(msg)) && (cur->data[strlen(msg)] < 33)))) {
02157          if (!resp && (seqno == p->pendinginvite)) {
02158             if (option_debug)
02159                ast_log(LOG_DEBUG, "Acked pending invite %d\n", p->pendinginvite);
02160             p->pendinginvite = 0;
02161          }
02162          /* this is our baby */
02163          res = TRUE;
02164          UNLINK(cur, p->packets, prev);
02165          if (cur->retransid > -1) {
02166             if (sipdebug && option_debug > 3)
02167                ast_log(LOG_DEBUG, "** SIP TIMER: Cancelling retransmit of packet (reply received) Retransid #%d\n", cur->retransid);
02168          }
02169          /* This odd section is designed to thwart a 
02170           * race condition in the packet scheduler. There are
02171           * two conditions under which deleting the packet from the
02172           * scheduler can fail.
02173           *
02174           * 1. The packet has been removed from the scheduler because retransmission
02175           * is being attempted. The problem is that if the packet is currently attempting
02176           * retransmission and we are at this point in the code, then that MUST mean
02177           * that retrans_pkt is waiting on p's lock. Therefore we will relinquish the
02178           * lock temporarily to allow retransmission.
02179           *
02180           * 2. The packet has reached its maximum number of retransmissions and has
02181           * been permanently removed from the packet scheduler. If this is the case, then
02182           * the packet's retransid will be set to -1. The atomicity of the setting and checking
02183           * of the retransid to -1 is ensured since in both cases p's lock is held.
02184           */
02185          while (cur->retransid > -1 && ast_sched_del(sched, cur->retransid)) {
02186             DEADLOCK_AVOIDANCE(&p->lock);
02187          }
02188          free(cur);
02189          break;
02190       }
02191    }
02192    if (option_debug)
02193       ast_log(LOG_DEBUG, "Stopping retransmission on '%s' of %s %d: Match %s\n", p->callid, resp ? "Response" : "Request", seqno, res == FALSE ? "Not Found" : "Found");
02194 }

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

Kill a SIP dialog (called by scheduler).

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

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

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

Execute destruction of SIP dialog structure, release memory.

Definition at line 3069 of file chan_sip.c.

References ast_channel::_softhangup, ast_channel_lock, ast_channel_unlock, ast_extension_state_del(), AST_LIST_REMOVE_HEAD, ast_log(), ast_mutex_destroy(), ast_rtp_destroy(), ast_rtp_get_bridged(), AST_SCHED_DEL, AST_SOFTHANGUP_DEV, 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_destroy_peer(), 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().

03070 {
03071    struct sip_pvt *cur, *prev = NULL;
03072    struct sip_pkt *cp;
03073 
03074    /* We absolutely cannot destroy the rtp struct while a bridge is active or we WILL crash */
03075    if (p->rtp && ast_rtp_get_bridged(p->rtp)) {
03076       ast_verbose("Bridge still active.  Delaying destroy of SIP dialog '%s' Method: %s\n", p->callid, sip_methods[p->method].text);
03077       return -1;
03078    }
03079 
03080    if (p->vrtp && ast_rtp_get_bridged(p->vrtp)) {
03081       ast_verbose("Bridge still active.  Delaying destroy of SIP dialog '%s' Method: %s\n", p->callid, sip_methods[p->method].text);
03082       return -1;
03083    }
03084 
03085    if (sip_debug_test_pvt(p) || option_debug > 2)
03086       ast_verbose("Really destroying SIP dialog '%s' Method: %s\n", p->callid, sip_methods[p->method].text);
03087 
03088    if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) {
03089       update_call_counter(p, DEC_CALL_LIMIT);
03090       if (option_debug > 1)
03091          ast_log(LOG_DEBUG, "This call did not properly clean up call limits. Call ID %s\n", p->callid);
03092    }
03093 
03094    /* Unlink us from the owner if we have one */
03095    if (p->owner) {
03096       if (lockowner)
03097          ast_channel_lock(p->owner);
03098       if (option_debug)
03099          ast_log(LOG_DEBUG, "Detaching from %s\n", p->owner->name);
03100       p->owner->tech_pvt = NULL;
03101       /* Make sure that the channel knows its backend is going away */
03102       p->owner->_softhangup |= AST_SOFTHANGUP_DEV;
03103       if (lockowner)
03104          ast_channel_unlock(p->owner);
03105       /* Give the channel a chance to react before deallocation */
03106       usleep(1);
03107    }
03108 
03109    /* Remove link from peer to subscription of MWI */
03110    if (p->relatedpeer) {
03111       p->relatedpeer->mwipvt = NULL;
03112       ASTOBJ_UNREF(p->relatedpeer, sip_destroy_peer);
03113    }
03114 
03115    if (dumphistory)
03116       sip_dump_history(p);
03117 
03118    if (p->options)
03119       free(p->options);
03120 
03121    if (p->stateid > -1)
03122       ast_extension_state_del(p->stateid, NULL);
03123    AST_SCHED_DEL(sched, p->initid);
03124    AST_SCHED_DEL(sched, p->waitid);
03125    AST_SCHED_DEL(sched, p->autokillid);
03126 
03127    if (p->rtp) {
03128       ast_rtp_destroy(p->rtp);
03129    }
03130    if (p->vrtp) {
03131       ast_rtp_destroy(p->vrtp);
03132    }
03133    if (p->udptl)
03134       ast_udptl_destroy(p->udptl);
03135    if (p->refer)
03136       free(p->refer);
03137    if (p->route) {
03138       free_old_route(p->route);
03139       p->route = NULL;
03140    }
03141    if (p->registry) {
03142       if (p->registry->call == p)
03143          p->registry->call = NULL;
03144       ASTOBJ_UNREF(p->registry, sip_registry_destroy);
03145    }
03146 
03147    /* Clear history */
03148    if (p->history) {
03149       struct sip_history *hist;
03150       while ( (hist = AST_LIST_REMOVE_HEAD(p->history, list)) ) {
03151          free(hist);
03152          p->history_entries--;
03153       }
03154       free(p->history);
03155       p->history = NULL;
03156    }
03157 
03158    for (prev = NULL, cur = iflist; cur; prev = cur, cur = cur->next) {
03159       if (cur == p) {
03160          UNLINK(cur, iflist, prev);
03161          break;
03162       }
03163    }
03164    if (!cur) {
03165       ast_log(LOG_WARNING, "Trying to destroy \"%s\", not found in dialog list?!?! \n", p->callid);
03166       return 0;
03167    } 
03168 
03169    /* remove all current packets in this dialog */
03170    while((cp = p->packets)) {
03171       p->packets = p->packets->next;
03172       AST_SCHED_DEL(sched, cp->retransid);
03173       free(cp);
03174    }
03175    if (p->chanvars) {
03176       ast_variables_destroy(p->chanvars);
03177       p->chanvars = NULL;
03178    }
03179    ast_mutex_destroy(&p->lock);
03180 
03181    ast_string_field_free_memory(p);
03182 
03183    free(p);
03184    return 0;
03185 }

static int __sip_do_register ( struct sip_registry r  )  [static]

Register with SIP proxy.

Definition at line 7494 of file chan_sip.c.

References SIP_REGISTER, and transmit_register().

Referenced by sip_reregister().

07495 {
07496    int res;
07497 
07498    res = transmit_register(r, SIP_REGISTER, NULL, NULL);
07499    return res;
07500 }

static void __sip_pretend_ack ( struct sip_pvt p  )  [static]

Pretend to ack all packets called with p locked.

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

02199 {
02200    struct sip_pkt *cur = NULL;
02201 
02202    while (p->packets) {
02203       int method;
02204       if (cur == p->packets) {
02205          ast_log(LOG_WARNING, "Have a packet that doesn't want to give up! %s\n", sip_methods[cur->method].text);
02206          return;
02207       }
02208       cur = p->packets;
02209       method = (cur->method) ? cur->method : find_sip_method(cur->data);
02210       __sip_ack(p, cur->seqno, ast_test_flag(cur, FLAG_RESPONSE), method);
02211    }
02212 }

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

References __sip_xmit(), append_history, ast_calloc, AST_FAILURE, ast_log(), ast_sched_add_variable(), 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().

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

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

02216 {
02217    struct sip_pkt *cur;
02218    int res = -1;
02219 
02220    for (cur = p->packets; cur; cur = cur->next) {
02221       if (cur->seqno == seqno && ast_test_flag(cur, FLAG_RESPONSE) == resp &&
02222          (ast_test_flag(cur, FLAG_RESPONSE) || method_match(sipmethod, cur->data))) {
02223          /* this is our baby */
02224          if (cur->retransid > -1) {
02225             if (option_debug > 3 && sipdebug)
02226                ast_log(LOG_DEBUG, "*** SIP TIMER: Cancelling retransmission #%d - %s (got response)\n", cur->retransid, sip_methods[sipmethod].text);
02227          }
02228          AST_SCHED_DEL(sched, cur->retransid);
02229          res = 0;
02230          break;
02231       }
02232    }
02233    if (option_debug)
02234       ast_log(LOG_DEBUG, "(Provisional) Stopping retransmission (but retaining packet) on '%s' %s %d: %s\n", p->callid, resp ? "Response" : "Request", seqno, res == -1 ? "Not Found" : "Found");
02235    return res;
02236 }

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

SIP show channels CLI (main function).

Definition at line 10942 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, SIPBUFSIZE, sip_refer::status, sip_pvt::subscribed, and subscription_type2str().

Referenced by sip_show_channels(), and sip_show_subscriptions().

10943 {
10944 #define FORMAT3 "%-15.15s  %-10.10s  %-11.11s  %-15.15s  %-13.13s  %-15.15s %-10.10s\n"
10945 #define FORMAT2 "%-15.15s  %-10.10s  %-11.11s  %-11.11s  %-15.15s  %-7.7s  %-15.15s\n"
10946 #define FORMAT  "%-15.15s  %-10.10s  %-11.11s  %5.5d/%5.5d  %-15.15s  %-3.3s %-3.3s  %-15.15s %-10.10s\n"
10947    struct sip_pvt *cur;
10948    int numchans = 0;
10949    char *referstatus = NULL;
10950 
10951    if (argc != 3)
10952       return RESULT_SHOWUSAGE;
10953    ast_mutex_lock(&iflock);
10954    cur = iflist;
10955    if (!subscriptions)
10956       ast_cli(fd, FORMAT2, "Peer", "User/ANR", "Call ID", "Seq (Tx/Rx)", "Format", "Hold", "Last Message");
10957    else 
10958       ast_cli(fd, FORMAT3, "Peer", "User", "Call ID", "Extension", "Last state", "Type", "Mailbox");
10959    for (; cur; cur = cur->next) {
10960       referstatus = "";
10961       if (cur->refer) { /* SIP transfer in progress */
10962          referstatus = referstatus2str(cur->refer->status);
10963       }
10964       if (cur->subscribed == NONE && !subscriptions) {
10965          char formatbuf[SIPBUFSIZE/2];
10966          ast_cli(fd, FORMAT, ast_inet_ntoa(cur->sa.sin_addr), 
10967             S_OR(cur->username, S_OR(cur->cid_num, "(None)")),
10968             cur->callid, 
10969             cur->ocseq, cur->icseq,
10970             ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->owner ? cur->owner->nativeformats : 0),
10971             ast_test_flag(&cur->flags[1], SIP_PAGE2_CALL_ONHOLD) ? "Yes" : "No",
10972             ast_test_flag(&cur->flags[0], SIP_NEEDDESTROY) ? "(d)" : "",
10973             cur->lastmsg ,
10974             referstatus
10975          );
10976          numchans++;
10977       }
10978       if (cur->subscribed != NONE && subscriptions) {
10979          ast_cli(fd, FORMAT3, ast_inet_ntoa(cur->sa.sin_addr),
10980             S_OR(cur->username, S_OR(cur->cid_num, "(None)")), 
10981                cur->callid,
10982             /* the 'complete' exten/context is hidden in the refer_to field for subscriptions */
10983             cur->subscribed == MWI_NOTIFICATION ? "--" : cur->subscribeuri,
10984             cur->subscribed == MWI_NOTIFICATION ? "<none>" : ast_extension_state2str(cur->laststate), 
10985             subscription_type2str(cur->subscribed),
10986             cur->subscribed == MWI_NOTIFICATION ? (cur->relatedpeer ? cur->relatedpeer->mailbox : "<none>") : "<none>"
10987 );
10988          numchans++;
10989       }
10990    }
10991    ast_mutex_unlock(&iflock);
10992    if (!subscriptions)
10993       ast_cli(fd, "%d active SIP channel%s\n", numchans, (numchans != 1) ? "s" : "");
10994    else
10995       ast_cli(fd, "%d active SIP subscription%s\n", numchans, (numchans != 1) ? "s" : "");
10996    return RESULT_SUCCESS;
10997 #undef FORMAT
10998 #undef FORMAT2
10999 #undef FORMAT3
11000 }

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

Transmit SIP message.

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

01771 {
01772    int res;
01773    const struct sockaddr_in *dst = sip_real_dst(p);
01774    res = sendto(sipsock, data, len, 0, (const struct sockaddr *)dst, sizeof(struct sockaddr_in));
01775 
01776    if (res == -1) {
01777       switch (errno) {
01778       case EBADF:       /* Bad file descriptor - seems like this is generated when the host exist, but doesn't accept the UDP packet */
01779       case EHOSTUNREACH:   /* Host can't be reached */
01780       case ENETDOWN:       /* Inteface down */
01781       case ENETUNREACH: /* Network failure */
01782       case ECONNREFUSED:      /* ICMP port unreachable */ 
01783          res = XMIT_ERROR; /* Don't bother with trying to transmit again */
01784       }
01785    }
01786    if (res != len)
01787       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));
01788    return res;
01789 }

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

06034 {
06035    struct sip_request resp;
06036    int seqno = 0;
06037 
06038    if (reliable && (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1)) {
06039       ast_log(LOG_WARNING, "Unable to determine sequence number from '%s'\n", get_header(req, "CSeq"));
06040       return -1;
06041    }
06042    respprep(&resp, p, msg, req);
06043    add_header_contentLength(&resp, 0);
06044    /* If we are cancelling an incoming invite for some reason, add information
06045       about the reason why we are doing this in clear text */
06046    if (p->method == SIP_INVITE && msg[0] != '1' && p->owner && p->owner->hangupcause) {
06047       char buf[10];
06048 
06049       add_header(&resp, "X-Asterisk-HangupCause", ast_cause2str(p->owner->hangupcause));
06050       snprintf(buf, sizeof(buf), "%d", p->owner->hangupcause);
06051       add_header(&resp, "X-Asterisk-HangupCauseCode", buf);
06052    }
06053    return send_response(p, &resp, reliable, seqno);
06054 }

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

10501 {
10502    char status[30] = "";
10503    char cbuf[256];
10504    struct sip_peer *peer;
10505    char codec_buf[512];
10506    struct ast_codec_pref *pref;
10507    struct ast_variable *v;
10508    struct sip_auth *auth;
10509    int x = 0, codec = 0, load_realtime;
10510    int realtimepeers;
10511 
10512    realtimepeers = ast_check_realtime("sippeers");
10513 
10514    if (argc < 4)
10515       return RESULT_SHOWUSAGE;
10516 
10517    load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? TRUE : FALSE;
10518    peer = find_peer(argv[3], NULL, load_realtime);
10519    if (s) {    /* Manager */
10520       if (peer) {
10521          const char *id = astman_get_header(m,"ActionID");
10522 
10523          astman_append(s, "Response: Success\r\n");
10524          if (!ast_strlen_zero(id))
10525             astman_append(s, "ActionID: %s\r\n",id);
10526       } else {
10527          snprintf (cbuf, sizeof(cbuf), "Peer %s not found.\n", argv[3]);
10528          astman_send_error(s, m, cbuf);
10529          return 0;
10530       }
10531    }
10532    if (peer && type==0 ) { /* Normal listing */
10533       ast_cli(fd,"\n\n");
10534       ast_cli(fd, "  * Name       : %s\n", peer->name);
10535       if (realtimepeers) { /* Realtime is enabled */
10536          ast_cli(fd, "  Realtime peer: %s\n", ast_test_flag(&peer->flags[0], SIP_REALTIME) ? "Yes, cached" : "No");
10537       }
10538       ast_cli(fd, "  Secret       : %s\n", ast_strlen_zero(peer->secret)?"<Not set>":"<Set>");
10539       ast_cli(fd, "  MD5Secret    : %s\n", ast_strlen_zero(peer->md5secret)?"<Not set>":"<Set>");
10540       for (auth = peer->auth; auth; auth = auth->next) {
10541          ast_cli(fd, "  Realm-auth   : Realm %-15.15s User %-10.20s ", auth->realm, auth->username);
10542          ast_cli(fd, "%s\n", !ast_strlen_zero(auth->secret)?"<Secret set>":(!ast_strlen_zero(auth->md5secret)?"<MD5secret set>" : "<Not set>"));
10543       }
10544       ast_cli(fd, "  Context      : %s\n", peer->context);
10545       ast_cli(fd, "  Subscr.Cont. : %s\n", S_OR(peer->subscribecontext, "<Not set>") );
10546       ast_cli(fd, "  Language     : %s\n", peer->language);
10547       if (!ast_strlen_zero(peer->accountcode))
10548          ast_cli(fd, "  Accountcode  : %s\n", peer->accountcode);
10549       ast_cli(fd, "  AMA flags    : %s\n", ast_cdr_flags2str(peer->amaflags));
10550       ast_cli(fd, "  Transfer mode: %s\n", transfermode2str(peer->allowtransfer));
10551       ast_cli(fd, "  CallingPres  : %s\n", ast_describe_caller_presentation(peer->callingpres));
10552       if (!ast_strlen_zero(peer->fromuser))
10553          ast_cli(fd, "  FromUser     : %s\n", peer->fromuser);
10554       if (!ast_strlen_zero(peer->fromdomain))
10555          ast_cli(fd, "  FromDomain   : %s\n", peer->fromdomain);
10556       ast_cli(fd, "  Callgroup    : ");
10557       print_group(fd, peer->callgroup, 0);
10558       ast_cli(fd, "  Pickupgroup  : ");
10559       print_group(fd, peer->pickupgroup, 0);
10560       ast_cli(fd, "  Mailbox      : %s\n", peer->mailbox);
10561       ast_cli(fd, "  VM Extension : %s\n", peer->vmexten);
10562       ast_cli(fd, "  LastMsgsSent : %d/%d\n", (peer->lastmsgssent & 0x7fff0000) >> 16, peer->lastmsgssent & 0xffff);
10563       ast_cli(fd, "  Call limit   : %d\n", peer->call_limit);
10564       ast_cli(fd, "  Dynamic      : %s\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)?"Yes":"No"));
10565       ast_cli(fd, "  Callerid     : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>"));
10566       ast_cli(fd, "  MaxCallBR    : %d kbps\n", peer->maxcallbitrate);
10567       ast_cli(fd, "  Expire       : %ld\n", ast_sched_when(sched, peer->expire));
10568       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)));
10569       ast_cli(fd, "  Nat          : %s\n", nat2str(ast_test_flag(&peer->flags[0], SIP_NAT)));
10570       ast_cli(fd, "  ACL          : %s\n", (peer->ha?"Yes":"No"));
10571       ast_cli(fd, "  T38 pt UDPTL : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT_UDPTL)?"Yes":"No");
10572 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS
10573       ast_cli(fd, "  T38 pt RTP   : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT_RTP)?"Yes":"No");
10574       ast_cli(fd, "  T38 pt TCP   : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT_TCP)?"Yes":"No");
10575 #endif
10576       ast_cli(fd, "  CanReinvite  : %s\n", ast_test_flag(&peer->flags[0], SIP_CAN_REINVITE)?"Yes":"No");
10577       ast_cli(fd, "  PromiscRedir : %s\n", ast_test_flag(&peer->flags[0], SIP_PROMISCREDIR)?"Yes":"No");
10578       ast_cli(fd, "  User=Phone   : %s\n", ast_test_flag(&peer->flags[0], SIP_USEREQPHONE)?"Yes":"No");
10579       ast_cli(fd, "  Video Support: %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_VIDEOSUPPORT)?"Yes":"No");
10580       ast_cli(fd, "  Trust RPID   : %s\n", ast_test_flag(&peer->flags[0], SIP_TRUSTRPID) ? "Yes" : "No");
10581       ast_cli(fd, "  Send RPID    : %s\n", ast_test_flag(&peer->flags[0], SIP_SENDRPID) ? "Yes" : "No");
10582       ast_cli(fd, "  Subscriptions: %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE) ? "Yes" : "No");
10583       ast_cli(fd, "  Overlap dial : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWOVERLAP) ? "Yes" : "No");
10584 
10585       /* - is enumerated */
10586       ast_cli(fd, "  DTMFmode     : %s\n", dtmfmode2str(ast_test_flag(&peer->flags[0], SIP_DTMF)));
10587       ast_cli(fd, "  LastMsg      : %d\n", peer->lastmsg);
10588       ast_cli(fd, "  ToHost       : %s\n", peer->tohost);
10589       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));
10590       ast_cli(fd, "  Defaddr->IP  : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port));
10591       if (!ast_strlen_zero(global_regcontext))
10592          ast_cli(fd, "  Reg. exten   : %s\n", peer->regexten);
10593       ast_cli(fd, "  Def. Username: %s\n", peer->username);
10594       ast_cli(fd, "  SIP Options  : ");
10595       if (peer->sipoptions) {
10596          int lastoption = -1;
10597          for (x=0 ; (x < (sizeof(sip_options) / sizeof(sip_options[0]))); x++) {
10598             if (sip_options[x].id != lastoption) {
10599                if (peer->sipoptions & sip_options[x].id)
10600                   ast_cli(fd, "%s ", sip_options[x].text);
10601                lastoption = x;
10602             }
10603          }
10604       } else
10605          ast_cli(fd, "(none)");
10606 
10607       ast_cli(fd, "\n");
10608       ast_cli(fd, "  Codecs       : ");
10609       ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability);
10610       ast_cli(fd, "%s\n", codec_buf);
10611       ast_cli(fd, "  Codec Order  : (");
10612       print_codec_to_cli(fd, &peer->prefs);
10613       ast_cli(fd, ")\n");
10614 
10615       ast_cli(fd, "  Auto-Framing:  %s \n", peer->autoframing ? "Yes" : "No");
10616       ast_cli(fd, "  Status       : ");
10617       peer_status(peer, status, sizeof(status));
10618       ast_cli(fd, "%s\n",status);
10619       ast_cli(fd, "  Useragent    : %s\n", peer->useragent);
10620       ast_cli(fd, "  Reg. Contact : %s\n", peer->fullcontact);
10621       if (peer->chanvars) {
10622          ast_cli(fd, "  Variables    :\n");
10623          for (v = peer->chanvars ; v ; v = v->next)
10624             ast_cli(fd, "                 %s = %s\n", v->name, v->value);
10625       }
10626       ast_cli(fd,"\n");
10627       ASTOBJ_UNREF(peer,sip_destroy_peer);
10628    } else  if (peer && type == 1) { /* manager listing */
10629       char buf[256];
10630       astman_append(s, "Channeltype: SIP\r\n");
10631       astman_append(s, "ObjectName: %s\r\n", peer->name);
10632       astman_append(s, "ChanObjectType: peer\r\n");
10633       astman_append(s, "SecretExist: %s\r\n", ast_strlen_zero(peer->secret)?"N":"Y");
10634       astman_append(s, "MD5SecretExist: %s\r\n", ast_strlen_zero(peer->md5secret)?"N":"Y");
10635       astman_append(s, "Context: %s\r\n", peer->context);
10636       astman_append(s, "Language: %s\r\n", peer->language);
10637       if (!ast_strlen_zero(peer->accountcode))
10638          astman_append(s, "Accountcode: %s\r\n", peer->accountcode);
10639       astman_append(s, "AMAflags: %s\r\n", ast_cdr_flags2str(peer->amaflags));
10640       astman_append(s, "CID-CallingPres: %s\r\n", ast_describe_caller_presentation(peer->callingpres));
10641       if (!ast_strlen_zero(peer->fromuser))
10642          astman_append(s, "SIP-FromUser: %s\r\n", peer->fromuser);
10643       if (!ast_strlen_zero(peer->fromdomain))
10644          astman_append(s, "SIP-FromDomain: %s\r\n", peer->fromdomain);
10645       astman_append(s, "Callgroup: ");
10646       astman_append(s, "%s\r\n", ast_print_group(buf, sizeof(buf), peer->callgroup));
10647       astman_append(s, "Pickupgroup: ");
10648       astman_append(s, "%s\r\n", ast_print_group(buf, sizeof(buf), peer->pickupgroup));
10649       astman_append(s, "VoiceMailbox: %s\r\n", peer->mailbox);
10650       astman_append(s, "TransferMode: %s\r\n", transfermode2str(peer->allowtransfer));
10651       astman_append(s, "LastMsgsSent: %d\r\n", peer->lastmsgssent);
10652       astman_append(s, "Call-limit: %d\r\n", peer->call_limit);
10653       astman_append(s, "MaxCallBR: %d kbps\r\n", peer->maxcallbitrate);
10654       astman_append(s, "Dynamic: %s\r\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)?"Y":"N"));
10655       astman_append(s, "Callerid: %s\r\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, ""));
10656       astman_append(s, "RegExpire: %ld seconds\r\n", ast_sched_when(sched,peer->expire));
10657       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)));
10658       astman_append(s, "SIP-NatSupport: %s\r\n", nat2str(ast_test_flag(&peer->flags[0], SIP_NAT)));
10659       astman_append(s, "ACL: %s\r\n", (peer->ha?"Y":"N"));
10660       astman_append(s, "SIP-CanReinvite: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_CAN_REINVITE)?"Y":"N"));
10661       astman_append(s, "SIP-PromiscRedir: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_PROMISCREDIR)?"Y":"N"));
10662       astman_append(s, "SIP-UserPhone: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_USEREQPHONE)?"Y":"N"));
10663       astman_append(s, "SIP-VideoSupport: %s\r\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_VIDEOSUPPORT)?"Y":"N"));
10664 
10665       /* - is enumerated */
10666       astman_append(s, "SIP-DTMFmode: %s\r\n", dtmfmode2str(ast_test_flag(&peer->flags[0], SIP_DTMF)));
10667       astman_append(s, "SIPLastMsg: %d\r\n", peer->lastmsg);
10668       astman_append(s, "ToHost: %s\r\n", peer->tohost);
10669       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));
10670       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));
10671       astman_append(s, "Default-Username: %s\r\n", peer->username);
10672       if (!ast_strlen_zero(global_regcontext))
10673          astman_append(s, "RegExtension: %s\r\n", peer->regexten);
10674       astman_append(s, "Codecs: ");
10675       ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability);
10676       astman_append(s, "%s\r\n", codec_buf);
10677       astman_append(s, "CodecOrder: ");
10678       pref = &peer->prefs;
10679       for(x = 0; x < 32 ; x++) {
10680          codec = ast_codec_pref_index(pref,x);
10681          if (!codec)
10682             break;
10683          astman_append(s, "%s", ast_getformatname(codec));
10684          if (x < 31 && ast_codec_pref_index(pref,x+1))
10685             astman_append(s, ",");
10686       }
10687 
10688       astman_append(s, "\r\n");
10689       astman_append(s, "Status: ");
10690       peer_status(peer, status, sizeof(status));
10691       astman_append(s, "%s\r\n", status);
10692       astman_append(s, "SIP-Useragent: %s\r\n", peer->useragent);
10693       astman_append(s, "Reg-Contact : %s\r\n", peer->fullcontact);
10694       if (peer->chanvars) {
10695          for (v = peer->chanvars ; v ; v = v->next) {
10696             astman_append(s, "ChanVariable:\n");
10697             astman_append(s, " %s,%s\r\n", v->name, v->value);
10698          }
10699       }
10700 
10701       ASTOBJ_UNREF(peer,sip_destroy_peer);
10702 
10703    } else {
10704       ast_cli(fd,"Peer %s not found.\n", argv[3]);
10705       ast_cli(fd,"\n");
10706    }
10707 
10708    return RESULT_SUCCESS;
10709 }

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

10051 {
10052    regex_t regexbuf;
10053    int havepattern = FALSE;
10054 
10055 #define FORMAT2 "%-25.25s  %-15.15s %-3.3s %-3.3s %-3.3s %-8s %-10s %-10s\n"
10056 #define FORMAT  "%-25.25s  %-15.15s %-3.3s %-3.3s %-3.3s %-8d %-10s %-10s\n"
10057 
10058    char name[256];
10059    int total_peers = 0;
10060    int peers_mon_online = 0;
10061    int peers_mon_offline = 0;
10062    int peers_unmon_offline = 0;
10063    int peers_unmon_online = 0;
10064    const char *id;
10065    char idtext[256] = "";
10066    int realtimepeers;
10067 
10068    realtimepeers = ast_check_realtime("sippeers");
10069 
10070    if (s) { /* Manager - get ActionID */
10071       id = astman_get_header(m,"ActionID");
10072       if (!ast_strlen_zero(id))
10073          snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
10074    }
10075 
10076    switch (argc) {
10077    case 5:
10078       if (!strcasecmp(argv[3], "like")) {
10079          if (regcomp(&regexbuf, argv[4], REG_EXTENDED | REG_NOSUB))
10080             return RESULT_SHOWUSAGE;
10081          havepattern = TRUE;
10082       } else
10083          return RESULT_SHOWUSAGE;
10084    case 3:
10085       break;
10086    default:
10087       return RESULT_SHOWUSAGE;
10088    }
10089 
10090    if (!s) /* Normal list */
10091       ast_cli(fd, FORMAT2, "Name/username", "Host", "Dyn", "Nat", "ACL", "Port", "Status", (realtimepeers ? "Realtime" : ""));
10092    
10093    ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do {
10094       char status[20] = "";
10095       char srch[2000];
10096       char pstatus;
10097       
10098       ASTOBJ_RDLOCK(iterator);
10099 
10100       if (havepattern && regexec(&regexbuf, iterator->name, 0, NULL, 0)) {
10101          ASTOBJ_UNLOCK(iterator);
10102          continue;
10103       }
10104 
10105       if (!ast_strlen_zero(iterator->username) && !s)
10106          snprintf(name, sizeof(name), "%s/%s", iterator->name, iterator->username);
10107       else
10108          ast_copy_string(name, iterator->name, sizeof(name));
10109       
10110       pstatus = peer_status(iterator, status, sizeof(status));
10111       if (pstatus == 1)
10112          peers_mon_online++;
10113       else if (pstatus == 0)
10114          peers_mon_offline++;
10115       else {
10116          if (iterator->addr.sin_port == 0)
10117             peers_unmon_offline++;
10118          else
10119             peers_unmon_online++;
10120       }
10121 
10122       snprintf(srch, sizeof(srch), FORMAT, name,
10123          iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iterator->addr.sin_addr) : "(Unspecified)",
10124          ast_test_flag(&iterator->flags[1], SIP_PAGE2_DYNAMIC) ? " D " : "   ",  /* Dynamic or not? */
10125          ast_test_flag(&iterator->flags[0], SIP_NAT_ROUTE) ? " N " : "   ",   /* NAT=yes? */
10126          iterator->ha ? " A " : "   ",    /* permit/deny */
10127          ntohs(iterator->addr.sin_port), status,
10128          realtimepeers ? (ast_test_flag(&iterator->flags[0], SIP_REALTIME) ? "Cached RT":"") : "");
10129 
10130       if (!s)  {/* Normal CLI list */
10131          ast_cli(fd, FORMAT, name, 
10132          iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iterator->addr.sin_addr) : "(Unspecified)",
10133          ast_test_flag(&iterator->flags[1], SIP_PAGE2_DYNAMIC) ? " D " : "   ",  /* Dynamic or not? */
10134          ast_test_flag(&iterator->flags[0], SIP_NAT_ROUTE) ? " N " : "   ",   /* NAT=yes? */
10135          iterator->ha ? " A " : "   ",       /* permit/deny */
10136          
10137          ntohs(iterator->addr.sin_port), status,
10138          realtimepeers ? (ast_test_flag(&iterator->flags[0], SIP_REALTIME) ? "Cached RT":"") : "");
10139       } else { /* Manager format */
10140          /* The names here need to be the same as other channels */
10141          astman_append(s, 
10142          "Event: PeerEntry\r\n%s"
10143          "Channeltype: SIP\r\n"
10144          "ObjectName: %s\r\n"
10145          "ChanObjectType: peer\r\n" /* "peer" or "user" */
10146          "IPaddress: %s\r\n"
10147          "IPport: %d\r\n"
10148          "Dynamic: %s\r\n"
10149          "Natsupport: %s\r\n"
10150          "VideoSupport: %s\r\n"
10151          "ACL: %s\r\n"
10152          "Status: %s\r\n"
10153          "RealtimeDevice: %s\r\n\r\n", 
10154          idtext,
10155          iterator->name, 
10156          iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iterator->addr.sin_addr) : "-none-",
10157          ntohs(iterator->addr.sin_port), 
10158          ast_test_flag(&iterator->flags[1], SIP_PAGE2_DYNAMIC) ? "yes" : "no",   /* Dynamic or not? */
10159          ast_test_flag(&iterator->flags[0], SIP_NAT_ROUTE) ? "yes" : "no", /* NAT=yes? */
10160          ast_test_flag(&iterator->flags[1], SIP_PAGE2_VIDEOSUPPORT) ? "yes" : "no", /* VIDEOSUPPORT=yes? */
10161          iterator->ha ? "yes" : "no",       /* permit/deny */
10162          status,
10163          realtimepeers ? (ast_test_flag(&iterator->flags[0], SIP_REALTIME) ? "yes":"no") : "no");
10164       }
10165 
10166       ASTOBJ_UNLOCK(iterator);
10167 
10168       total_peers++;
10169    } while(0) );
10170    
10171    if (!s)
10172       ast_cli(fd, "%d sip peers [Monitored: %d online, %d offline Unmonitored: %d online, %d offline]\n",
10173               total_peers, peers_mon_online, peers_mon_offline, peers_unmon_online, peers_unmon_offline);
10174 
10175    if (havepattern)
10176       regfree(&regexbuf);
10177 
10178    if (total)
10179       *total = total_peers;
10180    
10181 
10182    return RESULT_SUCCESS;
10183 #undef FORMAT
10184 #undef FORMAT2
10185 }

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

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

15162 {
15163    struct ast_rtp_quality qos;
15164    struct sip_pvt *p = chan->tech_pvt;
15165    char *all = "", *parse = ast_strdupa(preparse);
15166    AST_DECLARE_APP_ARGS(args,
15167       AST_APP_ARG(param);
15168       AST_APP_ARG(type);
15169       AST_APP_ARG(field);
15170    );
15171    AST_STANDARD_APP_ARGS(args, parse);
15172 
15173    /* Sanity check */
15174    if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) {
15175       ast_log(LOG_ERROR, "Cannot call %s on a non-SIP channel\n", funcname);
15176       return 0;
15177    }
15178 
15179    if (strcasecmp(args.param, "rtpqos"))
15180       return 0;
15181 
15182    /* Default arguments of audio,all */
15183    if (ast_strlen_zero(args.type))
15184       args.type = "audio";
15185    if (ast_strlen_zero(args.field))
15186       args.field = "all";
15187 
15188    memset(buf, 0, buflen);
15189    memset(&qos, 0, sizeof(qos));
15190 
15191    if (strcasecmp(args.type, "AUDIO") == 0) {
15192       all = ast_rtp_get_quality(p->rtp, &qos);
15193    } else if (strcasecmp(args.type, "VIDEO") == 0) {
15194       all = ast_rtp_get_quality(p->vrtp, &qos);
15195    }
15196 
15197    if (strcasecmp(args.field, "local_ssrc") == 0)
15198       snprintf(buf, buflen, "%u", qos.local_ssrc);
15199    else if (strcasecmp(args.field, "local_lostpackets") == 0)
15200       snprintf(buf, buflen, "%u", qos.local_lostpackets);
15201    else if (strcasecmp(args.field, "local_jitter") == 0)
15202       snprintf(buf, buflen, "%.0lf", qos.local_jitter * 1000.0);
15203    else if (strcasecmp(args.field, "local_count") == 0)
15204       snprintf(buf, buflen, "%u", qos.local_count);
15205    else if (strcasecmp(args.field, "remote_ssrc") == 0)
15206       snprintf(buf, buflen, "%u", qos.remote_ssrc);
15207    else if (strcasecmp(args.field, "remote_lostpackets") == 0)
15208       snprintf(buf, buflen, "%u", qos.remote_lostpackets);
15209    else if (strcasecmp(args.field, "remote_jitter") == 0)
15210       snprintf(buf, buflen, "%.0lf", qos.remote_jitter * 1000.0);
15211    else if (strcasecmp(args.field, "remote_count") == 0)
15212       snprintf(buf, buflen, "%u", qos.remote_count);
15213    else if (strcasecmp(args.field, "rtt") == 0)
15214       snprintf(buf, buflen, "%.0lf", qos.rtt * 1000.0);
15215    else if (strcasecmp(args.field, "all") == 0)
15216       ast_copy_string(buf, all, buflen);
15217    else {
15218       ast_log(LOG_WARNING, "Unrecognized argument '%s' to %s\n", preparse, funcname);
15219       return -1;
15220    }
15221    return 0;
15222 }

static void add_blank ( struct sip_request req  )  [static]

add a blank line if no body

Definition at line 2249 of file chan_sip.c.

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

Referenced by send_request(), and send_response().

02250 {
02251    if (!req->lines) {
02252       /* Add extra empty return. add_header() reserves 4 bytes so cannot be truncated */
02253       snprintf(req->data + req->len, sizeof(req->data) - req->len, "\r\n");
02254       req->len += strlen(req->data + req->len);
02255    }
02256 }

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

06241 {
06242    int rtp_code;
06243    struct ast_format_list fmt;
06244 
06245 
06246    if (debug)
06247       ast_verbose("Adding codec 0x%x (%s) to SDP\n", codec, ast_getformatname(codec));
06248    if ((rtp_code = ast_rtp_lookup_code(p->rtp, 1, codec)) == -1)
06249       return;
06250 
06251    if (p->rtp) {
06252       struct ast_codec_pref *pref = ast_rtp_codec_getpref(p->rtp);
06253       fmt = ast_codec_pref_getsize(pref, codec);
06254    } 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 */
06255       return;
06256    ast_build_string(m_buf, m_size, " %d", rtp_code);
06257    ast_build_string(a_buf, a_size, "a=rtpmap:%d %s/%d\r\n", rtp_code,
06258           ast_rtp_lookup_mime_subtype(1, codec,
06259                        ast_test_flag(&p->flags[0], SIP_G726_NONSTANDARD) ? AST_RTP_OPT_G726_NONSTANDARD : 0),
06260           sample_rate);
06261    if (codec == AST_FORMAT_G729A) {
06262       /* Indicate that we don't support VAD (G.729 annex B) */
06263       ast_build_string(a_buf, a_size, "a=fmtp:%d annexb=no\r\n", rtp_code);
06264    } else if (codec == AST_FORMAT_G723_1) {
06265       /* Indicate that we don't support VAD (G.723.1 annex A) */
06266       ast_build_string(a_buf, a_size, "a=fmtp:%d annexa=no\r\n", rtp_code);
06267    } else if (codec == AST_FORMAT_ILBC) {
06268       /* Add information about us using only 20/30 ms packetization */
06269       ast_build_string(a_buf, a_size, "a=fmtp:%d mode=%d\r\n", rtp_code, fmt.cur_ms);
06270    }
06271 
06272    if (fmt.cur_ms && (fmt.cur_ms < *min_packet_size))
06273       *min_packet_size = fmt.cur_ms;
06274 
06275    /* Our first codec packetization processed cannot be less than zero */
06276    if ((*min_packet_size) == 0  && fmt.cur_ms)
06277       *min_packet_size = fmt.cur_ms;
06278 }

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

Add DTMF INFO tone to sip message.

Definition at line 6206 of file chan_sip.c.

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

Referenced by transmit_info_with_digit().

06207 {
06208    char tmp[256];
06209 
06210    snprintf(tmp, sizeof(tmp), "Signal=%c\r\nDuration=%u\r\n", digit, duration);
06211    add_header(req, "Content-Type", "application/dtmf-relay");
06212    add_header_contentLength(req, strlen(tmp));
06213    add_line(req, tmp);
06214    return 0;
06215 }

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

Add header to SIP message.

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

05601 {
05602    int maxlen = sizeof(req->data) - 4 - req->len; /* 4 bytes are for two \r\n ? */
05603 
05604    if (req->headers == SIP_MAX_HEADERS) {
05605       ast_log(LOG_WARNING, "Out of SIP header space\n");
05606       return -1;
05607    }
05608 
05609    if (req->lines) {
05610       ast_log(LOG_WARNING, "Can't add more headers when lines have been added\n");
05611       return -1;
05612    }
05613 
05614    if (maxlen <= 0) {
05615       ast_log(LOG_WARNING, "Out of space, can't add anymore (%s:%s)\n", var, value);
05616       return -1;
05617    }
05618 
05619    req->header[req->headers] = req->data + req->len;
05620 
05621    if (compactheaders)
05622       var = find_alias(var, var);
05623 
05624    snprintf(req->header[req->headers], maxlen, "%s: %s\r\n", var, value);
05625    req->len += strlen(req->header[req->headers]);
05626    req->headers++;
05627 
05628    return 0;   
05629 }

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

05642 {
05643    if (req->lines == SIP_MAX_LINES)  {
05644       ast_log(LOG_WARNING, "Out of SIP line space\n");
05645       return -1;
05646    }
05647    if (!req->lines) {
05648       /* Add extra empty return */
05649       snprintf(req->data + req->len, sizeof(req->data) - req->len, "\r\n");
05650       req->len += strlen(req->data + req->len);
05651    }
05652    if (req->len >= sizeof(req->data) - 4) {
05653       ast_log(LOG_WARNING, "Out of space, can't add anymore\n");
05654       return -1;
05655    }
05656    req->line[req->lines] = req->data + req->len;
05657    snprintf(req->line[req->lines], sizeof(req->data) - req->len, "%s", line);
05658    req->len += strlen(req->line[req->lines]);
05659    req->lines++;
05660    return 0;   
05661 }

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

06417 {
06418    int rtp_code;
06419 
06420    if (debug)
06421       ast_verbose("Adding non-codec 0x%x (%s) to SDP\n", format, ast_rtp_lookup_mime_subtype(0, format, 0));
06422    if ((rtp_code = ast_rtp_lookup_code(p->rtp, 0, format)) == -1)
06423       return;
06424 
06425    ast_build_string(m_buf, m_size, " %d", rtp_code);
06426    ast_build_string(a_buf, a_size, "a=rtpmap:%d %s/%d\r\n", rtp_code,
06427           ast_rtp_lookup_mime_subtype(0, format, 0),
06428           sample_rate);
06429    if (format == AST_RTP_DTMF)
06430       /* Indicate we support DTMF and FLASH... */
06431       ast_build_string(a_buf, a_size, "a=fmtp:%d 0-16\r\n", rtp_code);
06432 }

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

16780 {
16781    char authcopy[256];
16782    char *username=NULL, *realm=NULL, *secret=NULL, *md5secret=NULL;
16783    char *stringp;
16784    struct sip_auth *a, *b, *auth;
16785 
16786    if (ast_strlen_zero(configuration))
16787       return authlist;
16788 
16789    if (option_debug)
16790       ast_log(LOG_DEBUG, "Auth config ::  %s\n", configuration);
16791 
16792    ast_copy_string(authcopy, configuration, sizeof(authcopy));
16793    stringp = authcopy;
16794 
16795    username = stringp;
16796    realm = strrchr(stringp, '@');
16797    if (realm)
16798       *realm++ = '\0';
16799    if (ast_strlen_zero(username) || ast_strlen_zero(realm)) {
16800       ast_log(LOG_WARNING, "Format for authentication entry is user[:secret]@realm at line %d\n", lineno);
16801       return authlist;
16802    }
16803    stringp = username;
16804    username = strsep(&stringp, ":");
16805    if (username) {
16806       secret = strsep(&stringp, ":");
16807       if (!secret) {
16808          stringp = username;
16809          md5secret = strsep(&stringp,"#");
16810       }
16811    }
16812    if (!(auth = ast_calloc(1, sizeof(*auth))))
16813       return authlist;
16814 
16815    ast_copy_string(auth->realm, realm, sizeof(auth->realm));
16816    ast_copy_string(auth->username, username, sizeof(auth->username));
16817    if (secret)
16818       ast_copy_string(auth->secret, secret, sizeof(auth->secret));
16819    if (md5secret)
16820       ast_copy_string(auth->md5secret, md5secret, sizeof(auth->md5secret));
16821 
16822    /* find the end of the list */
16823    for (b = NULL, a = authlist; a ; b = a, a = a->next)
16824       ;
16825    if (b)
16826       b->next = auth;   /* Add structure add end of list */
16827    else
16828       authlist = auth;
16829 
16830    if (option_verbose > 2)
16831       ast_verbose("Added authentication for realm %s\n", realm);
16832 
16833    return authlist;
16834 
16835 }

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

Add route header into request per learned route.

Definition at line 5762 of file chan_sip.c.

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

Referenced by reqprep().

05763 {
05764    char r[SIPBUFSIZE*2], *p;
05765    int n, rem = sizeof(r);
05766 
05767    if (!route)
05768       return;
05769 
05770    p = r;
05771    for (;route ; route = route->next) {
05772       n = strlen(route->hop);
05773       if (rem < n+3) /* we need room for ",<route>" */
05774          break;
05775       if (p != r) {  /* add a separator after fist route */
05776          *p++ = ',';
05777          --rem;
05778       }
05779       *p++ = '<';
05780       ast_copy_string(p, route->hop, rem); /* cannot fail */
05781       p += n;
05782       *p++ = '>';
05783       rem -= (n+2);
05784    }
05785    *p = '\0';
05786    add_header(req, "Route", r);
05787 }

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

Add Session Description Protocol message.

Definition at line 6442 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, SIPBUFSIZE, sip_pvt::t38, t38properties::t38support, TRUE, sip_pvt::vredirip, and sip_pvt::vrtp.

06443 {
06444    int len = 0;
06445    int alreadysent = 0;
06446 
06447    struct sockaddr_in sin;
06448    struct sockaddr_in vsin;
06449    struct sockaddr_in dest;
06450    struct sockaddr_in vdest = { 0, };
06451 
06452    /* SDP fields */
06453    char *version =   "v=0\r\n";     /* Protocol version */
06454    char *subject =   "s=session\r\n";  /* Subject of the session */
06455    char owner[256];           /* Session owner/creator */
06456    char connection[256];            /* Connection data */
06457    char *stime = "t=0 0\r\n";          /* Time the session is active */
06458    char bandwidth[256] = "";        /* Max bitrate */
06459    char *hold;
06460    char m_audio[256];            /* Media declaration line for audio */
06461    char m_video[256];            /* Media declaration line for video */
06462    char a_audio[1024];           /* Attributes for audio */
06463    char a_video[1024];           /* Attributes for video */
06464    char *m_audio_next = m_audio;
06465    char *m_video_next = m_video;
06466    size_t m_audio_left = sizeof(m_audio);
06467    size_t m_video_left = sizeof(m_video);
06468    char *a_audio_next = a_audio;
06469    char *a_video_next = a_video;
06470    size_t a_audio_left = sizeof(a_audio);
06471    size_t a_video_left = sizeof(a_video);
06472 
06473    int x;
06474    int capability;
06475    int needvideo = FALSE;
06476    int debug = sip_debug_test_pvt(p);
06477    int min_audio_packet_size = 0;
06478    int min_video_packet_size = 0;
06479 
06480    m_video[0] = '\0';   /* Reset the video media string if it's not needed */
06481 
06482    if (!p->rtp) {
06483       ast_log(LOG_WARNING, "No way to add SDP without an RTP structure\n");
06484       return AST_FAILURE;
06485    }
06486 
06487    /* Set RTP Session ID and version */
06488    if (!p->sessionid) {
06489       p->sessionid = getpid();
06490       p->sessionversion = p->sessionid;
06491    } else
06492       p->sessionversion++;
06493 
06494    /* Get our addresses */
06495    ast_rtp_get_us(p->rtp, &sin);
06496    if (p->vrtp)
06497       ast_rtp_get_us(p->vrtp, &vsin);
06498 
06499    /* Is this a re-invite to move the media out, then use the original offer from caller  */
06500    if (p->redirip.sin_addr.s_addr) {
06501       dest.sin_port = p->redirip.sin_port;
06502       dest.sin_addr = p->redirip.sin_addr;
06503    } else {
06504       dest.sin_addr = p->ourip;
06505       dest.sin_port = sin.sin_port;
06506    }
06507 
06508    capability = p->jointcapability;
06509 
06510 
06511    if (option_debug > 1) {
06512       char codecbuf[SIPBUFSIZE];
06513       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");
06514       ast_log(LOG_DEBUG, "** Our prefcodec: %s \n", ast_getformatname_multiple(codecbuf, sizeof(codecbuf), p->prefcodec));
06515    }
06516    
06517 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS
06518    if (ast_test_flag(&p->t38.t38support, SIP_PAGE2_T38SUPPORT_RTP)) {
06519       ast_build_string(&m_audio_next, &m_audio_left, " %d", 191);
06520       ast_build_string(&a_audio_next, &a_audio_left, "a=rtpmap:%d %s/%d\r\n", 191, "t38", 8000);
06521    }
06522 #endif
06523 
06524    /* Check if we need video in this call */
06525    if ((capability & AST_FORMAT_VIDEO_MASK) && !ast_test_flag(&p->flags[0], SIP_NOVIDEO)) {
06526       if (p->vrtp) {
06527          needvideo = TRUE;
06528          if (option_debug > 1)
06529             ast_log(LOG_DEBUG, "This call needs video offers!\n");
06530       } else if (option_debug > 1)
06531          ast_log(LOG_DEBUG, "This call needs video offers, but there's no video support enabled!\n");
06532    }
06533       
06534 
06535    /* Ok, we need video. Let's add what we need for video and set codecs.
06536       Video is handled differently than audio since we can not transcode. */
06537    if (needvideo) {
06538       /* Determine video destination */
06539       if (p->vredirip.sin_addr.s_addr) {
06540          vdest.sin_addr = p->vredirip.sin_addr;
06541          vdest.sin_port = p->vredirip.sin_port;
06542       } else {
06543          vdest.sin_addr = p->ourip;
06544          vdest.sin_port = vsin.sin_port;
06545       }
06546       ast_build_string(&m_video_next, &m_video_left, "m=video %d RTP/AVP", ntohs(vdest.sin_port));
06547 
06548       /* Build max bitrate string */
06549       if (p->maxcallbitrate)
06550          snprintf(bandwidth, sizeof(bandwidth), "b=CT:%d\r\n", p->maxcallbitrate);
06551       if (debug) 
06552          ast_verbose("Video is at %s port %d\n", ast_inet_ntoa(p->ourip), ntohs(vsin.sin_port));   
06553    }
06554 
06555    if (debug) 
06556       ast_verbose("Audio is at %s port %d\n", ast_inet_ntoa(p->ourip), ntohs(sin.sin_port)); 
06557 
06558    /* Start building generic SDP headers */
06559 
06560    /* We break with the "recommendation" and send our IP, in order that our
06561       peer doesn't have to ast_gethostbyname() us */
06562 
06563    snprintf(owner, sizeof(owner), "o=root %d %d IN IP4 %s\r\n", p->sessionid, p->sessionversion, ast_inet_ntoa(dest.sin_addr));
06564    snprintf(connection, sizeof(connection), "c=IN IP4 %s\r\n", ast_inet_ntoa(dest.sin_addr));
06565    ast_build_string(&m_audio_next, &m_audio_left, "m=audio %d RTP/AVP", ntohs(dest.sin_port));
06566 
06567    if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) == SIP_PAGE2_CALL_ONHOLD_ONEDIR)
06568       hold = "a=recvonly\r\n";
06569    else if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) == SIP_PAGE2_CALL_ONHOLD_INACTIVE)
06570       hold = "a=inactive\r\n";
06571    else
06572       hold = "a=sendrecv\r\n";
06573 
06574    /* Now, start adding audio codecs. These are added in this order:
06575       - First what was requested by the calling channel
06576       - Then preferences in order from sip.conf device config for this peer/user
06577       - Then other codecs in capabilities, including video
06578    */
06579 
06580    /* Prefer the audio codec we were requested to use, first, no matter what 
06581       Note that p->prefcodec can include video codecs, so mask them out
06582     */
06583    if (capability & p->prefcodec) {
06584       int codec = p->prefcodec & AST_FORMAT_AUDIO_MASK;
06585 
06586       add_codec_to_sdp(p, codec, SDP_SAMPLE_RATE(codec),
06587              &m_audio_next, &m_audio_left,
06588              &a_audio_next, &a_audio_left,
06589              debug, &min_audio_packet_size);
06590       alreadysent |= codec;
06591    }
06592 
06593    /* Start by sending our preferred audio codecs */
06594    for (x = 0; x < 32; x++) {
06595       int codec;
06596 
06597       if (!(codec = ast_codec_pref_index(&p->prefs, x)))
06598          break; 
06599 
06600       if (!(capability & codec))
06601          continue;
06602 
06603       if (alreadysent & codec)
06604          continue;
06605 
06606       add_codec_to_sdp(p, codec, SDP_SAMPLE_RATE(codec),
06607              &m_audio_next, &m_audio_left,
06608              &a_audio_next, &a_audio_left,
06609              debug, &min_audio_packet_size);
06610       alreadysent |= codec;
06611    }
06612 
06613    /* Now send any other common audio and video codecs, and non-codec formats: */
06614    for (x = 1; x <= (needvideo ? AST_FORMAT_MAX_VIDEO : AST_FORMAT_MAX_AUDIO); x <<= 1) {
06615       if (!(capability & x))  /* Codec not requested */
06616          continue;
06617 
06618       if (alreadysent & x) /* Already added to SDP */
06619          continue;
06620 
06621       if (x <= AST_FORMAT_MAX_AUDIO)
06622          add_codec_to_sdp(p, x, SDP_SAMPLE_RATE(x),
06623                 &m_audio_next, &m_audio_left,
06624                 &a_audio_next, &a_audio_left,
06625                 debug, &min_audio_packet_size);
06626       else 
06627          add_codec_to_sdp(p, x, 90000,
06628                 &m_video_next, &m_video_left,
06629                 &a_video_next, &a_video_left,
06630                 debug, &min_video_packet_size);
06631    }
06632 
06633    /* Now add DTMF RFC2833 telephony-event as a codec */
06634    for (x = 1; x <= AST_RTP_MAX; x <<= 1) {
06635       if (!(p->jointnoncodeccapability & x))
06636          continue;
06637 
06638       add_noncodec_to_sdp(p, x, 8000,
06639                 &m_audio_next, &m_audio_left,
06640                 &a_audio_next, &a_audio_left,
06641                 debug);
06642    }
06643 
06644    if (option_debug > 2)
06645       ast_log(LOG_DEBUG, "-- Done with adding codecs to SDP\n");
06646 
06647    if (!p->owner || !ast_internal_timing_enabled(p->owner))
06648       ast_build_string(&a_audio_next, &a_audio_left, "a=silenceSupp:off - - - -\r\n");
06649 
06650    if (min_audio_packet_size)
06651       ast_build_string(&a_audio_next, &a_audio_left, "a=ptime:%d\r\n", min_audio_packet_size);
06652 
06653    if (min_video_packet_size)
06654       ast_build_string(&a_video_next, &a_video_left, "a=ptime:%d\r\n", min_video_packet_size);
06655 
06656    if ((m_audio_left < 2) || (m_video_left < 2) || (a_audio_left == 0) || (a_video_left == 0))
06657       ast_log(LOG_WARNING, "SIP SDP may be truncated due to undersized buffer!!\n");
06658 
06659    ast_build_string(&m_audio_next, &m_audio_left, "\r\n");
06660    if (needvideo)
06661       ast_build_string(&m_video_next, &m_video_left, "\r\n");
06662 
06663    len = strlen(version) + strlen(subject) + strlen(owner) + strlen(connection) + strlen(stime) + strlen(m_audio) + strlen(a_audio) + strlen(hold);
06664    if (needvideo) /* only if video response is appropriate */
06665       len += strlen(m_video) + strlen(a_video) + strlen(bandwidth) + strlen(hold);
06666 
06667    add_header(resp, "Content-Type", "application/sdp");
06668    add_header_contentLength(resp, len);
06669    add_line(resp, version);
06670    add_line(resp, owner);
06671    add_line(resp, subject);
06672    add_line(resp, connection);
06673    if (needvideo)    /* only if video response is appropriate */
06674       add_line(resp, bandwidth);
06675    add_line(resp, stime);
06676    add_line(resp, m_audio);
06677    add_line(resp, a_audio);
06678    add_line(resp, hold);
06679    if (needvideo) { /* only if video response is appropriate */
06680       add_line(resp, m_video);
06681       add_line(resp, a_video);
06682       add_line(resp, hold);   /* Repeat hold for the video stream */
06683    }
06684 
06685    /* Update lastrtprx when we send our SDP */
06686    p->lastrtprx = p->lastrtptx = time(NULL); /* XXX why both ? */
06687 
06688    if (option_debug > 2) {
06689       char buf[SIPBUFSIZE];
06690       ast_log(LOG_DEBUG, "Done building SDP. Settling with this capability: %s\n", ast_getformatname_multiple(buf, SIPBUFSIZE, capability));
06691    }
06692 
06693    return AST_SUCCESS;
06694 }

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

16716 {
16717    struct domain *d;
16718 
16719    if (ast_strlen_zero(domain)) {
16720       ast_log(LOG_WARNING, "Zero length domain.\n");
16721       return 1;
16722    }
16723 
16724    if (!(d = ast_calloc(1, sizeof(*d))))
16725       return 0;
16726 
16727    ast_copy_string(d->domain, domain, sizeof(d->domain));
16728 
16729    if (!ast_strlen_zero(context))
16730       ast_copy_string(d->context, context, sizeof(d->context));
16731 
16732    d->mode = mode;
16733 
16734    AST_LIST_LOCK(&domain_list);
16735    AST_LIST_INSERT_TAIL(&domain_list, d, list);
16736    AST_LIST_UNLOCK(&domain_list);
16737 
16738    if (sipdebug)  
16739       ast_log(LOG_DEBUG, "Added local SIP domain '%s'\n", domain);
16740 
16741    return 1;
16742 }

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

Add T.38 Session Description Protocol message.

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

06318 {
06319    int len = 0;
06320    int x = 0;
06321    struct sockaddr_in udptlsin;
06322    char v[256] = "";
06323    char s[256] = "";
06324    char o[256] = "";
06325    char c[256] = "";
06326    char t[256] = "";
06327    char m_modem[256];
06328    char a_modem[1024];
06329    char *m_modem_next = m_modem;
06330    size_t m_modem_left = sizeof(m_modem);
06331    char *a_modem_next = a_modem;
06332    size_t a_modem_left = sizeof(a_modem);
06333    struct sockaddr_in udptldest = { 0, };
06334    int debug;
06335    
06336    debug = sip_debug_test_pvt(p);
06337    len = 0;
06338    if (!p->udptl) {
06339       ast_log(LOG_WARNING, "No way to add SDP without an UDPTL structure\n");
06340       return -1;
06341    }
06342    
06343    if (!p->sessionid) {
06344       p->sessionid = getpid();
06345       p->sessionversion = p->sessionid;
06346    } else
06347       p->sessionversion++;
06348    
06349    /* Our T.38 end is */
06350    ast_udptl_get_us(p->udptl, &udptlsin);
06351    
06352    /* Determine T.38 UDPTL destination */
06353    if (p->udptlredirip.sin_addr.s_addr) {
06354       udptldest.sin_port = p->udptlredirip.sin_port;
06355       udptldest.sin_addr = p->udptlredirip.sin_addr;
06356    } else {
06357       udptldest.sin_addr = p->ourip;
06358       udptldest.sin_port = udptlsin.sin_port;
06359    }
06360    
06361    if (debug) 
06362       ast_log(LOG_DEBUG, "T.38 UDPTL is at %s port %d\n", ast_inet_ntoa(p->ourip), ntohs(udptlsin.sin_port));
06363    
06364    /* We break with the "recommendation" and send our IP, in order that our
06365       peer doesn't have to ast_gethostbyname() us */
06366    
06367    if (debug) {
06368       ast_log(LOG_DEBUG, "Our T38 capability (%d), peer T38 capability (%d), joint capability (%d)\n",
06369          p->t38.capability,
06370          p->t38.peercapability,
06371          p->t38.jointcapability);
06372    }
06373    snprintf(v, sizeof(v), "v=0\r\n");
06374    snprintf(o, sizeof(o), "o=root %d %d IN IP4 %s\r\n", p->sessionid, p->sessionversion, ast_inet_ntoa(udptldest.sin_addr));
06375    snprintf(s, sizeof(s), "s=session\r\n");
06376    snprintf(c, sizeof(c), "c=IN IP4 %s\r\n", ast_inet_ntoa(udptldest.sin_addr));
06377    snprintf(t, sizeof(t), "t=0 0\r\n");
06378    ast_build_string(&m_modem_next, &m_modem_left, "m=image %d udptl t38\r\n", ntohs(udptldest.sin_port));
06379    
06380    if ((p->t38.jointcapability & T38FAX_VERSION) == T38FAX_VERSION_0)
06381       ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxVersion:0\r\n");
06382    if ((p->t38.jointcapability & T38FAX_VERSION) == T38FAX_VERSION_1)
06383       ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxVersion:1\r\n");
06384    if ((x = t38_get_rate(p->t38.jointcapability)))
06385       ast_build_string(&a_modem_next, &a_modem_left, "a=T38MaxBitRate:%d\r\n",x);
06386    ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxFillBitRemoval:%d\r\n", (p->t38.jointcapability & T38FAX_FILL_BIT_REMOVAL) ? 1 : 0);
06387    ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxTranscodingMMR:%d\r\n", (p->t38.jointcapability & T38FAX_TRANSCODING_MMR) ? 1 : 0);
06388    ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxTranscodingJBIG:%d\r\n", (p->t38.jointcapability & T38FAX_TRANSCODING_JBIG) ? 1 : 0);
06389    ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxRateManagement:%s\r\n", (p->t38.jointcapability & T38FAX_RATE_MANAGEMENT_LOCAL_TCF) ? "localTCF" : "transferredTCF");
06390    x = ast_udptl_get_local_max_datagram(p->udptl);
06391    ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxMaxBuffer:%d\r\n",x);
06392    ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxMaxDatagram:%d\r\n",x);
06393    if (p->t38.jointcapability != T38FAX_UDP_EC_NONE)
06394       ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxUdpEC:%s\r\n", (p->t38.jointcapability & T38FAX_UDP_EC_REDUNDANCY) ? "t38UDPRedundancy" : "t38UDPFEC");
06395    len = strlen(v) + strlen(s) + strlen(o) + strlen(c) + strlen(t) + strlen(m_modem) + strlen(a_modem);
06396    add_header(resp, "Content-Type", "application/sdp");
06397    add_header_contentLength(resp, len);
06398    add_line(resp, v);
06399    add_line(resp, o);
06400    add_line(resp, s);
06401    add_line(resp, c);
06402    add_line(resp, t);
06403    add_line(resp, m_modem);
06404    add_line(resp, a_modem);
06405    
06406    /* Update lastrtprx when we send our SDP */
06407    p->lastrtprx = p->lastrtptx = time(NULL);
06408    
06409    return 0;
06410 }

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

Add text body to SIP message.

Definition at line 6195 of file chan_sip.c.

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

Referenced by transmit_message_with_text().

06196 {
06197    /* XXX Convert \n's to \r\n's XXX */
06198    add_header(req, "Content-Type", "text/plain");
06199    add_header_contentLength(req, strlen(text));
06200    add_line(req, text);
06201    return 0;
06202 }

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

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

Referenced by transmit_info_with_vidupdate().

06220 {
06221    const char *xml_is_a_huge_waste_of_space =
06222       "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\r\n"
06223       " <media_control>\r\n"
06224       "  <vc_primitive>\r\n"
06225       "   <to_encoder>\r\n"
06226       "    <picture_fast_update>\r\n"
06227       "    </picture_fast_update>\r\n"
06228       "   </to_encoder>\r\n"
06229       "  </vc_primitive>\r\n"
06230       " </media_control>\r\n";
06231    add_header(req, "Content-Type", "application/media_control+xml");
06232    add_header_contentLength(req, strlen(xml_is_a_huge_waste_of_space));
06233    add_line(req, xml_is_a_huge_waste_of_space);
06234    return 0;
06235 }

static void append_date ( struct sip_request req  )  [static]

Append date to SIP message.

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

06143 {
06144    char tmpdat[256];
06145    struct tm tm;
06146    time_t t = time(NULL);
06147 
06148    gmtime_r(&t, &tm);
06149    strftime(tmpdat, sizeof(tmpdat), "%a, %d %b %Y %T GMT", &tm);
06150    add_header(req, "Date", tmpdat);
06151 }

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

Append to SIP dialog history with arg list.

Definition at line 1876 of file chan_sip.c.

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

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

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

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

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

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

Referenced by attempt_transfer(), and handle_invite_replaces().

13393 {
13394    if (chan && chan->_state == AST_STATE_UP) {
13395       if (ast_test_flag(chan, AST_FLAG_MOH))
13396          ast_moh_stop(chan);
13397       else if (chan->generatordata)
13398          ast_deactivate_generator(chan);
13399    }
13400 }

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

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

AST_THREADSTORAGE ( check_auth_buf  ,
check_auth_buf_init   
)

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

13405 {
13406    int res = 0;
13407    struct ast_channel *peera = NULL,   
13408       *peerb = NULL,
13409       *peerc = NULL,
13410       *peerd = NULL;
13411 
13412 
13413    /* We will try to connect the transferee with the target and hangup
13414       all channels to the transferer */   
13415    if (option_debug > 3) {
13416       ast_log(LOG_DEBUG, "Sip transfer:--------------------\n");
13417       if (transferer->chan1)
13418          ast_log(LOG_DEBUG, "-- Transferer to PBX channel: %s State %s\n", transferer->chan1->name, ast_state2str(transferer->chan1->_state));
13419       else
13420          ast_log(LOG_DEBUG, "-- No transferer first channel - odd??? \n");
13421       if (target->chan1)
13422          ast_log(LOG_DEBUG, "-- Transferer to PBX second channel (target): %s State %s\n", target->chan1->name, ast_state2str(target->chan1->_state));
13423       else
13424          ast_log(LOG_DEBUG, "-- No target first channel ---\n");
13425       if (transferer->chan2)
13426          ast_log(LOG_DEBUG, "-- Bridged call to transferee: %s State %s\n", transferer->chan2->name, ast_state2str(transferer->chan2->_state));
13427       else
13428          ast_log(LOG_DEBUG, "-- No bridged call to transferee\n");
13429       if (target->chan2)
13430          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)");
13431       else
13432          ast_log(LOG_DEBUG, "-- No target second channel ---\n");
13433       ast_log(LOG_DEBUG, "-- END Sip transfer:--------------------\n");
13434    }
13435    if (transferer->chan2) { /* We have a bridge on the transferer's channel */
13436       peera = transferer->chan1; /* Transferer - PBX -> transferee channel * the one we hangup */
13437       peerb = target->chan1;     /* Transferer - PBX -> target channel - This will get lost in masq */
13438       peerc = transferer->chan2; /* Asterisk to Transferee */
13439       peerd = target->chan2;     /* Asterisk to Target */
13440       if (option_debug > 2)
13441          ast_log(LOG_DEBUG, "SIP transfer: Four channels to handle\n");
13442    } else if (target->chan2) {   /* Transferer has no bridge (IVR), but transferee */
13443       peera = target->chan1;     /* Transferer to PBX -> target channel */
13444       peerb = transferer->chan1; /* Transferer to IVR*/
13445       peerc = target->chan2;     /* Asterisk to Target */
13446       peerd = transferer->chan2; /* Nothing */
13447       if (option_debug > 2)
13448          ast_log(LOG_DEBUG, "SIP transfer: Three channels to handle\n");
13449    }
13450 
13451    if (peera && peerb && peerc && (peerb != peerc)) {
13452       ast_quiet_chan(peera);     /* Stop generators */
13453       ast_quiet_chan(peerb);  
13454       ast_quiet_chan(peerc);
13455       if (peerd)
13456          ast_quiet_chan(peerd);
13457 
13458       /* Fix CDRs so they're attached to the remaining channel */
13459       if (peera->cdr && peerb->cdr)
13460          peerb->cdr = ast_cdr_append(peerb->cdr, peera->cdr);
13461       else if (peera->cdr) 
13462          peerb->cdr = peera->cdr;
13463       peera->cdr = NULL;
13464 
13465       if (peerb->cdr && peerc->cdr) 
13466          peerb->cdr = ast_cdr_append(peerb->cdr, peerc->cdr);
13467       else if (peerc->cdr)
13468          peerb->cdr = peerc->cdr;
13469       peerc->cdr = NULL;
13470    
13471       if (option_debug > 3)
13472          ast_log(LOG_DEBUG, "SIP transfer: trying to masquerade %s into %s\n", peerc->name, peerb->name);
13473       if (ast_channel_masquerade(peerb, peerc)) {
13474          ast_log(LOG_WARNING, "Failed to masquerade %s into %s\n", peerb->name, peerc->name);
13475          res = -1;
13476       } else
13477          ast_log(LOG_DEBUG, "SIP transfer: Succeeded to masquerade channels.\n");
13478       return res;
13479    } else {
13480       ast_log(LOG_NOTICE, "SIP Transfer attempted with no appropriate bridged calls to transfer\n");
13481       if (transferer->chan1)
13482          ast_softhangup_nolock(transferer->chan1, AST_SOFTHANGUP_DEV);
13483       if (target->chan1)
13484          ast_softhangup_nolock(target->chan1, AST_SOFTHANGUP_DEV);
13485       return -2;
13486    }
13487    return 0;
13488 }

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

Scheduled congestion on a call.

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

02933 {
02934    struct sip_pvt *p = (struct sip_pvt *)nothing;
02935 
02936    ast_mutex_lock(&p->lock);
02937    p->initid = -1;
02938    if (p->owner) {
02939       /* XXX fails on possible deadlock */
02940       if (!ast_channel_trylock(p->owner)) {
02941          ast_log(LOG_NOTICE, "Auto-congesting %s\n", p->owner->name);
02942          append_history(p, "Cong", "Auto-congesting (timer)");
02943          ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
02944          ast_channel_unlock(p->owner);
02945       }
02946    }
02947    ast_mutex_unlock(&p->lock);
02948    return 0;
02949 }

static void build_callid_pvt ( struct sip_pvt pvt  )  [static]

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

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

04418 {
04419    char buf[33];
04420 
04421    const char *host = S_OR(pvt->fromdomain, ast_inet_ntoa(pvt->ourip));
04422    
04423    ast_string_field_build(pvt, callid, "%s@%s", generate_random_string(buf, sizeof(buf)), host);
04424 
04425 }

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

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

Referenced by transmit_register().

04429 {
04430    char buf[33];
04431 
04432    const char *host = S_OR(fromdomain, ast_inet_ntoa(ourip));
04433 
04434    ast_string_field_build(reg, callid, "%s@%s", generate_random_string(buf, sizeof(buf)), host);
04435 }

static void build_contact ( struct sip_pvt p  )  [static]

Build contact header - the contact header we send out.

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

06866 {
06867    /* Construct Contact: header */
06868    if (ourport != STANDARD_SIP_PORT)
06869       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);
06870    else
06871       ast_string_field_build(p, our_contact, "<sip:%s%s%s>", p->exten, ast_strlen_zero(p->exten) ? "" : "@", ast_inet_ntoa(p->ourip));
06872 }

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 17046 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_RTCACHEFRIENDS, 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.

17047 {
17048    struct sip_peer *peer = NULL;
17049    struct ast_ha *oldha = NULL;
17050    int obproxyfound=0;
17051    int found=0;
17052    int firstpass=1;
17053    int format=0;     /* Ama flags */
17054    time_t regseconds = 0;
17055    char *varname = NULL, *varval = NULL;
17056    struct ast_variable *tmpvar = NULL;
17057    struct ast_flags peerflags[2] = {{(0)}};
17058    struct ast_flags mask[2] = {{(0)}};
17059    char fullcontact[sizeof(peer->fullcontact)] = "";
17060 
17061    if (!realtime || ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS))
17062       /* Note we do NOT use find_peer here, to avoid realtime recursion */
17063       /* We also use a case-sensitive comparison (unlike find_peer) so
17064          that case changes made to the peer name will be properly handled
17065          during reload
17066       */
17067       peer = ASTOBJ_CONTAINER_FIND_UNLINK_FULL(&peerl, name, name, 0, 0, strcmp);
17068 
17069    if (peer) {
17070       /* Already in the list, remove it and it will be added back (or FREE'd)  */
17071       found = 1;
17072       if (!(peer->objflags & ASTOBJ_FLAG_MARKED))
17073          firstpass = 0;
17074    } else {
17075       if (!(peer = ast_calloc(1, sizeof(*peer))))
17076          return NULL;
17077 
17078       if (realtime && !ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS))
17079          rpeerobjs++;
17080       else
17081          speerobjs++;
17082       ASTOBJ_INIT(peer);
17083    }
17084    /* Note that our peer HAS had its reference count incrased */
17085    if (firstpass) {
17086       peer->lastmsgssent = -1;
17087       oldha = peer->ha;
17088       peer->ha = NULL;
17089       set_peer_defaults(peer);   /* Set peer defaults */
17090    }
17091    if (!found && name)
17092          ast_copy_string(peer->name, name, sizeof(peer->name));
17093 
17094    /* If we have channel variables, remove them (reload) */
17095    if (peer->chanvars) {
17096       ast_variables_destroy(peer->chanvars);
17097       peer->chanvars = NULL;
17098       /* XXX should unregister ? */
17099    }
17100 
17101    /* If we have realm authentication information, remove them (reload) */
17102    clear_realm_authentication(peer->auth);
17103    peer->auth = NULL;
17104 
17105    for (; v || ((v = alt) && !(alt=NULL)); v = v->next) {
17106       if (handle_common_options(&peerflags[0], &mask[0], v))
17107          continue;
17108       if (realtime && !strcasecmp(v->name, "regseconds")) {
17109          ast_get_time_t(v->value, &regseconds, 0, NULL);
17110       } else if (realtime && !strcasecmp(v->name, "ipaddr") && !ast_strlen_zero(v->value) ) {
17111          inet_aton(v->value, &(peer->addr.sin_addr));
17112       } else if (realtime && !strcasecmp(v->name, "name"))
17113          ast_copy_string(peer->name, v->value, sizeof(peer->name));
17114       else if (realtime && !strcasecmp(v->name, "fullcontact")) {
17115          /* Reconstruct field, because realtime separates our value at the ';' */
17116          if (!ast_strlen_zero(fullcontact)) {
17117             strncat(fullcontact, ";", sizeof(fullcontact) - strlen(fullcontact) - 1);
17118             strncat(fullcontact, v->value, sizeof(fullcontact) - strlen(fullcontact) - 1);
17119          } else {
17120             ast_copy_string(fullcontact, v->value, sizeof(fullcontact));
17121             ast_set_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT);
17122          }
17123       } else if (!strcasecmp(v->name, "secret")) 
17124          ast_copy_string(peer->secret, v->value, sizeof(peer->secret));
17125       else if (!strcasecmp(v->name, "md5secret")) 
17126          ast_copy_string(peer->md5secret, v->value, sizeof(peer->md5secret));
17127       else if (!strcasecmp(v->name, "auth"))
17128          peer->auth = add_realm_authentication(peer->auth, v->value, v->lineno);
17129       else if (!strcasecmp(v->name, "callerid")) {
17130          ast_callerid_split(v->value, peer->cid_name, sizeof(peer->cid_name), peer->cid_num, sizeof(peer->cid_num));
17131       } else if (!strcasecmp(v->name, "fullname")) {
17132          ast_copy_string(peer->cid_name, v->value, sizeof(peer->cid_name));
17133       } else if (!strcasecmp(v->name, "cid_number")) {
17134          ast_copy_string(peer->cid_num, v->value, sizeof(peer->cid_num));
17135       } else if (!strcasecmp(v->name, "context")) {
17136          ast_copy_string(peer->context, v->value, sizeof(peer->context));
17137       } else if (!strcasecmp(v->name, "subscribecontext")) {
17138          ast_copy_string(peer->subscribecontext, v->value, sizeof(peer->subscribecontext));
17139       } else if (!strcasecmp(v->name, "fromdomain")) {
17140          ast_copy_string(peer->fromdomain, v->value, sizeof(peer->fromdomain));
17141       } else if (!strcasecmp(v->name, "usereqphone")) {
17142          ast_set2_flag(&peer->flags[0], ast_true(v->value), SIP_USEREQPHONE);
17143       } else if (!strcasecmp(v->name, "fromuser")) {
17144          ast_copy_string(peer->fromuser, v->value, sizeof(peer->fromuser));
17145       } else if (!strcasecmp(v->name, "host") || !strcasecmp(v->name, "outboundproxy")) {
17146          if (!strcasecmp(v->value, "dynamic")) {
17147             if (!strcasecmp(v->name, "outboundproxy") || obproxyfound) {
17148                ast_log(LOG_WARNING, "You can't have a dynamic outbound proxy, you big silly head at line %d.\n", v->lineno);
17149             } else {
17150                /* They'll register with us */
17151                if (!found || !ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)) {
17152                   /* Initialize stuff if this is a new peer, or if it used to be
17153                    * non-dynamic before the reload. */
17154                   memset(&peer->addr.sin_addr, 0, 4);
17155                   if (peer->addr.sin_port) {
17156                      /* If we've already got a port, make it the default rather than absolute */
17157                      peer->defaddr.sin_port = peer->addr.sin_port;
17158                      peer->addr.sin_port = 0;
17159                   }
17160                }
17161                ast_set_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC);
17162             }
17163          } else {
17164             /* Non-dynamic.  Make sure we become that way if we're not */
17165             if (!AST_SCHED_DEL(sched, peer->expire)) {
17166                struct sip_peer *peer_ptr = peer;
17167                ASTOBJ_UNREF(peer_ptr, sip_destroy_peer);
17168             }
17169             ast_clear_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC);
17170             if (!obproxyfound || !strcasecmp(v->name, "outboundproxy")) {
17171                if (ast_get_ip_or_srv(&peer->addr, v->value, srvlookup ? "_sip._udp" : NULL)) {
17172                   ASTOBJ_UNREF(peer, sip_destroy_peer);
17173                   return NULL;
17174                }
17175             }
17176             if (!strcasecmp(v->name, "outboundproxy"))
17177                obproxyfound=1;
17178             else {
17179                ast_copy_string(peer->tohost, v->value, sizeof(peer->tohost));
17180                if (!peer->addr.sin_port)
17181                   peer->addr.sin_port = htons(STANDARD_SIP_PORT);
17182             }
17183          }
17184       } else if (!strcasecmp(v->name, "defaultip")) {
17185          if (ast_get_ip(&peer->defaddr, v->value)) {
17186             ASTOBJ_UNREF(peer, sip_destroy_peer);
17187             return NULL;
17188          }
17189       } else if (!strcasecmp(v->name, "permit") || !strcasecmp(v->name, "deny")) {
17190          peer->ha = ast_append_ha(v->name, v->value, peer->ha);
17191       } else if (!strcasecmp(v->name, "port")) {
17192          if (!realtime && ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC))
17193             peer->defaddr.sin_port = htons(atoi(v->value));
17194          else
17195             peer->addr.sin_port = htons(atoi(v->value));
17196       } else if (!strcasecmp(v->name, "callingpres")) {
17197          peer->callingpres = ast_parse_caller_presentation(v->value);
17198          if (peer->callingpres == -1)
17199             peer->callingpres = atoi(v->value);
17200       } else if (!strcasecmp(v->name, "username")) {
17201          ast_copy_string(peer->username, v->value, sizeof(peer->username));
17202       } else if (!strcasecmp(v->name, "language")) {
17203          ast_copy_string(peer->language, v->value, sizeof(peer->language));
17204       } else if (!strcasecmp(v->name, "regexten")) {
17205          ast_copy_string(peer->regexten, v->value, sizeof(peer->regexten));
17206       } else if (!strcasecmp(v->name, "call-limit") || !strcasecmp(v->name, "incominglimit")) {
17207          peer->call_limit = atoi(v->value);
17208          if (peer->call_limit < 0)
17209             peer->call_limit = 0;
17210       } else if (!strcasecmp(v->name, "amaflags")) {
17211          format = ast_cdr_amaflags2int(v->value);
17212          if (format < 0) {
17213             ast_log(LOG_WARNING, "Invalid AMA Flags for peer: %s at line %d\n", v->value, v->lineno);
17214          } else {
17215             peer->amaflags = format;
17216          }
17217       } else if (!strcasecmp(v->name, "accountcode")) {
17218          ast_copy_string(peer->accountcode, v->value, sizeof(peer->accountcode));
17219       } else if (!strcasecmp(v->name, "mohinterpret")
17220          || !strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) {
17221          ast_copy_string(peer->mohinterpret, v->value, sizeof(peer->mohinterpret));
17222       } else if (!strcasecmp(v->name, "mohsuggest")) {
17223          ast_copy_string(peer->mohsuggest, v->value, sizeof(peer->mohsuggest));
17224       } else if (!strcasecmp(v->name, "mailbox")) {
17225          ast_copy_string(peer->mailbox, v->value, sizeof(peer->mailbox));
17226       } else if (!strcasecmp(v->name, "subscribemwi")) {
17227          ast_set2_flag(&peer->flags[1], ast_true(v->value), SIP_PAGE2_SUBSCRIBEMWIONLY);
17228       } else if (!strcasecmp(v->name, "vmexten")) {
17229          ast_copy_string(peer->vmexten, v->value, sizeof(peer->vmexten));
17230       } else if (!strcasecmp(v->name, "callgroup")) {
17231          peer->callgroup = ast_get_group(v->value);
17232       } else if (!strcasecmp(v->name, "allowtransfer")) {
17233          peer->allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED;
17234       } else if (!strcasecmp(v->name, "pickupgroup")) {
17235          peer->pickupgroup = ast_get_group(v->value);
17236       } else if (!strcasecmp(v->name, "allow")) {
17237          ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1);
17238       } else if (!strcasecmp(v->name, "disallow")) {
17239          ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0);
17240       } else if (!strcasecmp(v->name, "autoframing")) {
17241          peer->autoframing = ast_true(v->value);
17242       } else if (!strcasecmp(v->name, "rtptimeout")) {
17243          if ((sscanf(v->value, "%d", &peer->rtptimeout) != 1) || (peer->rtptimeout < 0)) {
17244             ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d.  Using default.\n", v->value, v->lineno);
17245             peer->rtptimeout = global_rtptimeout;
17246          }
17247       } else if (!strcasecmp(v->name, "rtpholdtimeout")) {
17248          if ((sscanf(v->value, "%d", &peer->rtpholdtimeout) != 1) || (peer->rtpholdtimeout < 0)) {
17249             ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d.  Using default.\n", v->value, v->lineno);
17250             peer->rtpholdtimeout = global_rtpholdtimeout;
17251          }
17252       } else if (!strcasecmp(v->name, "rtpkeepalive")) {
17253          if ((sscanf(v->value, "%d", &peer->rtpkeepalive) != 1) || (peer->rtpkeepalive < 0)) {
17254             ast_log(LOG_WARNING, "'%s' is not a valid RTP keepalive time at line %d.  Using default.\n", v->value, v->lineno);
17255             peer->rtpkeepalive = global_rtpkeepalive;
17256          }
17257       } else if (!strcasecmp(v->name, "setvar")) {
17258          /* Set peer channel variable */
17259          varname = ast_strdupa(v->value);
17260          if ((varval = strchr(varname, '='))) {
17261             *varval++ = '\0';
17262             if ((tmpvar = ast_variable_new(varname, varval))) {
17263                tmpvar->next = peer->chanvars;
17264                peer->chanvars = tmpvar;
17265             }
17266          }
17267       } else if (!strcasecmp(v->name, "qualify")) {
17268          if (!strcasecmp(v->value, "no")) {
17269             peer->maxms = 0;
17270          } else if (!strcasecmp(v->value, "yes")) {
17271             peer->maxms = default_qualify ? default_qualify : DEFAULT_MAXMS;
17272          } else if (sscanf(v->value, "%d", &peer->maxms) != 1) {
17273             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);
17274             peer->maxms = 0;
17275          }
17276       } else if (!strcasecmp(v->name, "maxcallbitrate")) {
17277          peer->maxcallbitrate = atoi(v->value);
17278          if (peer->maxcallbitrate < 0)
17279             peer->maxcallbitrate = default_maxcallbitrate;
17280       }
17281    }
17282    if (!ast_strlen_zero(fullcontact)) {
17283       ast_copy_string(peer->fullcontact, fullcontact, sizeof(peer->fullcontact));
17284    }
17285 
17286    if (!ast_test_flag(&global_flags[1], SIP_PAGE2_IGNOREREGEXPIRE) && ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC) && realtime) {
17287       time_t nowtime = time(NULL);
17288 
17289       if ((nowtime - regseconds) > 0) {
17290          destroy_association(peer);
17291          memset(&peer->addr, 0, sizeof(peer->addr));
17292          if (option_debug)
17293             ast_log(LOG_DEBUG, "Bah, we're expired (%d/%d/%d)!\n", (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
17294       }
17295    }
17296    ast_copy_flags(&peer->flags[0], &peerflags[0], mask[0].flags);
17297    ast_copy_flags(&peer->flags[1], &peerflags[1], mask[1].flags);
17298    if (ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE))
17299       global_allowsubscribe = TRUE; /* No global ban any more */
17300    if (!found && ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC) && !ast_test_flag(&peer->flags[0], SIP_REALTIME))
17301       reg_source_db(peer);
17302    ASTOBJ_UNMARK(peer);
17303    ast_free_ha(oldha);
17304    return peer;
17305 }

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

11693 {
11694    char a1[256];
11695    char a2[256];
11696    char a1_hash[256];
11697    char a2_hash[256];
11698    char resp[256];
11699    char resp_hash[256];
11700    char uri[256];
11701    char opaque[256] = "";
11702    char cnonce[80];
11703    const char *username;
11704    const char *secret;
11705    const char *md5secret;
11706    struct sip_auth *auth = NULL; /* Realm authentication */
11707 
11708    if (!ast_strlen_zero(p->domain))
11709       ast_copy_string(uri, p->domain, sizeof(uri));
11710    else if (!ast_strlen_zero(p->uri))
11711       ast_copy_string(uri, p->uri, sizeof(uri));
11712    else
11713       snprintf(uri, sizeof(uri), "sip:%s@%s",p->username, ast_inet_ntoa(p->sa.sin_addr));
11714 
11715    snprintf(cnonce, sizeof(cnonce), "%08lx", ast_random());
11716 
11717    /* Check if we have separate auth credentials */
11718    if ((auth = find_realm_authentication(authl, p->realm))) {
11719       ast_log(LOG_WARNING, "use realm [%s] from peer [%s][%s]\n",
11720          auth->username, p->peername, p->username);
11721       username = auth->username;
11722       secret = auth->secret;
11723       md5secret = auth->md5secret;
11724       if (sipdebug)
11725          ast_log(LOG_DEBUG,"Using realm %s authentication for call %s\n", p->realm, p->callid);
11726    } else {
11727       /* No authentication, use peer or register= config */
11728       username = p->authname;
11729       secret =  p->peersecret;
11730       md5secret = p->peermd5secret;
11731    }
11732    if (ast_strlen_zero(username))   /* We have no authentication */
11733       return -1;
11734 
11735    /* Calculate SIP digest response */
11736    snprintf(a1,sizeof(a1),"%s:%s:%s", username, p->realm, secret);
11737    snprintf(a2,sizeof(a2),"%s:%s", sip_methods[method].text, uri);
11738    if (!ast_strlen_zero(md5secret))
11739       ast_copy_string(a1_hash, md5secret, sizeof(a1_hash));
11740    else
11741       ast_md5_hash(a1_hash,a1);
11742    ast_md5_hash(a2_hash,a2);
11743 
11744    p->noncecount++;
11745    if (!ast_strlen_zero(p->qop))
11746       snprintf(resp,sizeof(resp),"%s:%s:%08x:%s:%s:%s", a1_hash, p->nonce, p->noncecount, cnonce, "auth", a2_hash);
11747    else
11748       snprintf(resp,sizeof(resp),"%s:%s:%s", a1_hash, p->nonce, a2_hash);
11749    ast_md5_hash(resp_hash, resp);
11750 
11751    /* only include the opaque string if it's set */
11752    if (!ast_strlen_zero(p->opaque)) {
11753      snprintf(opaque, sizeof(opaque), ", opaque=\"%s\"", p->opaque);
11754    }
11755 
11756    /* XXX We hard code our qop to "auth" for now.  XXX */
11757    if (!ast_strlen_zero(p->qop))
11758       snprintf(digest, digest_len, "Digest username=\"%s\", realm=\"%s\", algorithm=MD5, uri=\"%s\", nonce=\"%s\", response=\"%s\"%s, qop=auth, cnonce=\"%s\", nc=%08x", username, p->realm, uri, p->nonce, resp_hash, opaque, cnonce, p->noncecount);
11759    else
11760       snprintf(digest, digest_len, "Digest username=\"%s\", realm=\"%s\", algorithm=MD5, uri=\"%s\", nonce=\"%s\", response=\"%s\"%s", username, p->realm, uri, p->nonce, resp_hash, opaque);
11761 
11762    append_history(p, "AuthResp", "Auth response sent for %s in realm %s - nc %d", username, p->realm, p->noncecount);
11763 
11764    return 0;
11765 }

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

08293 {
08294    struct sip_route *thishop, *head, *tail;
08295    int start = 0;
08296    int len;
08297    const char *rr, *contact, *c;
08298 
08299    /* Once a persistant route is set, don't fool with it */
08300    if (p->route && p->route_persistant) {
08301       if (option_debug)
08302          ast_log(LOG_DEBUG, "build_route: Retaining previous route: <%s>\n", p->route->hop);
08303       return;
08304    }
08305 
08306    if (p->route) {
08307       free_old_route(p->route);
08308       p->route = NULL;
08309    }
08310 
08311    /* We only want to create the route set the first time this is called */
08312    p->route_persistant = 1;
08313    
08314    /* Build a tailq, then assign it to p->route when done.
08315     * If backwards, we add entries from the head so they end up
08316     * in reverse order. However, we do need to maintain a correct
08317     * tail pointer because the contact is always at the end.
08318     */
08319    head = NULL;
08320    tail = head;
08321    /* 1st we pass through all the hops in any Record-Route headers */
08322    for (;;) {
08323       /* Each Record-Route header */
08324       rr = __get_header(req, "Record-Route", &start);
08325       if (*rr == '\0')
08326          break;
08327       for (; (rr = strchr(rr, '<')) ; rr += len) { /* Each route entry */
08328          ++rr;
08329          len = strcspn(rr, ">") + 1;
08330          /* Make a struct route */
08331          if ((thishop = ast_malloc(sizeof(*thishop) + len))) {
08332             /* ast_calloc is not needed because all fields are initialized in this block */
08333             ast_copy_string(thishop->hop, rr, len);
08334             if (option_debug > 1)
08335                ast_log(LOG_DEBUG, "build_route: Record-Route hop: <%s>\n", thishop->hop);
08336             /* Link in */
08337             if (backwards) {
08338                /* Link in at head so they end up in reverse order */
08339                thishop->next = head;
08340                head = thishop;
08341                /* If this was the first then it'll be the tail */
08342                if (!tail)
08343                   tail = thishop;
08344             } else {
08345                thishop->next = NULL;
08346                /* Link in at the end */
08347                if (tail)
08348                   tail->next = thishop;
08349                else
08350                   head = thishop;
08351                tail = thishop;
08352             }
08353          }
08354       }
08355    }
08356 
08357    /* Only append the contact if we are dealing with a strict router */
08358    if (!head || (!ast_strlen_zero(head->hop) && strstr(head->hop,";lr") == NULL) ) {
08359       /* 2nd append the Contact: if there is one */
08360       /* Can be multiple Contact headers, comma separated values - we just take the first */
08361       contact = get_header(req, "Contact");
08362       if (!ast_strlen_zero(contact)) {
08363          if (option_debug > 1)
08364             ast_log(LOG_DEBUG, "build_route: Contact hop: %s\n", contact);
08365          /* Look for <: delimited address */
08366          c = strchr(contact, '<');
08367          if (c) {
08368             /* Take to > */
08369             ++c;
08370             len = strcspn(c, ">") + 1;
08371          } else {
08372             /* No <> - just take the lot */
08373             c = contact;
08374             len = strlen(contact) + 1;
08375          }
08376          if ((thishop = ast_malloc(sizeof(*thishop) + len))) {
08377             /* ast_calloc is not needed because all fields are initialized in this block */
08378             ast_copy_string(thishop->hop, c, len);
08379             thishop->next = NULL;
08380             /* Goes at the end */
08381             if (tail)
08382                tail->next = thishop;
08383             else
08384                head = thishop;
08385          }
08386       }
08387    }
08388 
08389    /* Store as new route */
08390    p->route = head;
08391 
08392    /* For debugging dump what we ended up with */
08393    if (sip_debug_test_pvt(p))
08394       list_route(p->route);
08395 }

static void build_rpid ( struct sip_pvt p  )  [static]

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

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

06876 {
06877    int send_pres_tags = TRUE;
06878    const char *privacy=NULL;
06879    const char *screen=NULL;
06880    char buf[256];
06881    const char *clid = default_callerid;
06882    const char *clin = NULL;
06883    const char *fromdomain;
06884 
06885    if (!ast_strlen_zero(p->rpid) || !ast_strlen_zero(p->rpid_from))  
06886       return;
06887 
06888    if (p->owner && p->owner->cid.cid_num)
06889       clid = p->owner->cid.cid_num;
06890    if (p->owner && p->owner->cid.cid_name)
06891       clin = p->owner->cid.cid_name;
06892    if (ast_strlen_zero(clin))
06893       clin = clid;
06894 
06895    switch (p->callingpres) {
06896    case AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED:
06897       privacy = "off";
06898       screen = "no";
06899       break;
06900    case AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN:
06901       privacy = "off";
06902       screen = "yes";
06903       break;
06904    case AST_PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN:
06905       privacy = "off";
06906       screen = "no";
06907       break;
06908    case AST_PRES_ALLOWED_NETWORK_NUMBER:
06909       privacy = "off";
06910       screen = "yes";
06911       break;
06912    case AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED:
06913       privacy = "full";
06914       screen = "no";
06915       break;
06916    case AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN:
06917       privacy = "full";
06918       screen = "yes";
06919       break;
06920    case AST_PRES_PROHIB_USER_NUMBER_FAILED_SCREEN:
06921       privacy = "full";
06922       screen = "no";
06923       break;
06924    case AST_PRES_PROHIB_NETWORK_NUMBER:
06925       privacy = "full";
06926       screen = "yes";
06927       break;
06928    case AST_PRES_NUMBER_NOT_AVAILABLE:
06929       send_pres_tags = FALSE;
06930       break;
06931    default:
06932       ast_log(LOG_WARNING, "Unsupported callingpres (%d)\n", p->callingpres);
06933       if ((p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED)
06934          privacy = "full";
06935       else
06936          privacy = "off";
06937       screen = "no";
06938       break;
06939    }
06940    
06941    fromdomain = S_OR(p->fromdomain, ast_inet_ntoa(p->ourip));
06942 
06943    snprintf(buf, sizeof(buf), "\"%s\" <sip:%s@%s>", clin, clid, fromdomain);
06944    if (send_pres_tags)
06945       snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), ";privacy=%s;screen=%s", privacy, screen);
06946    ast_string_field_set(p, rpid, buf);
06947 
06948    ast_string_field_build(p, rpid_from, "\"%s\" <sip:%s@%s>;tag=%s", clin,
06949                 S_OR(p->fromuser, clid),
06950                 fromdomain, p->tag);
06951 }

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

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

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

16867 {
16868    struct sip_user *user;
16869    int format;
16870    struct ast_ha *oldha = NULL;
16871    char *varname = NULL, *varval = NULL;
16872    struct ast_variable *tmpvar = NULL;
16873    struct ast_flags userflags[2] = {{(0)}};
16874    struct ast_flags mask[2] = {{(0)}};
16875 
16876 
16877    if (!(user = ast_calloc(1, sizeof(*user))))
16878       return NULL;
16879       
16880    suserobjs++;
16881    ASTOBJ_INIT(user);
16882    ast_copy_string(user->name, name, sizeof(user->name));
16883    oldha = user->ha;
16884    user->ha = NULL;
16885    ast_copy_flags(&user->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY);
16886    ast_copy_flags(&user->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY);
16887    user->capability = global_capability;
16888    user->allowtransfer = global_allowtransfer;
16889    user->maxcallbitrate = default_maxcallbitrate;
16890    user->autoframing = global_autoframing;
16891    user->prefs = default_prefs;
16892    /* set default context */
16893    strcpy(user->context, default_context);
16894    strcpy(user->language, default_language);
16895    strcpy(user->mohinterpret, default_mohinterpret);
16896    strcpy(user->mohsuggest, default_mohsuggest);
16897    /* First we walk through the v parameters list and then the alt parameters list */
16898    for (; v || ((v = alt) && !(alt=NULL)); v = v->next) {
16899       if (handle_common_options(&userflags[0], &mask[0], v))
16900          continue;
16901 
16902       if (!strcasecmp(v->name, "context")) {
16903          ast_copy_string(user->context, v->value, sizeof(user->context));
16904       } else if (!strcasecmp(v->name, "subscribecontext")) {
16905          ast_copy_string(user->subscribecontext, v->value, sizeof(user->subscribecontext));
16906       } else if (!strcasecmp(v->name, "setvar")) {
16907          varname = ast_strdupa(v->value);
16908          if ((varval = strchr(varname,'='))) {
16909             *varval++ = '\0';
16910             if ((tmpvar = ast_variable_new(varname, varval))) {
16911                tmpvar->next = user->chanvars;
16912                user->chanvars = tmpvar;
16913             }
16914          }
16915       } else if (!strcasecmp(v->name, "permit") ||
16916                !strcasecmp(v->name, "deny")) {
16917          user->ha = ast_append_ha(v->name, v->value, user->ha);
16918       } else if (!strcasecmp(v->name, "allowtransfer")) {
16919          user->allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED;
16920       } else if (!strcasecmp(v->name, "secret")) {
16921          ast_copy_string(user->secret, v->value, sizeof(user->secret)); 
16922       } else if (!strcasecmp(v->name, "md5secret")) {
16923          ast_copy_string(user->md5secret, v->value, sizeof(user->md5secret));
16924       } else if (!strcasecmp(v->name, "callerid")) {
16925          ast_callerid_split(v->value, user->cid_name, sizeof(user->cid_name), user->cid_num, sizeof(user->cid_num));
16926       } else if (!strcasecmp(v->name, "fullname")) {
16927          ast_copy_string(user->cid_name, v->value, sizeof(user->cid_name));
16928       } else if (!strcasecmp(v->name, "cid_number")) {
16929          ast_copy_string(user->cid_num, v->value, sizeof(user->cid_num));
16930       } else if (!strcasecmp(v->name, "callgroup")) {
16931          user->callgroup = ast_get_group(v->value);
16932       } else if (!strcasecmp(v->name, "pickupgroup")) {
16933          user->pickupgroup = ast_get_group(v->value);
16934       } else if (!strcasecmp(v->name, "language")) {
16935          ast_copy_string(user->language, v->value, sizeof(user->language));
16936       } else if (!strcasecmp(v->name, "mohinterpret") 
16937          || !strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) {
16938          ast_copy_string(user->mohinterpret, v->value, sizeof(user->mohinterpret));
16939       } else if (!strcasecmp(v->name, "mohsuggest")) {
16940          ast_copy_string(user->mohsuggest, v->value, sizeof(user->mohsuggest));
16941       } else if (!strcasecmp(v->name, "accountcode")) {
16942          ast_copy_string(user->accountcode, v->value, sizeof(user->accountcode));
16943       } else if (!strcasecmp(v->name, "call-limit")) {
16944          user->call_limit = atoi(v->value);
16945          if (user->call_limit < 0)
16946             user->call_limit = 0;
16947       } else if (!strcasecmp(v->name, "amaflags")) {
16948          format = ast_cdr_amaflags2int(v->value);
16949          if (format < 0) {
16950             ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
16951          } else {
16952             user->amaflags = format;
16953          }
16954       } else if (!strcasecmp(v->name, "allow")) {
16955          ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1);
16956       } else if (!strcasecmp(v->name, "disallow")) {
16957          ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 0);
16958       } else if (!strcasecmp(v->name, "autoframing")) {
16959          user->autoframing = ast_true(v->value);
16960       } else if (!strcasecmp(v->name, "callingpres")) {
16961          user->callingpres = ast_parse_caller_presentation(v->value);
16962          if (user->callingpres == -1)
16963             user->callingpres = atoi(v->value);
16964       } else if (!strcasecmp(v->name, "maxcallbitrate")) {
16965          user->maxcallbitrate = atoi(v->value);
16966          if (user->maxcallbitrate < 0)
16967             user->maxcallbitrate = default_maxcallbitrate;
16968       }
16969       /* We can't just report unknown options here because this may be a
16970        * type=friend entry.  All user options are valid for a peer, but not
16971        * the other way around.  */
16972    }
16973    ast_copy_flags(&user->flags[0], &userflags[0], mask[0].flags);
16974    ast_copy_flags(&user->flags[1], &userflags[1], mask[1].flags);
16975    if (ast_test_flag(&user->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE))
16976       global_allowsubscribe = TRUE; /* No global ban any more */
16977    ast_free_ha(oldha);
16978    return user;
16979 }

static void build_via ( struct sip_pvt p  )  [static]

Build a Via header for a request.

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

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

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

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

Referenced by handle_request_subscribe(), and handle_response().

08601 {
08602    struct sip_pvt *p = data;
08603 
08604    ast_mutex_lock(&p->lock);
08605 
08606    switch(state) {
08607    case AST_EXTENSION_DEACTIVATED:  /* Retry after a while */
08608    case AST_EXTENSION_REMOVED:   /* Extension is gone */
08609       if (p->autokillid > -1 && sip_cancel_destroy(p))   /* Remove subscription expiry for renewals */
08610          ast_log(LOG_WARNING, "Unable to cancel SIP destruction.  Expect bad things.\n");
08611       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);  /* Delete subscription in 32 secs */
08612       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);
08613       p->stateid = -1;
08614       p->subscribed = NONE;
08615       append_history(p, "Subscribestatus", "%s", state == AST_EXTENSION_REMOVED ? "HintRemoved" : "Deactivated");
08616       break;
08617    default: /* Tell user */
08618       p->laststate = state;
08619       break;
08620    }
08621    if (p->subscribed != NONE) {  /* Only send state NOTIFY if we know the format */
08622       if (!p->pendinginvite) {
08623          transmit_state_notify(p, state, 1, FALSE);
08624       } else {
08625          /* We already have a NOTIFY sent that is not answered. Queue the state up.
08626             if many state changes happen meanwhile, we will only send a notification of the last one */
08627          ast_set_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE);
08628       }
08629    }
08630    if (option_verbose > 1)
08631       ast_verbose(VERBOSE_PREFIX_1 "Extension Changed %s[%s] new state %s for Notify User %s %s\n", exten, context, ast_extension_state2str(state), p->username,
08632             ast_test_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE) ? "(queued)" : "");
08633 
08634    
08635    ast_mutex_unlock(&p->lock);
08636 
08637    return 0;
08638 }

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

04985 {
04986    if (global_notifyhold && (!holdstate || !ast_test_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD)))
04987       sip_peer_hold(dialog, holdstate);
04988    if (global_callevents)
04989       manager_event(EVENT_FLAG_CALL, holdstate ? "Hold" : "Unhold",
04990                "Channel: %s\r\n"
04991                "Uniqueid: %s\r\n",
04992                dialog->owner->name, 
04993                dialog->owner->uniqueid);
04994    append_history(dialog, holdstate ? "Hold" : "Unhold", "%s", req->data);
04995    if (!holdstate) {    /* Put off remote hold */
04996       ast_clear_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD);   /* Clear both flags */
04997       return;
04998    }
04999    /* No address for RTP, we're on hold */
05000 
05001    if (sendonly == 1)   /* One directional hold (sendonly/recvonly) */
05002       ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_ONEDIR);
05003    else if (sendonly == 2) /* Inactive stream */
05004       ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_INACTIVE);
05005    else
05006       ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_ACTIVE);
05007    return;
05008 }

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

XXX

Todo:
need a better return code here

XXX

Todo:
need a better return code here

Definition at line 8405 of file chan_sip.c.

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

Referenced by check_user_full(), and register_verify().

08408 {
08409    const char *response = "407 Proxy Authentication Required";
08410    const char *reqheader = "Proxy-Authorization";
08411    const char *respheader = "Proxy-Authenticate";
08412    const char *authtoken;
08413    char a1_hash[256];
08414    char resp_hash[256]="";
08415    char *c;
08416    int  wrongnonce = FALSE;
08417    int  good_response;
08418    const char *usednonce = p->randdata;
08419    struct ast_dynamic_str *buf;
08420    int res;
08421 
08422    /* table of recognised keywords, and their value in the digest */
08423    enum keys { K_RESP, K_URI, K_USER, K_NONCE, K_LAST };
08424    struct x {
08425       const char *key;
08426       const char *s;
08427    } *i, keys[] = {
08428       [K_RESP] = { "response=", "" },
08429       [K_URI] = { "uri=", "" },
08430       [K_USER] = { "username=", "" },
08431       [K_NONCE] = { "nonce=", "" },
08432       [K_LAST] = { NULL, NULL}
08433    };
08434 
08435    /* Always OK if no secret */
08436    if (ast_strlen_zero(secret) && ast_strlen_zero(md5secret))
08437       return AUTH_SUCCESSFUL;
08438    if (sipmethod == SIP_REGISTER || sipmethod == SIP_SUBSCRIBE) {
08439       /* On a REGISTER, we have to use 401 and its family of headers instead of 407 and its family
08440          of headers -- GO SIP!  Whoo hoo!  Two things that do the same thing but are used in
08441          different circumstances! What a surprise. */
08442       response = "401 Unauthorized";
08443       reqheader = "Authorization";
08444       respheader = "WWW-Authenticate";
08445    }
08446    authtoken =  get_header(req, reqheader);  
08447    if (ignore && !ast_strlen_zero(p->randdata) && ast_strlen_zero(authtoken)) {
08448       /* This is a retransmitted invite/register/etc, don't reconstruct authentication
08449          information */
08450       if (!reliable) {
08451          /* Resend message if this was NOT a reliable delivery.   Otherwise the
08452             retransmission should get it */
08453          transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0);
08454          /* Schedule auto destroy in 32 seconds (according to RFC 3261) */
08455          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
08456       }
08457       return AUTH_CHALLENGE_SENT;
08458    } else if (ast_strlen_zero(p->randdata) || ast_strlen_zero(authtoken)) {
08459       /* We have no auth, so issue challenge and request authentication */
08460       ast_string_field_build(p, randdata, "%08lx", ast_random()); /* Create nonce for challenge */
08461       transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0);
08462       /* Schedule auto destroy in 32 seconds */
08463       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
08464       return AUTH_CHALLENGE_SENT;
08465    } 
08466 
08467    /* --- We have auth, so check it */
08468 
08469    /* Whoever came up with the authentication section of SIP can suck my %&#$&* for not putting
08470          an example in the spec of just what it is you're doing a hash on. */
08471 
08472    if (!(buf = ast_dynamic_str_thread_get(&check_auth_buf, CHECK_AUTH_BUF_INITLEN)))
08473       return AUTH_SECRET_FAILED; /*! XXX \todo need a better return code here */
08474 
08475    /* Make a copy of the response and parse it */
08476    res = ast_dynamic_str_thread_set(&buf, 0, &check_auth_buf, "%s", authtoken);
08477 
08478    if (res == AST_DYNSTR_BUILD_FAILED)
08479       return AUTH_SECRET_FAILED; /*! XXX \todo need a better return code here */
08480 
08481    c = buf->str;
08482 
08483    while(c && *(c = ast_skip_blanks(c)) ) { /* lookup for keys */
08484       for (i = keys; i->key != NULL; i++) {
08485          const char *separator = ",";  /* default */
08486 
08487          if (strncasecmp(c, i->key, strlen(i->key)) != 0)
08488             continue;
08489          /* Found. Skip keyword, take text in quotes or up to the separator. */
08490          c += strlen(i->key);
08491          if (*c == '"') { /* in quotes. Skip first and look for last */
08492             c++;
08493             separator = "\"";
08494          }
08495          i->s = c;
08496          strsep(&c, separator);
08497          break;
08498       }
08499       if (i->key == NULL) /* not found, jump after space or comma */
08500          strsep(&c, " ,");
08501    }
08502 
08503    /* Verify that digest username matches  the username we auth as */
08504    if (strcmp(username, keys[K_USER].s)) {
08505       ast_log(LOG_WARNING, "username mismatch, have <%s>, digest has <%s>\n",
08506          username, keys[K_USER].s);
08507       /* Oops, we're trying something here */
08508       return AUTH_USERNAME_MISMATCH;
08509    }
08510 
08511    /* Verify nonce from request matches our nonce.  If not, send 401 with new nonce */
08512    if (strcasecmp(p->randdata, keys[K_NONCE].s)) { /* XXX it was 'n'casecmp ? */
08513       wrongnonce = TRUE;
08514       usednonce = keys[K_NONCE].s;
08515    }
08516 
08517    if (!ast_strlen_zero(md5secret))
08518       ast_copy_string(a1_hash, md5secret, sizeof(a1_hash));
08519    else {
08520       char a1[256];
08521       snprintf(a1, sizeof(a1), "%s:%s:%s", username, global_realm, secret);
08522       ast_md5_hash(a1_hash, a1);
08523    }
08524 
08525    /* compute the expected response to compare with what we received */
08526    {
08527       char a2[256];
08528       char a2_hash[256];
08529       char resp[256];
08530 
08531       snprintf(a2, sizeof(a2), "%s:%s", sip_methods[sipmethod].text,
08532             S_OR(keys[K_URI].s, uri));
08533       ast_md5_hash(a2_hash, a2);
08534       snprintf(resp, sizeof(resp), "%s:%s:%s", a1_hash, usednonce, a2_hash);
08535       ast_md5_hash(resp_hash, resp);
08536    }
08537 
08538    good_response = keys[K_RESP].s &&
08539          !strncasecmp(keys[K_RESP].s, resp_hash, strlen(resp_hash));
08540    if (wrongnonce) {
08541       if (good_response) {
08542          if (sipdebug)
08543             ast_log(LOG_NOTICE, "Correct auth, but based on stale nonce received from '%s'\n", get_header(req, "To"));
08544          /* We got working auth token, based on stale nonce . */
08545          ast_string_field_build(p, randdata, "%08lx", ast_random());
08546          transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, TRUE);
08547       } else {
08548          /* Everything was wrong, so give the device one more try with a new challenge */
08549          if (!ast_test_flag(req, SIP_PKT_IGNORE)) {
08550             if (sipdebug)
08551                ast_log(LOG_NOTICE, "Bad authentication received from '%s'\n", get_header(req, "To"));
08552             ast_string_field_build(p, randdata, "%08lx", ast_random());
08553          } else {
08554             if (sipdebug)
08555                ast_log(LOG_NOTICE, "Duplicate authentication received from '%s'\n", get_header(req, "To"));
08556          }
08557          transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, FALSE);
08558       }
08559 
08560       /* Schedule auto destroy in 32 seconds */
08561       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
08562       return AUTH_CHALLENGE_SENT;
08563    } 
08564    if (good_response) {
08565       append_history(p, "AuthOK", "Auth challenge succesful for %s", username);
08566       return AUTH_SUCCESSFUL;
08567    }
08568 
08569    /* Ok, we have a bad username/secret pair */
08570    /* Tell the UAS not to re-send this authentication data, because
08571       it will continue to fail
08572    */
08573 
08574    return AUTH_SECRET_FAILED;
08575 }

static void check_pendings ( struct sip_pvt p  )  [static]

Check pending actions on SIP call.

Definition at line 12160 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, sip_pvt::lastinvite, LOG_DEBUG, 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().

12161 {
12162    if (ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) {
12163       /* if we can't BYE, then this is really a pending CANCEL */
12164       if (p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA)
12165          transmit_request(p, SIP_CANCEL, p->lastinvite, XMIT_RELIABLE, FALSE);
12166          /* Actually don't destroy us yet, wait for the 487 on our original 
12167             INVITE, but do set an autodestruct just in case we never get it. */
12168       else {
12169          /* We have a pending outbound invite, don't send someting
12170             new in-transaction */
12171          if (p->pendinginvite)
12172             return;
12173 
12174          /* Perhaps there is an SD change INVITE outstanding */
12175          transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, TRUE);
12176       }
12177       ast_clear_flag(&p->flags[0], SIP_PENDINGBYE);   
12178       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
12179    } else if (ast_test_flag(&p->flags[0], SIP_NEEDREINVITE)) {
12180       /* if we can't REINVITE, hold it for later */
12181       if (p->pendinginvite || p->invitestate == INV_CALLING || p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA || p->waitid > 0) {
12182          if (option_debug)
12183             ast_log(LOG_DEBUG, "NOT Sending pending reinvite (yet) on '%s'\n", p->callid);
12184       } else {
12185          if (option_debug)
12186             ast_log(LOG_DEBUG, "Sending pending reinvite on '%s'\n", p->callid);
12187          /* Didn't get to reinvite yet, so do it now */
12188          transmit_reinvite_with_sdp(p);
12189          ast_clear_flag(&p->flags[0], SIP_NEEDREINVITE); 
12190       }
12191    }
12192 }

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

16746 {
16747    struct domain *d;
16748    int result = 0;
16749 
16750    AST_LIST_LOCK(&domain_list);
16751    AST_LIST_TRAVERSE(&domain_list, d, list) {
16752       if (strcasecmp(d->domain, domain))
16753          continue;
16754 
16755       if (len && !ast_strlen_zero(d->context))
16756          ast_copy_string(context, d->context, len);
16757       
16758       result = 1;
16759       break;
16760    }
16761    AST_LIST_UNLOCK(&domain_list);
16762 
16763    return result;
16764 }

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

References check_user_full().

Referenced by handle_request_invite().

09797 {
09798    return check_user_full(p, req, sipmethod, uri, reliable, sin, NULL);
09799 }

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 9476 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, LOG_WARNING, 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().

09479 {
09480    struct sip_user *user = NULL;
09481    struct sip_peer *peer;
09482    char from[256], *c;
09483    char *of;
09484    char rpid_num[50];
09485    const char *rpid;
09486    enum check_auth_result res = AUTH_SUCCESSFUL;
09487    char *t;
09488    char calleridname[50];
09489    int debug=sip_debug_test_addr(sin);
09490    struct ast_variable *tmpvar = NULL, *v = NULL;
09491    char *uri2 = ast_strdupa(uri);
09492 
09493    /* Terminate URI */
09494    t = uri2;
09495    while (*t && *t > 32 && *t != ';')
09496       t++;
09497    *t = '\0';
09498    ast_copy_string(from, get_header(req, "From"), sizeof(from));  /* XXX bug in original code, overwrote string */
09499    if (pedanticsipchecking)
09500       ast_uri_decode(from);
09501    /* XXX here tries to map the username for invite things */
09502    memset(calleridname, 0, sizeof(calleridname));
09503    get_calleridname(from, calleridname, sizeof(calleridname));
09504    if (calleridname[0])
09505       ast_string_field_set(p, cid_name, calleridname);
09506 
09507    rpid = get_header(req, "Remote-Party-ID");
09508    memset(rpid_num, 0, sizeof(rpid_num));
09509    if (!ast_strlen_zero(rpid)) 
09510       p->callingpres = get_rpid_num(rpid, rpid_num, sizeof(rpid_num));
09511 
09512    of = get_in_brackets(from);
09513    if (ast_strlen_zero(p->exten)) {
09514       t = uri2;
09515       if (!strncasecmp(t, "sip:", 4))
09516          t+= 4;
09517       ast_string_field_set(p, exten, t);
09518       t = strchr(p->exten, '@');
09519       if (t)
09520          *t = '\0';
09521       if (ast_strlen_zero(p->our_contact))
09522          build_contact(p);
09523    }
09524    /* save the URI part of the From header */
09525    ast_string_field_set(p, from, of);
09526    if (strncasecmp(of, "sip:", 4)) {
09527       ast_log(LOG_NOTICE, "From address missing 'sip:', using it anyway\n");
09528    } else
09529       of += 4;
09530    /* Get just the username part */
09531    if ((c = strchr(of, '@'))) {
09532       char *tmp;
09533       *c = '\0';
09534       if ((c = strchr(of, ':')))
09535          *c = '\0';
09536       tmp = ast_strdupa(of);
09537       /* We need to be able to handle auth-headers looking like
09538          <sip:8164444422;phone-context=+1@1.2.3.4:5060;user=phone;tag=SDadkoa01-gK0c3bdb43>
09539       */
09540       tmp = strsep(&tmp, ";");
09541       if (ast_is_shrinkable_phonenumber(tmp))
09542          ast_shrink_phone_number(tmp);
09543       ast_string_field_set(p, cid_num, tmp);
09544    }
09545 
09546    if (!authpeer) /* If we are looking for a peer, don't check the user objects (or realtime) */
09547       user = find_user(of, 1);
09548 
09549    /* Find user based on user name in the from header */
09550    if (user && ast_apply_ha(user->ha, sin)) {
09551       ast_copy_flags(&p->flags[0], &user->flags[0], SIP_FLAGS_TO_COPY);
09552       ast_copy_flags(&p->flags[1], &user->flags[1], SIP_PAGE2_FLAGS_TO_COPY);
09553       /* copy channel vars */
09554       for (v = user->chanvars ; v ; v = v->next) {
09555          if ((tmpvar = ast_variable_new(v->name, v->value))) {
09556             tmpvar->next = p->chanvars; 
09557             p->chanvars = tmpvar;
09558          }
09559       }
09560       p->prefs = user->prefs;
09561       /* Set Frame packetization */
09562       if (p->rtp) {
09563          ast_rtp_codec_setpref(p->rtp, &p->prefs);
09564          p->autoframing = user->autoframing;
09565       }
09566       /* replace callerid if rpid found, and not restricted */
09567       if (!ast_strlen_zero(rpid_num) && ast_test_flag(&p->flags[0], SIP_TRUSTRPID)) {
09568          char *tmp;
09569          if (*calleridname)
09570             ast_string_field_set(p, cid_name, calleridname);
09571          tmp = ast_strdupa(rpid_num);
09572          if (ast_is_shrinkable_phonenumber(tmp))
09573             ast_shrink_phone_number(tmp);
09574          ast_string_field_set(p, cid_num, tmp);
09575       }
09576       
09577       do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT_ROUTE) );
09578 
09579       if (!(res = check_auth(p, req, user->name, user->secret, user->md5secret, sipmethod, uri2, reliable, ast_test_flag(req, SIP_PKT_IGNORE)))) {
09580          if (sip_cancel_destroy(p))
09581             ast_log(LOG_WARNING, "Unable to cancel SIP destruction.  Expect bad things.\n");
09582          ast_copy_flags(&p->flags[0], &user->flags[0], SIP_FLAGS_TO_COPY);
09583          ast_copy_flags(&p->flags[1], &user->flags[1], SIP_PAGE2_FLAGS_TO_COPY);
09584          /* Copy SIP extensions profile from INVITE */
09585          if (p->sipoptions)
09586             user->sipoptions = p->sipoptions;
09587 
09588          /* If we have a call limit, set flag */
09589          if (user->call_limit)
09590             ast_set_flag(&p->flags[0], SIP_CALL_LIMIT);
09591          if (!ast_strlen_zero(user->context))
09592             ast_string_field_set(p, context, user->context);
09593          if (!ast_strlen_zero(user->cid_num)) {
09594             char *tmp = ast_strdupa(user->cid_num);
09595             if (ast_is_shrinkable_phonenumber(tmp))
09596                ast_shrink_phone_number(tmp);
09597             ast_string_field_set(p, cid_num, tmp);
09598          }
09599          if (!ast_strlen_zero(user->cid_name))
09600             ast_string_field_set(p, cid_name, user->cid_name);
09601          ast_string_field_set(p, username, user->name);
09602          ast_string_field_set(p, peername, user->name);
09603          ast_string_field_set(p, peersecret, user->secret);
09604          ast_string_field_set(p, peermd5secret, user->md5secret);
09605          ast_string_field_set(p, subscribecontext, user->subscribecontext);
09606          ast_string_field_set(p, accountcode, user->accountcode);
09607          ast_string_field_set(p, language, user->language);
09608          ast_string_field_set(p, mohsuggest, user->mohsuggest);
09609          ast_string_field_set(p, mohinterpret, user->mohinterpret);
09610          p->allowtransfer = user->allowtransfer;
09611          p->amaflags = user->amaflags;
09612          p->callgroup = user->callgroup;
09613          p->pickupgroup = user->pickupgroup;
09614          if (user->callingpres)  /* User callingpres setting will override RPID header */
09615             p->callingpres = user->callingpres;
09616          
09617          /* Set default codec settings for this call */
09618          p->capability = user->capability;      /* User codec choice */
09619          p->jointcapability = user->capability;    /* Our codecs */
09620          if (p->peercapability)           /* AND with peer's codecs */
09621             p->jointcapability &= p->peercapability;
09622          if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) ||
09623              (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO))
09624             p->noncodeccapability |= AST_RTP_DTMF;
09625          else
09626             p->noncodeccapability &= ~AST_RTP_DTMF;
09627          p->jointnoncodeccapability = p->noncodeccapability;
09628          if (p->t38.peercapability)
09629             p->t38.jointcapability &= p->t38.peercapability;
09630          p->maxcallbitrate = user->maxcallbitrate;
09631          /* If we do not support video, remove video from call structure */
09632          if ((!ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) || !(p->capability & AST_FORMAT_VIDEO_MASK)) && p->vrtp) {
09633             ast_rtp_destroy(p->vrtp);
09634             p->vrtp = NULL;
09635          }
09636       }
09637       if (user && debug)
09638          ast_verbose("Found user '%s'\n", user->name);
09639    } else {
09640       if (user) {
09641          if (!authpeer && debug)
09642             ast_verbose("Found user '%s', but fails host access\n", user->name);
09643          ASTOBJ_UNREF(user,sip_destroy_user);
09644       }
09645       user = NULL;
09646    }
09647 
09648    if (!user) {
09649       /* If we didn't find a user match, check for peers */
09650       if (sipmethod == SIP_SUBSCRIBE)
09651          /* For subscribes, match on peer name only */
09652          peer = find_peer(of, NULL, 1);
09653       else
09654          /* Look for peer based on the IP address we received data from */
09655          /* If peer is registered from this IP address or have this as a default
09656             IP address, this call is from the peer 
09657          */
09658          peer = find_peer(NULL, &p->recv, 1);
09659 
09660       if (peer) {
09661          /* Set Frame packetization */
09662          if (p->rtp) {
09663             ast_rtp_codec_setpref(p->rtp, &peer->prefs);
09664             p->autoframing = peer->autoframing;
09665          }
09666          if (debug)
09667             ast_verbose("Found peer '%s'\n", peer->name);
09668 
09669          /* Take the peer */
09670          ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY);
09671          ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY);
09672 
09673          /* Copy SIP extensions profile to peer */
09674          if (p->sipoptions)
09675             peer->sipoptions = p->sipoptions;
09676 
09677          /* replace callerid if rpid found, and not restricted */
09678          if (!ast_strlen_zero(rpid_num) && ast_test_flag(&p->flags[0], SIP_TRUSTRPID)) {
09679             char *tmp = ast_strdupa(rpid_num);
09680             if (*calleridname)
09681                ast_string_field_set(p, cid_name, calleridname);
09682             if (ast_is_shrinkable_phonenumber(tmp))
09683                ast_shrink_phone_number(tmp);
09684             ast_string_field_set(p, cid_num, tmp);
09685          }
09686          do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT_ROUTE));
09687 
09688          ast_string_field_set(p, peersecret, peer->secret);
09689          ast_string_field_set(p, peermd5secret, peer->md5secret);
09690          ast_string_field_set(p, subscribecontext, peer->subscribecontext);
09691          ast_string_field_set(p, mohinterpret, peer->mohinterpret);
09692          ast_string_field_set(p, mohsuggest, peer->mohsuggest);
09693          if (peer->callingpres)  /* Peer calling pres setting will override RPID */
09694             p->callingpres = peer->callingpres;
09695          if (peer->maxms && peer->lastms)
09696             p->timer_t1 = peer->lastms < global_t1min ? global_t1min : peer->lastms;
09697          if (ast_test_flag(&peer->flags[0], SIP_INSECURE_INVITE)) {
09698             /* Pretend there is no required authentication */
09699             ast_string_field_free(p, peersecret);
09700             ast_string_field_free(p, peermd5secret);
09701          }
09702          if (!(res = check_auth(p, req, peer->name, p->peersecret, p->peermd5secret, sipmethod, uri2, reliable, ast_test_flag(req, SIP_PKT_IGNORE)))) {
09703             ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY);
09704             ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY);
09705             /* If we have a call limit, set flag */
09706             if (peer->call_limit)
09707                ast_set_flag(&p->flags[0], SIP_CALL_LIMIT);
09708             ast_string_field_set(p, peername, peer->name);
09709             ast_string_field_set(p, authname, peer->name);
09710 
09711             /* copy channel vars */
09712             for (v = peer->chanvars ; v ; v = v->next) {
09713                if ((tmpvar = ast_variable_new(v->name, v->value))) {
09714                   tmpvar->next = p->chanvars; 
09715                   p->chanvars = tmpvar;
09716                }
09717             }
09718             if (authpeer) {
09719                (*authpeer) = ASTOBJ_REF(peer);  /* Add a ref to the object here, to keep it in memory a bit longer if it is realtime */
09720             }
09721 
09722             if (!ast_strlen_zero(peer->username)) {
09723                ast_string_field_set(p, username, peer->username);
09724                /* Use the default username for authentication on outbound calls */
09725                /* XXX this takes the name from the caller... can we override ? */
09726                ast_string_field_set(p, authname, peer->username);
09727             }
09728             if (!ast_strlen_zero(peer->cid_num)) {
09729                char *tmp = ast_strdupa(peer->cid_num);
09730                if (ast_is_shrinkable_phonenumber(tmp))
09731                   ast_shrink_phone_number(tmp);
09732                ast_string_field_set(p, cid_num, tmp);
09733             }
09734             if (!ast_strlen_zero(peer->cid_name)) 
09735                ast_string_field_set(p, cid_name, peer->cid_name);
09736             ast_string_field_set(p, fullcontact, peer->fullcontact);
09737             if (!ast_strlen_zero(peer->context))
09738                ast_string_field_set(p, context, peer->context);
09739             ast_string_field_set(p, peersecret, peer->secret);
09740             ast_string_field_set(p, peermd5secret, peer->md5secret);
09741             ast_string_field_set(p, language, peer->language);
09742             ast_string_field_set(p, accountcode, peer->accountcode);
09743             p->amaflags = peer->amaflags;
09744             p->callgroup = peer->callgroup;
09745             p->pickupgroup = peer->pickupgroup;
09746             p->capability = peer->capability;
09747             p->prefs = peer->prefs;
09748             p->jointcapability = peer->capability;
09749             if (p->peercapability)
09750                p->jointcapability &= p->peercapability;
09751             p->maxcallbitrate = peer->maxcallbitrate;
09752             if ((!ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) || !(p->capability & AST_FORMAT_VIDEO_MASK)) && p->vrtp) {
09753                ast_rtp_destroy(p->vrtp);
09754                p->vrtp = NULL;
09755             }
09756             if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) ||
09757                 (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO))
09758                p->noncodeccapability |= AST_RTP_DTMF;
09759             else
09760                p->noncodeccapability &= ~AST_RTP_DTMF;
09761             p->jointnoncodeccapability = p->noncodeccapability;
09762             if (p->t38.peercapability)
09763                p->t38.jointcapability &= p->t38.peercapability;
09764          }
09765          ASTOBJ_UNREF(peer, sip_destroy_peer);
09766       } else { 
09767          if (debug)
09768             ast_verbose("Found no matching peer or user for '%s:%d'\n", ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port));
09769 
09770          /* do we allow guests? */
09771          if (!global_allowguest) {
09772             if (global_alwaysauthreject)
09773                res = AUTH_FAKE_AUTH; /* reject with fake authorization request */
09774             else
09775                res = AUTH_SECRET_FAILED; /* we don't want any guests, authentication will fail */
09776          } else if (!ast_strlen_zero(rpid_num) && ast_test_flag(&p->flags[0], SIP_TRUSTRPID)) {
09777             char *tmp = ast_strdupa(rpid_num);
09778             if (*calleridname)
09779                ast_string_field_set(p, cid_name, calleridname);
09780             if (ast_is_shrinkable_phonenumber(tmp))
09781                ast_shrink_phone_number(tmp);
09782             ast_string_field_set(p, cid_num, tmp);
09783                         }
09784       }
09785 
09786    }
09787 
09788    if (user)
09789       ASTOBJ_UNREF(user, sip_destroy_user);
09790    return res;
09791 }

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

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

Definition at line 9344 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(), handle_request_subscribe(), and transmit_response_using_temp().

09345 {
09346    char via[512];
09347    char *c, *pt;
09348    struct hostent *hp;
09349    struct ast_hostent ahp;
09350 
09351    ast_copy_string(via, get_header(req, "Via"), sizeof(via));
09352 
09353    /* Work on the leftmost value of the topmost Via header */
09354    c = strchr(via, ',');
09355    if (c)
09356       *c = '\0';
09357 
09358    /* Check for rport */
09359    c = strstr(via, ";rport");
09360    if (c && (c[6] != '=')) /* rport query, not answer */
09361       ast_set_flag(&p->flags[0], SIP_NAT_ROUTE);
09362 
09363    c = strchr(via, ';');
09364    if (c) 
09365       *c = '\0';
09366 
09367    c = strchr(via, ' ');
09368    if (c) {
09369       *c = '\0';
09370       c = ast_skip_blanks(c+1);
09371       if (strcasecmp(via, "SIP/2.0/UDP")) {
09372          ast_log(LOG_WARNING, "Don't know how to respond via '%s'\n", via);
09373          return;
09374       }
09375       pt = strchr(c, ':');
09376       if (pt)
09377          *pt++ = '\0';  /* remember port pointer */
09378       hp = ast_gethostbyname(c, &ahp);
09379       if (!hp) {
09380          ast_log(LOG_WARNING, "'%s' is not a valid host\n", c);
09381          return;
09382       }
09383       memset(&p->sa, 0, sizeof(p->sa));
09384       p->sa.sin_family = AF_INET;
09385       memcpy(&p->sa.sin_addr, hp->h_addr, sizeof(p->sa.sin_addr));
09386       p->sa.sin_port = htons(pt ? atoi(pt) : STANDARD_SIP_PORT);
09387 
09388       if (sip_debug_test_pvt(p)) {
09389          const struct sockaddr_in *dst = sip_real_dst(p);
09390          ast_verbose("Sending to %s : %d (%s)\n", ast_inet_ntoa(dst->sin_addr), ntohs(dst->sin_port), sip_nat_mode(p));
09391       }
09392    }
09393 }

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

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

Referenced by reload_config().

10241 {
10242    char *oldcontext, *newcontext, *stalecontext, *stringp, newlist[AST_MAX_CONTEXT];
10243 
10244    while ((oldcontext = strsep(&old, "&"))) {
10245       stalecontext = '\0';
10246       ast_copy_string(newlist, new, sizeof(newlist));
10247       stringp = newlist;
10248       while ((newcontext = strsep(&stringp, "&"))) {
10249          if (strcmp(newcontext, oldcontext) == 0) {
10250             /* This is not the context you're looking for */
10251             stalecontext = '\0';
10252             break;
10253          } else if (strcmp(newcontext, oldcontext)) {
10254             stalecontext = oldcontext;
10255          }
10256          
10257       }
10258       if (stalecontext)
10259          ast_context_destroy(ast_context_find(stalecontext), "SIP");
10260    }
10261 }

static int clear_realm_authentication ( struct sip_auth authlist  )  [static]

Clear realm authentication list (at reload).

Definition at line 16838 of file chan_sip.c.

References free, and sip_auth::next.

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

16839 {
16840    struct sip_auth *a = authlist;
16841    struct sip_auth *b;
16842 
16843    while (a) {
16844       b = a;
16845       a = a->next;
16846       free(b);
16847    }
16848 
16849    return 1;
16850 }

static void clear_sip_domains ( void   )  [static]

Clear our domain list (at reload).

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

16768 {
16769    struct domain *d;
16770 
16771    AST_LIST_LOCK(&domain_list);
16772    while ((d = AST_LIST_REMOVE_HEAD(&domain_list, list)))
16773       free(d);
16774    AST_LIST_UNLOCK(&domain_list);
16775 }

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

References complete_sip_peer().

11053 {
11054    if (pos == 3)
11055       return complete_sip_peer(word, state, 0);
11056 
11057    return NULL;
11058 }

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

Do completion on peer name.

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

11027 {
11028    char *result = NULL;
11029    int wordlen = strlen(word);
11030    int which = 0;
11031 
11032    ASTOBJ_CONTAINER_TRAVERSE(&peerl, !result, do {
11033       /* locking of the object is not required because only the name and flags are being compared */
11034       if (!strncasecmp(word, iterator->name, wordlen) &&
11035             (!flags2 || ast_test_flag(&iterator->flags[1], flags2)) &&
11036             ++which > state)
11037          result = ast_strdup(iterator->name);
11038    } while(0) );
11039    return result;
11040 }

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

References complete_sip_peer(), and SIP_PAGE2_RTCACHEFRIENDS.

11121 {
11122    if (pos == 4)
11123       return complete_sip_peer(word, state, SIP_PAGE2_RTCACHEFRIENDS);
11124    return NULL;
11125 }

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

References complete_sip_user(), and SIP_PAGE2_RTCACHEFRIENDS.

11129 {
11130    if (pos == 4)
11131       return complete_sip_user(word, state, SIP_PAGE2_RTCACHEFRIENDS);
11132 
11133    return NULL;
11134 }

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

References complete_sip_peer().

11044 {
11045    if (pos == 3)
11046       return complete_sip_peer(word, state, 0);
11047 
11048    return NULL;
11049 }

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

References complete_sip_user().

11082 {
11083    if (pos == 3)
11084       return complete_sip_user(word, state, 0);
11085 
11086    return NULL;
11087 }

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

Do completion on user name.

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

11062 {
11063    char *result = NULL;
11064    int wordlen = strlen(word);
11065    int which = 0;
11066 
11067    ASTOBJ_CONTAINER_TRAVERSE(&userl, !result, do {
11068       /* locking of the object is not required because only the name and flags are being compared */
11069       if (!strncasecmp(word, iterator->name, wordlen)) {
11070          if (flags2 && !ast_test_flag(&iterator->flags[1], flags2))
11071             continue;
11072          if (++which > state) {
11073             result = ast_strdup(iterator->name);
11074          }
11075       }
11076    } while(0) );
11077    return result;
11078 }

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

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

11004 {
11005    int which=0;
11006    struct sip_pvt *cur;
11007    char *c = NULL;
11008    int wordlen = strlen(word);
11009 
11010    if (pos != 3) {
11011       return NULL;
11012    }
11013 
11014    ast_mutex_lock(&iflock);
11015    for (cur = iflist; cur; cur = cur->next) {
11016       if (!strncasecmp(word, cur->callid, wordlen) && ++which > state) {
11017          c = ast_strdup(cur->callid);
11018          break;
11019       }
11020    }
11021    ast_mutex_unlock(&iflock);
11022    return c;
11023 }

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

Support routine for 'sip notify' CLI.

Definition at line 11090 of file chan_sip.c.

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

11091 {
11092    char *c = NULL;
11093 
11094    if (pos == 2) {
11095       int which = 0;
11096       char *cat = NULL;
11097       int wordlen = strlen(word);
11098 
11099       /* do completion for notify type */
11100 
11101       if (!notify_types)
11102          return NULL;
11103       
11104       while ( (cat = ast_category_browse(notify_types, cat)) ) {
11105          if (!strncasecmp(word, cat, wordlen) && ++which > state) {
11106             c = ast_strdup(cat);
11107             break;
11108          }
11109       }
11110       return c;
11111    }
11112 
11113    if (pos > 2)
11114       return complete_sip_peer(word, state, 0);
11115 
11116    return NULL;
11117 }

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

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

Referenced by respprep().

05676 {
05677    int start = 0;
05678    int copied = 0;
05679    for (;;) {
05680       const char *tmp = __get_header(orig, field, &start);
05681 
05682       if (ast_strlen_zero(tmp))
05683          break;
05684       /* Add what we're responding to */
05685       add_header(req, field, tmp);
05686       copied++;
05687    }
05688    return copied ? 0 : -1;
05689 }

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

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

Referenced by reqprep(), and respprep().

05665 {
05666    const char *tmp = get_header(orig, field);
05667 
05668    if (!ast_strlen_zero(tmp)) /* Add what we're responding to */
05669       return add_header(req, field, tmp);
05670    ast_log(LOG_NOTICE, "No field '%s' present to copy\n", field);
05671    return -1;
05672 }

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

06719 {
06720    long offset;
06721    int x;
06722    offset = ((void *)dst) - ((void *)src);
06723    /* First copy stuff */
06724    memcpy(dst, src, sizeof(*dst));
06725    /* Now fix pointer arithmetic */
06726    for (x=0; x < src->headers; x++)
06727       dst->header[x] += offset;
06728    for (x=0; x < src->lines; x++)
06729       dst->line[x] += offset;
06730    dst->rlPart1 += offset;
06731    dst->rlPart2 += offset;
06732 }

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

05698 {
05699    int copied = 0;
05700    int start = 0;
05701 
05702    for (;;) {
05703       char new[512];
05704       const char *oh = __get_header(orig, field, &start);
05705 
05706       if (ast_strlen_zero(oh))
05707          break;
05708 
05709       if (!copied) { /* Only check for empty rport in topmost via header */
05710          char leftmost[512], *others, *rport;
05711 
05712          /* Only work on leftmost value */
05713          ast_copy_string(leftmost, oh, sizeof(leftmost));
05714          others = strchr(leftmost, ',');
05715          if (others)
05716              *others++ = '\0';
05717 
05718          /* Find ;rport;  (empty request) */
05719          rport = strstr(leftmost, ";rport");
05720          if (rport && *(rport+6) == '=') 
05721             rport = NULL;     /* We already have a parameter to rport */
05722 
05723          /* Check rport if NAT=yes or NAT=rfc3581 (which is the default setting)  */
05724          if (rport && ((ast_test_flag(&p->flags[0], SIP_NAT) == SIP_NAT_ALWAYS) || (ast_test_flag(&p->flags[0], SIP_NAT) == SIP_NAT_RFC3581))) {
05725             /* We need to add received port - rport */
05726             char *end;
05727 
05728             rport = strstr(leftmost, ";rport");
05729 
05730             if (rport) {
05731                end = strchr(rport + 1, ';');
05732                if (end)
05733                   memmove(rport, end, strlen(end) + 1);
05734                else
05735                   *rport = '\0';
05736             }
05737 
05738             /* Add rport to first VIA header if requested */
05739             snprintf(new, sizeof(new), "%s;received=%s;rport=%d%s%s",
05740                leftmost, ast_inet_ntoa(p->recv.sin_addr),
05741                ntohs(p->recv.sin_port),
05742                others ? "," : "", others ? others : "");
05743          } else {
05744             /* We should *always* add a received to the topmost via */
05745             snprintf(new, sizeof(new), "%s;received=%s%s%s",
05746                leftmost, ast_inet_ntoa(p->recv.sin_addr),
05747                others ? "," : "", others ? others : "");
05748          }
05749          oh = new;   /* the header to copy */
05750       }  /* else add the following via headers untouched */
05751       add_header(req, field, oh);
05752       copied++;
05753    }
05754    if (!copied) {
05755       ast_log(LOG_NOTICE, "No header field '%s' present to copy\n", field);
05756       return -1;
05757    }
05758    return 0;
05759 }

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

02883 {
02884    struct hostent *hp;
02885    struct ast_hostent ahp;
02886    struct sip_peer *p;
02887    char *port;
02888    int portno;
02889    char host[MAXHOSTNAMELEN], *hostn;
02890    char peer[256];
02891 
02892    ast_copy_string(peer, opeer, sizeof(peer));
02893    port = strchr(peer, ':');
02894    if (port)
02895       *port++ = '\0';
02896    dialog->sa.sin_family = AF_INET;
02897    dialog->timer_t1 = 500; /* Default SIP retransmission timer T1 (RFC 3261) */
02898    p = find_peer(peer, NULL, 1);
02899 
02900    if (p) {
02901       int res = create_addr_from_peer(dialog, p);
02902       ASTOBJ_UNREF(p, sip_destroy_peer);
02903       return res;
02904    }
02905    hostn = peer;
02906    portno = port ? atoi(port) : STANDARD_SIP_PORT;
02907    if (srvlookup) {
02908       char service[MAXHOSTNAMELEN];
02909       int tportno;
02910       int ret;
02911 
02912       snprintf(service, sizeof(service), "_sip._udp.%s", peer);
02913       ret = ast_get_srv(NULL, host, sizeof(host), &tportno, service);
02914       if (ret > 0) {
02915          hostn = host;
02916          portno = tportno;
02917       }
02918    }
02919    hp = ast_gethostbyname(hostn, &ahp);
02920    if (!hp) {
02921       ast_log(LOG_WARNING, "No such host: %s\n", peer);
02922       return -1;
02923    }
02924    ast_string_field_set(dialog, tohost, peer);
02925    memcpy(&dialog->sa.sin_addr, hp->h_addr, sizeof(dialog->sa.sin_addr));
02926    dialog->sa.sin_port = htons(portno);
02927    dialog->recv = dialog->sa;
02928    return 0;
02929 }

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

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

static void destroy_association ( struct sip_peer peer  )  [static]

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

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

07899 {
07900    if (!ast_test_flag(&global_flags[1], SIP_PAGE2_IGNOREREGEXPIRE)) {
07901       if (ast_test_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT))
07902          ast_update_realtime("sippeers", "name", peer->name, "fullcontact", "", "ipaddr", "", "port", "", "regseconds", "0", "username", "", "regserver", "", NULL);
07903       else 
07904          ast_db_del("SIP/Registry", peer->name);
07905    }
07906 }

static int determine_firstline_parts ( struct sip_request req  )  [static]

Parse first line of incoming SIP request.

Definition at line 6762 of file chan_sip.c.

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

Referenced by parse_request().

06763 {
06764    char *e = ast_skip_blanks(req->header[0]);   /* there shouldn't be any */
06765 
06766    if (!*e)
06767       return -1;
06768    req->rlPart1 = e; /* method or protocol */
06769    e = ast_skip_nonblanks(e);
06770    if (*e)
06771       *e++ = '\0';
06772    /* Get URI or status code */
06773    e = ast_skip_blanks(e);
06774    if ( !*e )
06775       return -1;
06776    ast_trim_blanks(e);
06777 
06778    if (!strcasecmp(req->rlPart1, "SIP/2.0") ) { /* We have a response */
06779       if (strlen(e) < 3)   /* status code is 3 digits */
06780          return -1;
06781       req->rlPart2 = e;
06782    } else { /* We have a request */
06783       if ( *e == '<' ) { /* XXX the spec says it must not be in <> ! */
06784          ast_log(LOG_WARNING, "bogus uri in <> %s\n", e);
06785          e++;
06786          if (!*e)
06787             return -1; 
06788       }
06789       req->rlPart2 = e; /* URI */
06790       e = ast_skip_nonblanks(e);
06791       if (*e)
06792          *e++ = '\0';
06793       e = ast_skip_blanks(e);
06794       if (strcasecmp(e, "SIP/2.0") ) {
06795          ast_log(LOG_WARNING, "Bad request protocol %s\n", e);
06796          return -1;
06797       }
06798    }
06799    return 1;
06800 }

static void display_nat_warning ( const char *  cat,
int  reason,
struct ast_flags flags 
) [static]

Definition at line 17307 of file chan_sip.c.

References ast_log(), ast_test_flag, CHANNEL_MODULE_LOAD, LOG_WARNING, nat2str(), and SIP_NAT.

Referenced by reload_config().

17307                                                                                       {
17308    int global_nat, specific_nat;
17309 
17310    if (reason == CHANNEL_MODULE_LOAD && (specific_nat = ast_test_flag(&flags[0], SIP_NAT)) != (global_nat = ast_test_flag(&global_flags[0], SIP_NAT))) {
17311       ast_log(LOG_WARNING, "sip.conf: Different 'nat' settings between [general] and section [%s]. See /usr/share/doc/asterisk/README.Debian.gz (global='%s' peer/user='%s')\n",
17312             cat, nat2str(global_nat), nat2str(specific_nat));
17313    }
17314 }

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 16057 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_remove(), 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, DEADLOCK_AVOIDANCE, 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.

16058 {
16059    int res;
16060    struct sip_pvt *sip;
16061    struct sip_peer *peer = NULL;
16062    time_t t;
16063    int fastrestart = FALSE;
16064    int lastpeernum = -1;
16065    int curpeernum;
16066    int reloading;
16067 
16068    /* Add an I/O event to our SIP UDP socket */
16069    if (sipsock > -1) 
16070       sipsock_read_id = ast_io_add(io, sipsock, sipsock_read, AST_IO_IN, NULL);
16071    
16072    /* From here on out, we die whenever asked */
16073    for(;;) {
16074       /* Check for a reload request */
16075       ast_mutex_lock(&sip_reload_lock);
16076       reloading = sip_reloading;
16077       sip_reloading = FALSE;
16078       ast_mutex_unlock(&sip_reload_lock);
16079       if (reloading) {
16080          if (option_verbose > 0)
16081             ast_verbose(VERBOSE_PREFIX_1 "Reloading SIP\n");
16082          sip_do_reload(sip_reloadreason);
16083 
16084          /* Change the I/O fd of our UDP socket */
16085          if (sipsock > -1) {
16086             if (sipsock_read_id)
16087                sipsock_read_id = ast_io_change(io, sipsock_read_id, sipsock, NULL, 0, NULL);
16088             else
16089                sipsock_read_id = ast_io_add(io, sipsock, sipsock_read, AST_IO_IN, NULL);
16090          } else if (sipsock_read_id) {
16091             ast_io_remove(io, sipsock_read_id);
16092             sipsock_read_id = NULL;
16093          }
16094       }
16095 restartsearch:    
16096       /* Check for interfaces needing to be killed */
16097       ast_mutex_lock(&iflock);
16098       t = time(NULL);
16099       /* don't scan the interface list if it hasn't been a reasonable period
16100          of time since the last time we did it (when MWI is being sent, we can
16101          get back to this point every millisecond or less)
16102       */
16103       for (sip = iflist; !fastrestart && sip; sip = sip->next) {
16104          /*! \note If we can't get a lock on an interface, skip it and come
16105           * back later. Note that there is the possibility of a deadlock with
16106           * sip_hangup otherwise, because sip_hangup is called with the channel
16107           * locked first, and the iface lock is attempted second.
16108           */
16109          if (ast_mutex_trylock(&sip->lock))
16110             continue;
16111 
16112          /* Check RTP timeouts and kill calls if we have a timeout set and do not get RTP */
16113          if (sip->rtp && sip->owner &&
16114              (sip->owner->_state == AST_STATE_UP) &&
16115              !sip->redirip.sin_addr.s_addr &&
16116              sip->t38.state != T38_ENABLED) {
16117             if (sip->lastrtptx &&
16118                 ast_rtp_get_rtpkeepalive(sip->rtp) &&
16119                 (t > sip->lastrtptx + ast_rtp_get_rtpkeepalive(sip->rtp))) {
16120                /* Need to send an empty RTP packet */
16121                sip->lastrtptx = time(NULL);
16122                ast_rtp_sendcng(sip->rtp, 0);
16123             }
16124             if (sip->lastrtprx &&
16125                (ast_rtp_get_rtptimeout(sip->rtp) || ast_rtp_get_rtpholdtimeout(sip->rtp)) &&
16126                 (t > sip->lastrtprx + ast_rtp_get_rtptimeout(sip->rtp))) {
16127                /* Might be a timeout now -- see if we're on hold */
16128                struct sockaddr_in sin;
16129                ast_rtp_get_peer(sip->rtp, &sin);
16130                if (sin.sin_addr.s_addr || 
16131                    (ast_rtp_get_rtpholdtimeout(sip->rtp) &&
16132                     (t > sip->lastrtprx + ast_rtp_get_rtpholdtimeout(sip->rtp)))) {
16133                   /* Needs a hangup */
16134                   if (ast_rtp_get_rtptimeout(sip->rtp)) {
16135                      while (sip->owner && ast_channel_trylock(sip->owner)) {
16136                         DEADLOCK_AVOIDANCE(&sip->lock);
16137                      }
16138                      if (sip->owner) {
16139                         ast_log(LOG_NOTICE,
16140                            "Disconnecting call '%s' for lack of RTP activity in %ld seconds\n",
16141                            sip->owner->name,
16142                            (long) (t - sip->lastrtprx));
16143                         /* Issue a softhangup */
16144                         ast_softhangup_nolock(sip->owner, AST_SOFTHANGUP_DEV);
16145                         ast_channel_unlock(sip->owner);
16146                         /* forget the timeouts for this call, since a hangup
16147                            has already been requested and we don't want to
16148                            repeatedly request hangups
16149                         */
16150                         ast_rtp_set_rtptimeout(sip->rtp, 0);
16151                         ast_rtp_set_rtpholdtimeout(sip->rtp, 0);
16152                         if (sip->vrtp) {
16153                            ast_rtp_set_rtptimeout(sip->vrtp, 0);
16154                            ast_rtp_set_rtpholdtimeout(sip->vrtp, 0);
16155                         }
16156                      }
16157                   }
16158                }
16159             }
16160          }
16161          /* If we have sessions that needs to be destroyed, do it now */
16162          if (ast_test_flag(&sip->flags[0], SIP_NEEDDESTROY) && !sip->packets &&
16163              !sip->owner) {
16164             ast_mutex_unlock(&sip->lock);
16165             __sip_destroy(sip, 1);
16166             ast_mutex_unlock(&iflock);
16167             usleep(1);
16168             goto restartsearch;
16169          }
16170          ast_mutex_unlock(&sip->lock);
16171       }
16172       ast_mutex_unlock(&iflock);
16173 
16174       pthread_testcancel();
16175       /* Wait for sched or io */
16176       res = ast_sched_wait(sched);
16177       if ((res < 0) || (res > 1000))
16178          res = 1000;
16179       /* If we might need to send more mailboxes, don't wait long at all.*/
16180       if (fastrestart)
16181          res = 1;
16182       res = ast_io_wait(io, res);
16183       if (option_debug && res > 20)
16184          ast_log(LOG_DEBUG, "chan_sip: ast_io_wait ran %d all at once\n", res);
16185       ast_mutex_lock(&monlock);
16186       if (res >= 0)  {
16187          res = ast_sched_runq(sched);
16188          if (option_debug && res >= 20)
16189             ast_log(LOG_DEBUG, "chan_sip: ast_sched_runq ran %d all at once\n", res);
16190       }
16191 
16192       /* Send MWI notifications to peers - static and cached realtime peers */
16193       t = time(NULL);
16194       fastrestart = FALSE;
16195       curpeernum = 0;
16196       peer = NULL;
16197       /* Find next peer that needs mwi */
16198       ASTOBJ_CONTAINER_TRAVERSE(&peerl, !peer, do {
16199          if ((curpeernum > lastpeernum) && does_peer_need_mwi(iterator)) {
16200             fastrestart = TRUE;
16201             lastpeernum = curpeernum;
16202             peer = ASTOBJ_REF(iterator);
16203          };
16204          curpeernum++;
16205       } while (0)
16206       );
16207       /* Send MWI to the peer */
16208       if (peer) {
16209          ASTOBJ_WRLOCK(peer);
16210          sip_send_mwi_to_peer(peer);
16211          ASTOBJ_UNLOCK(peer);
16212          ASTOBJ_UNREF(peer,sip_destroy_peer);
16213       } else {
16214          /* Reset where we come from */
16215          lastpeernum = -1;
16216       }
16217       ast_mutex_unlock(&monlock);
16218    }
16219    /* Never reached */
16220    return NULL;
16221    
16222 }

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

11594 {
11595    char digest[1024];
11596 
11597    if (!p->options && !(p->options = ast_calloc(1, sizeof(*p->options))))
11598       return -2;
11599 
11600    p->authtries++;
11601    if (option_debug > 1)
11602       ast_log(LOG_DEBUG, "Auth attempt %d on %s\n", p->authtries, sip_methods[sipmethod].text);
11603    memset(digest, 0, sizeof(digest));
11604    if (reply_digest(p, req, header, sipmethod, digest, sizeof(digest) )) {
11605       /* No way to authenticate */
11606       return -1;
11607    }
11608    /* Now we have a reply digest */
11609    p->options->auth = digest;
11610    p->options->authheader = respheader;
11611    return transmit_invite(p, sipmethod, sipmethod == SIP_INVITE, init); 
11612 }

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

11573 {
11574    char digest[1024];
11575    p->authtries++;
11576    memset(digest,0,sizeof(digest));
11577    if (reply_digest(p, req, header, SIP_REGISTER, digest, sizeof(digest))) {
11578       /* There's nothing to use for authentication */
11579       /* No digest challenge in request */
11580       if (sip_debug_test_pvt(p) && p->registry)
11581          ast_verbose("No authentication challenge, sending blank registration to domain/host name %s\n", p->registry->hostname);
11582          /* No old challenge */
11583       return -1;
11584    }
11585    if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY))
11586       append_history(p, "RegistryAuth", "Try: %d", p->authtries);
11587    if (sip_debug_test_pvt(p) && p->registry)
11588       ast_verbose("Responding to challenge, registration to domain/host name %s\n", p->registry->hostname);
11589    return transmit_register(p->registry, SIP_REGISTER, digest, respheader); 
11590 }

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

Set nat mode on the various data sockets.

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

02751 {
02752    const char *mode = natflags ? "On" : "Off";
02753 
02754    if (p->rtp) {
02755       if (option_debug)
02756          ast_log(LOG_DEBUG, "Setting NAT on RTP to %s\n", mode);
02757       ast_rtp_setnat(p->rtp, natflags);
02758    }
02759    if (p->vrtp) {
02760       if (option_debug)
02761          ast_log(LOG_DEBUG, "Setting NAT on VRTP to %s\n", mode);
02762       ast_rtp_setnat(p->vrtp, natflags);
02763    }
02764    if (p->udptl) {
02765       if (option_debug)
02766          ast_log(LOG_DEBUG, "Setting NAT on UDPTL to %s\n", mode);
02767       ast_udptl_setnat(p->udptl, natflags);
02768    }
02769 }

static int does_peer_need_mwi ( struct sip_peer peer  )  [static]

Check whether peer needs a new MWI notification check.

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

16037 {
16038    time_t t = time(NULL);
16039 
16040    if (ast_test_flag(&peer->flags[1], SIP_PAGE2_SUBSCRIBEMWIONLY) &&
16041        !peer->mwipvt) { /* We don't have a subscription */
16042       peer->lastmsgcheck = t; /* Reset timer */
16043       return FALSE;
16044    }
16045 
16046    if (!ast_strlen_zero(peer->mailbox) && (t - peer->lastmsgcheck) > global_mwitime)
16047       return TRUE;
16048 
16049    return FALSE;
16050 }

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

Print domain mode to cli.

Definition at line 10429 of file chan_sip.c.

References SIP_DOMAIN_AUTO, and SIP_DOMAIN_CONFIG.

Referenced by sip_show_domains().

10430 {
10431    switch (mode) {
10432    case SIP_DOMAIN_AUTO:
10433       return "[Automatic]";
10434    case SIP_DOMAIN_CONFIG:
10435       return "[Configured]";
10436    }
10437 
10438    return "";
10439 }

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

Convert DTMF mode to printable string.

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

10210 {
10211    switch (mode) {
10212    case SIP_DTMF_RFC2833:
10213       return "rfc2833";
10214    case SIP_DTMF_INFO:
10215       return "info";
10216    case SIP_DTMF_INBAND:
10217       return "inband";
10218    case SIP_DTMF_AUTO:
10219       return "auto";
10220    }
10221    return "<error>";
10222 }

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

Expire registration of SIP peer.

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

07910 {
07911    struct sip_peer *peer = (struct sip_peer *)data;
07912    
07913    if (!peer)     /* Hmmm. We have no peer. Weird. */
07914       return 0;
07915 
07916    memset(&peer->addr, 0, sizeof(peer->addr));
07917 
07918    destroy_association(peer); /* remove registration data from storage */
07919    
07920    manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name);
07921    register_peer_exten(peer, FALSE);   /* Remove regexten */
07922    peer->expire = -1;
07923    ast_device_state_changed("SIP/%s", peer->name);
07924 
07925    /* Do we need to release this peer from memory? 
07926       Only for realtime peers and autocreated peers
07927    */
07928    if (ast_test_flag(&peer->flags[1], SIP_PAGE2_SELFDESTRUCT) ||
07929        ast_test_flag(&peer->flags[1], SIP_PAGE2_RTAUTOCLEAR)) {
07930       struct sip_peer *peer_ptr = peer_ptr;
07931       peer_ptr = ASTOBJ_CONTAINER_UNLINK(&peerl, peer);
07932       if (peer_ptr) {
07933          ASTOBJ_UNREF(peer_ptr, sip_destroy_peer);
07934       }
07935    }
07936 
07937    ASTOBJ_UNREF(peer, sip_destroy_peer);
07938 
07939    return 0;
07940 }

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

Check Contact: URI of SIP message.

Definition at line 6852 of file chan_sip.c.

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

Referenced by handle_request(), and handle_request_invite().

06853 {
06854    char stripped[SIPBUFSIZE];
06855    char *c;
06856 
06857    ast_copy_string(stripped, get_header(req, "Contact"), sizeof(stripped));
06858    c = get_in_brackets(stripped);
06859    c = strsep(&c, ";"); /* trim ; and beyond */
06860    if (!ast_strlen_zero(c))
06861       ast_string_field_set(p, uri, c);
06862 }

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

References aliases.

04215 {
04216    /*! \brief Structure for conversion between compressed SIP and "normal" SIP */
04217    static const struct cfalias {
04218       char * const fullname;
04219       char * const shortname;
04220    } aliases[] = {
04221       { "Content-Type",  "c" },
04222       { "Content-Encoding",    "e" },
04223       { "From",       "f" },
04224       { "Call-ID",       "i" },
04225       { "Contact",       "m" },
04226       { "Content-Length",   "l" },
04227       { "Subject",       "s" },
04228       { "To",         "t" },
04229       { "Supported",     "k" },
04230       { "Refer-To",      "r" },
04231       { "Referred-By",   "b" },
04232       { "Allow-Events",  "u" },
04233       { "Event",      "o" },
04234       { "Via",     "v" },
04235       { "Accept-Contact",      "a" },
04236       { "Reject-Contact",      "j" },
04237       { "Request-Disposition", "d" },
04238       { "Session-Expires",     "x" },
04239       { "Identity",            "y" },
04240       { "Identity-Info",       "n" },
04241    };
04242    int x;
04243 
04244    for (x=0; x<sizeof(aliases) / sizeof(aliases[0]); x++) 
04245       if (!strcasecmp(aliases[x].fullname, name))
04246          return aliases[x].shortname;
04247 
04248    return _default;
04249 }

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

04574 {
04575    struct sip_pvt *p = NULL;
04576    char *tag = "";   /* note, tag is never NULL */
04577    char totag[128];
04578    char fromtag[128];
04579    const char *callid = get_header(req, "Call-ID");
04580    const char *from = get_header(req, "From");
04581    const char *to = get_header(req, "To");
04582    const char *cseq = get_header(req, "Cseq");
04583 
04584    /* Call-ID, to, from and Cseq are required by RFC 3261. (Max-forwards and via too - ignored now) */
04585    /* get_header always returns non-NULL so we must use ast_strlen_zero() */
04586    if (ast_strlen_zero(callid) || ast_strlen_zero(to) ||
04587          ast_strlen_zero(from) || ast_strlen_zero(cseq))
04588       return NULL;   /* Invalid packet */
04589 
04590    if (pedanticsipchecking) {
04591       /* In principle Call-ID's uniquely identify a call, but with a forking SIP proxy
04592          we need more to identify a branch - so we have to check branch, from
04593          and to tags to identify a call leg.
04594          For Asterisk to behave correctly, you need to turn on pedanticsipchecking
04595          in sip.conf
04596          */
04597       if (gettag(req, "To", totag, sizeof(totag)))
04598          ast_set_flag(req, SIP_PKT_WITH_TOTAG); /* Used in handle_request/response */
04599       gettag(req, "From", fromtag, sizeof(fromtag));
04600 
04601       tag = (req->method == SIP_RESPONSE) ? totag : fromtag;
04602 
04603       if (option_debug > 4 )
04604          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);
04605    }
04606 
04607    ast_mutex_lock(&iflock);
04608    for (p = iflist; p; p = p->next) {
04609       /* In pedantic, we do not want packets with bad syntax to be connected to a PVT */
04610       int found = FALSE;
04611       if (ast_strlen_zero(p->callid))
04612          continue;
04613       if (req->method == SIP_REGISTER)
04614          found = (!strcmp(p->callid, callid));
04615       else 
04616          found = (!strcmp(p->callid, callid) && 
04617          (!pedanticsipchecking || ast_strlen_zero(tag) || ast_strlen_zero(p->theirtag) || !strcmp(p->theirtag, tag))) ;
04618 
04619       if (option_debug > 4)
04620          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);
04621 
04622       /* If we get a new request within an existing to-tag - check the to tag as well */
04623       if (pedanticsipchecking && found  && req->method != SIP_RESPONSE) {  /* SIP Request */
04624          if (p->tag[0] == '\0' && totag[0]) {
04625             /* We have no to tag, but they have. Wrong dialog */
04626             found = FALSE;
04627          } else if (totag[0]) {        /* Both have tags, compare them */
04628             if (strcmp(totag, p->tag)) {
04629                found = FALSE;    /* This is not our packet */
04630             }
04631          }
04632          if (!found && option_debug > 4)
04633             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);
04634       }
04635       if (found) {
04636          /* Found the call */
04637          ast_mutex_lock(&p->lock);
04638          ast_mutex_unlock(&iflock);
04639          return p;
04640       }
04641    }
04642    ast_mutex_unlock(&iflock);
04643 
04644    /* See if the method is capable of creating a dialog */
04645    if (sip_methods[intended_method].can_create == CAN_CREATE_DIALOG) {
04646       if (intended_method == SIP_REFER) {
04647          /* We do support REFER, but not outside of a dialog yet */
04648          transmit_response_using_temp(callid, sin, 1, intended_method, req, "603 Declined (no dialog)");
04649       } else if (intended_method == SIP_NOTIFY) {
04650          /* We do not support out-of-dialog NOTIFY either,
04651             like voicemail notification, so cancel that early */
04652          transmit_response_using_temp(callid, sin, 1, intended_method, req, "489 Bad event");
04653       } else {
04654          /* Ok, time to create a new SIP dialog object, a pvt */
04655          if ((p = sip_alloc(callid, sin, 1, intended_method)))  {
04656             /* Ok, we've created a dialog, let's go and process it */
04657             ast_mutex_lock(&p->lock);
04658          } else {
04659             /* We have a memory or file/socket error (can't allocate RTP sockets or something) so we're not
04660                getting a dialog from sip_alloc. 
04661    
04662                Without a dialog we can't retransmit and handle ACKs and all that, but at least
04663                send an error message.
04664    
04665                Sorry, we apologize for the inconvienience
04666             */
04667             transmit_response_using_temp(callid, sin, 1, intended_method, req, "500 Server internal error");
04668             if (option_debug > 3)
04669                ast_log(LOG_DEBUG, "Failed allocating SIP dialog, sending 500 Server internal error and giving up\n");
04670          }
04671       }
04672       return p;
04673    } else if( sip_methods[intended_method].can_create == CAN_CREATE_DIALOG_UNSUPPORTED_METHOD) {
04674       /* A method we do not support, let's take it on the volley */
04675       transmit_response_using_temp(callid, sin, 1, intended_method, req, "501 Method Not Implemented");
04676    } else if (intended_method != SIP_RESPONSE && intended_method != SIP_ACK) {
04677       /* This is a request outside of a dialog that we don't know about 
04678          ...never reply to an ACK!
04679       */
04680       transmit_response_using_temp(callid, sin, 1, intended_method, req, "481 Call leg/transaction does not exist");
04681    }
04682    /* We do not respond to responses for dialogs that we don't know about, we just drop
04683       the session quickly */
04684 
04685    return p;
04686 }

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

References s.

Referenced by get_in_brackets().

02314 {
02315         char last_char = '\0';
02316         const char *s;
02317         for (s = start; *s && s != lim; last_char = *s++) {
02318                 if (*s == '"' && last_char != '\\')
02319                         break;
02320         }
02321         return s;
02322 }

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

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

02663 {
02664    struct sip_peer *p = NULL;
02665 
02666    if (peer)
02667       p = ASTOBJ_CONTAINER_FIND(&peerl, peer);
02668    else
02669       p = ASTOBJ_CONTAINER_FIND_FULL(&peerl, sin, name, sip_addr_hashfunc, 1, sip_addrcmp);
02670 
02671    if (!p && realtime)
02672       p = realtime_peer(peer, sin);
02673 
02674    return p;
02675 }

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

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

Referenced by build_reply_digest().

16854 {
16855    struct sip_auth *a;
16856 
16857    for (a = authlist; a; a = a->next) {
16858       if (!strcasecmp(a->realm, realm))
16859          break;
16860    }
16861 
16862    return a;
16863 }

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

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

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

04893 {
04894    const char *content_type;
04895    const char *content_length;
04896    const char *search;
04897    char *boundary;
04898    unsigned int x;
04899    int boundaryisquoted = FALSE;
04900    int found_application_sdp = FALSE;
04901    int found_end_of_headers = FALSE;
04902 
04903    content_length = get_header(req, "Content-Length");
04904 
04905    if (!ast_strlen_zero(content_length)) {
04906       if (sscanf(content_length, "%ud", &x) != 1) {
04907          ast_log(LOG_WARNING, "Invalid Content-Length: %s\n", content_length);
04908          return 0;
04909       }
04910 
04911       /* Content-Length of zero means there can't possibly be an
04912          SDP here, even if the Content-Type says there is */
04913       if (x == 0)
04914          return 0;
04915    }
04916 
04917    content_type = get_header(req, "Content-Type");
04918 
04919    /* if the body contains only SDP, this is easy */
04920    if (!strcasecmp(content_type, "application/sdp")) {
04921       req->sdp_start = 0;
04922       req->sdp_end = req->lines;
04923       return req->lines ? 1 : 0;
04924    }
04925 
04926    /* if it's not multipart/mixed, there cannot be an SDP */
04927    if (strncasecmp(content_type, "multipart/mixed", 15))
04928       return 0;
04929 
04930    /* if there is no boundary marker, it's invalid */
04931    if ((search = strcasestr(content_type, ";boundary=")))
04932       search += 10;
04933    else if ((search = strcasestr(content_type, "; boundary=")))
04934       search += 11;
04935    else
04936       return 0;
04937 
04938    if (ast_strlen_zero(search))
04939       return 0;
04940 
04941    /* If the boundary is quoted with ", remove quote */
04942    if (*search == '\"')  {
04943       search++;
04944       boundaryisquoted = TRUE;
04945    }
04946 
04947    /* make a duplicate of the string, with two extra characters
04948       at the beginning */
04949    boundary = ast_strdupa(search - 2);
04950    boundary[0] = boundary[1] = '-';
04951    /* Remove final quote */
04952    if (boundaryisquoted)
04953       boundary[strlen(boundary) - 1] = '\0';
04954 
04955    /* search for the boundary marker, the empty line delimiting headers from
04956       sdp part and the end boundry if it exists */
04957 
04958    for (x = 0; x < (req->lines ); x++) {
04959       if(!strncasecmp(req->line[x], boundary, strlen(boundary))){
04960          if(found_application_sdp && found_end_of_headers){
04961             req->sdp_end = x-1;
04962             return 1;
04963          }
04964          found_application_sdp = FALSE;
04965       }
04966       if(!strcasecmp(req->line[x], "Content-Type: application/sdp"))
04967          found_application_sdp = TRUE;
04968       
04969       if(strlen(req->line[x]) == 0 ){
04970          if(found_application_sdp && !found_end_of_headers){
04971             req->sdp_start = x;
04972             found_end_of_headers = TRUE;
04973          }
04974       }
04975    }
04976    if(found_application_sdp && found_end_of_headers) {
04977       req->sdp_end = x;
04978       return TRUE;
04979    }
04980    return FALSE;
04981 }

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

find_sip_method: Find SIP method from header

Definition at line 1678 of file chan_sip.c.

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

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

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

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

Find subscription type in array.

Definition at line 10917 of file chan_sip.c.

References subscription_types, and type.

Referenced by transmit_state_notify().

10918 {
10919    int i;
10920 
10921    for (i = 1; (i < (sizeof(subscription_types) / sizeof(subscription_types[0]))); i++) {
10922       if (subscription_types[i].type == subtype) {
10923          return &subscription_types[i];
10924       }
10925    }
10926    return &subscription_types[0];
10927 }

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

References ASTOBJ_CONTAINER_FIND, realtime_user(), and userl.

02742 {
02743    struct sip_user *u = ASTOBJ_CONTAINER_FIND(&userl, name);
02744    if (!u && realtime)
02745       u = realtime_user(name);
02746    return u;
02747 }

static void free_old_route ( struct sip_route route  )  [static]

Remove route from route list.

Definition at line 8269 of file chan_sip.c.

References free, and sip_route::next.

Referenced by __sip_destroy(), and build_route().

08270 {
08271    struct sip_route *next;
08272 
08273    while (route) {
08274       next = route->next;
08275       free(route);
08276       route = next;
08277    }
08278 }

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

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

11927 {
11928    if (ast_strlen_zero(data)) {
11929       ast_log(LOG_WARNING, "CHECKSIPDOMAIN requires an argument - A domain name\n");
11930       return -1;
11931    }
11932    if (check_sip_domain(data, NULL, 0))
11933       ast_copy_string(buf, data, len);
11934    else
11935       buf[0] = '\0';
11936    return 0;
11937 }

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

11863 {
11864    struct sip_pvt *p;
11865    const char *content = NULL;
11866    AST_DECLARE_APP_ARGS(args,
11867       AST_APP_ARG(header);
11868       AST_APP_ARG(number);
11869    );
11870    int i, number, start = 0;
11871 
11872    if (ast_strlen_zero(data)) {
11873       ast_log(LOG_WARNING, "This function requires a header name.\n");
11874       return -1;
11875    }
11876 
11877    ast_channel_lock(chan);
11878    if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) {
11879       ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n");
11880       ast_channel_unlock(chan);
11881       return -1;
11882    }
11883 
11884    AST_STANDARD_APP_ARGS(args, data);
11885    if (!args.number) {
11886       number = 1;
11887    } else {
11888       sscanf(args.number, "%d", &number);
11889       if (number < 1)
11890          number = 1;
11891    }
11892 
11893    p = chan->tech_pvt;
11894 
11895    /* If there is no private structure, this channel is no longer alive */
11896    if (!p) {
11897       ast_channel_unlock(chan);
11898       return -1;
11899    }
11900 
11901    for (i = 0; i < number; i++)
11902       content = __get_header(&p->initreq, args.header, &start);
11903 
11904    if (ast_strlen_zero(content)) {
11905       ast_channel_unlock(chan);
11906       return -1;
11907    }
11908 
11909    ast_copy_string(buf, content, len);
11910    ast_channel_unlock(chan);
11911 
11912    return 0;
11913 }

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

12042 {
12043    struct sip_pvt *p;
12044 
12045    *buf = 0;
12046    
12047    if (!data) {
12048       ast_log(LOG_WARNING, "This function requires a parameter name.\n");
12049       return -1;
12050    }
12051 
12052    ast_channel_lock(chan);
12053    if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) {
12054       ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n");
12055       ast_channel_unlock(chan);
12056       return -1;
12057    }
12058 
12059    p = chan->tech_pvt;
12060 
12061    /* If there is no private structure, this channel is no longer alive */
12062    if (!p) {
12063       ast_channel_unlock(chan);
12064       return -1;
12065    }
12066 
12067    if (!strcasecmp(data, "peerip")) {
12068       ast_copy_string(buf, p->sa.sin_addr.s_addr ? ast_inet_ntoa(p->sa.sin_addr) : "", len);
12069    } else  if (!strcasecmp(data, "recvip")) {
12070       ast_copy_string(buf, p->recv.sin_addr.s_addr ? ast_inet_ntoa(p->recv.sin_addr) : "", len);
12071    } else  if (!strcasecmp(data, "from")) {
12072       ast_copy_string(buf, p->from, len);
12073    } else  if (!strcasecmp(data, "uri")) {
12074       ast_copy_string(buf, p->uri, len);
12075    } else  if (!strcasecmp(data, "useragent")) {
12076       ast_copy_string(buf, p->useragent, len);
12077    } else  if (!strcasecmp(data, "peername")) {
12078       ast_copy_string(buf, p->peername, len);
12079    } else if (!strcasecmp(data, "t38passthrough")) {
12080       if (p->t38.state == T38_DISABLED)
12081          ast_copy_string(buf, "0", sizeof("0"));
12082       else    /* T38 is offered or enabled in this call */
12083          ast_copy_string(buf, "1", sizeof("1"));
12084    } else {
12085       ast_channel_unlock(chan);
12086       return -1;
12087    }
12088    ast_channel_unlock(chan);
12089 
12090    return 0;
12091 }

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

11952 {
11953    struct sip_peer *peer;
11954    char *colname;
11955 
11956    if ((colname = strchr(data, ':')))  /*! \todo Will be deprecated after 1.4 */
11957       *colname++ = '\0';
11958    else if ((colname = strchr(data, '|')))
11959       *colname++ = '\0';
11960    else
11961       colname = "ip";
11962 
11963    if (!(peer = find_peer(data, NULL, 1)))
11964       return -1;
11965 
11966    if (!strcasecmp(colname, "ip")) {
11967       ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "", len);
11968    } else  if (!strcasecmp(colname, "status")) {
11969       peer_status(peer, buf, len);
11970    } else  if (!strcasecmp(colname, "language")) {
11971       ast_copy_string(buf, peer->language, len);
11972    } else  if (!strcasecmp(colname, "regexten")) {
11973       ast_copy_string(buf, peer->regexten, len);
11974    } else  if (!strcasecmp(colname, "limit")) {
11975       snprintf(buf, len, "%d", peer->call_limit);
11976    } else  if (!strcasecmp(colname, "curcalls")) {
11977       snprintf(buf, len, "%d", peer->inUse);
11978    } else  if (!strcasecmp(colname, "accountcode")) {
11979       ast_copy_string(buf, peer->accountcode, len);
11980    } else  if (!strcasecmp(colname, "useragent")) {
11981       ast_copy_string(buf, peer->useragent, len);
11982    } else  if (!strcasecmp(colname, "mailbox")) {
11983       ast_copy_string(buf, peer->mailbox, len);
11984    } else  if (!strcasecmp(colname, "context")) {
11985       ast_copy_string(buf, peer->context, len);
11986    } else  if (!strcasecmp(colname, "expire")) {
11987       snprintf(buf, len, "%d", peer->expire);
11988    } else  if (!strcasecmp(colname, "dynamic")) {
11989       ast_copy_string(buf, (ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC) ? "yes" : "no"), len);
11990    } else  if (!strcasecmp(colname, "callerid_name")) {
11991       ast_copy_string(buf, peer->cid_name, len);
11992    } else  if (!strcasecmp(colname, "callerid_num")) {
11993       ast_copy_string(buf, peer->cid_num, len);
11994    } else  if (!strcasecmp(colname, "codecs")) {
11995       ast_getformatname_multiple(buf, len -1, peer->capability);
11996    } else  if (!strncasecmp(colname, "codec[", 6)) {
11997       char *codecnum;
11998       int index = 0, codec = 0;
11999       
12000       codecnum = colname + 6; /* move past the '[' */
12001       codecnum = strsep(&codecnum, "]"); /* trim trailing ']' if any */
12002       index = atoi(codecnum);
12003       if((codec = ast_codec_pref_index(&peer->prefs, index))) {
12004          ast_copy_string(buf, ast_getformatname(codec), len);
12005       }
12006    }
12007 
12008    ASTOBJ_UNREF(peer, sip_destroy_peer);
12009 
12010    return 0;
12011 }

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

Generate 32 byte random string for callid's etc.

Definition at line 4404 of file chan_sip.c.

References ast_random().

Referenced by build_callid_pvt(), and build_callid_registry().

04405 {
04406    long val[4];
04407    int x;
04408 
04409    for (x=0; x<4; x++)
04410       val[x] = ast_random();
04411    snprintf(buf, size, "%08lx%08lx%08lx%08lx", val[0], val[1], val[2], val[3]);
04412 
04413    return buf;
04414 }

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

09285 {
09286    char tmp[256] = "", *c, *a;
09287    struct sip_request *req = oreq ? oreq : &p->initreq;
09288    struct sip_refer *referdata = NULL;
09289    const char *transfer_context = NULL;
09290    
09291    if (!p->refer && !sip_refer_allocate(p))
09292       return -1;
09293 
09294    referdata = p->refer;
09295 
09296    ast_copy_string(tmp, get_header(req, "Also"), sizeof(tmp));
09297    c = get_in_brackets(tmp);
09298 
09299    if (pedanticsipchecking)
09300       ast_uri_decode(c);
09301    
09302    if (strncasecmp(c, "sip:", 4)) {
09303       ast_log(LOG_WARNING, "Huh?  Not a SIP header in Also: transfer (%s)?\n", c);
09304       return -1;
09305    }
09306    c += 4;
09307    if ((a = strchr(c, ';')))  /* Remove arguments */
09308       *a = '\0';
09309    
09310    if ((a = strchr(c, '@'))) {   /* Separate Domain */
09311       *a++ = '\0';
09312       ast_copy_string(referdata->refer_to_domain, a, sizeof(referdata->refer_to_domain));
09313    }
09314    
09315    if (sip_debug_test_pvt(p))
09316       ast_verbose("Looking for %s in %s\n", c, p->context);
09317 
09318    if (p->owner)  /* Mimic behaviour in res_features.c */
09319       transfer_context = pbx_builtin_getvar_helper(p->owner, "TRANSFER_CONTEXT");
09320 
09321    /* By default, use the context in the channel sending the REFER */
09322    if (ast_strlen_zero(transfer_context)) {
09323       transfer_context = S_OR(p->owner->macrocontext,
09324                S_OR(p->context, default_context));
09325    }
09326    if (ast_exists_extension(NULL, transfer_context, c, 1, NULL)) {
09327       /* This is a blind transfer */
09328       if (option_debug)
09329          ast_log(LOG_DEBUG,"SIP Bye-also transfer to Extension %s@%s \n", c, transfer_context);
09330       ast_copy_string(referdata->refer_to, c, sizeof(referdata->refer_to));
09331       ast_copy_string(referdata->referred_by, "", sizeof(referdata->referred_by));
09332       ast_copy_string(referdata->refer_contact, "", sizeof(referdata->refer_contact));
09333       referdata->refer_call = NULL;
09334       /* Set new context */
09335       ast_string_field_set(p, context, transfer_context);
09336       return 0;
09337    } else if (ast_canmatch_extension(NULL, p->context, c, 1, NULL)) {
09338       return 1;
09339    }
09340 
09341    return -1;
09342 }

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

Get a specific line from the message body.

Definition at line 4198 of file chan_sip.c.

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

Referenced by handle_request_info().

04199 {
04200    int x;
04201    int len = strlen(name);
04202    char *r;
04203 
04204    for (x = 0; x < req->lines; x++) {
04205       r = get_body_by_line(req->line[x], name, len);
04206       if (r[0] != '\0')
04207          return r;
04208    }
04209 
04210    return "";
04211 }

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

Referenced by get_body(), and get_sdp_iterate().

04165 {
04166    if (strncasecmp(line, name, nameLen) == 0 && line[nameLen] == '=')
04167       return ast_skip_blanks(line + nameLen + 1);
04168 
04169    return "";
04170 }

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

Get caller id name from SIP headers.

Definition at line 9396 of file chan_sip.c.

Referenced by check_user_full().

09397 {
09398    const char *end = strchr(input,'<');   /* first_bracket */
09399    const char *tmp = strchr(input,'"');   /* first quote */
09400    int bytes = 0;
09401    int maxbytes = outputsize - 1;
09402 
09403    if (!end || end == input)  /* we require a part in brackets */
09404       return NULL;
09405 
09406    end--; /* move just before "<" */
09407 
09408    if (tmp && tmp <= end) {
09409       /* The quote (tmp) precedes the bracket (end+1).
09410        * Find the matching quote and return the content.
09411        */
09412       end = strchr(tmp+1, '"');
09413       if (!end)
09414          return NULL;
09415       bytes = (int) (end - tmp);
09416       /* protect the output buffer */
09417       if (bytes > maxbytes)
09418          bytes = maxbytes;
09419       ast_copy_string(output, tmp + 1, bytes);
09420    } else {
09421       /* No quoted string, or it is inside brackets. */
09422       /* clear the empty characters in the begining*/
09423       input = ast_skip_blanks(input);
09424       /* clear the empty characters in the end */
09425       while(*end && *end < 33 && end > input)
09426          end--;
09427       if (end >= input) {
09428          bytes = (int) (end - input) + 2;
09429          /* protect the output buffer */
09430          if (bytes > maxbytes)
09431             bytes = maxbytes;
09432          ast_copy_string(output, input, bytes);
09433       } else
09434          return NULL;
09435    }
09436    return output;
09437 }

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

08942 {
08943    char tmp[256] = "", *uri, *a;
08944    char tmpf[256] = "", *from;
08945    struct sip_request *req;
08946    char *colon;
08947    
08948    req = oreq;
08949    if (!req)
08950       req = &p->initreq;
08951 
08952    /* Find the request URI */
08953    if (req->rlPart2)
08954       ast_copy_string(tmp, req->rlPart2, sizeof(tmp));
08955    
08956    if (pedanticsipchecking)
08957       ast_uri_decode(tmp);
08958 
08959    uri = get_in_brackets(tmp);
08960 
08961    if (strncasecmp(uri, "sip:", 4)) {
08962       ast_log(LOG_WARNING, "Huh?  Not a SIP header (%s)?\n", uri);
08963       return -1;
08964    }
08965    uri += 4;
08966 
08967    /* Now find the From: caller ID and name */
08968    ast_copy_string(tmpf, get_header(req, "From"), sizeof(tmpf));
08969    if (!ast_strlen_zero(tmpf)) {
08970       if (pedanticsipchecking)
08971          ast_uri_decode(tmpf);
08972       from = get_in_brackets(tmpf);
08973    } else {
08974       from = NULL;
08975    }
08976    
08977    if (!ast_strlen_zero(from)) {
08978       if (strncasecmp(from, "sip:", 4)) {
08979          ast_log(LOG_WARNING, "Huh?  Not a SIP header (%s)?\n", from);
08980          return -1;
08981       }
08982       from += 4;
08983       if ((a = strchr(from, '@')))
08984          *a++ = '\0';
08985       else
08986          a = from;   /* just a domain */
08987       from = strsep(&from, ";"); /* Remove userinfo options */
08988       a = strsep(&a, ";");    /* Remove URI options */
08989       ast_string_field_set(p, fromdomain, a);
08990    }
08991 
08992    /* Skip any options and find the domain */
08993 
08994    /* Get the target domain */
08995    if ((a = strchr(uri, '@'))) {
08996       *a++ = '\0';
08997    } else { /* No username part */
08998       a = uri;
08999       uri = "s";  /* Set extension to "s" */
09000    }
09001    colon = strchr(a, ':'); /* Remove :port */
09002    if (colon)
09003       *colon = '\0';
09004 
09005    uri = strsep(&uri, ";");   /* Remove userinfo options */
09006    a = strsep(&a, ";");    /* Remove URI options */
09007 
09008    ast_string_field_set(p, domain, a);
09009 
09010    if (!AST_LIST_EMPTY(&domain_list)) {
09011       char domain_context[AST_MAX_EXTENSION];
09012 
09013       domain_context[0] = '\0';
09014       if (!check_sip_domain(p->domain, domain_context, sizeof(domain_context))) {
09015          if (!allow_external_domains && (req->method == SIP_INVITE || req->method == SIP_REFER)) {
09016             if (option_debug)
09017                ast_log(LOG_DEBUG, "Got SIP %s to non-local domain '%s'; refusing request.\n", sip_methods[req->method].text, p->domain);
09018             return -2;
09019          }
09020       }
09021       /* If we have a context defined, overwrite the original context */
09022       if (!ast_strlen_zero(domain_context))
09023          ast_string_field_set(p, context, domain_context);
09024    }
09025 
09026    /* If the request coming in is a subscription and subscribecontext has been specified use it */
09027    if (req->method == SIP_SUBSCRIBE && !ast_strlen_zero(p->subscribecontext))
09028       ast_string_field_set(p, context, p->subscribecontext);
09029 
09030    if (sip_debug_test_pvt(p))
09031       ast_verbose("Looking for %s in %s (domain %s)\n", uri, p->context, p->domain);
09032 
09033    /* If this is a subscription we actually just need to see if a hint exists for the extension */
09034    if (req->method == SIP_SUBSCRIBE) {
09035       char hint[AST_MAX_EXTENSION];
09036       return (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, p->context, p->exten) ? 0 : -1);
09037    } else {
09038       /* Check the dialplan for the username part of the request URI,
09039          the domain will be stored in the SIPDOMAIN variable
09040          Since extensions.conf can have unescaped characters, try matching a decoded
09041          uri in addition to the non-decoded uri
09042          Return 0 if we have a matching extension */
09043       char *decoded_uri = ast_strdupa(uri);
09044       ast_uri_decode(decoded_uri);
09045       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)) ||
09046           !strcmp(uri, ast_pickup_ext())) {
09047          if (!oreq)
09048             ast_string_field_set(p, exten, uri);
09049          return 0;
09050       } 
09051    }
09052 
09053    /* Return 1 for pickup extension or overlap dialling support (if we support it) */
09054    if((ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP) && 
09055        ast_canmatch_extension(NULL, p->context, uri, 1, S_OR(p->cid_num, from))) ||
09056        !strncmp(uri, ast_pickup_ext(), strlen(uri))) {
09057       return 1;
09058    }
09059    
09060    return -1;
09061 }

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

Get header from SIP request.

Definition at line 4287 of file chan_sip.c.

References __get_header().

04288 {
04289    int start = 0;
04290    return __get_header(req, name, &start);
04291 }

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

02336 {
02337    const char *parse = tmp;
02338    char *first_bracket;
02339 
02340    /*
02341     * Skip any quoted text until we find the part in brackets.
02342          * On any error give up and return the full string.
02343          */
02344         while ( (first_bracket = strchr(parse, '<')) ) {
02345                 char *first_quote = strchr(parse, '"');
02346 
02347       if (!first_quote || first_quote > first_bracket)
02348          break; /* no need to look at quoted part */
02349       /* the bracket is within quotes, so ignore it */
02350       parse = find_closing_quote(first_quote + 1, NULL);
02351       if (!*parse) { /* not found, return full string ? */
02352          /* XXX or be robust and return in-bracket part ? */
02353          ast_log(LOG_WARNING, "No closing quote found in '%s'\n", tmp);
02354          break;
02355       }
02356       parse++;
02357    }
02358    if (first_bracket) {
02359       char *second_bracket = strchr(first_bracket + 1, '>');
02360       if (second_bracket) {
02361          *second_bracket = '\0';
02362          tmp = first_bracket + 1;
02363       } else {
02364          ast_log(LOG_WARNING, "No closing bracket found in '%s'\n", tmp);
02365       }
02366    }
02367    return tmp;
02368 }

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

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

Referenced by handle_request_notify(), and receive_message().

09803 {
09804    int x;
09805    int y;
09806 
09807    buf[0] = '\0';
09808    y = len - strlen(buf) - 5;
09809    if (y < 0)
09810       y = 0;
09811    for (x=0;x<req->lines;x++) {
09812       strncat(buf, req->line[x], y); /* safe */
09813       y -= strlen(req->line[x]) + 1;
09814       if (y < 0)
09815          y = 0;
09816       if (y != 0)
09817          strcat(buf, "\n"); /* safe */
09818    }
09819    return 0;
09820 }

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

Get referring dnis.

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

08913 {
08914    char tmp[256], *c, *a;
08915    struct sip_request *req;
08916    
08917    req = oreq;
08918    if (!req)
08919       req = &p->initreq;
08920    ast_copy_string(tmp, get_header(req, "Diversion"), sizeof(tmp));
08921    if (ast_strlen_zero(tmp))
08922       return 0;
08923    c = get_in_brackets(tmp);
08924    if (strncasecmp(c, "sip:", 4)) {
08925       ast_log(LOG_WARNING, "Huh?  Not an RDNIS SIP header (%s)?\n", c);
08926       return -1;
08927    }
08928    c += 4;
08929    a = c;
08930    strsep(&a, "@;"); /* trim anything after @ or ; */
08931    if (sip_debug_test_pvt(p))
08932       ast_verbose("RDNIS is %s\n", c);
08933    ast_string_field_set(p, rdnis, c);
08934 
08935    return 0;
08936 }

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

09119 {
09120 
09121    const char *p_referred_by = NULL;
09122    char *h_refer_to = NULL; 
09123    char *h_referred_by = NULL;
09124    char *refer_to;
09125    const char *p_refer_to;
09126    char *referred_by_uri = NULL;
09127    char *ptr;
09128    struct sip_request *req = NULL;
09129    const char *transfer_context = NULL;
09130    struct sip_refer *referdata;
09131 
09132 
09133    req = outgoing_req;
09134    referdata = transferer->refer;
09135 
09136    if (!req)
09137       req = &transferer->initreq;
09138 
09139    p_refer_to = get_header(req, "Refer-To");
09140    if (ast_strlen_zero(p_refer_to)) {
09141       ast_log(LOG_WARNING, "Refer-To Header missing. Skipping transfer.\n");
09142       return -2;  /* Syntax error */
09143    }
09144    h_refer_to = ast_strdupa(p_refer_to);
09145    refer_to = get_in_brackets(h_refer_to);
09146    if (pedanticsipchecking)
09147       ast_uri_decode(refer_to);
09148 
09149    if (strncasecmp(refer_to, "sip:", 4)) {
09150       ast_log(LOG_WARNING, "Can't transfer to non-sip: URI.  (Refer-to: %s)?\n", refer_to);
09151       return -3;
09152    }
09153    refer_to += 4;       /* Skip sip: */
09154 
09155    /* Get referred by header if it exists */
09156    p_referred_by = get_header(req, "Referred-By");
09157    if (!ast_strlen_zero(p_referred_by)) {
09158       char *lessthan;
09159       h_referred_by = ast_strdupa(p_referred_by);
09160       if (pedanticsipchecking)
09161          ast_uri_decode(h_referred_by);
09162 
09163       /* Store referrer's caller ID name */
09164       ast_copy_string(referdata->referred_by_name, h_referred_by, sizeof(referdata->referred_by_name));
09165       if ((lessthan = strchr(referdata->referred_by_name, '<'))) {
09166          *(lessthan - 1) = '\0'; /* Space */
09167       }
09168 
09169       referred_by_uri = get_in_brackets(h_referred_by);
09170       if(strncasecmp(referred_by_uri, "sip:", 4)) {
09171          ast_log(LOG_WARNING, "Huh?  Not a sip: header (Referred-by: %s). Skipping.\n", referred_by_uri);
09172          referred_by_uri = (char *) NULL;
09173       } else {
09174          referred_by_uri += 4;      /* Skip sip: */
09175       }
09176    }
09177 
09178    /* Check for arguments in the refer_to header */
09179    if ((ptr = strchr(refer_to, '?'))) { /* Search for arguments */
09180       *ptr++ = '\0';
09181       if (!strncasecmp(ptr, "REPLACES=", 9)) {
09182          char *to = NULL, *from = NULL;
09183 
09184          /* This is an attended transfer */
09185          referdata->attendedtransfer = 1;
09186          ast_copy_string(referdata->replaces_callid, ptr+9, sizeof(referdata->replaces_callid));
09187          ast_uri_decode(referdata->replaces_callid);
09188          if ((ptr = strchr(referdata->replaces_callid, ';')))  /* Find options */ {
09189             *ptr++ = '\0';
09190          }
09191 
09192          if (ptr) {
09193             /* Find the different tags before we destroy the string */
09194             to = strcasestr(ptr, "to-tag=");
09195             from = strcasestr(ptr, "from-tag=");
09196          }
09197 
09198          /* Grab the to header */
09199          if (to) {
09200             ptr = to + 7;
09201             if ((to = strchr(ptr, '&')))
09202                *to = '\0';
09203             if ((to = strchr(ptr, ';')))
09204                *to = '\0';
09205             ast_copy_string(referdata->replaces_callid_totag, ptr, sizeof(referdata->replaces_callid_totag));
09206          }
09207 
09208          if (from) {
09209             ptr = from + 9;
09210             if ((to = strchr(ptr, '&')))
09211                *to = '\0';
09212             if ((to = strchr(ptr, ';')))
09213                *to = '\0';
09214             ast_copy_string(referdata->replaces_callid_fromtag, ptr, sizeof(referdata->replaces_callid_fromtag));
09215          }
09216 
09217          if (option_debug > 1) {
09218             if (!pedanticsipchecking)
09219                ast_log(LOG_DEBUG,"Attended transfer: Will use Replace-Call-ID : %s (No check of from/to tags)\n", referdata->replaces_callid );
09220             else
09221                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>" );
09222          }
09223       }
09224    }
09225    
09226    if ((ptr = strchr(refer_to, '@'))) {   /* Separate domain */
09227       char *urioption = NULL, *domain;
09228       *ptr++ = '\0';
09229 
09230       if ((urioption = strchr(ptr, ';'))) /* Separate urioptions */
09231          *urioption++ = '\0';
09232       
09233       domain = ptr;
09234       if ((ptr = strchr(domain, ':'))) /* Remove :port */
09235          *ptr = '\0';
09236       
09237       /* Save the domain for the dial plan */
09238       ast_copy_string(referdata->refer_to_domain, domain, sizeof(referdata->refer_to_domain));
09239       if (urioption)
09240          ast_copy_string(referdata->refer_to_urioption, urioption, sizeof(referdata->refer_to_urioption));
09241    }
09242 
09243    if ((ptr = strchr(refer_to, ';')))  /* Remove options */
09244       *ptr = '\0';
09245    ast_copy_string(referdata->refer_to, refer_to, sizeof(referdata->refer_to));
09246    
09247    if (referred_by_uri) {
09248       if ((ptr = strchr(referred_by_uri, ';')))    /* Remove options */
09249          *ptr = '\0';
09250       ast_copy_string(referdata->referred_by, referred_by_uri, sizeof(referdata->referred_by));
09251    } else {
09252       referdata->referred_by[0] = '\0';
09253    }
09254 
09255    /* Determine transfer context */
09256    if (transferer->owner)  /* Mimic behaviour in res_features.c */
09257       transfer_context = pbx_builtin_getvar_helper(transferer->owner, "TRANSFER_CONTEXT");
09258 
09259    /* By default, use the context in the channel sending the REFER */
09260    if (ast_strlen_zero(transfer_context)) {
09261       transfer_context = S_OR(transferer->owner->macrocontext,
09262                S_OR(transferer->context, default_context));
09263    }
09264 
09265    ast_copy_string(referdata->refer_to_context, transfer_context, sizeof(referdata->refer_to_context));
09266    
09267    /* Either an existing extension or the parking extension */
09268    if (ast_exists_extension(NULL, transfer_context, refer_to, 1, NULL) ) {
09269       if (sip_debug_test_pvt(transferer)) {
09270          ast_verbose("SIP transfer to extension %s@%s by %s\n", refer_to, transfer_context, referred_by_uri);
09271       }
09272       /* We are ready to transfer to the extension */
09273       return 0;
09274    } 
09275    if (sip_debug_test_pvt(transferer))
09276       ast_verbose("Failed SIP Transfer to non-existing extension %s in context %s\n n", refer_to, transfer_context);
09277 
09278    /* Failure, we can't find this extension */
09279    return -1;
09280 }

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

References AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED.

Referenced by check_user_full().

09444 {
09445    char *start;
09446    char *end;
09447 
09448    start = strchr(input,':');
09449    if (!start) {
09450       output[0] = '\0';
09451       return 0;
09452    }
09453    start++;
09454 
09455    /* we found "number" */
09456    ast_copy_string(output,start,maxlen);
09457    output[maxlen-1] = '\0';
09458 
09459    end = strchr(output,'@');
09460    if (end)
09461       *end = '\0';
09462    else
09463       output[0] = '\0';
09464    if (strstr(input,"privacy=full") || strstr(input,"privacy=uri"))
09465       return AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED;
09466 
09467    return 0;
09468 }

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

Get a line from an SDP message body.

Definition at line 4190 of file chan_sip.c.

References get_sdp_iterate().

04191 {
04192    int dummy = 0;
04193 
04194    return get_sdp_iterate(&dummy, req, name);
04195 }

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

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

04177 {
04178    int len = strlen(name);
04179 
04180    while (*start < req->sdp_end) {
04181       const char *r = get_body_by_line(req->line[(*start)++], name, len);
04182       if (r[0] != '\0')
04183          return r;
04184    }
04185 
04186    return "";
04187 }

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

References ast_channel_trylock, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_strlen_zero(), ast_test_flag, DEADLOCK_AVOIDANCE, 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().

09069 {
09070    struct sip_pvt *sip_pvt_ptr;
09071 
09072    ast_mutex_lock(&iflock);
09073 
09074    if (option_debug > 3 && totag)
09075       ast_log(LOG_DEBUG, "Looking for callid %s (fromtag %s totag %s)\n", callid, fromtag ? fromtag : "<no fromtag>", totag ? totag : "<no totag>");
09076 
09077    /* Search interfaces and find the match */
09078    for (sip_pvt_ptr = iflist; sip_pvt_ptr; sip_pvt_ptr = sip_pvt_ptr->next) {
09079       if (!strcmp(sip_pvt_ptr->callid, callid)) {
09080          int match = 1;
09081          char *ourtag = sip_pvt_ptr->tag;
09082 
09083          /* Go ahead and lock it (and its owner) before returning */
09084          ast_mutex_lock(&sip_pvt_ptr->lock);
09085 
09086          /* Check if tags match. If not, this is not the call we want
09087             (With a forking SIP proxy, several call legs share the
09088             call id, but have different tags)
09089          */
09090          if (pedanticsipchecking && (strcmp(fromtag, sip_pvt_ptr->theirtag) || (!ast_strlen_zero(totag) && strcmp(totag, ourtag))))
09091             match = 0;
09092 
09093          if (!match) {
09094             ast_mutex_unlock(&sip_pvt_ptr->lock);
09095             continue;
09096          }
09097 
09098          if (option_debug > 3 && totag)             
09099             ast_log(LOG_DEBUG, "Matched %s call - their tag is %s Our tag is %s\n",
09100                ast_test_flag(&sip_pvt_ptr->flags[0], SIP_OUTGOING) ? "OUTGOING": "INCOMING",
09101                sip_pvt_ptr->theirtag, sip_pvt_ptr->tag);
09102 
09103          /* deadlock avoidance... */
09104          while (sip_pvt_ptr->owner && ast_channel_trylock(sip_pvt_ptr->owner)) {
09105             DEADLOCK_AVOIDANCE(&sip_pvt_ptr->lock);
09106          }
09107          break;
09108       }
09109    }
09110    ast_mutex_unlock(&iflock);
09111    if (option_debug > 3 && !sip_pvt_ptr)
09112       ast_log(LOG_DEBUG, "Found no match for callid %s to-tag %s from-tag %s\n", callid, totag, fromtag);
09113    return sip_pvt_ptr;
09114 }

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

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

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

13496 {
13497    const char *thetag;
13498 
13499    if (!tagbuf)
13500       return NULL;
13501    tagbuf[0] = '\0';    /* reset the buffer */
13502    thetag = get_header(req, header);
13503    thetag = strcasestr(thetag, ";tag=");
13504    if (thetag) {
13505       thetag += 5;
13506       ast_copy_string(tagbuf, thetag, tagbufsize);
13507       return strsep(&tagbuf, ";");
13508    }
13509    return NULL;
13510 }

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

References ast_clear_flag, ast_false(), ast_log(), ast_set2_flag, ast_set_flag, ast_set_flags_to, 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_UDPTL_DESTINATION, 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().

16604 {
16605    int res = 1;
16606 
16607    if (!strcasecmp(v->name, "trustrpid")) {
16608       ast_set_flag(&mask[0], SIP_TRUSTRPID);
16609       ast_set2_flag(&flags[0], ast_true(v->value), SIP_TRUSTRPID);
16610    } else if (!strcasecmp(v->name, "sendrpid")) {
16611       ast_set_flag(&mask[0], SIP_SENDRPID);
16612       ast_set2_flag(&flags[0], ast_true(v->value), SIP_SENDRPID);
16613    } else if (!strcasecmp(v->name, "g726nonstandard")) {
16614       ast_set_flag(&mask[0], SIP_G726_NONSTANDARD);
16615       ast_set2_flag(&flags[0], ast_true(v->value), SIP_G726_NONSTANDARD);
16616    } else if (!strcasecmp(v->name, "useclientcode")) {
16617       ast_set_flag(&mask[0], SIP_USECLIENTCODE);
16618       ast_set2_flag(&flags[0], ast_true(v->value), SIP_USECLIENTCODE);
16619    } else if (!strcasecmp(v->name, "dtmfmode")) {
16620       ast_set_flag(&mask[0], SIP_DTMF);
16621       ast_clear_flag(&flags[0], SIP_DTMF);
16622       if (!strcasecmp(v->value, "inband"))
16623          ast_set_flag(&flags[0], SIP_DTMF_INBAND);
16624       else if (!strcasecmp(v->value, "rfc2833"))
16625          ast_set_flag(&flags[0], SIP_DTMF_RFC2833);
16626       else if (!strcasecmp(v->value, "info"))
16627          ast_set_flag(&flags[0], SIP_DTMF_INFO);
16628       else if (!strcasecmp(v->value, "auto"))
16629          ast_set_flag(&flags[0], SIP_DTMF_AUTO);
16630       else {
16631          ast_log(LOG_WARNING, "Unknown dtmf mode '%s' on line %d, using rfc2833\n", v->value, v->lineno);
16632          ast_set_flag(&flags[0], SIP_DTMF_RFC2833);
16633       }
16634    } else if (!strcasecmp(v->name, "nat")) {
16635       ast_set_flag(&mask[0], SIP_NAT);
16636       ast_set_flag(&flags[0], SIP_NAT_ALWAYS);
16637       if (!strcasecmp(v->value, "never")) {
16638          ast_set_flags_to(&flags[0], SIP_NAT, SIP_NAT_NEVER);
16639       } else if (!strcasecmp(v->value, "route")) {
16640          ast_set_flags_to(&flags[0], SIP_NAT, SIP_NAT_ROUTE);
16641       } else if (ast_false(v->value)) {
16642          ast_set_flags_to(&flags[0], SIP_NAT, SIP_NAT_RFC3581);
16643       }
16644    } else if (!strcasecmp(v->name, "canreinvite")) {
16645       ast_set_flag(&mask[0], SIP_REINVITE);
16646       ast_clear_flag(&flags[0], SIP_REINVITE);
16647       if(ast_true(v->value)) {
16648          ast_set_flag(&flags[0], SIP_CAN_REINVITE | SIP_CAN_REINVITE_NAT);
16649       } else if (!ast_false(v->value)) {
16650          char buf[64];
16651          char *word, *next = buf;
16652 
16653          ast_copy_string(buf, v->value, sizeof(buf));
16654          while ((word = strsep(&next, ","))) {
16655             if(!strcasecmp(word, "update")) {
16656                ast_set_flag(&flags[0], SIP_REINVITE_UPDATE | SIP_CAN_REINVITE);
16657             } else if(!strcasecmp(word, "nonat")) {
16658                ast_set_flag(&flags[0], SIP_CAN_REINVITE);
16659                ast_clear_flag(&flags[0], SIP_CAN_REINVITE_NAT);
16660             } else {
16661                ast_log(LOG_WARNING, "Unknown canreinvite mode '%s' on line %d\n", v->value, v->lineno);
16662             }
16663          }
16664       }
16665    } else if (!strcasecmp(v->name, "insecure")) {
16666       ast_set_flag(&mask[0], SIP_INSECURE_PORT | SIP_INSECURE_INVITE);
16667       ast_clear_flag(&flags[0], SIP_INSECURE_PORT | SIP_INSECURE_INVITE);
16668       set_insecure_flags(flags, v->value, v->lineno);
16669    } else if (!strcasecmp(v->name, "progressinband")) {
16670       ast_set_flag(&mask[0], SIP_PROG_INBAND);
16671       ast_clear_flag(&flags[0], SIP_PROG_INBAND);
16672       if (ast_true(v->value))
16673          ast_set_flag(&flags[0], SIP_PROG_INBAND_YES);
16674       else if (strcasecmp(v->value, "never"))
16675          ast_set_flag(&flags[0], SIP_PROG_INBAND_NO);
16676    } else if (!strcasecmp(v->name, "promiscredir")) {
16677       ast_set_flag(&mask[0], SIP_PROMISCREDIR);
16678       ast_set2_flag(&flags[0], ast_true(v->value), SIP_PROMISCREDIR);
16679    } else if (!strcasecmp(v->name, "videosupport")) {
16680       ast_set_flag(&mask[1], SIP_PAGE2_VIDEOSUPPORT);
16681       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_VIDEOSUPPORT);
16682    } else if (!strcasecmp(v->name, "allowoverlap")) {
16683       ast_set_flag(&mask[1], SIP_PAGE2_ALLOWOVERLAP);
16684       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_ALLOWOVERLAP);
16685    } else if (!strcasecmp(v->name, "allowsubscribe")) {
16686       ast_set_flag(&mask[1], SIP_PAGE2_ALLOWSUBSCRIBE);
16687       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_ALLOWSUBSCRIBE);
16688    } else if (!strcasecmp(v->name, "t38pt_udptl")) {
16689       ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT_UDPTL);
16690       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_T38SUPPORT_UDPTL);
16691 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS
16692    } else if (!strcasecmp(v->name, "t38pt_rtp")) {
16693       ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT_RTP);
16694       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_T38SUPPORT_RTP);
16695    } else if (!strcasecmp(v->name, "t38pt_tcp")) {
16696       ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT_TCP);
16697       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_T38SUPPORT_TCP);
16698 #endif
16699    } else if (!strcasecmp(v->name, "rfc2833compensate")) {
16700       ast_set_flag(&mask[1], SIP_PAGE2_RFC2833_COMPENSATE);
16701       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_RFC2833_COMPENSATE);
16702    } else if (!strcasecmp(v->name, "buggymwi")) {
16703       ast_set_flag(&mask[1], SIP_PAGE2_BUGGY_MWI);
16704       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_BUGGY_MWI);
16705    } else if (!strcasecmp(v->name, "t38pt_usertpsource")) {
16706       ast_set_flag(&mask[1], SIP_PAGE2_UDPTL_DESTINATION);
16707       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_UDPTL_DESTINATION);
16708    } else
16709       res = 0;
16710 
16711    return res;
16712 }

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

13675 {
13676    struct ast_frame *f;
13677    int earlyreplace = 0;
13678    int oneleggedreplace = 0;     /* Call with no bridge, propably IVR or voice message */
13679    struct ast_channel *c = p->owner;   /* Our incoming call */
13680    struct ast_channel *replacecall = p->refer->refer_call->owner; /* The channel we're about to take over */
13681    struct ast_channel *targetcall;     /* The bridge to the take-over target */
13682 
13683    /* Check if we're in ring state */
13684    if (replacecall->_state == AST_STATE_RING)
13685       earlyreplace = 1;
13686 
13687    /* Check if we have a bridge */
13688    if (!(targetcall = ast_bridged_channel(replacecall))) {
13689       /* We have no bridge */
13690       if (!earlyreplace) {
13691          if (option_debug > 1)
13692             ast_log(LOG_DEBUG, " Attended transfer attempted to replace call with no bridge (maybe ringing). Channel %s!\n", replacecall->name);
13693          oneleggedreplace = 1;
13694       }
13695    } 
13696    if (option_debug > 3 && targetcall && targetcall->_state == AST_STATE_RINGING)
13697          ast_log(LOG_DEBUG, "SIP transfer: Target channel is in ringing state\n");
13698 
13699    if (option_debug > 3) {
13700       if (targetcall) 
13701          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); 
13702       else
13703          ast_log(LOG_DEBUG, "SIP transfer: Invite Replace incoming channel should replace and hang up channel %s (one call leg)\n", replacecall->name); 
13704    }
13705 
13706    if (ignore) {
13707       ast_log(LOG_NOTICE, "Ignoring this INVITE with replaces in a stupid way.\n");
13708       /* We should answer something here. If we are here, the
13709          call we are replacing exists, so an accepted 
13710          can't harm */
13711       transmit_response_with_sdp(p, "200 OK", req, XMIT_RELIABLE);
13712       /* Do something more clever here */
13713       ast_channel_unlock(c);
13714       ast_mutex_unlock(&p->refer->refer_call->lock);
13715       return 1;
13716    } 
13717    if (!c) {
13718       /* What to do if no channel ??? */
13719       ast_log(LOG_ERROR, "Unable to create new channel.  Invite/replace failed.\n");
13720       transmit_response_reliable(p, "503 Service Unavailable", req);
13721       append_history(p, "Xfer", "INVITE/Replace Failed. No new channel.");
13722       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
13723       ast_mutex_unlock(&p->refer->refer_call->lock);
13724       return 1;
13725    }
13726    append_history(p, "Xfer", "INVITE/Replace received");
13727    /* We have three channels to play with
13728       channel c: New incoming call
13729       targetcall: Call from PBX to target
13730       p->refer->refer_call: SIP pvt dialog from transferer to pbx.
13731       replacecall: The owner of the previous
13732       We need to masq C into refer_call to connect to 
13733       targetcall;
13734       If we are talking to internal audio stream, target call is null.
13735    */
13736 
13737    /* Fake call progress */
13738    transmit_response(p, "100 Trying", req);
13739    ast_setstate(c, AST_STATE_RING);
13740 
13741    /* Masquerade the new call into the referred call to connect to target call 
13742       Targetcall is not touched by the masq */
13743 
13744    /* Answer the incoming call and set channel to UP state */
13745    transmit_response_with_sdp(p, "200 OK", req, XMIT_RELIABLE);
13746       
13747    ast_setstate(c, AST_STATE_UP);
13748    
13749    /* Stop music on hold and other generators */
13750    ast_quiet_chan(replacecall);
13751    ast_quiet_chan(targetcall);
13752    if (option_debug > 3)
13753       ast_log(LOG_DEBUG, "Invite/Replaces: preparing to masquerade %s into %s\n", c->name, replacecall->name);
13754    /* Unlock clone, but not original (replacecall) */
13755    if (!oneleggedreplace)
13756       ast_channel_unlock(c);
13757 
13758    /* Unlock PVT */
13759    ast_mutex_unlock(&p->refer->refer_call->lock);
13760 
13761    /* Make sure that the masq does not free our PVT for the old call */
13762    if (! earlyreplace && ! oneleggedreplace )
13763       ast_set_flag(&p->refer->refer_call->flags[0], SIP_DEFER_BYE_ON_TRANSFER);  /* Delay hangup */
13764       
13765    /* Prepare the masquerade - if this does not happen, we will be gone */
13766    if(ast_channel_masquerade(replacecall, c))
13767       ast_log(LOG_ERROR, "Failed to masquerade C into Replacecall\n");
13768    else if (option_debug > 3)
13769       ast_log(LOG_DEBUG, "Invite/Replaces: Going to masquerade %s into %s\n", c->name, replacecall->name);
13770 
13771    /* The masquerade will happen as soon as someone reads a frame from the channel */
13772 
13773    /* C should now be in place of replacecall */
13774    /* ast_read needs to lock channel */
13775    ast_channel_unlock(c);
13776    
13777    if (earlyreplace || oneleggedreplace ) {
13778       /* Force the masq to happen */
13779       if ((f = ast_read(replacecall))) {  /* Force the masq to happen */
13780          ast_frfree(f);
13781          f = NULL;
13782          if (option_debug > 3)
13783             ast_log(LOG_DEBUG, "Invite/Replace:  Could successfully read frame from RING channel!\n");
13784       } else {
13785          ast_log(LOG_WARNING, "Invite/Replace:  Could not read frame from RING channel \n");
13786       }
13787       c->hangupcause = AST_CAUSE_SWITCH_CONGESTION;
13788       if (!oneleggedreplace)
13789          ast_channel_unlock(replacecall);
13790    } else { /* Bridged call, UP channel */
13791       if ((f = ast_read(replacecall))) {  /* Force the masq to happen */
13792          /* Masq ok */
13793          ast_frfree(f);
13794          f = NULL;
13795          if (option_debug > 2)
13796             ast_log(LOG_DEBUG, "Invite/Replace:  Could successfully read frame from channel! Masq done.\n");
13797       } else {
13798          ast_log(LOG_WARNING, "Invite/Replace:  Could not read frame from channel. Transfer failed\n");
13799       }
13800       ast_channel_unlock(replacecall);
13801    }
13802    ast_mutex_unlock(&p->refer->refer_call->lock);
13803 
13804    ast_setstate(c, AST_STATE_DOWN);
13805    if (option_debug > 3) {
13806       struct ast_channel *test;
13807       ast_log(LOG_DEBUG, "After transfer:----------------------------\n");
13808       ast_log(LOG_DEBUG, " -- C:        %s State %s\n", c->name, ast_state2str(c->_state));
13809       if (replacecall)
13810          ast_log(LOG_DEBUG, " -- replacecall:        %s State %s\n", replacecall->name, ast_state2str(replacecall->_state));
13811       if (p->owner) {
13812          ast_log(LOG_DEBUG, " -- P->owner: %s State %s\n", p->owner->name, ast_state2str(p->owner->_state));
13813          test = ast_bridged_channel(p->owner);
13814          if (test)
13815             ast_log(LOG_DEBUG, " -- Call bridged to P->owner: %s State %s\n", test->name, ast_state2str(test->_state));
13816          else
13817             ast_log(LOG_DEBUG, " -- No call bridged to C->owner \n");
13818       } else 
13819          ast_log(LOG_DEBUG, " -- No channel yet \n");
13820       ast_log(LOG_DEBUG, "End After transfer:----------------------------\n");
13821    }
13822 
13823    ast_channel_unlock(p->owner); /* Unlock new owner */
13824    if (!oneleggedreplace)
13825       ast_mutex_unlock(&p->lock);   /* Unlock SIP structure */
13826 
13827    /* The call should be down with no ast_channel, so hang it up */
13828    c->tech_pvt = NULL;
13829    ast_hangup(c);
13830    return 0;
13831 }

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

15661 {
15662    /* Called with p->lock held, as well as p->owner->lock if appropriate, keeping things
15663       relatively static */
15664    const char *cmd;
15665    const char *cseq;
15666    const char *useragent;
15667    int seqno;
15668    int len;
15669    int ignore = FALSE;
15670    int respid;
15671    int res = 0;
15672    int debug = sip_debug_test_pvt(p);
15673    char *e;
15674    int error = 0;
15675 
15676    /* Get Method and Cseq */
15677    cseq = get_header(req, "Cseq");
15678    cmd = req->header[0];
15679 
15680    /* Must have Cseq */
15681    if (ast_strlen_zero(cmd) || ast_strlen_zero(cseq)) {
15682       ast_log(LOG_ERROR, "Missing Cseq. Dropping this SIP message, it's incomplete.\n");
15683       error = 1;
15684    }
15685    if (!error && sscanf(cseq, "%d%n", &seqno, &len) != 1) {
15686       ast_log(LOG_ERROR, "No seqno in '%s'. Dropping incomplete message.\n", cmd);
15687       error = 1;
15688    }
15689    if (error) {
15690       if (!p->initreq.headers)   /* New call */
15691          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); /* Make sure we destroy this dialog */
15692       return -1;
15693    }
15694    /* Get the command XXX */
15695 
15696    cmd = req->rlPart1;
15697    e = req->rlPart2;
15698 
15699    /* Save useragent of the client */
15700    useragent = get_header(req, "User-Agent");
15701    if (!ast_strlen_zero(useragent))
15702       ast_string_field_set(p, useragent, useragent);
15703 
15704    /* Find out SIP method for incoming request */
15705    if (req->method == SIP_RESPONSE) {  /* Response to our request */
15706       /* Response to our request -- Do some sanity checks */   
15707       if (!p->initreq.headers) {
15708          if (option_debug)
15709             ast_log(LOG_DEBUG, "That's odd...  Got a response on a call we dont know about. Cseq %d Cmd %s\n", seqno, cmd);
15710          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
15711          return 0;
15712       } else if (p->ocseq && (p->ocseq < seqno) && (seqno != p->lastnoninvite)) {
15713          if (option_debug)
15714             ast_log(LOG_DEBUG, "Ignoring out of order response %d (expecting %d)\n", seqno, p->ocseq);
15715          return -1;
15716       } else if (p->ocseq && (p->ocseq != seqno) && (seqno != p->lastnoninvite)) {
15717          /* ignore means "don't do anything with it" but still have to 
15718             respond appropriately  */
15719          ignore = TRUE;
15720          ast_set_flag(req, SIP_PKT_IGNORE);
15721          ast_set_flag(req, SIP_PKT_IGNORE_RESP);
15722          append_history(p, "Ignore", "Ignoring this retransmit\n");
15723       } else if (e) {
15724          e = ast_skip_blanks(e);
15725          if (sscanf(e, "%d %n", &respid, &len) != 1) {
15726             ast_log(LOG_WARNING, "Invalid response: '%s'\n", e);
15727          } else {
15728             if (respid <= 0) {
15729                ast_log(LOG_WARNING, "Invalid SIP response code: '%d'\n", respid);
15730                return 0;
15731             }
15732             /* More SIP ridiculousness, we have to ignore bogus contacts in 100 etc responses */
15733             if ((respid == 200) || ((respid >= 300) && (respid <= 399)))
15734                extract_uri(p, req);
15735             handle_response(p, respid, e + len, req, ignore, seqno);
15736          }
15737       }
15738       return 0;
15739    }
15740 
15741    /* New SIP request coming in 
15742       (could be new request in existing SIP dialog as well...) 
15743     */         
15744    
15745    p->method = req->method;   /* Find out which SIP method they are using */
15746    if (option_debug > 3)
15747       ast_log(LOG_DEBUG, "**** Received %s (%d) - Command in SIP %s\n", sip_methods[p->method].text, sip_methods[p->method].id, cmd); 
15748 
15749    if (p->icseq && (p->icseq > seqno) ) {
15750       if (p->pendinginvite && seqno == p->pendinginvite && (req->method == SIP_ACK || req->method == SIP_CANCEL)) {
15751          if (option_debug > 2)
15752             ast_log(LOG_DEBUG, "Got CANCEL or ACK on INVITE with transactions in between.\n");
15753       }  else {
15754          if (option_debug)
15755             ast_log(LOG_DEBUG, "Ignoring too old SIP packet packet %d (expecting >= %d)\n", seqno, p->icseq);
15756          if (req->method != SIP_ACK)
15757             transmit_response(p, "503 Server error", req);  /* We must respond according to RFC 3261 sec 12.2 */
15758          return -1;
15759       }
15760    } else if (p->icseq &&
15761          p->icseq == seqno &&
15762          req->method != SIP_ACK &&
15763          (p->method != SIP_CANCEL || ast_test_flag(&p->flags[0], SIP_ALREADYGONE))) {
15764       /* ignore means "don't do anything with it" but still have to 
15765          respond appropriately.  We do this if we receive a repeat of
15766          the last sequence number  */
15767       ignore = 2;
15768       ast_set_flag(req, SIP_PKT_IGNORE);
15769       ast_set_flag(req, SIP_PKT_IGNORE_REQ);
15770       if (option_debug > 2)
15771          ast_log(LOG_DEBUG, "Ignoring SIP message because of retransmit (%s Seqno %d, ours %d)\n", sip_methods[p->method].text, p->icseq, seqno);
15772    }
15773       
15774    if (seqno >= p->icseq)
15775       /* Next should follow monotonically (but not necessarily 
15776          incrementally -- thanks again to the genius authors of SIP --
15777          increasing */
15778       p->icseq = seqno;
15779 
15780    /* Find their tag if we haven't got it */
15781    if (ast_strlen_zero(p->theirtag)) {
15782       char tag[128];
15783 
15784       gettag(req, "From", tag, sizeof(tag));
15785       ast_string_field_set(p, theirtag, tag);
15786    }
15787    snprintf(p->lastmsg, sizeof(p->lastmsg), "Rx: %s", cmd);
15788 
15789    if (pedanticsipchecking) {
15790       /* If this is a request packet without a from tag, it's not
15791          correct according to RFC 3261  */
15792       /* Check if this a new request in a new dialog with a totag already attached to it,
15793          RFC 3261 - section 12.2 - and we don't want to mess with recovery  */
15794       if (!p->initreq.headers && ast_test_flag(req, SIP_PKT_WITH_TOTAG)) {
15795          /* If this is a first request and it got a to-tag, it is not for us */
15796          if (!ast_test_flag(req, SIP_PKT_IGNORE) && req->method == SIP_INVITE) {
15797             transmit_response_reliable(p, "481 Call/Transaction Does Not Exist", req);
15798             /* Will cease to exist after ACK */
15799          } else if (req->method != SIP_ACK) {
15800             transmit_response(p, "481 Call/Transaction Does Not Exist", req);
15801             sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
15802          }
15803          return res;
15804       }
15805    }
15806 
15807    if (!e && (p->method == SIP_INVITE || p->method == SIP_SUBSCRIBE || p->method == SIP_REGISTER || p->method == SIP_NOTIFY)) {
15808       transmit_response(p, "400 Bad request", req);
15809       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
15810       return -1;
15811    }
15812 
15813    /* Handle various incoming SIP methods in requests */
15814    switch (p->method) {
15815    case SIP_OPTIONS:
15816       res = handle_request_options(p, req);
15817       break;
15818    case SIP_INVITE:
15819       res = handle_request_invite(p, req, debug, seqno, sin, recount, e, nounlock);
15820       break;
15821    case SIP_REFER:
15822       res = handle_request_refer(p, req, debug, ignore, seqno, nounlock);
15823       break;
15824    case SIP_CANCEL:
15825       res = handle_request_cancel(p, req);
15826       break;
15827    case SIP_BYE:
15828       res = handle_request_bye(p, req);
15829       break;
15830    case SIP_MESSAGE:
15831       res = handle_request_message(p, req);
15832       break;
15833    case SIP_SUBSCRIBE:
15834       res = handle_request_subscribe(p, req, sin, seqno, e);
15835       break;
15836    case SIP_REGISTER:
15837       res = handle_request_register(p, req, sin, e);
15838       break;
15839    case SIP_INFO:
15840       if (ast_test_flag(req, SIP_PKT_DEBUG))
15841          ast_verbose("Receiving INFO!\n");
15842       if (!ignore) 
15843          handle_request_info(p, req);
15844       else  /* if ignoring, transmit response */
15845          transmit_response(p, "200 OK", req);
15846       break;
15847    case SIP_NOTIFY:
15848       res = handle_request_notify(p, req, sin, seqno, e);
15849       break;
15850    case SIP_ACK:
15851       /* Make sure we don't ignore this */
15852       if (seqno == p->pendinginvite) {
15853          p->invitestate = INV_TERMINATED;
15854          p->pendinginvite = 0;
15855          __sip_ack(p, seqno, FLAG_RESPONSE, 0);
15856          if (find_sdp(req)) {
15857             if (process_sdp(p, req))
15858                return -1;
15859          } 
15860          check_pendings(p);
15861       }
15862       /* Got an ACK that we did not match. Ignore silently */
15863       if (!p->lastinvite && ast_strlen_zero(p->randdata))
15864          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
15865       break;
15866    default:
15867       transmit_response_with_allow(p, "501 Method Not Implemented", req, 0);
15868       ast_log(LOG_NOTICE, "Unknown SIP command '%s' from '%s'\n", 
15869          cmd, ast_inet_ntoa(p->sa.sin_addr));
15870       /* If this is some new method, and we don't have a call, destroy it now */
15871       if (!p->initreq.headers)
15872          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
15873       break;
15874    }
15875    return res;
15876 }

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

Handle incoming BYE request.

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

15226 {
15227    struct ast_channel *c=NULL;
15228    int res;
15229    struct ast_channel *bridged_to;
15230    
15231    /* If we have an INCOMING invite that we haven't answered, terminate that transaction */
15232    if (p->pendinginvite && !ast_test_flag(&p->flags[0], SIP_OUTGOING) && !ast_test_flag(req, SIP_PKT_IGNORE) && !p->owner) 
15233       transmit_response_reliable(p, "487 Request Terminated", &p->initreq);
15234 
15235    p->invitestate = INV_TERMINATED;
15236 
15237    copy_request(&p->initreq, req);
15238    check_via(p, req);
15239    sip_alreadygone(p);
15240 
15241    /* Get RTCP quality before end of call */
15242    if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY) || p->owner) {
15243       char *audioqos, *videoqos;
15244       if (p->rtp) {
15245          audioqos = ast_rtp_get_quality(p->rtp, NULL);
15246          if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY))
15247             append_history(p, "RTCPaudio", "Quality:%s", audioqos);
15248          if (p->owner)
15249             pbx_builtin_setvar_helper(p->owner, "RTPAUDIOQOS", audioqos);
15250       }
15251       if (p->vrtp) {
15252          videoqos = ast_rtp_get_quality(p->vrtp, NULL);
15253          if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY))
15254             append_history(p, "RTCPvideo", "Quality:%s", videoqos);
15255          if (p->owner)
15256             pbx_builtin_setvar_helper(p->owner, "RTPVIDEOQOS", videoqos);
15257       }
15258    }
15259 
15260    stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */
15261 
15262    if (!ast_strlen_zero(get_header(req, "Also"))) {
15263       ast_log(LOG_NOTICE, "Client '%s' using deprecated BYE/Also transfer method.  Ask vendor to support REFER instead\n",
15264          ast_inet_ntoa(p->recv.sin_addr));
15265       if (ast_strlen_zero(p->context))
15266          ast_string_field_set(p, context, default_context);
15267       res = get_also_info(p, req);
15268       if (!res) {
15269          c = p->owner;
15270          if (c) {
15271             bridged_to = ast_bridged_channel(c);
15272             if (bridged_to) {
15273                /* Don't actually hangup here... */
15274                ast_queue_control(c, AST_CONTROL_UNHOLD);
15275                ast_async_goto(bridged_to, p->context, p->refer->refer_to,1);
15276             } else
15277                ast_queue_hangup(p->owner);
15278          }
15279       } else {
15280          ast_log(LOG_WARNING, "Invalid transfer information from '%s'\n", ast_inet_ntoa(p->recv.sin_addr));
15281          if (p->owner)
15282             ast_queue_hangup(p->owner);
15283       }
15284    } else if (p->owner) {
15285       ast_queue_hangup(p->owner);
15286       if (option_debug > 2)
15287          ast_log(LOG_DEBUG, "Received bye, issuing owner hangup\n");
15288    } else {
15289       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
15290       if (option_debug > 2)
15291          ast_log(LOG_DEBUG, "Received bye, no owner, selfdestruct soon.\n");
15292    }
15293    transmit_response(p, "200 OK", req);
15294 
15295    return 1;
15296 }

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

Handle incoming CANCEL request.

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

15120 {
15121       
15122    check_via(p, req);
15123    sip_alreadygone(p);
15124 
15125    /* At this point, we could have cancelled the invite at the same time
15126       as the other side sends a CANCEL. Our final reply with error code
15127       might not have been received by the other side before the CANCEL
15128       was sent, so let's just give up retransmissions and waiting for
15129       ACK on our error code. The call is hanging up any way. */
15130    if (p->invitestate == INV_TERMINATED)
15131       __sip_pretend_ack(p);
15132    else
15133       p->invitestate = INV_CANCELLED;
15134    
15135    if (p->owner && p->owner->_state == AST_STATE_UP) {
15136       /* This call is up, cancel is ignored, we need a bye */
15137       transmit_response(p, "200 OK", req);
15138       if (option_debug)
15139          ast_log(LOG_DEBUG, "Got CANCEL on an answered call. Ignoring... \n");
15140       return 0;
15141    }
15142 
15143    if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) 
15144       update_call_counter(p, DEC_CALL_LIMIT);
15145 
15146    stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */
15147    if (p->owner)
15148       ast_queue_hangup(p->owner);
15149    else
15150       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
15151    if (p->initreq.len > 0) {
15152       transmit_response_reliable(p, "487 Request Terminated", &p->initreq);
15153       transmit_response(p, "200 OK", req);
15154       return 1;
15155    } else {
15156       transmit_response(p, "481 Call Leg Does Not Exist", req);
15157       return 0;
15158    }
15159 }

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

11276 {
11277    char buf[1024];
11278    unsigned int event;
11279    const char *c = get_header(req, "Content-Type");
11280 
11281    /* Need to check the media/type */
11282    if (!strcasecmp(c, "application/dtmf-relay") ||
11283        !strcasecmp(c, "application/vnd.nortelnetworks.digits")) {
11284       unsigned int duration = 0;
11285 
11286       /* Try getting the "signal=" part */
11287       if (ast_strlen_zero(c = get_body(req, "Signal")) && ast_strlen_zero(c = get_body(req, "d"))) {
11288          ast_log(LOG_WARNING, "Unable to retrieve DTMF signal from INFO message from %s\n", p->callid);
11289          transmit_response(p, "200 OK", req); /* Should return error */
11290          return;
11291       } else {
11292          ast_copy_string(buf, c, sizeof(buf));
11293       }
11294 
11295       if (!ast_strlen_zero((c = get_body(req, "Duration"))))
11296          duration = atoi(c);
11297       if (!duration)
11298          duration = 100; /* 100 ms */
11299 
11300       if (!p->owner) {  /* not a PBX call */
11301          transmit_response(p, "481 Call leg/transaction does not exist", req);
11302          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
11303          return;
11304       }
11305 
11306       if (ast_strlen_zero(buf)) {
11307          transmit_response(p, "200 OK", req);
11308          return;
11309       }
11310 
11311       if (buf[0] == '*')
11312          event = 10;
11313       else if (buf[0] == '#')
11314          event = 11;
11315       else if ((buf[0] >= 'A') && (buf[0] <= 'D'))
11316          event = 12 + buf[0] - 'A';
11317       else
11318          event = atoi(buf);
11319       if (event == 16) {
11320          /* send a FLASH event */
11321          struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_FLASH, };
11322          ast_queue_frame(p->owner, &f);
11323          if (sipdebug)
11324             ast_verbose("* DTMF-relay event received: FLASH\n");
11325       } else {
11326          /* send a DTMF event */
11327          struct ast_frame f = { AST_FRAME_DTMF, };
11328          if (event < 10) {
11329             f.subclass = '0' + event;
11330          } else if (event < 11) {
11331             f.subclass = '*';
11332          } else if (event < 12) {
11333             f.subclass = '#';
11334          } else if (event < 16) {
11335             f.subclass = 'A' + (event - 12);
11336          }
11337          f.len = duration;
11338          ast_queue_frame(p->owner, &f);
11339          if (sipdebug)
11340             ast_verbose("* DTMF-relay event received: %c\n", f.subclass);
11341       }
11342       transmit_response(p, "200 OK", req);
11343       return;
11344    } else if (!strcasecmp(c, "application/media_control+xml")) {
11345       /* Eh, we'll just assume it's a fast picture update for now */
11346       if (p->owner)
11347          ast_queue_control(p->owner, AST_CONTROL_VIDUPDATE);
11348       transmit_response(p, "200 OK", req);
11349       return;
11350    } else if (!ast_strlen_zero(c = get_header(req, "X-ClientCode"))) {
11351       /* Client code (from SNOM phone) */
11352       if (ast_test_flag(&p->flags[0], SIP_USECLIENTCODE)) {
11353          if (p->owner && p->owner->cdr)
11354             ast_cdr_setuserfield(p->owner, c);
11355          if (p->owner && ast_bridged_channel(p->owner) && ast_bridged_channel(p->owner)->cdr)
11356             ast_cdr_setuserfield(ast_bridged_channel(p->owner), c);
11357          transmit_response(p, "200 OK", req);
11358       } else {
11359          transmit_response(p, "403 Unauthorized", req);
11360       }
11361       return;
11362    } else if (ast_strlen_zero(c = get_header(req, "Content-Length")) || !strcasecmp(c, "0")) {
11363       /* This is probably just a packet making sure the signalling is still up, just send back a 200 OK */
11364       transmit_response(p, "200 OK", req);
11365       return;
11366    }
11367 
11368    /* Other type of INFO message, not really understood by Asterisk */
11369    /* if (get_msg_text(buf, sizeof(buf), req)) { */
11370 
11371    ast_log(LOG_WARNING, "Unable to parse INFO message from %s. Content %s\n", p->callid, buf);
11372    transmit_response(p, "415 Unsupported media type", req);
11373    return;
11374 }

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 14122 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_check_hangup(), 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_SCHED_DEL, 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(), create_addr(), 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, sip_pvt::icseq, 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(), sip_pkt::method, sip_pkt::next, option_debug, sip_pvt::owner, sip_pvt::packets, parse_ok_contact(), parse_sip_options(), sip_pvt::pendinginvite, process_sdp(), sip_pvt::refer, sip_refer::refer_call, sip_pkt::retransid, sip_request::rlPart2, sip_pvt::rtp, S_OR, sip_pkt::seqno, 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, sip_uri_cmp(), 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_invite(), 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().

14123 {
14124    int res = 1;
14125    int gotdest;
14126    const char *p_replaces;
14127    char *replace_id = NULL;
14128    const char *required;
14129    unsigned int required_profile = 0;
14130    struct ast_channel *c = NULL;    /* New channel */
14131    int reinvite = 0;
14132 
14133    /* Find out what they support */
14134    if (!p->sipoptions) {
14135       const char *supported = get_header(req, "Supported");
14136       if (!ast_strlen_zero(supported))
14137          parse_sip_options(p, supported);
14138    }
14139 
14140    /* Find out what they require */
14141    required = get_header(req, "Require");
14142    if (!ast_strlen_zero(required)) {
14143       required_profile = parse_sip_options(NULL, required);
14144       if (required_profile && required_profile != SIP_OPT_REPLACES) {
14145          /* At this point we only support REPLACES */
14146          transmit_response_with_unsupported(p, "420 Bad extension (unsupported)", req, required);
14147          ast_log(LOG_WARNING,"Received SIP INVITE with unsupported required extension: %s\n", required);
14148          p->invitestate = INV_COMPLETED;
14149          if (!p->lastinvite)
14150             sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
14151          return -1;
14152       }
14153    }
14154 
14155    /* Check if this is a loop */
14156    if (ast_test_flag(&p->flags[0], SIP_OUTGOING) && p->owner && (p->owner->_state != AST_STATE_UP)) {
14157       /* This is a call to ourself.  Send ourselves an error code and stop
14158          processing immediately, as SIP really has no good mechanism for
14159          being able to call yourself */
14160       /* If pedantic is on, we need to check the tags. If they're different, this is
14161          in fact a forked call through a SIP proxy somewhere. */
14162       int different;
14163       if (pedanticsipchecking)
14164          different = sip_uri_cmp(p->initreq.rlPart2, req->rlPart2);
14165       else
14166          different = strcmp(p->initreq.rlPart2, req->rlPart2);
14167       if (!different) {
14168          transmit_response(p, "482 Loop Detected", req);
14169          p->invitestate = INV_COMPLETED;
14170          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
14171          return 0;
14172       } else {
14173          /* This is a spiral. What we need to do is to just change the outgoing INVITE
14174           * so that it now routes to the new Request URI. Since we created the INVITE ourselves
14175           * that should be all we need to do.
14176           */
14177          char *uri = ast_strdupa(req->rlPart2);
14178          char *at = strchr(uri, '@');
14179          char *peerorhost;
14180          struct sip_pkt *pkt = NULL;
14181          if (option_debug > 2) {
14182             ast_log(LOG_DEBUG, "Potential spiral detected. Original RURI was %s, new RURI is %s\n", p->initreq.rlPart2, req->rlPart2);
14183          }
14184          if (at) {
14185             *at = '\0';
14186          }
14187          /* Parse out "sip:" */
14188          if ((peerorhost = strchr(uri, ':'))) {
14189             *peerorhost++ = '\0';
14190          }
14191          create_addr(p, peerorhost);
14192          ast_string_field_free(p, theirtag);
14193          for (pkt = p->packets; pkt; pkt = pkt->next) {
14194             if (pkt->seqno == p->icseq && pkt->method == SIP_INVITE) {
14195                AST_SCHED_DEL(sched, pkt->retransid);
14196             }
14197          }
14198          return transmit_invite(p, SIP_INVITE, 1, 3);
14199       }
14200    }
14201    
14202    if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->pendinginvite) {
14203       /* We already have a pending invite. Sorry. You are on hold. */
14204       transmit_response(p, "491 Request Pending", req);
14205       if (option_debug)
14206          ast_log(LOG_DEBUG, "Got INVITE on call where we already have pending INVITE, deferring that - %s\n", p->callid);
14207       /* Don't destroy dialog here */
14208       return 0;
14209    }
14210 
14211    p_replaces = get_header(req, "Replaces");
14212    if (!ast_strlen_zero(p_replaces)) {
14213       /* We have a replaces header */
14214       char *ptr;
14215       char *fromtag = NULL;
14216       char *totag = NULL;
14217       char *start, *to;
14218       int error = 0;
14219 
14220       if (p->owner) {
14221          if (option_debug > 2)
14222             ast_log(LOG_DEBUG, "INVITE w Replaces on existing call? Refusing action. [%s]\n", p->callid);
14223          transmit_response(p, "400 Bad request", req);   /* The best way to not not accept the transfer */
14224          /* Do not destroy existing call */
14225          return -1;
14226       }
14227 
14228       if (sipdebug && option_debug > 2)
14229          ast_log(LOG_DEBUG, "INVITE part of call transfer. Replaces [%s]\n", p_replaces);
14230       /* Create a buffer we can manipulate */
14231       replace_id = ast_strdupa(p_replaces);
14232       ast_uri_decode(replace_id);
14233 
14234       if (!p->refer && !sip_refer_allocate(p)) {
14235          transmit_response(p, "500 Server Internal Error", req);
14236          append_history(p, "Xfer", "INVITE/Replace Failed. Out of memory.");
14237          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
14238          p->invitestate = INV_COMPLETED;
14239          return -1;
14240       }
14241 
14242       /*  Todo: (When we find phones that support this)
14243          if the replaces header contains ";early-only"
14244          we can only replace the call in early
14245          stage, not after it's up.
14246 
14247          If it's not in early mode, 486 Busy.
14248       */
14249       
14250       /* Skip leading whitespace */
14251       replace_id = ast_skip_blanks(replace_id);
14252 
14253       start = replace_id;
14254       while ( (ptr = strsep(&start, ";")) ) {
14255          ptr = ast_skip_blanks(ptr); /* XXX maybe unnecessary ? */
14256          if ( (to = strcasestr(ptr, "to-tag=") ) )
14257             totag = to + 7;   /* skip the keyword */
14258          else if ( (to = strcasestr(ptr, "from-tag=") ) ) {
14259             fromtag = to + 9; /* skip the keyword */
14260             fromtag = strsep(&fromtag, "&"); /* trim what ? */
14261          }
14262       }
14263 
14264       if (sipdebug && option_debug > 3) 
14265          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>");
14266 
14267 
14268       /* Try to find call that we are replacing 
14269          If we have a Replaces  header, we need to cancel that call if we succeed with this call 
14270       */
14271       if ((p->refer->refer_call = get_sip_pvt_byid_locked(replace_id, totag, fromtag)) == NULL) {
14272          ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-existent call id (%s)!\n", replace_id);
14273          transmit_response(p, "481 Call Leg Does Not Exist (Replaces)", req);
14274          error = 1;
14275       }
14276 
14277       /* At this point, bot the pvt and the owner of the call to be replaced is locked */
14278 
14279       /* The matched call is the call from the transferer to Asterisk .
14280          We want to bridge the bridged part of the call to the 
14281          incoming invite, thus taking over the refered call */
14282 
14283       if (p->refer->refer_call == p) {
14284          ast_log(LOG_NOTICE, "INVITE with replaces into it's own call id (%s == %s)!\n", replace_id, p->callid);
14285          p->refer->refer_call = NULL;
14286          transmit_response(p, "400 Bad request", req);   /* The best way to not not accept the transfer */
14287          error = 1;
14288       }
14289 
14290       if (!error && !p->refer->refer_call->owner) {
14291          /* Oops, someting wrong anyway, no owner, no call */
14292          ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-existing call id (%s)!\n", replace_id);
14293          /* Check for better return code */
14294          transmit_response(p, "481 Call Leg Does Not Exist (Replace)", req);
14295          error = 1;
14296       }
14297 
14298       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 ) {
14299          ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-ringing or active call id (%s)!\n", replace_id);
14300          transmit_response(p, "603 Declined (Replaces)", req);
14301          error = 1;
14302       }
14303 
14304       if (error) {   /* Give up this dialog */
14305          append_history(p, "Xfer", "INVITE/Replace Failed.");
14306          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
14307          ast_mutex_unlock(&p->lock);
14308          if (p->refer->refer_call) {
14309             ast_mutex_unlock(&p->refer->refer_call->lock);
14310             ast_channel_unlock(p->refer->refer_call->owner);
14311          }
14312          p->invitestate = INV_COMPLETED;
14313          return -1;
14314       }
14315    }
14316 
14317 
14318    /* Check if this is an INVITE that sets up a new dialog or
14319       a re-invite in an existing dialog */
14320 
14321    if (!ast_test_flag(req, SIP_PKT_IGNORE)) {
14322       int newcall = (p->initreq.headers ? TRUE : FALSE);
14323 
14324       if (sip_cancel_destroy(p))
14325          ast_log(LOG_WARNING, "Unable to cancel SIP destruction.  Expect bad things.\n");
14326       /* This also counts as a pending invite */
14327       p->pendinginvite = seqno;
14328       check_via(p, req);
14329 
14330       copy_request(&p->initreq, req);     /* Save this INVITE as the transaction basis */
14331       if (!p->owner) {  /* Not a re-invite */
14332          if (debug)
14333             ast_verbose("Using INVITE request as basis request - %s\n", p->callid);
14334          if (newcall)
14335             append_history(p, "Invite", "New call: %s", p->callid);
14336          parse_ok_contact(p, req);
14337       } else { /* Re-invite on existing call */
14338          ast_clear_flag(&p->flags[0], SIP_OUTGOING);  /* This is now an inbound dialog */
14339          /* Handle SDP here if we already have an owner */
14340          if (find_sdp(req)) {
14341             if (process_sdp(p, req)) {
14342                transmit_response(p, "488 Not acceptable here", req);
14343                if (!p->lastinvite)
14344                   sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
14345                return -1;
14346             }
14347          } else {
14348             p->jointcapability = p->capability;
14349             if (option_debug > 2)
14350                ast_log(LOG_DEBUG, "Hm....  No sdp for the moment\n");
14351             /* Some devices signal they want to be put off hold by sending a re-invite
14352                *without* an SDP, which is supposed to mean "Go back to your state"
14353                and since they put os on remote hold, we go back to off hold */
14354             if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD))
14355                change_hold_state(p, req, FALSE, 0);
14356          }
14357          if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) /* This is a response, note what it was for */
14358             append_history(p, "ReInv", "Re-invite received");
14359       }
14360    } else if (debug)
14361       ast_verbose("Ignoring this INVITE request\n");
14362 
14363    
14364    if (!p->lastinvite && !ast_test_flag(req, SIP_PKT_IGNORE) && !p->owner) {
14365       /* This is a new invite */
14366       /* Handle authentication if this is our first invite */
14367       res = check_user(p, req, SIP_INVITE, e, XMIT_RELIABLE, sin);
14368       if (res == AUTH_CHALLENGE_SENT) {
14369          p->invitestate = INV_COMPLETED;     /* Needs to restart in another INVITE transaction */
14370          return 0;
14371       }
14372       if (res < 0) { /* Something failed in authentication */
14373          if (res == AUTH_FAKE_AUTH) {
14374             ast_log(LOG_NOTICE, "Sending fake auth rejection for user %s\n", get_header(req, "From"));
14375             transmit_fake_auth_response(p, SIP_INVITE, req, XMIT_RELIABLE);
14376          } else {
14377             ast_log(LOG_NOTICE, "Failed to authenticate user %s\n", get_header(req, "From"));
14378             transmit_response_reliable(p, "403 Forbidden", req);
14379          }
14380          p->invitestate = INV_COMPLETED;  
14381          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
14382          ast_string_field_free(p, theirtag);
14383          return 0;
14384       }
14385 
14386       /* We have a succesful authentication, process the SDP portion if there is one */
14387       if (find_sdp(req)) {
14388          if (process_sdp(p, req)) {
14389             /* Unacceptable codecs */
14390             transmit_response_reliable(p, "488 Not acceptable here", req);
14391             p->invitestate = INV_COMPLETED;  
14392             sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
14393             if (option_debug)
14394                ast_log(LOG_DEBUG, "No compatible codecs for this SIP call.\n");
14395             return -1;
14396          }
14397       } else { /* No SDP in invite, call control session */
14398          p->jointcapability = p->capability;
14399          if (option_debug > 1)
14400             ast_log(LOG_DEBUG, "No SDP in Invite, third party call control\n");
14401       }
14402 
14403       /* Queue NULL frame to prod ast_rtp_bridge if appropriate */
14404       /* This seems redundant ... see !p-owner above */
14405       if (p->owner)
14406          ast_queue_frame(p->owner, &ast_null_frame);
14407 
14408 
14409       /* Initialize the context if it hasn't been already */
14410       if (ast_strlen_zero(p->context))
14411          ast_string_field_set(p, context, default_context);
14412 
14413 
14414       /* Check number of concurrent calls -vs- incoming limit HERE */
14415       if (option_debug)
14416          ast_log(LOG_DEBUG, "Checking SIP call limits for device %s\n", p->username);
14417       if ((res = update_call_counter(p, INC_CALL_LIMIT))) {
14418          if (res < 0) {
14419             ast_log(LOG_NOTICE, "Failed to place call for user %s, too many calls\n", p->username);
14420             transmit_response_reliable(p, "480 Temporarily Unavailable (Call limit) ", req);
14421             sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
14422             p->invitestate = INV_COMPLETED;  
14423          }
14424          return 0;
14425       }
14426       gotdest = get_destination(p, NULL); /* Get destination right away */
14427       get_rdnis(p, NULL);        /* Get redirect information */
14428       extract_uri(p, req);       /* Get the Contact URI */
14429       build_contact(p);       /* Build our contact header */
14430 
14431       if (p->rtp) {
14432          ast_rtp_setdtmf(p->rtp, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833);
14433          ast_rtp_setdtmfcompensate(p->rtp, ast_test_flag(&p->flags[1], SIP_PAGE2_RFC2833_COMPENSATE));
14434       }
14435 
14436       if (!replace_id && gotdest) { /* No matching extension found */
14437          if (gotdest == 1 && ast_test_flag(&p->flags[1], SIP_PAGE2_ALLOWOVERLAP))
14438             transmit_response_reliable(p, "484 Address Incomplete", req);
14439          else {
14440             transmit_response_reliable(p, "404 Not Found", req);
14441             ast_log(LOG_NOTICE, "Call from '%s' to extension"
14442                " '%s' rejected because extension not found.\n",
14443                S_OR(p->username, p->peername), p->exten);
14444          }
14445          p->invitestate = INV_COMPLETED;  
14446          update_call_counter(p, DEC_CALL_LIMIT);
14447          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
14448          return 0;
14449       } else {
14450          /* If no extension was specified, use the s one */
14451          /* Basically for calling to IP/Host name only */
14452          if (ast_strlen_zero(p->exten))
14453             ast_string_field_set(p, exten, "s");
14454          /* Initialize our tag */   
14455 
14456          make_our_tag(p->tag, sizeof(p->tag));
14457          /* First invitation - create the channel */
14458          c = sip_new(p, AST_STATE_DOWN, S_OR(p->username, NULL));
14459          *recount = 1;
14460 
14461          /* Save Record-Route for any later requests we make on this dialogue */
14462          build_route(p, req, 0);
14463 
14464          if (c) {
14465             /* Pre-lock the call */
14466             ast_channel_lock(c);
14467          }
14468       }
14469    } else {
14470       if (option_debug > 1 && sipdebug) {
14471          if (!ast_test_flag(req, SIP_PKT_IGNORE))
14472             ast_log(LOG_DEBUG, "Got a SIP re-invite for call %s\n", p->callid);
14473          else
14474             ast_log(LOG_DEBUG, "Got a SIP re-transmit of INVITE for call %s\n", p->callid);
14475       }
14476       reinvite = 1;
14477       c = p->owner;
14478    }
14479 
14480    if (!ast_test_flag(req, SIP_PKT_IGNORE) && p)
14481       p->lastinvite = seqno;
14482 
14483    if (replace_id) {    /* Attended transfer or call pickup - we're the target */
14484       /* Go and take over the target call */
14485       if (sipdebug && option_debug > 3)
14486          ast_log(LOG_DEBUG, "Sending this call to the invite/replcaes handler %s\n", p->callid);
14487       return handle_invite_replaces(p, req, debug, ast_test_flag(req, SIP_PKT_IGNORE), seqno, sin);
14488    }
14489 
14490 
14491    if (c) { /* We have a call  -either a new call or an old one (RE-INVITE) */
14492       switch(c->_state) {
14493       case AST_STATE_DOWN:
14494          if (option_debug > 1)
14495             ast_log(LOG_DEBUG, "%s: New call is still down.... Trying... \n", c->name);
14496          transmit_response(p, "100 Trying", req);
14497          p->invitestate = INV_PROCEEDING;
14498          ast_setstate(c, AST_STATE_RING);
14499          if (strcmp(p->exten, ast_pickup_ext())) { /* Call to extension -start pbx on this call */
14500             enum ast_pbx_result res;
14501 
14502             res = ast_pbx_start(c);
14503 
14504             switch(res) {
14505             case AST_PBX_FAILED:
14506                ast_log(LOG_WARNING, "Failed to start PBX :(\n");
14507                p->invitestate = INV_COMPLETED;
14508                if (ast_test_flag(req, SIP_PKT_IGNORE))
14509                   transmit_response(p, "503 Unavailable", req);
14510                else
14511                   transmit_response_reliable(p, "503 Unavailable", req);
14512                break;
14513             case AST_PBX_CALL_LIMIT:
14514                ast_log(LOG_WARNING, "Failed to start PBX (call limit reached) \n");
14515                p->invitestate = INV_COMPLETED;
14516                if (ast_test_flag(req, SIP_PKT_IGNORE))
14517                   transmit_response(p, "480 Temporarily Unavailable", req);
14518                else
14519                   transmit_response_reliable(p, "480 Temporarily Unavailable", req);
14520                break;
14521             case AST_PBX_SUCCESS:
14522                /* nothing to do */
14523                break;
14524             }
14525 
14526             if (res) {
14527 
14528                /* Unlock locks so ast_hangup can do its magic */
14529                ast_mutex_unlock(&c->lock);
14530                ast_mutex_unlock(&p->lock);
14531                ast_hangup(c);
14532                ast_mutex_lock(&p->lock);
14533                c = NULL;
14534             }
14535          } else { /* Pickup call in call group */
14536             ast_channel_unlock(c);
14537             *nounlock = 1;
14538             if (ast_pickup_call(c)) {
14539                ast_log(LOG_NOTICE, "Nothing to pick up for %s\n", p->callid);
14540                if (ast_test_flag(req, SIP_PKT_IGNORE))
14541                   transmit_response(p, "503 Unavailable", req);   /* OEJ - Right answer? */
14542                else
14543                   transmit_response_reliable(p, "503 Unavailable", req);
14544                sip_alreadygone(p);
14545                /* Unlock locks so ast_hangup can do its magic */
14546                ast_mutex_unlock(&p->lock);
14547                c->hangupcause = AST_CAUSE_CALL_REJECTED;
14548             } else {
14549                ast_mutex_unlock(&p->lock);
14550                ast_setstate(c, AST_STATE_DOWN);
14551                c->hangupcause = AST_CAUSE_NORMAL_CLEARING;
14552             }
14553             p->invitestate = INV_COMPLETED;
14554             ast_hangup(c);
14555             ast_mutex_lock(&p->lock);
14556             c = NULL;
14557          }
14558          break;
14559       case AST_STATE_RING:
14560          transmit_response(p, "100 Trying", req);
14561          p->invitestate = INV_PROCEEDING;
14562          break;
14563       case AST_STATE_RINGING:
14564          transmit_response(p, "180 Ringing", req);
14565          p->invitestate = INV_PROCEEDING;
14566          break;
14567       case AST_STATE_UP:
14568          if (option_debug > 1)
14569             ast_log(LOG_DEBUG, "%s: This call is UP.... \n", c->name);
14570 
14571          transmit_response(p, "100 Trying", req);
14572 
14573          if (p->t38.state == T38_PEER_REINVITE) {
14574             struct ast_channel *bridgepeer = NULL;
14575             struct sip_pvt *bridgepvt = NULL;
14576             
14577             if ((bridgepeer = ast_bridged_channel(p->owner))) {
14578                /* 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*/
14579                /*! XXX: we should also check here does the other side supports t38 at all !!! XXX */
14580                if (bridgepeer->tech == &sip_tech || bridgepeer->tech == &sip_tech_info) {
14581                   bridgepvt = (struct sip_pvt*)bridgepeer->tech_pvt;
14582                   if (bridgepvt->t38.state == T38_DISABLED) {
14583                      if (bridgepvt->udptl) { /* If everything is OK with other side's udptl struct */
14584                         /* Send re-invite to the bridged channel */
14585                         sip_handle_t38_reinvite(bridgepeer, p, 1);
14586                      } else { /* Something is wrong with peers udptl struct */
14587                         ast_log(LOG_WARNING, "Strange... The other side of the bridge don't have udptl struct\n");
14588                         ast_mutex_lock(&bridgepvt->lock);
14589                         bridgepvt->t38.state = T38_DISABLED;
14590                         ast_mutex_unlock(&bridgepvt->lock);
14591                         if (option_debug > 1)
14592                            ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", bridgepvt->t38.state, bridgepeer->name);
14593                         if (ast_test_flag(req, SIP_PKT_IGNORE))
14594                            transmit_response(p, "488 Not acceptable here", req);
14595                         else
14596                            transmit_response_reliable(p, "488 Not acceptable here", req);
14597                      
14598                      }
14599                   } else {
14600                      /* The other side is already setup for T.38 most likely so we need to acknowledge this too */
14601                      transmit_response_with_t38_sdp(p, "200 OK", req, XMIT_CRITICAL);
14602                      p->t38.state = T38_ENABLED;
14603                      if (option_debug)
14604                         ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>");
14605                   }
14606                } else {
14607                   /* Other side is not a SIP channel */
14608                   if (ast_test_flag(req, SIP_PKT_IGNORE))
14609                      transmit_response(p, "488 Not acceptable here", req);
14610                   else
14611                      transmit_response_reliable(p, "488 Not acceptable here", req);
14612                   p->t38.state = T38_DISABLED;
14613                   if (option_debug > 1)
14614                      ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>");
14615 
14616                   if (!p->lastinvite) /* Only destroy if this is *not* a re-invite */
14617                      sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
14618                }
14619             } else {
14620                /* we are not bridged in a call */
14621                transmit_response_with_t38_sdp(p, "200 OK", req, XMIT_CRITICAL);
14622                p->t38.state = T38_ENABLED;
14623                if (option_debug)
14624                   ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>");
14625             }
14626          } else if (p->t38.state == T38_DISABLED) { /* Channel doesn't have T38 offered or enabled */
14627             int sendok = TRUE;
14628 
14629             /* If we are bridged to a channel that has T38 enabled than this is a case of RTP re-invite after T38 session */
14630             /* so handle it here (re-invite other party to RTP) */
14631             struct ast_channel *bridgepeer = NULL;
14632             struct sip_pvt *bridgepvt = NULL;
14633             if ((bridgepeer = ast_bridged_channel(p->owner))) {
14634                if ((bridgepeer->tech == &sip_tech || bridgepeer->tech == &sip_tech_info) && !ast_check_hangup(bridgepeer)) {
14635                   bridgepvt = (struct sip_pvt*)bridgepeer->tech_pvt;
14636                   /* Does the bridged peer have T38 ? */
14637                   if (bridgepvt->t38.state == T38_ENABLED) {
14638                      ast_log(LOG_WARNING, "RTP re-invite after T38 session not handled yet !\n");
14639                      /* Insted of this we should somehow re-invite the other side of the bridge to RTP */
14640                      if (ast_test_flag(req, SIP_PKT_IGNORE))
14641                         transmit_response(p, "488 Not Acceptable Here (unsupported)", req);
14642                      else
14643                         transmit_response_reliable(p, "488 Not Acceptable Here (unsupported)", req);
14644                      sendok = FALSE;
14645                   } 
14646                   /* No bridged peer with T38 enabled*/
14647                }
14648             } 
14649             /* Respond to normal re-invite */
14650             if (sendok)
14651                /* If this is not a re-invite or something to ignore - it's critical */
14652                transmit_response_with_sdp(p, "200 OK", req, (reinvite ? XMIT_RELIABLE : (ast_test_flag(req, SIP_PKT_IGNORE) ? XMIT_UNRELIABLE : XMIT_CRITICAL)));
14653          }
14654          p->invitestate = INV_TERMINATED;
14655          break;
14656       default:
14657          ast_log(LOG_WARNING, "Don't know how to handle INVITE in state %d\n", c->_state);
14658          transmit_response(p, "100 Trying", req);
14659          break;
14660       }
14661    } else {
14662       if (p && (p->autokillid == -1)) {
14663          const char *msg;
14664 
14665          if (!p->jointcapability)
14666             msg = "488 Not Acceptable Here (codec error)";
14667          else {
14668             ast_log(LOG_NOTICE, "Unable to create/find SIP channel for this INVITE\n");
14669             msg = "503 Unavailable";
14670          }
14671          if (ast_test_flag(req, SIP_PKT_IGNORE))
14672             transmit_response(p, msg, req);
14673          else
14674             transmit_response_reliable(p, msg, req);
14675          p->invitestate = INV_COMPLETED;
14676          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
14677       }
14678    }
14679    return res;
14680 }

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

Handle incoming MESSAGE request.

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

15300 {
15301    if (!ast_test_flag(req, SIP_PKT_IGNORE)) {
15302       if (ast_test_flag(req, SIP_PKT_DEBUG))
15303          ast_verbose("Receiving message!\n");
15304       receive_message(p, req);
15305    } else
15306       transmit_response(p, "202 Accepted", req);
15307    return 1;
15308 }

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

13514 {
13515    /* This is mostly a skeleton for future improvements */
13516    /* Mostly created to return proper answers on notifications on outbound REFER's */
13517    int res = 0;
13518    const char *event = get_header(req, "Event");
13519    char *eventid = NULL;
13520    char *sep;
13521 
13522    if( (sep = strchr(event, ';')) ) {  /* XXX bug here - overwriting string ? */
13523       *sep++ = '\0';
13524       eventid = sep;
13525    }
13526    
13527    if (option_debug > 1 && sipdebug)
13528       ast_log(LOG_DEBUG, "Got NOTIFY Event: %s\n", event);
13529 
13530    if (strcmp(event, "refer")) {
13531       /* We don't understand this event. */
13532       /* Here's room to implement incoming voicemail notifications :-) */
13533       transmit_response(p, "489 Bad event", req);
13534       res = -1;
13535    } else {
13536       /* Save nesting depth for now, since there might be other events we will
13537          support in the future */
13538 
13539       /* Handle REFER notifications */
13540 
13541       char buf[1024];
13542       char *cmd, *code;
13543       int respcode;
13544       int success = TRUE;
13545 
13546       /* EventID for each transfer... EventID is basically the REFER cseq 
13547 
13548        We are getting notifications on a call that we transfered
13549        We should hangup when we are getting a 200 OK in a sipfrag
13550        Check if we have an owner of this event */
13551       
13552       /* Check the content type */
13553       if (strncasecmp(get_header(req, "Content-Type"), "message/sipfrag", strlen("message/sipfrag"))) {
13554          /* We need a sipfrag */
13555          transmit_response(p, "400 Bad request", req);
13556          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
13557          return -1;
13558       }
13559 
13560       /* Get the text of the attachment */
13561       if (get_msg_text(buf, sizeof(buf), req)) {
13562          ast_log(LOG_WARNING, "Unable to retrieve attachment from NOTIFY %s\n", p->callid);
13563          transmit_response(p, "400 Bad request", req);
13564          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
13565          return -1;
13566       }
13567 
13568       /*
13569       From the RFC...
13570       A minimal, but complete, implementation can respond with a single
13571          NOTIFY containing either the body:
13572                SIP/2.0 100 Trying
13573       
13574          if the subscription is pending, the body:
13575                SIP/2.0 200 OK
13576          if the reference was successful, the body:
13577                SIP/2.0 503 Service Unavailable
13578          if the reference failed, or the body:
13579                SIP/2.0 603 Declined
13580 
13581          if the REFER request was accepted before approval to follow the
13582          reference could be obtained and that approval was subsequently denied
13583          (see Section 2.4.7).
13584       
13585       If there are several REFERs in the same dialog, we need to
13586       match the ID of the event header...
13587       */
13588       if (option_debug > 2)
13589          ast_log(LOG_DEBUG, "* SIP Transfer NOTIFY Attachment: \n---%s\n---\n", buf);
13590       cmd = ast_skip_blanks(buf);
13591       code = cmd;
13592       /* We are at SIP/2.0 */
13593       while(*code && (*code > 32)) {   /* Search white space */
13594          code++;
13595       }
13596       *code++ = '\0';
13597       code = ast_skip_blanks(code);
13598       sep = code;
13599       sep++;
13600       while(*sep && (*sep > 32)) {  /* Search white space */
13601          sep++;
13602       }
13603       *sep++ = '\0';       /* Response string */
13604       respcode = atoi(code);
13605       switch (respcode) {
13606       case 100:   /* Trying: */
13607       case 101:   /* dialog establishment */
13608          /* Don't do anything yet */
13609          break;
13610       case 183:   /* Ringing: */
13611          /* Don't do anything yet */
13612          break;
13613       case 200:   /* OK: The new call is up, hangup this call */
13614          /* Hangup the call that we are replacing */
13615          break;
13616       case 301: /* Moved permenantly */
13617       case 302: /* Moved temporarily */
13618          /* Do we get the header in the packet in this case? */
13619          success = FALSE;
13620          break;
13621       case 503:   /* Service Unavailable: The new call failed */
13622             /* Cancel transfer, continue the call */
13623          success = FALSE;
13624          break;
13625       case 603:   /* Declined: Not accepted */
13626             /* Cancel transfer, continue the current call */
13627          success = FALSE;
13628          break;
13629       }
13630       if (!success) {
13631          ast_log(LOG_NOTICE, "Transfer failed. Sorry. Nothing further to do with this call\n");
13632       }
13633       
13634       /* Confirm that we received this packet */
13635       transmit_response(p, "200 OK", req);
13636    };
13637 
13638    if (!p->lastinvite)
13639       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
13640 
13641    return res;
13642 }

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

Handle incoming OPTIONS request.

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

13646 {
13647    int res;
13648 
13649    res = get_destination(p, req);
13650    build_contact(p);
13651 
13652    /* XXX Should we authenticate OPTIONS? XXX */
13653 
13654    if (ast_strlen_zero(p->context))
13655       ast_string_field_set(p, context, default_context);
13656 
13657    if (ast_shutting_down())
13658       transmit_response_with_allow(p, "503 Unavailable", req, 0);
13659    else if (res < 0)
13660       transmit_response_with_allow(p, "404 Not Found", req, 0);
13661    else 
13662       transmit_response_with_allow(p, "200 OK", req, 0);
13663 
13664    /* Destroy if this OPTIONS was the opening request, but not if
13665       it's in the middle of a normal call flow. */
13666    if (!p->lastinvite)
13667       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
13668 
13669    return res;
13670 }

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 14848 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(), SIPBUFSIZE, sipdebug, sip_refer::status, TRANSFER_CLOSED, transmit_notify_with_sipfrag(), transmit_response(), and TRUE.

Referenced by handle_request().

14849 {
14850    struct sip_dual current;   /* Chan1: Call between asterisk and transferer */
14851                /* Chan2: Call between asterisk and transferee */
14852 
14853    int res = 0;
14854 
14855    if (ast_test_flag(req, SIP_PKT_DEBUG))
14856       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");
14857 
14858    if (!p->owner) {
14859       /* This is a REFER outside of an existing SIP dialog */
14860       /* We can't handle that, so decline it */
14861       if (option_debug > 2)
14862          ast_log(LOG_DEBUG, "Call %s: Declined REFER, outside of dialog...\n", p->callid);
14863       transmit_response(p, "603 Declined (No dialog)", req);
14864       if (!ast_test_flag(req, SIP_PKT_IGNORE)) {
14865          append_history(p, "Xfer", "Refer failed. Outside of dialog.");
14866          sip_alreadygone(p);
14867          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
14868       }
14869       return 0;
14870    }  
14871 
14872 
14873    /* Check if transfer is allowed from this device */
14874    if (p->allowtransfer == TRANSFER_CLOSED ) {
14875       /* Transfer not allowed, decline */
14876       transmit_response(p, "603 Declined (policy)", req);
14877       append_history(p, "Xfer", "Refer failed. Allowtransfer == closed.");
14878       /* Do not destroy SIP session */
14879       return 0;
14880    }
14881 
14882    if(!ignore && ast_test_flag(&p->flags[0], SIP_GOTREFER)) {
14883       /* Already have a pending REFER */  
14884       transmit_response(p, "491 Request pending", req);
14885       append_history(p, "Xfer", "Refer failed. Request pending.");
14886       return 0;
14887    }
14888 
14889    /* Allocate memory for call transfer data */
14890    if (!p->refer && !sip_refer_allocate(p)) {
14891       transmit_response(p, "500 Internal Server Error", req);
14892       append_history(p, "Xfer", "Refer failed. Memory allocation error.");
14893       return -3;
14894    }
14895 
14896    res = get_refer_info(p, req); /* Extract headers */
14897 
14898    p->refer->status = REFER_SENT;
14899 
14900    if (res != 0) {
14901       switch (res) {
14902       case -2: /* Syntax error */
14903          transmit_response(p, "400 Bad Request (Refer-to missing)", req);
14904          append_history(p, "Xfer", "Refer failed. Refer-to missing.");
14905          if (ast_test_flag(req, SIP_PKT_DEBUG) && option_debug)
14906             ast_log(LOG_DEBUG, "SIP transfer to black hole can't be handled (no refer-to: )\n");
14907          break;
14908       case -3:
14909          transmit_response(p, "603 Declined (Non sip: uri)", req);
14910          append_history(p, "Xfer", "Refer failed. Non SIP uri");
14911          if (ast_test_flag(req, SIP_PKT_DEBUG) && option_debug)
14912             ast_log(LOG_DEBUG, "SIP transfer to non-SIP uri denied\n");
14913          break;
14914       default:
14915          /* Refer-to extension not found, fake a failed transfer */
14916          transmit_response(p, "202 Accepted", req);
14917          append_history(p, "Xfer", "Refer failed. Bad extension.");
14918          transmit_notify_with_sipfrag(p, seqno, "404 Not found", TRUE);
14919          ast_clear_flag(&p->flags[0], SIP_GOTREFER);  
14920          if (ast_test_flag(req, SIP_PKT_DEBUG) && option_debug)
14921             ast_log(LOG_DEBUG, "SIP transfer to bad extension: %s\n", p->refer->refer_to);
14922          break;
14923       } 
14924       return 0;
14925    }
14926    if (ast_strlen_zero(p->context))
14927       ast_string_field_set(p, context, default_context);
14928 
14929    /* If we do not support SIP domains, all transfers are local */
14930    if (allow_external_domains && check_sip_domain(p->refer->refer_to_domain, NULL, 0)) {
14931       p->refer->localtransfer = 1;
14932       if (sipdebug && option_debug > 2)
14933          ast_log(LOG_DEBUG, "This SIP transfer is local : %s\n", p->refer->refer_to_domain);
14934    } else if (AST_LIST_EMPTY(&domain_list) || check_sip_domain(p->refer->refer_to_domain, NULL, 0)) {
14935       /* This PBX doesn't bother with SIP domains or domain is local, so this transfer is local */
14936       p->refer->localtransfer = 1;
14937    } else if (sipdebug && option_debug > 2)
14938          ast_log(LOG_DEBUG, "This SIP transfer is to a remote SIP extension (remote domain %s)\n", p->refer->refer_to_domain);
14939    
14940    /* Is this a repeat of a current request? Ignore it */
14941    /* Don't know what else to do right now. */
14942    if (ignore) 
14943       return res;
14944 
14945    /* If this is a blind transfer, we have the following
14946       channels to work with:
14947       - chan1, chan2: The current call between transferer and transferee (2 channels)
14948       - target_channel: A new call from the transferee to the target (1 channel)
14949       We need to stay tuned to what happens in order to be able
14950       to bring back the call to the transferer */
14951 
14952    /* If this is a attended transfer, we should have all call legs within reach:
14953       - chan1, chan2: The call between the transferer and transferee (2 channels)
14954       - target_channel, targetcall_pvt: The call between the transferer and the target (2 channels)
14955    We want to bridge chan2 with targetcall_pvt!
14956    
14957       The replaces call id in the refer message points
14958       to the call leg between Asterisk and the transferer.
14959       So we need to connect the target and the transferee channel
14960       and hangup the two other channels silently 
14961    
14962       If the target is non-local, the call ID could be on a remote
14963       machine and we need to send an INVITE with replaces to the
14964       target. We basically handle this as a blind transfer
14965       and let the sip_call function catch that we need replaces
14966       header in the INVITE.
14967    */
14968 
14969 
14970    /* Get the transferer's channel */
14971    current.chan1 = p->owner;
14972 
14973    /* Find the other part of the bridge (2) - transferee */
14974    current.chan2 = ast_bridged_channel(current.chan1);
14975    
14976    if (sipdebug && option_debug > 2)
14977       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>");
14978 
14979    if (!current.chan2 && !p->refer->attendedtransfer) {
14980       /* No bridged channel, propably IVR or echo or similar... */
14981       /* Guess we should masquerade or something here */
14982       /* Until we figure it out, refuse transfer of such calls */
14983       if (sipdebug && option_debug > 2)
14984          ast_log(LOG_DEBUG,"Refused SIP transfer on non-bridged channel.\n");
14985       p->refer->status = REFER_FAILED;
14986       append_history(p, "Xfer", "Refer failed. Non-bridged channel.");
14987       transmit_response(p, "603 Declined", req);
14988       return -1;
14989    }
14990 
14991    if (current.chan2) {
14992       if (sipdebug && option_debug > 3)
14993          ast_log(LOG_DEBUG, "Got SIP transfer, applying to bridged peer '%s'\n", current.chan2->name);
14994 
14995       ast_queue_control(current.chan1, AST_CONTROL_UNHOLD);
14996    }
14997 
14998    ast_set_flag(&p->flags[0], SIP_GOTREFER); 
14999 
15000    /* Attended transfer: Find all call legs and bridge transferee with target*/
15001    if (p->refer->attendedtransfer) {
15002       if ((res = local_attended_transfer(p, &current, req, seqno)))
15003          return res; /* We're done with the transfer */
15004       /* Fall through for remote transfers that we did not find locally */
15005       if (sipdebug && option_debug > 3)
15006          ast_log(LOG_DEBUG, "SIP attended transfer: Still not our call - generating INVITE with replaces\n");
15007       /* Fallthrough if we can't find the call leg internally */
15008    }
15009 
15010 
15011    /* Parking a call */
15012    if (p->refer->localtransfer && !strcmp(p->refer->refer_to, ast_parking_ext())) {
15013       /* Must release c's lock now, because it will not longer be accessible after the transfer! */
15014       *nounlock = 1;
15015       ast_channel_unlock(current.chan1);
15016       copy_request(&current.req, req);
15017       ast_clear_flag(&p->flags[0], SIP_GOTREFER);  
15018       p->refer->status = REFER_200OK;
15019       append_history(p, "Xfer", "REFER to call parking.");
15020       if (sipdebug && option_debug > 3)
15021          ast_log(LOG_DEBUG, "SIP transfer to parking: trying to park %s. Parked by %s\n", current.chan2->name, current.chan1->name);
15022       sip_park(current.chan2, current.chan1, req, seqno);
15023       return res;
15024    } 
15025 
15026    /* Blind transfers and remote attended xfers */
15027    transmit_response(p, "202 Accepted", req);
15028 
15029    if (current.chan1 && current.chan2) {
15030       if (option_debug > 2)
15031          ast_log(LOG_DEBUG, "chan1->name: %s\n", current.chan1->name);
15032       pbx_builtin_setvar_helper(current.chan1, "BLINDTRANSFER", current.chan2->name);
15033    }
15034    if (current.chan2) {
15035       pbx_builtin_setvar_helper(current.chan2, "BLINDTRANSFER", current.chan1->name);
15036       pbx_builtin_setvar_helper(current.chan2, "SIPDOMAIN", p->refer->refer_to_domain);
15037       pbx_builtin_setvar_helper(current.chan2, "SIPTRANSFER", "yes");
15038       /* One for the new channel */
15039       pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER", "yes");
15040       /* Attended transfer to remote host, prepare headers for the INVITE */
15041       if (p->refer->referred_by) 
15042          pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER_REFERER", p->refer->referred_by);
15043    }
15044    /* Generate a Replaces string to be used in the INVITE during attended transfer */
15045    if (p->refer->replaces_callid && !ast_strlen_zero(p->refer->replaces_callid)) {
15046       char tempheader[SIPBUFSIZE];
15047       snprintf(tempheader, sizeof(tempheader), "%s%s%s%s%s", p->refer->replaces_callid, 
15048             p->refer->replaces_callid_totag ? ";to-tag=" : "", 
15049             p->refer->replaces_callid_totag, 
15050             p->refer->replaces_callid_fromtag ? ";from-tag=" : "",
15051             p->refer->replaces_callid_fromtag);
15052       if (current.chan2)
15053          pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER_REPLACES", tempheader);
15054    }
15055    /* Must release lock now, because it will not longer
15056          be accessible after the transfer! */
15057    *nounlock = 1;
15058    ast_channel_unlock(current.chan1);
15059 
15060    /* Connect the call */
15061 
15062    /* FAKE ringing if not attended transfer */
15063    if (!p->refer->attendedtransfer)
15064       transmit_notify_with_sipfrag(p, seqno, "183 Ringing", FALSE); 
15065       
15066    /* For blind transfer, this will lead to a new call */
15067    /* For attended transfer to remote host, this will lead to
15068          a new SIP call with a replaces header, if the dial plan allows it 
15069    */
15070    if (!current.chan2) {
15071       /* We have no bridge, so we're talking with Asterisk somehow */
15072       /* We need to masquerade this call */
15073       /* What to do to fix this situation:
15074          * Set up the new call in a new channel 
15075          * Let the new channel masq into this channel
15076          Please add that code here :-)
15077       */
15078       p->refer->status = REFER_FAILED;
15079       transmit_notify_with_sipfrag(p, seqno, "503 Service Unavailable (can't handle one-legged xfers)", TRUE);
15080       ast_clear_flag(&p->flags[0], SIP_GOTREFER);  
15081       append_history(p, "Xfer", "Refer failed (only bridged calls).");
15082       return -1;
15083    }
15084    ast_set_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER);   /* Delay hangup */
15085 
15086    /* For blind transfers, move the call to the new extensions. For attended transfers on multiple
15087       servers - generate an INVITE with Replaces. Either way, let the dial plan decided  */
15088    res = ast_async_goto(current.chan2, p->refer->refer_to_context, p->refer->refer_to, 1);
15089 
15090    if (!res) {
15091       /* Success  - we have a new channel */
15092       if (option_debug > 2)
15093          ast_log(LOG_DEBUG, "%s transfer succeeded. Telling transferer.\n", p->refer->attendedtransfer? "Attended" : "Blind");
15094       transmit_notify_with_sipfrag(p, seqno, "200 Ok", TRUE);
15095       if (p->refer->localtransfer)
15096          p->refer->status = REFER_200OK;
15097       if (p->owner)
15098          p->owner->hangupcause = AST_CAUSE_NORMAL_CLEARING;
15099       append_history(p, "Xfer", "Refer succeeded.");
15100       ast_clear_flag(&p->flags[0], SIP_GOTREFER);  
15101       /* Do not hangup call, the other side do that when we say 200 OK */
15102       /* We could possibly implement a timer here, auto congestion */
15103       res = 0;
15104    } else {
15105       ast_clear_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Don't delay hangup */
15106       if (option_debug > 2)
15107          ast_log(LOG_DEBUG, "%s transfer failed. Resuming original call.\n", p->refer->attendedtransfer? "Attended" : "Blind");
15108       append_history(p, "Xfer", "Refer failed.");
15109       /* Failure of some kind */
15110       p->refer->status = REFER_FAILED;
15111       transmit_notify_with_sipfrag(p, seqno, "503 Service Unavailable", TRUE);
15112       ast_clear_flag(&p->flags[0], SIP_GOTREFER);  
15113       res = -1;
15114    }
15115    return res;
15116 }

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

15608 {
15609    enum check_auth_result res;
15610 
15611    /* Use this as the basis */
15612    if (ast_test_flag(req, SIP_PKT_DEBUG))
15613       ast_verbose("Using latest REGISTER request as basis request\n");
15614    copy_request(&p->initreq, req);
15615    check_via(p, req);
15616    if ((res = register_verify(p, sin, req, e)) < 0) {
15617       const char *reason;
15618 
15619       switch (res) {
15620       case AUTH_SECRET_FAILED:
15621          reason = "Wrong password";
15622          break;
15623       case AUTH_USERNAME_MISMATCH:
15624          reason = "Username/auth name mismatch";
15625          break;
15626       case AUTH_NOT_FOUND:
15627          reason = "No matching peer found";
15628          break;
15629       case AUTH_UNKNOWN_DOMAIN:
15630          reason = "Not a local domain";
15631          break;
15632       case AUTH_PEER_NOT_DYNAMIC:
15633          reason = "Peer is not supposed to register";
15634          break;
15635       case AUTH_ACL_FAILED:
15636          reason = "Device does not match ACL";
15637          break;
15638       default:
15639          reason = "Unknown failure";
15640          break;
15641       }
15642       ast_log(LOG_NOTICE, "Registration from '%s' failed for '%s' - %s\n",
15643          get_header(req, "To"), ast_inet_ntoa(sin->sin_addr),
15644          reason);
15645       append_history(p, "RegRequest", "Failed : Account %s : %s", get_header(req, "To"), reason);
15646    } else
15647       append_history(p, "RegRequest", "Succeeded : Account %s", get_header(req, "To"));
15648 
15649    if (res < 1) {
15650       /* Destroy the session, but keep us around for just a bit in case they don't
15651          get our 200 OK */
15652       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
15653    }
15654    return res;
15655 }

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 15311 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_REF, 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(), gettag(), 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(), XMIT_UNRELIABLE, and XPIDF_XML.

Referenced by handle_request().

15312 {
15313    int gotdest;
15314    int res = 0;
15315    int firststate = AST_EXTENSION_REMOVED;
15316    struct sip_peer *authpeer = NULL;
15317    const char *eventheader = get_header(req, "Event");   /* Get Event package name */
15318    const char *accept = get_header(req, "Accept");
15319    int resubscribe = (p->subscribed != NONE);
15320    char *temp, *event;
15321 
15322    if (p->initreq.headers) {  
15323       /* We already have a dialog */
15324       if (p->initreq.method != SIP_SUBSCRIBE) {
15325          /* This is a SUBSCRIBE within another SIP dialog, which we do not support */
15326          /* For transfers, this could happen, but since we haven't seen it happening, let us just refuse this */
15327          transmit_response(p, "403 Forbidden (within dialog)", req);
15328          /* Do not destroy session, since we will break the call if we do */
15329          if (option_debug)
15330             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);
15331          return 0;
15332       } else if (ast_test_flag(req, SIP_PKT_DEBUG)) {
15333          if (option_debug) {
15334             if (resubscribe)
15335                ast_log(LOG_DEBUG, "Got a re-subscribe on existing subscription %s\n", p->callid);
15336             else
15337                ast_log(LOG_DEBUG, "Got a new subscription %s (possibly with auth)\n", p->callid);
15338          }
15339       }
15340    }
15341 
15342    /* Check if we have a global disallow setting on subscriptions. 
15343       if so, we don't have to check peer/user settings after auth, which saves a lot of processing
15344    */
15345    if (!global_allowsubscribe) {
15346       transmit_response(p, "403 Forbidden (policy)", req);
15347       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
15348       return 0;
15349    }
15350 
15351    if (!ast_test_flag(req, SIP_PKT_IGNORE) && !resubscribe) {  /* Set up dialog, new subscription */
15352       const char *to = get_header(req, "To");
15353       char totag[128];
15354 
15355       /* Check to see if a tag was provided, if so this is actually a resubscription of a dialog we no longer know about */
15356       if (!ast_strlen_zero(to) && gettag(req, "To", totag, sizeof(totag))) {
15357          if (ast_test_flag(req, SIP_PKT_DEBUG))
15358             ast_verbose("Received resubscription for a dialog we no longer know about. Telling remote side to subscribe again.\n");
15359          transmit_response(p, "481 Subscription does not exist", req);
15360          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
15361          return 0;
15362       }
15363 
15364       /* Use this as the basis */
15365       if (ast_test_flag(req, SIP_PKT_DEBUG))
15366          ast_verbose("Creating new subscription\n");
15367 
15368       copy_request(&p->initreq, req);
15369       check_via(p, req);
15370    } else if (ast_test_flag(req, SIP_PKT_DEBUG) && ast_test_flag(req, SIP_PKT_IGNORE))
15371       ast_verbose("Ignoring this SUBSCRIBE request\n");
15372 
15373    /* Find parameters to Event: header value and remove them for now */
15374    if (ast_strlen_zero(eventheader)) {
15375       transmit_response(p, "489 Bad Event", req);
15376       if (option_debug > 1)
15377          ast_log(LOG_DEBUG, "Received SIP subscribe for unknown event package: <none>\n");
15378       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
15379       return 0;
15380    }
15381 
15382    if ( (strchr(eventheader, ';'))) {
15383       event = ast_strdupa(eventheader);   /* Since eventheader is a const, we can't change it */
15384       temp = strchr(event, ';');       
15385       *temp = '\0';           /* Remove any options for now */
15386                      /* We might need to use them later :-) */
15387    } else
15388       event = (char *) eventheader;    /* XXX is this legal ? */
15389 
15390    /* Handle authentication */
15391    res = check_user_full(p, req, SIP_SUBSCRIBE, e, 0, sin, &authpeer);
15392    /* if an authentication response was sent, we are done here */
15393    if (res == AUTH_CHALLENGE_SENT) {
15394       if (authpeer)
15395          ASTOBJ_UNREF(authpeer, sip_destroy_peer);
15396       return 0;
15397    }
15398    if (res < 0) {
15399       if (res == AUTH_FAKE_AUTH) {
15400          ast_log(LOG_NOTICE, "Sending fake auth rejection for user %s\n", get_header(req, "From"));
15401          transmit_fake_auth_response(p, SIP_SUBSCRIBE, req, XMIT_UNRELIABLE);
15402       } else {
15403          ast_log(LOG_NOTICE, "Failed to authenticate user %s for SUBSCRIBE\n", get_header(req, "From"));
15404          transmit_response_reliable(p, "403 Forbidden", req);
15405       }
15406       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
15407       if (authpeer)
15408          ASTOBJ_UNREF(authpeer, sip_destroy_peer);
15409       return 0;
15410    }
15411 
15412    /* Check if this user/peer is allowed to subscribe at all */
15413    if (!ast_test_flag(&p->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)) {
15414       transmit_response(p, "403 Forbidden (policy)", req);
15415       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
15416       if (authpeer)
15417          ASTOBJ_UNREF(authpeer, sip_destroy_peer);
15418       return 0;
15419    }
15420 
15421    /* Get destination right away */
15422    gotdest = get_destination(p, NULL);
15423 
15424    /* Get full contact header - this needs to be used as a request URI in NOTIFY's */
15425    parse_ok_contact(p, req);
15426 
15427    build_contact(p);
15428    if (strcmp(event, "message-summary") && gotdest) {
15429       transmit_response(p, "404 Not Found", req);
15430       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
15431       if (authpeer)
15432          ASTOBJ_UNREF(authpeer, sip_destroy_peer);
15433       return 0;
15434    }
15435 
15436    /* Initialize tag for new subscriptions */   
15437    if (ast_strlen_zero(p->tag))
15438       make_our_tag(p->tag, sizeof(p->tag));
15439 
15440    if (!strcmp(event, "presence") || !strcmp(event, "dialog")) { /* Presence, RFC 3842 */
15441       if (authpeer)  /* No need for authpeer here */
15442          ASTOBJ_UNREF(authpeer, sip_destroy_peer);
15443 
15444       /* Header from Xten Eye-beam Accept: multipart/related, application/rlmi+xml, application/pidf+xml, application/xpidf+xml */
15445       /* Polycom phones only handle xpidf+xml, even if they say they can
15446          handle pidf+xml as well
15447       */
15448       if (strstr(p->useragent, "Polycom")) {
15449          p->subscribed = XPIDF_XML;
15450       } else if (strstr(accept, "application/pidf+xml")) {
15451          p->subscribed = PIDF_XML;         /* RFC 3863 format */
15452       } else if (strstr(accept, "application/dialog-info+xml")) {
15453          p->subscribed = DIALOG_INFO_XML;
15454          /* IETF draft: draft-ietf-sipping-dialog-package-05.txt */
15455       } else if (strstr(accept, "application/cpim-pidf+xml")) {
15456          p->subscribed = CPIM_PIDF_XML;    /* RFC 3863 format */
15457       } else if (strstr(accept, "application/xpidf+xml")) {
15458          p->subscribed = XPIDF_XML;        /* Early pre-RFC 3863 format with MSN additions (Microsoft Messenger) */
15459       } else if (ast_strlen_zero(accept)) {
15460          if (p->subscribed == NONE) { /* if the subscribed field is not already set, and there is no accept header... */
15461             transmit_response(p, "489 Bad Event", req);
15462   
15463             ast_log(LOG_WARNING,"SUBSCRIBE failure: no Accept header: pvt: stateid: %d, laststate: %d, dialogver: %d, subscribecont: '%s', subscribeuri: '%s'\n",
15464                p->stateid, p->laststate, p->dialogver, p->subscribecontext, p->subscribeuri);
15465             ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
15466             return 0;
15467          }
15468          /* if p->subscribed is non-zero, then accept is not obligatory; according to rfc 3265 section 3.1.3, at least.
15469             so, we'll just let it ride, keeping the value from a previous subscription, and not abort the subscription */
15470       } else {
15471          /* Can't find a format for events that we know about */
15472          char mybuf[200];
15473          snprintf(mybuf,sizeof(mybuf),"489 Bad Event (format %s)", accept);
15474          transmit_response(p, mybuf, req);
15475  
15476          ast_log(LOG_WARNING,"SUBSCRIBE failure: unrecognized format: '%s' pvt: subscribed: %d, stateid: %d, laststate: %d, dialogver: %d, subscribecont: '%s', subscribeuri: '%s'\n",
15477             accept, (int)p->subscribed, p->stateid, p->laststate, p->dialogver, p->subscribecontext, p->subscribeuri);
15478          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
15479          return 0;
15480       }
15481    } else if (!strcmp(event, "message-summary")) { 
15482       if (!ast_strlen_zero(accept) && strcmp(accept, "application/simple-message-summary")) {
15483          /* Format requested that we do not support */
15484          transmit_response(p, "406 Not Acceptable", req);
15485          if (option_debug > 1)
15486             ast_log(LOG_DEBUG, "Received SIP mailbox subscription for unknown format: %s\n", accept);
15487          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
15488          if (authpeer)  /* No need for authpeer here */
15489             ASTOBJ_UNREF(authpeer, sip_destroy_peer);
15490          return 0;
15491       }
15492       /* Looks like they actually want a mailbox status 
15493         This version of Asterisk supports mailbox subscriptions
15494         The subscribed URI needs to exist in the dial plan
15495         In most devices, this is configurable to the voicemailmain extension you use
15496       */
15497       if (!authpeer || ast_strlen_zero(authpeer->mailbox)) {
15498          transmit_response(p, "404 Not found (no mailbox)", req);
15499          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
15500          ast_log(LOG_NOTICE, "Received SIP subscribe for peer without mailbox: %s\n", authpeer->name);
15501          if (authpeer)  /* No need for authpeer here */
15502             ASTOBJ_UNREF(authpeer, sip_destroy_peer);
15503          return 0;
15504       }
15505 
15506       p->subscribed = MWI_NOTIFICATION;
15507       if (authpeer->mwipvt && authpeer->mwipvt != p)  /* Destroy old PVT if this is a new one */
15508          /* We only allow one subscription per peer */
15509          sip_destroy(authpeer->mwipvt);
15510       authpeer->mwipvt = p;      /* Link from peer to pvt */
15511       p->relatedpeer = ASTOBJ_REF(authpeer); /* Link from pvt to peer */
15512    } else { /* At this point, Asterisk does not understand the specified event */
15513       transmit_response(p, "489 Bad Event", req);
15514       if (option_debug > 1)
15515          ast_log(LOG_DEBUG, "Received SIP subscribe for unknown event package: %s\n", event);
15516       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
15517       if (authpeer)  /* No need for authpeer here */
15518          ASTOBJ_UNREF(authpeer, sip_destroy_peer);
15519       return 0;
15520    }
15521 
15522    if (p->subscribed != MWI_NOTIFICATION && !resubscribe) {
15523       if (p->stateid > -1)
15524          ast_extension_state_del(p->stateid, cb_extensionstate);
15525       p->stateid = ast_extension_state_add(p->context, p->exten, cb_extensionstate, p);
15526    }
15527 
15528    if (!ast_test_flag(req, SIP_PKT_IGNORE) && p)
15529       p->lastinvite = seqno;
15530    if (p && !ast_test_flag(&p->flags[0], SIP_NEEDDESTROY)) {
15531       p->expiry = atoi(get_header(req, "Expires"));
15532 
15533       /* check if the requested expiry-time is within the approved limits from sip.conf */
15534       if (p->expiry > max_expiry)
15535          p->expiry = max_expiry;
15536       if (p->expiry < min_expiry && p->expiry > 0)
15537          p->expiry = min_expiry;
15538 
15539       if (sipdebug || option_debug > 1) {
15540          if (p->subscribed == MWI_NOTIFICATION && p->relatedpeer)
15541             ast_log(LOG_DEBUG, "Adding subscription for mailbox notification - peer %s Mailbox %s\n", p->relatedpeer->name, p->relatedpeer->mailbox);
15542          else
15543             ast_log(LOG_DEBUG, "Adding subscription for extension %s context %s for peer %s\n", p->exten, p->context, p->username);
15544       }
15545       if (p->autokillid > -1 && sip_cancel_destroy(p))   /* Remove subscription expiry for renewals */
15546          ast_log(LOG_WARNING, "Unable to cancel SIP destruction.  Expect bad things.\n");
15547       if (p->expiry > 0)
15548          sip_scheddestroy(p, (p->expiry + 10) * 1000);   /* Set timer for destruction of call at expiration */
15549 
15550       if (p->subscribed == MWI_NOTIFICATION) {
15551          transmit_response(p, "200 OK", req);
15552          if (p->relatedpeer) {   /* Send first notification */
15553             ASTOBJ_WRLOCK(p->relatedpeer);
15554             sip_send_mwi_to_peer(p->relatedpeer);
15555             ASTOBJ_UNLOCK(p->relatedpeer);
15556          }
15557       } else {
15558          struct sip_pvt *p_old;
15559 
15560          if ((firststate = ast_extension_state(NULL, p->context, p->exten)) < 0) {
15561 
15562             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));
15563             transmit_response(p, "404 Not found", req);
15564             ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
15565             return 0;
15566          }
15567 
15568          transmit_response(p, "200 OK", req);
15569          transmit_state_notify(p, firststate, 1, FALSE); /* Send first notification */
15570          append_history(p, "Subscribestatus", "%s", ast_extension_state2str(firststate));
15571          /* hide the 'complete' exten/context in the refer_to field for later display */
15572          ast_string_field_build(p, subscribeuri, "%s@%s", p->exten, p->context);
15573 
15574          /* remove any old subscription from this peer for the same exten/context,
15575          as the peer has obviously forgotten about it and it's wasteful to wait
15576          for it to expire and send NOTIFY messages to the peer only to have them
15577          ignored (or generate errors)
15578          */
15579          ast_mutex_lock(&iflock);
15580          for (p_old = iflist; p_old; p_old = p_old->next) {
15581             if (p_old == p)
15582                continue;
15583             if (p_old->initreq.method != SIP_SUBSCRIBE)
15584                continue;
15585             if (p_old->subscribed == NONE)
15586                continue;
15587             ast_mutex_lock(&p_old->lock);
15588             if (!strcmp(p_old->username, p->username)) {
15589                if (!strcmp(p_old->exten, p->exten) &&
15590                    !strcmp(p_old->context, p->context)) {
15591                   ast_set_flag(&p_old->flags[0], SIP_NEEDDESTROY);
15592                   ast_mutex_unlock(&p_old->lock);
15593                   break;
15594                }
15595             }
15596             ast_mutex_unlock(&p_old->lock);
15597          }
15598          ast_mutex_unlock(&iflock);
15599       }
15600       if (!p->expiry)
15601          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
15602    }
15603    return 1;
15604 }

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

References __sip_ack(), __sip_semi_ack(), ast_clear_flag, 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, cb_extensionstate(), 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, sip_pvt::laststate, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, MAX_AUTHTRIES, sip_pvt::method, NONE, option_debug, option_verbose, sip_pvt::owner, parse_moved_contact(), sip_pvt::pendinginvite, 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_PAGE2_STATECHANGEQUEUE, 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.

12799 {
12800    struct ast_channel *owner;
12801    int sipmethod;
12802    int res = 1;
12803    const char *c = get_header(req, "Cseq");
12804    const char *msg = strchr(c, ' ');
12805 
12806    if (!msg)
12807       msg = "";
12808    else
12809       msg++;
12810    sipmethod = find_sip_method(msg);
12811 
12812    owner = p->owner;
12813    if (owner) 
12814       owner->hangupcause = hangup_sip2cause(resp);
12815 
12816    /* Acknowledge whatever it is destined for */
12817    if ((resp >= 100) && (resp <= 199))
12818       __sip_semi_ack(p, seqno, 0, sipmethod);
12819    else
12820       __sip_ack(p, seqno, 0, sipmethod);
12821 
12822    /* If this is a NOTIFY for a subscription clear the flag that indicates that we have a NOTIFY pending */
12823    if (!p->owner && sipmethod == SIP_NOTIFY && p->pendinginvite) 
12824       p->pendinginvite = 0;
12825 
12826    /* Get their tag if we haven't already */
12827    if (ast_strlen_zero(p->theirtag) || (resp >= 200)) {
12828       char tag[128];
12829 
12830       gettag(req, "To", tag, sizeof(tag));
12831       ast_string_field_set(p, theirtag, tag);
12832    }
12833    if (p->relatedpeer && p->method == SIP_OPTIONS) {
12834       /* We don't really care what the response is, just that it replied back. 
12835          Well, as long as it's not a 100 response...  since we might
12836          need to hang around for something more "definitive" */
12837       if (resp != 100)
12838          handle_response_peerpoke(p, resp, req);
12839    } else if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
12840       switch(resp) {
12841       case 100:   /* 100 Trying */
12842       case 101:   /* 101 Dialog establishment */
12843          if (sipmethod == SIP_INVITE) 
12844             handle_response_invite(p, resp, rest, req, seqno);
12845          break;
12846       case 183:   /* 183 Session Progress */
12847          if (sipmethod == SIP_INVITE) 
12848             handle_response_invite(p, resp, rest, req, seqno);
12849          break;
12850       case 180:   /* 180 Ringing */
12851          if (sipmethod == SIP_INVITE) 
12852             handle_response_invite(p, resp, rest, req, seqno);
12853          break;
12854       case 182:       /* 182 Queued */
12855          if (sipmethod == SIP_INVITE)
12856             handle_response_invite(p, resp, rest, req, seqno);
12857          break;
12858       case 200:   /* 200 OK */
12859          p->authtries = 0; /* Reset authentication counter */
12860          if (sipmethod == SIP_MESSAGE || sipmethod == SIP_INFO) {
12861             /* We successfully transmitted a message 
12862                or a video update request in INFO */
12863             /* Nothing happens here - the message is inside a dialog */
12864          } else if (sipmethod == SIP_INVITE) {
12865             handle_response_invite(p, resp, rest, req, seqno);
12866          } else if (sipmethod == SIP_NOTIFY) {
12867             /* They got the notify, this is the end */
12868             if (p->owner) {
12869                if (!p->refer) {
12870                   ast_log(LOG_WARNING, "Notify answer on an owned channel? - %s\n", p->owner->name);
12871                   ast_queue_hangup(p->owner);
12872                } else if (option_debug > 3) 
12873                   ast_log(LOG_DEBUG, "Got OK on REFER Notify message\n");
12874             } else {
12875                if (p->subscribed == NONE) 
12876                   ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12877                if (ast_test_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE)) {
12878                   /* Ready to send the next state we have on queue */
12879                   ast_clear_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE);
12880                   cb_extensionstate((char *)p->context, (char *)p->exten, p->laststate, (void *) p, NULL, NULL);
12881                }
12882             }
12883          } else if (sipmethod == SIP_REGISTER) 
12884             res = handle_response_register(p, resp, rest, req, ignore, seqno);
12885          else if (sipmethod == SIP_BYE)      /* 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: /* Not www-authorized on SIP method */
12893          if (sipmethod == SIP_INVITE)
12894             handle_response_invite(p, resp, rest, req, seqno);
12895          else if (sipmethod == SIP_REFER)
12896             handle_response_refer(p, resp, rest, req, seqno);
12897          else if (p->registry && sipmethod == SIP_REGISTER)
12898             res = handle_response_register(p, resp, rest, req, ignore, seqno);
12899          else if (sipmethod == SIP_BYE) {
12900             if (ast_strlen_zero(p->authname)) {
12901                ast_log(LOG_WARNING, "Asked to authenticate %s, to %s:%d but we have no matching peer!\n",
12902                      msg, ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port));
12903                ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12904             } else if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, "WWW-Authenticate", "Authorization", sipmethod, 0)) {
12905                ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From"));
12906                ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12907                /* We fail to auth bye on our own call, but still needs to tear down the call. 
12908                   Life, they call it. */
12909             }
12910          } else {
12911             ast_log(LOG_WARNING, "Got authentication request (401) on unknown %s to '%s'\n", sip_methods[sipmethod].text, get_header(req, "To"));
12912             ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12913          }
12914          break;
12915       case 403: /* Forbidden - we failed authentication */
12916          if (sipmethod == SIP_INVITE)
12917             handle_response_invite(p, resp, rest, req, seqno);
12918          else if (p->registry && sipmethod == SIP_REGISTER) 
12919             res = handle_response_register(p, resp, rest, req, ignore, seqno);
12920          else {
12921             ast_log(LOG_WARNING, "Forbidden - maybe wrong password on authentication for %s\n", msg);
12922             ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12923          }
12924          break;
12925       case 404: /* Not found */
12926          if (p->registry && sipmethod == SIP_REGISTER)
12927             res = handle_response_register(p, resp, rest, req, ignore, seqno);
12928          else if (sipmethod == SIP_INVITE)
12929             handle_response_invite(p, resp, rest, req, seqno);
12930          else if (owner)
12931             ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
12932          break;
12933       case 407: /* Proxy auth required */
12934          if (sipmethod == SIP_INVITE)
12935             handle_response_invite(p, resp, rest, req, seqno);
12936          else if (sipmethod == SIP_REFER)
12937             handle_response_refer(p, resp, rest, req, seqno);
12938          else if (p->registry && sipmethod == SIP_REGISTER)
12939             res = handle_response_register(p, resp, rest, req, ignore, seqno);
12940          else if (sipmethod == SIP_BYE) {
12941             if (ast_strlen_zero(p->authname)) {
12942                ast_log(LOG_WARNING, "Asked to authenticate %s, to %s:%d but we have no matching peer!\n",
12943                      msg, ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port));
12944                ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12945             } else if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, "Proxy-Authenticate", "Proxy-Authorization", sipmethod, 0)) {
12946                ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From"));
12947                ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12948             }
12949          } else   /* We can't handle this, giving up in a bad way */
12950             ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12951 
12952          break;
12953       case 408: /* Request timeout - terminate dialog */
12954          if (sipmethod == SIP_INVITE)
12955             handle_response_invite(p, resp, rest, req, seqno);
12956          else if (sipmethod == SIP_REGISTER) 
12957             res = handle_response_register(p, resp, rest, req, ignore, seqno);
12958          else if (sipmethod == SIP_BYE) {
12959             ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12960             if (option_debug)
12961                ast_log(LOG_DEBUG, "Got timeout on bye. Thanks for the answer. Now, kill this call\n");
12962          } else {
12963             if (owner)
12964                ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
12965             ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12966          }
12967          break;
12968       case 481: /* Call leg does not exist */
12969          if (sipmethod == SIP_INVITE) {
12970             handle_response_invite(p, resp, rest, req, seqno);
12971          } else if (sipmethod == SIP_REFER) {
12972             handle_response_refer(p, resp, rest, req, seqno);
12973          } else if (sipmethod == SIP_BYE) {
12974             /* The other side has no transaction to bye,
12975             just assume it's all right then */
12976             ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid);
12977          } else if (sipmethod == SIP_CANCEL) {
12978             /* The other side has no transaction to cancel,
12979             just assume it's all right then */
12980             ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid);
12981          } else {
12982             ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid);
12983             /* Guessing that this is not an important request */
12984          }
12985          break;
12986       case 487:
12987          if (sipmethod == SIP_INVITE)
12988             handle_response_invite(p, resp, rest, req, seqno);
12989          break;
12990       case 488: /* Not acceptable here - codec error */
12991          if (sipmethod == SIP_INVITE)
12992             handle_response_invite(p, resp, rest, req, seqno);
12993          break;
12994       case 491: /* Pending */
12995          if (sipmethod == SIP_INVITE)
12996             handle_response_invite(p, resp, rest, req, seqno);
12997          else {
12998             if (option_debug)
12999                ast_log(LOG_DEBUG, "Got 491 on %s, unspported. Call ID %s\n", sip_methods[sipmethod].text, p->callid);
13000             ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
13001          }
13002          break;
13003       case 501: /* Not Implemented */
13004          if (sipmethod == SIP_INVITE)
13005             handle_response_invite(p, resp, rest, req, seqno);
13006          else if (sipmethod == SIP_REFER)
13007             handle_response_refer(p, resp, rest, req, seqno);
13008          else
13009             ast_log(LOG_WARNING, "Host '%s' does not implement '%s'\n", ast_inet_ntoa(p->sa.sin_addr), msg);
13010          break;
13011       case 603:   /* Declined transfer */
13012          if (sipmethod == SIP_REFER) {
13013             handle_response_refer(p, resp, rest, req, seqno);
13014             break;
13015          }
13016          /* Fallthrough */
13017       default:
13018          if ((resp >= 300) && (resp < 700)) {
13019             /* Fatal response */
13020             if ((option_verbose > 2) && (resp != 487))
13021                ast_verbose(VERBOSE_PREFIX_3 "Got SIP response %d \"%s\" back from %s\n", resp, rest, ast_inet_ntoa(p->sa.sin_addr));
13022    
13023             if (sipmethod == SIP_INVITE)
13024                stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */
13025 
13026             /* XXX Locking issues?? XXX */
13027             switch(resp) {
13028             case 300: /* Multiple Choices */
13029             case 301: /* Moved permenantly */
13030             case 302: /* Moved temporarily */
13031             case 305: /* Use Proxy */
13032                parse_moved_contact(p, req);
13033                /* Fall through */
13034             case 486: /* Busy here */
13035             case 600: /* Busy everywhere */
13036             case 603: /* Decline */
13037                if (p->owner)
13038                   ast_queue_control(p->owner, AST_CONTROL_BUSY);
13039                break;
13040             case 482: /*
13041                \note SIP is incapable of performing a hairpin call, which
13042                is yet another failure of not having a layer 2 (again, YAY
13043                 IETF for thinking ahead).  So we treat this as a call
13044                 forward and hope we end up at the right place... */
13045                if (option_debug)
13046                   ast_log(LOG_DEBUG, "Hairpin detected, setting up call forward for what it's worth\n");
13047                if (p->owner)
13048                   ast_string_field_build(p->owner, call_forward,
13049                                "Local/%s@%s", p->username, p->context);
13050                /* Fall through */
13051             case 480: /* Temporarily Unavailable */
13052             case 404: /* Not Found */
13053             case 410: /* Gone */
13054             case 400: /* Bad Request */
13055             case 500: /* Server error */
13056                if (sipmethod == SIP_REFER) {
13057                   handle_response_refer(p, resp, rest, req, seqno);
13058                   break;
13059                }
13060                /* Fall through */
13061             case 502: /* Bad gateway */
13062             case 503: /* Service Unavailable */
13063             case 504: /* Server Timeout */
13064                if (owner)
13065                   ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
13066                break;
13067             default:
13068                /* Send hangup */ 
13069                if (owner && sipmethod != SIP_MESSAGE && sipmethod != SIP_INFO && sipmethod != SIP_BYE)
13070                   ast_queue_hangup(p->owner);
13071                break;
13072             }
13073             /* ACK on invite */
13074             if (sipmethod == SIP_INVITE) 
13075                transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
13076             if (sipmethod != SIP_MESSAGE && sipmethod != SIP_INFO) 
13077                sip_alreadygone(p);
13078             if (!p->owner)
13079                ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
13080          } else if ((resp >= 100) && (resp < 200)) {
13081             if (sipmethod == SIP_INVITE) {
13082                if (!ast_test_flag(req, SIP_PKT_IGNORE) && sip_cancel_destroy(p))
13083                   ast_log(LOG_WARNING, "Unable to cancel SIP destruction.  Expect bad things.\n");
13084                if (find_sdp(req))
13085                   process_sdp(p, req);
13086                if (p->owner) {
13087                   /* Queue a progress frame */
13088                   ast_queue_control(p->owner, AST_CONTROL_PROGRESS);
13089                }
13090             }
13091          } else
13092             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));
13093       }
13094    } else { 
13095       /* Responses to OUTGOING SIP requests on INCOMING calls 
13096          get handled here. As well as out-of-call message responses */
13097       if (ast_test_flag(req, SIP_PKT_DEBUG))
13098          ast_verbose("SIP Response message for INCOMING dialog %s arrived\n", msg);
13099 
13100       if (sipmethod == SIP_INVITE && resp == 200) {
13101          /* Tags in early session is replaced by the tag in 200 OK, which is 
13102          the final reply to our INVITE */
13103          char tag[128];
13104 
13105          gettag(req, "To", tag, sizeof(tag));
13106          ast_string_field_set(p, theirtag, tag);
13107       }
13108 
13109       switch(resp) {
13110       case 200:
13111          if (sipmethod == SIP_INVITE) {
13112             handle_response_invite(p, resp, rest, req, seqno);
13113          } else if (sipmethod == SIP_CANCEL) {
13114             if (option_debug)
13115                ast_log(LOG_DEBUG, "Got 200 OK on CANCEL\n");
13116 
13117             /* Wait for 487, then destroy */
13118          } else if (sipmethod == SIP_NOTIFY) {
13119             /* They got the notify, this is the end */
13120             if (p->owner) {
13121                if (p->refer) {
13122                   if (option_debug)
13123                      ast_log(LOG_DEBUG, "Got 200 OK on NOTIFY for transfer\n");
13124                } else
13125                   ast_log(LOG_WARNING, "Notify answer on an owned channel?\n");
13126                /* ast_queue_hangup(p->owner); Disabled */
13127             } else {
13128                if (!p->subscribed && !p->refer)
13129                   ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
13130                if (ast_test_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE)) {
13131                   /* Ready to send the next state we have on queue */
13132                   ast_clear_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE);
13133                   cb_extensionstate((char *)p->context, (char *)p->exten, p->laststate, (void *) p, NULL, NULL);
13134                }
13135             }
13136          } else if (sipmethod == SIP_BYE)
13137             ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
13138          else if (sipmethod == SIP_MESSAGE || sipmethod == SIP_INFO)
13139             /* We successfully transmitted a message or
13140                a video update request in INFO */
13141             ;
13142          else if (sipmethod == SIP_BYE) 
13143             /* Ok, we're ready to go */
13144             ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
13145          break;
13146       case 202:   /* Transfer accepted */
13147          if (sipmethod == SIP_REFER) 
13148             handle_response_refer(p, resp, rest, req, seqno);
13149          break;
13150       case 401:   /* www-auth */
13151       case 407:
13152          if (sipmethod == SIP_REFER)
13153             handle_response_refer(p, resp, rest, req, seqno);
13154          else if (sipmethod == SIP_INVITE) 
13155             handle_response_invite(p, resp, rest, req, seqno);
13156          else if (sipmethod == SIP_BYE) {
13157             char *auth, *auth2;
13158 
13159             auth = (resp == 407 ? "Proxy-Authenticate" : "WWW-Authenticate");
13160             auth2 = (resp == 407 ? "Proxy-Authorization" : "Authorization");
13161             if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, auth, auth2, sipmethod, 0)) {
13162                ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From"));
13163                ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
13164             }
13165          }
13166          break;
13167       case 481:   /* Call leg does not exist */
13168          if (sipmethod == SIP_INVITE) {
13169             /* Re-invite failed */
13170             handle_response_invite(p, resp, rest, req, seqno);
13171          } else if (sipmethod == SIP_BYE) {
13172             ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
13173          } else if (sipdebug) {
13174             ast_log  (LOG_DEBUG, "Remote host can't match request %s to call '%s'. Giving up\n", sip_methods[sipmethod].text, p->callid);
13175          }
13176          break;
13177       case 501: /* Not Implemented */
13178          if (sipmethod == SIP_INVITE) 
13179             handle_response_invite(p, resp, rest, req, seqno);
13180          else if (sipmethod == SIP_REFER) 
13181             handle_response_refer(p, resp, rest, req, seqno);
13182          break;
13183       case 603:   /* Declined transfer */
13184          if (sipmethod == SIP_REFER) {
13185             handle_response_refer(p, resp, rest, req, seqno);
13186             break;
13187          }
13188          /* Fallthrough */
13189       default: /* Errors without handlers */
13190          if ((resp >= 100) && (resp < 200)) {
13191             if (sipmethod == SIP_INVITE) {   /* re-invite */
13192                if (!ast_test_flag(req, SIP_PKT_IGNORE) && sip_cancel_destroy(p))
13193                   ast_log(LOG_WARNING, "Unable to cancel SIP destruction.  Expect bad things.\n");
13194             }
13195          }
13196          if ((resp >= 300) && (resp < 700)) {
13197             if ((option_verbose > 2) && (resp != 487))
13198                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));
13199             switch(resp) {
13200             case 488: /* Not acceptable here - codec error */
13201             case 603: /* Decline */
13202             case 500: /* Server error */
13203             case 502: /* Bad gateway */
13204             case 503: /* Service Unavailable */
13205             case 504: /* Server timeout */
13206 
13207                /* re-invite failed */
13208                if (sipmethod == SIP_INVITE && sip_cancel_destroy(p))
13209                   ast_log(LOG_WARNING, "Unable to cancel SIP destruction.  Expect bad things.\n");
13210                break;
13211             }
13212          }
13213          break;
13214       }
13215    }
13216 }

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 12209 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_CANCELLED, 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().

12210 {
12211    int outgoing = ast_test_flag(&p->flags[0], SIP_OUTGOING);
12212    int res = 0;
12213    int xmitres = 0;
12214    int reinvite = (p->owner && p->owner->_state == AST_STATE_UP);
12215    struct ast_channel *bridgepeer = NULL;
12216    
12217    if (option_debug > 3) {
12218       if (reinvite)
12219          ast_log(LOG_DEBUG, "SIP response %d to RE-invite on %s call %s\n", resp, outgoing ? "outgoing" : "incoming", p->callid);
12220       else
12221          ast_log(LOG_DEBUG, "SIP response %d to standard invite\n", resp);
12222    }
12223 
12224    if (ast_test_flag(&p->flags[0], SIP_ALREADYGONE)) { /* This call is already gone */
12225       if (option_debug)
12226          ast_log(LOG_DEBUG, "Got response on call that is already terminated: %s (ignoring)\n", p->callid);
12227       return;
12228    }
12229 
12230    /* Acknowledge sequence number - This only happens on INVITE from SIP-call */
12231    /* Don't auto congest anymore since we've gotten something useful back */
12232    AST_SCHED_DEL(sched, p->initid);
12233 
12234    /* RFC3261 says we must treat every 1xx response (but not 100)
12235       that we don't recognize as if it was 183.
12236    */
12237    if (resp > 100 && resp < 200 && resp!=101 && resp != 180 && resp != 182 && resp != 183)
12238       resp = 183;
12239 
12240    /* Any response between 100 and 199 is PROCEEDING */
12241    if (resp >= 100 && resp < 200 && p->invitestate == INV_CALLING)
12242       p->invitestate = INV_PROCEEDING;
12243  
12244    /* Final response, not 200 ? */
12245    if (resp >= 300 && (p->invitestate == INV_CALLING || p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA ))
12246       p->invitestate = INV_COMPLETED;
12247       
12248 
12249    switch (resp) {
12250    case 100:   /* Trying */
12251    case 101:   /* Dialog establishment */
12252       if (!ast_test_flag(req, SIP_PKT_IGNORE) && (p->invitestate != INV_CANCELLED) && sip_cancel_destroy(p))
12253          ast_log(LOG_WARNING, "Unable to cancel SIP destruction.  Expect bad things.\n");
12254       check_pendings(p);
12255       break;
12256 
12257    case 180:   /* 180 Ringing */
12258    case 182:       /* 182 Queued */
12259       if (!ast_test_flag(req, SIP_PKT_IGNORE) && (p->invitestate != INV_CANCELLED) && sip_cancel_destroy(p))
12260          ast_log(LOG_WARNING, "Unable to cancel SIP destruction.  Expect bad things.\n");
12261       if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) {
12262          ast_queue_control(p->owner, AST_CONTROL_RINGING);
12263          if (p->owner->_state != AST_STATE_UP) {
12264             ast_setstate(p->owner, AST_STATE_RINGING);
12265          }
12266       }
12267       if (find_sdp(req)) {
12268          if (p->invitestate != INV_CANCELLED)
12269             p->invitestate = INV_EARLY_MEDIA;
12270          res = process_sdp(p, req);
12271          if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) {
12272             /* Queue a progress frame only if we have SDP in 180 or 182 */
12273             ast_queue_control(p->owner, AST_CONTROL_PROGRESS);
12274          }
12275       }
12276       check_pendings(p);
12277       break;
12278 
12279    case 183:   /* Session progress */
12280       if (!ast_test_flag(req, SIP_PKT_IGNORE) && (p->invitestate != INV_CANCELLED) && sip_cancel_destroy(p))
12281          ast_log(LOG_WARNING, "Unable to cancel SIP destruction.  Expect bad things.\n");
12282       /* Ignore 183 Session progress without SDP */
12283       if (find_sdp(req)) {
12284          if (p->invitestate != INV_CANCELLED)
12285             p->invitestate = INV_EARLY_MEDIA;
12286          res = process_sdp(p, req);
12287          if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) {
12288             /* Queue a progress frame */
12289             ast_queue_control(p->owner, AST_CONTROL_PROGRESS);
12290          }
12291       }
12292       check_pendings(p);
12293       break;
12294 
12295    case 200:   /* 200 OK on invite - someone's answering our call */
12296       if (!ast_test_flag(req, SIP_PKT_IGNORE) && (p->invitestate != INV_CANCELLED) && sip_cancel_destroy(p))
12297          ast_log(LOG_WARNING, "Unable to cancel SIP destruction.  Expect bad things.\n");
12298       p->authtries = 0;
12299       if (find_sdp(req)) {
12300          if ((res = process_sdp(p, req)) && !ast_test_flag(req, SIP_PKT_IGNORE))
12301             if (!reinvite)
12302                /* This 200 OK's SDP is not acceptable, so we need to ack, then hangup */
12303                /* For re-invites, we try to recover */
12304                ast_set_flag(&p->flags[0], SIP_PENDINGBYE);  
12305       }
12306 
12307       /* Parse contact header for continued conversation */
12308       /* When we get 200 OK, we know which device (and IP) to contact for this call */
12309       /* This is important when we have a SIP proxy between us and the phone */
12310       if (outgoing) {
12311          update_call_counter(p, DEC_CALL_RINGING);
12312          parse_ok_contact(p, req);
12313          if(set_address_from_contact(p)) {
12314             /* Bad contact - we don't know how to reach this device */
12315             /* We need to ACK, but then send a bye */
12316             /* OEJ: Possible issue that may need a check:
12317                If we have a proxy route between us and the device,
12318                should we care about resolving the contact
12319                or should we just send it?
12320             */
12321             if (!ast_test_flag(req, SIP_PKT_IGNORE))
12322                ast_set_flag(&p->flags[0], SIP_PENDINGBYE);  
12323          } 
12324 
12325          /* Save Record-Route for any later requests we make on this dialogue */
12326          if (!reinvite)
12327             build_route(p, req, 1);
12328       }
12329       
12330       if (p->owner && (p->owner->_state == AST_STATE_UP) && (bridgepeer = ast_bridged_channel(p->owner))) { /* if this is a re-invite */
12331          struct sip_pvt *bridgepvt = NULL;
12332 
12333          if (!bridgepeer->tech) {
12334             ast_log(LOG_WARNING, "Ooooh.. no tech!  That's REALLY bad\n");
12335             break;
12336          }
12337          if (bridgepeer->tech == &sip_tech || bridgepeer->tech == &sip_tech_info) {
12338             bridgepvt = (struct sip_pvt*)(bridgepeer->tech_pvt);
12339             if (bridgepvt->udptl) {
12340                if (p->t38.state == T38_PEER_REINVITE) {
12341                   sip_handle_t38_reinvite(bridgepeer, p, 0);
12342                   ast_rtp_set_rtptimers_onhold(p->rtp);
12343                   if (p->vrtp)
12344                      ast_rtp_set_rtptimers_onhold(p->vrtp); /* Turn off RTP timers while we send fax */
12345                } else if (p->t38.state == T38_DISABLED && bridgepeer && (bridgepvt->t38.state == T38_ENABLED)) {
12346                   ast_log(LOG_WARNING, "RTP re-invite after T38 session not handled yet !\n");
12347                   /* Insted of this we should somehow re-invite the other side of the bridge to RTP */
12348                   /* XXXX Should we really destroy this session here, without any response at all??? */
12349                   sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
12350                }
12351             } else {
12352                if (option_debug > 1)
12353                   ast_log(LOG_DEBUG, "Strange... The other side of the bridge does not have a udptl struct\n");
12354                ast_mutex_lock(&bridgepvt->lock);
12355                bridgepvt->t38.state = T38_DISABLED;
12356                ast_mutex_unlock(&bridgepvt->lock);
12357                if (option_debug)
12358                   ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", bridgepvt->t38.state, bridgepeer->tech->type);
12359                p->t38.state = T38_DISABLED;
12360                if (option_debug > 1)
12361                   ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>");
12362             }
12363          } else {
12364             /* Other side is not a SIP channel */
12365             if (option_debug > 1)
12366                ast_log(LOG_DEBUG, "Strange... The other side of the bridge is not a SIP channel\n");
12367             p->t38.state = T38_DISABLED;
12368             if (option_debug > 1)
12369                ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>");
12370          }
12371       }
12372       if ((p->t38.state == T38_LOCAL_REINVITE) || (p->t38.state == T38_LOCAL_DIRECT)) {
12373          /* If there was T38 reinvite and we are supposed to answer with 200 OK than this should set us to T38 negotiated mode */
12374          p->t38.state = T38_ENABLED;
12375          if (option_debug)
12376             ast_log(LOG_DEBUG, "T38 changed state to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>");
12377       }
12378 
12379       if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) {
12380          if (!reinvite) {
12381             ast_queue_control(p->owner, AST_CONTROL_ANSWER);
12382          } else { /* RE-invite */
12383             ast_queue_frame(p->owner, &ast_null_frame);
12384          }
12385       } else {
12386           /* It's possible we're getting an 200 OK after we've tried to disconnect
12387               by sending CANCEL */
12388          /* First send ACK, then send bye */
12389          if (!ast_test_flag(req, SIP_PKT_IGNORE))
12390             ast_set_flag(&p->flags[0], SIP_PENDINGBYE);  
12391       }
12392       /* If I understand this right, the branch is different for a non-200 ACK only */
12393       p->invitestate = INV_TERMINATED;
12394       xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, TRUE);
12395       check_pendings(p);
12396       break;
12397    case 407: /* Proxy authentication */
12398    case 401: /* Www auth */
12399       /* First we ACK */
12400       xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
12401       if (p->options)
12402          p->options->auth_type = (resp == 401 ? WWW_AUTH : PROXY_AUTH);
12403 
12404       /* Then we AUTH */
12405       ast_string_field_free(p, theirtag); /* forget their old tag, so we don't match tags when getting response */
12406       if (!ast_test_flag(req, SIP_PKT_IGNORE)) {
12407          char *authenticate = (resp == 401 ? "WWW-Authenticate" : "Proxy-Authenticate");
12408          char *authorization = (resp == 401 ? "Authorization" : "Proxy-Authorization");
12409          if (p->authtries < MAX_AUTHTRIES)
12410             p->invitestate = INV_CALLING;
12411          if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, authenticate, authorization, SIP_INVITE, 1)) {
12412             ast_log(LOG_NOTICE, "Failed to authenticate on INVITE to '%s'\n", get_header(&p->initreq, "From"));
12413             ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12414             sip_alreadygone(p);
12415             if (p->owner)
12416                ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
12417          }
12418       }
12419       break;
12420 
12421    case 403: /* Forbidden */
12422       /* First we ACK */
12423       xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
12424       ast_log(LOG_WARNING, "Received response: \"Forbidden\" from '%s'\n", get_header(&p->initreq, "From"));
12425       if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner)
12426          ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
12427       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12428       sip_alreadygone(p);
12429       break;
12430 
12431    case 404: /* Not found */
12432       xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
12433       if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE))
12434          ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
12435       sip_alreadygone(p);
12436       break;
12437 
12438    case 408: /* Request timeout */
12439    case 481: /* Call leg does not exist */
12440       /* Could be REFER caused INVITE with replaces */
12441       ast_log(LOG_WARNING, "Re-invite to non-existing call leg on other UA. SIP dialog '%s'. Giving up.\n", p->callid);
12442       xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
12443       if (p->owner)
12444          ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
12445       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
12446       break;
12447    case 487: /* Cancelled transaction */
12448       /* We have sent CANCEL on an outbound INVITE 
12449          This transaction is already scheduled to be killed by sip_hangup().
12450       */
12451       xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
12452       if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) {
12453          ast_queue_hangup(p->owner);
12454          append_history(p, "Hangup", "Got 487 on CANCEL request from us. Queued AST hangup request");
12455       } else if (!ast_test_flag(req, SIP_PKT_IGNORE)) {
12456          update_call_counter(p, DEC_CALL_LIMIT);
12457          append_history(p, "Hangup", "Got 487 on CANCEL request from us on call without owner. Killing this dialog.");
12458          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12459          sip_alreadygone(p);
12460       }
12461       break;
12462    case 488: /* Not acceptable here */
12463       xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
12464       if (reinvite && p->udptl) {
12465          /* If this is a T.38 call, we should go back to 
12466             audio. If this is an audio call - something went
12467             terribly wrong since we don't renegotiate codecs,
12468             only IP/port .
12469          */
12470          p->t38.state = T38_DISABLED;
12471          /* Try to reset RTP timers */
12472          ast_rtp_set_rtptimers_onhold(p->rtp);
12473          ast_log(LOG_ERROR, "Got error on T.38 re-invite. Bad configuration. Peer needs to have T.38 disabled.\n");
12474 
12475          /*! \bug Is there any way we can go back to the audio call on both
12476             sides here? 
12477          */
12478          /* While figuring that out, hangup the call */
12479          if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE))
12480             ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
12481          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12482       } else if (p->udptl && p->t38.state == T38_LOCAL_DIRECT) {
12483          /* We tried to send T.38 out in an initial INVITE and the remote side rejected it,
12484             right now we can't fall back to audio so totally abort.
12485          */
12486          p->t38.state = T38_DISABLED;
12487          /* Try to reset RTP timers */
12488          ast_rtp_set_rtptimers_onhold(p->rtp);
12489          ast_log(LOG_ERROR, "Got error on T.38 initial invite. Bailing out.\n");
12490 
12491          /* The dialog is now terminated */
12492          if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE))
12493             ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
12494          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
12495          sip_alreadygone(p);
12496       } else {
12497          /* We can't set up this call, so give up */
12498          if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE))
12499             ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
12500          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
12501          /* If there's no dialog to end, then mark p as already gone */
12502          if (!reinvite)
12503             sip_alreadygone(p);
12504       }
12505       break;
12506    case 491: /* Pending */
12507       /* we really should have to wait a while, then retransmit
12508        * We should support the retry-after at some point 
12509        * At this point, we treat this as a congestion if the call is not in UP state 
12510        */
12511       xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
12512       if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) {
12513          if (p->owner->_state != AST_STATE_UP) {
12514             ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
12515             ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12516          } else {
12517             /* This is a re-invite that failed.
12518              * Reset the flag after a while 
12519              */
12520             int wait = 3 + ast_random() % 5;
12521             p->waitid = ast_sched_add(sched, wait, sip_reinvite_retry, p); 
12522             if (option_debug > 2)
12523                ast_log(LOG_DEBUG, "Reinvite race. Waiting %d secs before retry\n", wait);
12524          }
12525       }
12526       break;
12527 
12528    case 501: /* Not implemented */
12529       xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
12530       if (p->owner)
12531          ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
12532       break;
12533    }
12534    if (xmitres == XMIT_ERROR)
12535       ast_log(LOG_WARNING, "Could not transmit message in dialog %s\n", p->callid);
12536 }

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

Handle qualification responses (OPTIONS).

Definition at line 12731 of file chan_sip.c.

References ast_device_state_changed(), ast_log(), ast_sched_add(), AST_SCHED_DEL, ast_set_flag, ASTOBJ_REF, ASTOBJ_UNREF, 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_destroy_peer(), SIP_NEEDDESTROY, and sip_poke_peer_s().

Referenced by handle_response().

12732 {
12733    struct sip_peer *peer = p->relatedpeer;
12734    int statechanged, is_reachable, was_reachable;
12735    int pingtime = ast_tvdiff_ms(ast_tvnow(), peer->ps);
12736 
12737    /*
12738     * Compute the response time to a ping (goes in peer->lastms.)
12739     * -1 means did not respond, 0 means unknown,
12740     * 1..maxms is a valid response, >maxms means late response.
12741     */
12742    if (pingtime < 1) /* zero = unknown, so round up to 1 */
12743       pingtime = 1;
12744 
12745    /* Now determine new state and whether it has changed.
12746     * Use some helper variables to simplify the writing
12747     * of the expressions.
12748     */
12749    was_reachable = peer->lastms > 0 && peer->lastms <= peer->maxms;
12750    is_reachable = pingtime <= peer->maxms;
12751    statechanged = peer->lastms == 0 /* yes, unknown before */
12752       || was_reachable != is_reachable;
12753 
12754    peer->lastms = pingtime;
12755    peer->call = NULL;
12756    if (statechanged) {
12757       const char *s = is_reachable ? "Reachable" : "Lagged";
12758 
12759       ast_log(LOG_NOTICE, "Peer '%s' is now %s. (%dms / %dms)\n",
12760          peer->name, s, pingtime, peer->maxms);
12761       ast_device_state_changed("SIP/%s", peer->name);
12762       manager_event(EVENT_FLAG_SYSTEM, "PeerStatus",
12763          "Peer: SIP/%s\r\nPeerStatus: %s\r\nTime: %d\r\n",
12764          peer->name, s, pingtime);
12765    }
12766 
12767    if (!AST_SCHED_DEL(sched, peer->pokeexpire)) {
12768       struct sip_peer *peer_ptr = peer;
12769       ASTOBJ_UNREF(peer_ptr, sip_destroy_peer);
12770    }
12771 
12772    ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12773 
12774    /* Try again eventually */
12775    peer->pokeexpire = ast_sched_add(sched,
12776       is_reachable ? DEFAULT_FREQ_OK : DEFAULT_FREQ_NOTOK,
12777       sip_poke_peer_s, ASTOBJ_REF(peer));
12778 
12779    if (peer->pokeexpire == -1) {
12780       ASTOBJ_UNREF(peer, sip_destroy_peer);
12781    }
12782 }

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

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

12542 {
12543    char *auth = "Proxy-Authenticate";
12544    char *auth2 = "Proxy-Authorization";
12545 
12546    /* If no refer structure exists, then do nothing */
12547    if (!p->refer)
12548       return;
12549 
12550    switch (resp) {
12551    case 202:   /* Transfer accepted */
12552       /* We need  to do something here */
12553       /* The transferee is now sending INVITE to target */
12554       p->refer->status = REFER_ACCEPTED;
12555       /* Now wait for next message */
12556       if (option_debug > 2)
12557          ast_log(LOG_DEBUG, "Got 202 accepted on transfer\n");
12558       /* We should hang along, waiting for NOTIFY's here */
12559       break;
12560 
12561    case 401:   /* Not www-authorized on SIP method */
12562    case 407:   /* Proxy auth */
12563       if (ast_strlen_zero(p->authname)) {
12564          ast_log(LOG_WARNING, "Asked to authenticate REFER to %s:%d but we have no matching peer or realm auth!\n",
12565             ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port));
12566          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
12567       }
12568       if (resp == 401) {
12569          auth = "WWW-Authenticate";
12570          auth2 = "Authorization";
12571       }
12572       if ((p->authtries > 1) || do_proxy_auth(p, req, auth, auth2, SIP_REFER, 0)) {
12573          ast_log(LOG_NOTICE, "Failed to authenticate on REFER to '%s'\n", get_header(&p->initreq, "From"));
12574          p->refer->status = REFER_NOAUTH;
12575          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
12576       }
12577       break;
12578    case 481: /* Call leg does not exist */
12579 
12580       /* A transfer with Replaces did not work */
12581       /* OEJ: We should Set flag, cancel the REFER, go back
12582       to original call - but right now we can't */
12583       ast_log(LOG_WARNING, "Remote host can't match REFER request to call '%s'. Giving up.\n", p->callid);
12584       if (p->owner)
12585          ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
12586       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
12587       break;
12588 
12589    case 500:   /* Server error */
12590    case 501:   /* Method not implemented */
12591       /* Return to the current call onhold */
12592       /* Status flag needed to be reset */
12593       ast_log(LOG_NOTICE, "SIP transfer to %s failed, call miserably fails. \n", p->refer->refer_to);
12594       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
12595       p->refer->status = REFER_FAILED;
12596       break;
12597    case 603:   /* Transfer declined */
12598       ast_log(LOG_NOTICE, "SIP transfer to %s declined, call miserably fails. \n", p->refer->refer_to);
12599       p->refer->status = REFER_FAILED;
12600       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
12601       break;
12602    }
12603 }

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

12607 {
12608    int expires, expires_ms;
12609    struct sip_registry *r;
12610    r=p->registry;
12611 
12612    switch (resp) {
12613    case 401:   /* Unauthorized */
12614       if ((p->authtries == MAX_AUTHTRIES) || do_register_auth(p, req, "WWW-Authenticate", "Authorization")) {
12615          ast_log(LOG_NOTICE, "Failed to authenticate on REGISTER to '%s@%s' (Tries %d)\n", p->registry->username, p->registry->hostname, p->authtries);
12616          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12617          }
12618       break;
12619    case 403:   /* Forbidden */
12620       ast_log(LOG_WARNING, "Forbidden - wrong password on authentication for REGISTER for '%s' to '%s'\n", p->registry->username, p->registry->hostname);
12621       if (global_regattempts_max)
12622          p->registry->regattempts = global_regattempts_max+1;
12623       AST_SCHED_DEL(sched, r->timeout);
12624       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12625       break;
12626    case 404:   /* Not found */
12627       ast_log(LOG_WARNING, "Got 404 Not found on SIP register to service %s@%s, giving up\n", p->registry->username,p->registry->hostname);
12628       if (global_regattempts_max)
12629          p->registry->regattempts = global_regattempts_max+1;
12630       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12631       r->call = NULL;
12632       AST_SCHED_DEL(sched, r->timeout);
12633       break;
12634    case 407:   /* Proxy auth */
12635       if ((p->authtries == MAX_AUTHTRIES) || do_register_auth(p, req, "Proxy-Authenticate", "Proxy-Authorization")) {
12636          ast_log(LOG_NOTICE, "Failed to authenticate on REGISTER to '%s' (tries '%d')\n", get_header(&p->initreq, "From"), p->authtries);
12637          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12638       }
12639       break;
12640    case 408:   /* Request timeout */
12641       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12642       r->call = NULL;
12643       AST_SCHED_DEL(sched, r->timeout);
12644       break;
12645    case 479:   /* SER: Not able to process the URI - address is wrong in register*/
12646       ast_log(LOG_WARNING, "Got error 479 on register to %s@%s, giving up (check config)\n", p->registry->username,p->registry->hostname);
12647       if (global_regattempts_max)
12648          p->registry->regattempts = global_regattempts_max+1;
12649       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12650       r->call = NULL;
12651       AST_SCHED_DEL(sched, r->timeout);
12652       break;
12653    case 200:   /* 200 OK */
12654       if (!r) {
12655          ast_log(LOG_WARNING, "Got 200 OK on REGISTER that isn't a register\n");
12656          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12657          return 0;
12658       }
12659 
12660       r->regstate = REG_STATE_REGISTERED;
12661       r->regtime = time(NULL);      /* Reset time of last succesful registration */
12662       manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelDriver: SIP\r\nDomain: %s\r\nStatus: %s\r\n", r->hostname, regstate2str(r->regstate));
12663       r->regattempts = 0;
12664       if (option_debug)
12665          ast_log(LOG_DEBUG, "Registration successful\n");
12666       if (r->timeout > -1) {
12667          if (option_debug)
12668             ast_log(LOG_DEBUG, "Cancelling timeout %d\n", r->timeout);
12669       }
12670       AST_SCHED_DEL(sched, r->timeout);
12671       r->call = NULL;
12672       p->registry = NULL;
12673       /* Let this one hang around until we have all the responses */
12674       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
12675       /* ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); */
12676 
12677       /* set us up for re-registering */
12678       /* figure out how long we got registered for */
12679       AST_SCHED_DEL(sched, r->expire);
12680       /* according to section 6.13 of RFC, contact headers override
12681          expires headers, so check those first */
12682       expires = 0;
12683 
12684       /* XXX todo: try to save the extra call */
12685       if (!ast_strlen_zero(get_header(req, "Contact"))) {
12686          const char *contact = NULL;
12687          const char *tmptmp = NULL;
12688          int start = 0;
12689          for(;;) {
12690             contact = __get_header(req, "Contact", &start);
12691             /* this loop ensures we get a contact header about our register request */
12692             if(!ast_strlen_zero(contact)) {
12693                if( (tmptmp=strstr(contact, p->our_contact))) {
12694                   contact=tmptmp;
12695                   break;
12696                }
12697             } else
12698                break;
12699          }
12700          tmptmp = strcasestr(contact, "expires=");
12701          if (tmptmp) {
12702             if (sscanf(tmptmp + 8, "%d;", &expires) != 1)
12703                expires = 0;
12704          }
12705 
12706       }
12707       if (!expires) 
12708          expires=atoi(get_header(req, "expires"));
12709       if (!expires)
12710          expires=default_expiry;
12711 
12712       expires_ms = expires * 1000;
12713       if (expires <= EXPIRY_GUARD_LIMIT)
12714          expires_ms -= MAX((expires_ms * EXPIRY_GUARD_PCT),EXPIRY_GUARD_MIN);
12715       else
12716          expires_ms -= EXPIRY_GUARD_SECS * 1000;
12717       if (sipdebug)
12718          ast_log(LOG_NOTICE, "Outbound Registration: Expiry for %s is %d sec (Scheduling reregistration in %d s)\n", r->hostname, expires, expires_ms/1000); 
12719 
12720       r->refresh= (int) expires_ms / 1000;
12721 
12722       /* Schedule re-registration before we expire */
12723       AST_SCHED_DEL(sched, r->expire);
12724       r->expire = ast_sched_add(sched, expires_ms, sip_reregister, r); 
12725       ASTOBJ_UNREF(r, sip_registry_destroy);
12726    }
12727    return 1;
12728 }

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

03438 {
03439    switch (cause) {
03440       case AST_CAUSE_UNALLOCATED:      /* 1 */
03441       case AST_CAUSE_NO_ROUTE_DESTINATION:   /* 3 IAX2: Can't find extension in context */
03442       case AST_CAUSE_NO_ROUTE_TRANSIT_NET:   /* 2 */
03443          return "404 Not Found";
03444       case AST_CAUSE_CONGESTION:    /* 34 */
03445       case AST_CAUSE_SWITCH_CONGESTION:   /* 42 */
03446          return "503 Service Unavailable";
03447       case AST_CAUSE_NO_USER_RESPONSE: /* 18 */
03448          return "408 Request Timeout";
03449       case AST_CAUSE_NO_ANSWER:     /* 19 */
03450          return "480 Temporarily unavailable";
03451       case AST_CAUSE_CALL_REJECTED:    /* 21 */
03452          return "403 Forbidden";
03453       case AST_CAUSE_NUMBER_CHANGED:      /* 22 */
03454          return "410 Gone";
03455       case AST_CAUSE_NORMAL_UNSPECIFIED:  /* 31 */
03456          return "480 Temporarily unavailable";
03457       case AST_CAUSE_INVALID_NUMBER_FORMAT:
03458          return "484 Address incomplete";
03459       case AST_CAUSE_USER_BUSY:
03460          return "486 Busy here";
03461       case AST_CAUSE_FAILURE:
03462          return "500 Server internal failure";
03463       case AST_CAUSE_FACILITY_REJECTED:   /* 29 */
03464          return "501 Not Implemented";
03465       case AST_CAUSE_CHAN_NOT_IMPLEMENTED:
03466          return "503 Service Unavailable";
03467       /* Used in chan_iax2 */
03468       case AST_CAUSE_DESTINATION_OUT_OF_ORDER:
03469          return "502 Bad Gateway";
03470       case AST_CAUSE_BEARERCAPABILITY_NOTAVAIL: /* Can't find codec to connect to host */
03471          return "488 Not Acceptable Here";
03472          
03473       case AST_CAUSE_NOTDEFINED:
03474       default:
03475          if (option_debug)
03476             ast_log(LOG_DEBUG, "AST hangup cause %d (no match found in SIP)\n", cause);
03477          return NULL;
03478    }
03479 
03480    /* Never reached */
03481    return 0;
03482 }

static int hangup_sip2cause ( int  cause  )  [static]

Convert SIP hangup causes to Asterisk hangup causes.

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

03326 {
03327    /* Possible values taken from causes.h */
03328 
03329    switch(cause) {
03330       case 401:   /* Unauthorized */
03331          return AST_CAUSE_CALL_REJECTED;
03332       case 403:   /* Not found */
03333          return AST_CAUSE_CALL_REJECTED;
03334       case 404:   /* Not found */
03335          return AST_CAUSE_UNALLOCATED;
03336       case 405:   /* Method not allowed */
03337          return AST_CAUSE_INTERWORKING;
03338       case 407:   /* Proxy authentication required */
03339          return AST_CAUSE_CALL_REJECTED;
03340       case 408:   /* No reaction */
03341          return AST_CAUSE_NO_USER_RESPONSE;
03342       case 409:   /* Conflict */
03343          return AST_CAUSE_NORMAL_TEMPORARY_FAILURE;
03344       case 410:   /* Gone */
03345          return AST_CAUSE_UNALLOCATED;
03346       case 411:   /* Length required */
03347          return AST_CAUSE_INTERWORKING;
03348       case 413:   /* Request entity too large */
03349          return AST_CAUSE_INTERWORKING;
03350       case 414:   /* Request URI too large */
03351          return AST_CAUSE_INTERWORKING;
03352       case 415:   /* Unsupported media type */
03353          return AST_CAUSE_INTERWORKING;
03354       case 420:   /* Bad extension */
03355          return AST_CAUSE_NO_ROUTE_DESTINATION;
03356       case 480:   /* No answer */
03357          return AST_CAUSE_NO_ANSWER;
03358       case 481:   /* No answer */
03359          return AST_CAUSE_INTERWORKING;
03360       case 482:   /* Loop detected */
03361          return AST_CAUSE_INTERWORKING;
03362       case 483:   /* Too many hops */
03363          return AST_CAUSE_NO_ANSWER;
03364       case 484:   /* Address incomplete */
03365          return AST_CAUSE_INVALID_NUMBER_FORMAT;
03366       case 485:   /* Ambigous */
03367          return AST_CAUSE_UNALLOCATED;
03368       case 486:   /* Busy everywhere */
03369          return AST_CAUSE_BUSY;
03370       case 487:   /* Request terminated */
03371          return AST_CAUSE_INTERWORKING;
03372       case 488:   /* No codecs approved */
03373          return AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;
03374       case 491:   /* Request pending */
03375          return AST_CAUSE_INTERWORKING;
03376       case 493:   /* Undecipherable */
03377          return AST_CAUSE_INTERWORKING;
03378       case 500:   /* Server internal failure */
03379          return AST_CAUSE_FAILURE;
03380       case 501:   /* Call rejected */
03381          return AST_CAUSE_FACILITY_REJECTED;
03382       case 502:   
03383          return AST_CAUSE_DESTINATION_OUT_OF_ORDER;
03384       case 503:   /* Service unavailable */
03385          return AST_CAUSE_CONGESTION;
03386       case 504:   /* Gateway timeout */
03387          return AST_CAUSE_RECOVERY_ON_TIMER_EXPIRE;
03388       case 505:   /* SIP version not supported */
03389          return AST_CAUSE_INTERWORKING;
03390       case 600:   /* Busy everywhere */
03391          return AST_CAUSE_USER_BUSY;
03392       case 603:   /* Decline */
03393          return AST_CAUSE_CALL_REJECTED;
03394       case 604:   /* Does not exist anywhere */
03395          return AST_CAUSE_UNALLOCATED;
03396       case 606:   /* Not acceptable */
03397          return AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;
03398       default:
03399          return AST_CAUSE_NORMAL;
03400    }
03401    /* Never reached */
03402    return 0;
03403 }

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

Initialize SIP request.

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

05868 {
05869    /* Initialize a request */
05870    memset(req, 0, sizeof(*req));
05871         req->method = sipmethod;
05872    req->header[0] = req->data;
05873    snprintf(req->header[0], sizeof(req->data), "%s %s SIP/2.0\r\n", sip_methods[sipmethod].text, recip);
05874    req->len = strlen(req->header[0]);
05875    req->headers++;
05876    return 0;
05877 }

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

Initialize SIP response, based on SIP request.

Definition at line 5854 of file chan_sip.c.

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

05855 {
05856    /* Initialize a response */
05857    memset(resp, 0, sizeof(*resp));
05858    resp->method = SIP_RESPONSE;
05859    resp->header[0] = resp->data;
05860    snprintf(resp->header[0], sizeof(resp->data), "SIP/2.0 %s\r\n", msg);
05861    resp->len = strlen(resp->header[0]);
05862    resp->headers++;
05863    return 0;
05864 }

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

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

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

Initiate new SIP request to peer/user.

Definition at line 6954 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, SIPBUFSIZE, 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().

06955 {
06956    char invite_buf[256] = "";
06957    char *invite = invite_buf;
06958    size_t invite_max = sizeof(invite_buf);
06959    char from[256];
06960    char to[256];
06961    char tmp[SIPBUFSIZE/2];
06962    char tmp2[SIPBUFSIZE/2];
06963    const char *l = NULL, *n = NULL;
06964    const char *urioptions = "";
06965 
06966    if (ast_test_flag(&p->flags[0], SIP_USEREQPHONE)) {
06967       const char *s = p->username;  /* being a string field, cannot be NULL */
06968 
06969       /* Test p->username against allowed characters in AST_DIGIT_ANY
06970          If it matches the allowed characters list, then sipuser = ";user=phone"
06971          If not, then sipuser = ""
06972       */
06973       /* + is allowed in first position in a tel: uri */
06974       if (*s == '+')
06975          s++;
06976       for (; *s; s++) {
06977          if (!strchr(AST_DIGIT_ANYNUM, *s) )
06978             break;
06979       }
06980       /* If we have only digits, add ;user=phone to the uri */
06981       if (*s)
06982          urioptions = ";user=phone";
06983    }
06984 
06985 
06986    snprintf(p->lastmsg, sizeof(p->lastmsg), "Init: %s", sip_methods[sipmethod].text);
06987 
06988    if (p->owner) {
06989       l = p->owner->cid.cid_num;
06990       n = p->owner->cid.cid_name;
06991    }
06992    /* if we are not sending RPID and user wants his callerid restricted */
06993    if (!ast_test_flag(&p->flags[0], SIP_SENDRPID) &&
06994        ((p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED)) {
06995       l = CALLERID_UNKNOWN;
06996       n = l;
06997    }
06998    if (ast_strlen_zero(l))
06999       l = default_callerid;
07000    if (ast_strlen_zero(n))
07001       n = l;
07002    /* Allow user to be overridden */
07003    if (!ast_strlen_zero(p->fromuser))
07004       l = p->fromuser;
07005    else /* Save for any further attempts */
07006       ast_string_field_set(p, fromuser, l);
07007 
07008    /* Allow user to be overridden */
07009    if (!ast_strlen_zero(p->fromname))
07010       n = p->fromname;
07011    else /* Save for any further attempts */
07012       ast_string_field_set(p, fromname, n);
07013 
07014    if (pedanticsipchecking) {
07015       ast_uri_encode(n, tmp, sizeof(tmp), 0);
07016       n = tmp;
07017       ast_uri_encode(l, tmp2, sizeof(tmp2), 0);
07018       l = tmp2;
07019    }
07020 
07021    if (ourport != STANDARD_SIP_PORT && ast_strlen_zero(p->fromdomain))
07022       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);
07023    else
07024       snprintf(from, sizeof(from), "\"%s\" <sip:%s@%s>;tag=%s", n, l, S_OR(p->fromdomain, ast_inet_ntoa(p->ourip)), p->tag);
07025 
07026    /* If we're calling a registered SIP peer, use the fullcontact to dial to the peer */
07027    if (!ast_strlen_zero(p->fullcontact)) {
07028       /* If we have full contact, trust it */
07029       ast_build_string(&invite, &invite_max, "%s", p->fullcontact);
07030    } else {
07031       /* Otherwise, use the username while waiting for registration */
07032       ast_build_string(&invite, &invite_max, "sip:");
07033       if (!ast_strlen_zero(p->username)) {
07034          n = p->username;
07035          if (pedanticsipchecking) {
07036             ast_uri_encode(n, tmp, sizeof(tmp), 0);
07037             n = tmp;
07038          }
07039          ast_build_string(&invite, &invite_max, "%s@", n);
07040       }
07041       ast_build_string(&invite, &invite_max, "%s", p->tohost);
07042       if (ntohs(p->sa.sin_port) != STANDARD_SIP_PORT)
07043          ast_build_string(&invite, &invite_max, ":%d", ntohs(p->sa.sin_port));
07044       ast_build_string(&invite, &invite_max, "%s", urioptions);
07045    }
07046 
07047    /* If custom URI options have been provided, append them */
07048    if (p->options && !ast_strlen_zero(p->options->uri_options))
07049       ast_build_string(&invite, &invite_max, ";%s", p->options->uri_options);
07050    
07051    ast_string_field_set(p, uri, invite_buf);
07052 
07053    if (sipmethod == SIP_NOTIFY && !ast_strlen_zero(p->theirtag)) { 
07054       /* If this is a NOTIFY, use the From: tag in the subscribe (RFC 3265) */
07055       snprintf(to, sizeof(to), "<%s%s>;tag=%s", (strncasecmp(p->uri, "sip:", 4) ? "" : "sip:"), p->uri, p->theirtag);
07056    } else if (p->options && p->options->vxml_url) {
07057       /* If there is a VXML URL append it to the SIP URL */
07058       snprintf(to, sizeof(to), "<%s>;%s", p->uri, p->options->vxml_url);
07059    } else 
07060       snprintf(to, sizeof(to), "<%s>", p->uri);
07061    
07062    init_req(req, sipmethod, p->uri);
07063    snprintf(tmp, sizeof(tmp), "%d %s", ++p->ocseq, sip_methods[sipmethod].text);
07064 
07065    add_header(req, "Via", p->via);
07066    /* SLD: FIXME?: do Route: here too?  I think not cos this is the first request.
07067     * OTOH, then we won't have anything in p->route anyway */
07068    /* Build Remote Party-ID and From */
07069    if (ast_test_flag(&p->flags[0], SIP_SENDRPID) && (sipmethod == SIP_INVITE)) {
07070       build_rpid(p);
07071       add_header(req, "From", p->rpid_from);
07072    } else 
07073       add_header(req, "From", from);
07074    add_header(req, "To", to);
07075    ast_string_field_set(p, exten, l);
07076    build_contact(p);
07077    add_header(req, "Contact", p->our_contact);
07078    add_header(req, "Call-ID", p->callid);
07079    add_header(req, "CSeq", tmp);
07080    if (!ast_strlen_zero(global_useragent))
07081       add_header(req, "User-Agent", global_useragent);
07082    add_header(req, "Max-Forwards", DEFAULT_MAX_FORWARDS);
07083    if (!ast_strlen_zero(p->rpid))
07084       add_header(req, "Remote-Party-ID", p->rpid);
07085 }

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

Convert Insecure setting to printable string.

Definition at line 10225 of file chan_sip.c.

Referenced by _sip_show_peer().

10226 {
10227    if (port && invite)
10228       return "port,invite";
10229    else if (port)
10230       return "port";
10231    else if (invite)
10232       return "invite";
10233    else
10234       return "no";
10235 }

static void list_route ( struct sip_route route  )  [static]

List all routes - mostly for debugging.

Definition at line 8281 of file chan_sip.c.

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

Referenced by build_route().

08282 {
08283    if (!route)
08284       ast_verbose("list_route: no route\n");
08285    else {
08286       for (;route; route = route->next)
08287          ast_verbose("list_route: hop: <%s>\n", route->hop);
08288    }
08289 }

static int load_module ( void   )  [static]

PBX load module - initialization.

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

18557 {
18558    ASTOBJ_CONTAINER_INIT(&userl);   /* User object list */
18559    ASTOBJ_CONTAINER_INIT(&peerl);   /* Peer object list */
18560    ASTOBJ_CONTAINER_INIT(&regl); /* Registry object list */
18561 
18562    if (!(sched = sched_context_create())) {
18563       ast_log(LOG_ERROR, "Unable to create scheduler context\n");
18564       return AST_MODULE_LOAD_FAILURE;
18565    }
18566 
18567    if (!(io = io_context_create())) {
18568       ast_log(LOG_ERROR, "Unable to create I/O context\n");
18569       sched_context_destroy(sched);
18570       return AST_MODULE_LOAD_FAILURE;
18571    }
18572 
18573    sip_reloadreason = CHANNEL_MODULE_LOAD;
18574 
18575    if(reload_config(sip_reloadreason)) /* Load the configuration from sip.conf */
18576       return AST_MODULE_LOAD_DECLINE;
18577 
18578    /* Make sure we can register our sip channel type */
18579    if (ast_channel_register(&sip_tech)) {
18580       ast_log(LOG_ERROR, "Unable to register channel type 'SIP'\n");
18581       io_context_destroy(io);
18582       sched_context_destroy(sched);
18583       return AST_MODULE_LOAD_FAILURE;
18584    }
18585 
18586    /* Register all CLI functions for SIP */
18587    ast_cli_register_multiple(cli_sip, sizeof(cli_sip)/ sizeof(struct ast_cli_entry));
18588 
18589    /* Tell the RTP subdriver that we're here */
18590    ast_rtp_proto_register(&sip_rtp);
18591 
18592    /* Tell the UDPTL subdriver that we're here */
18593    ast_udptl_proto_register(&sip_udptl);
18594 
18595    /* Register dialplan applications */
18596    ast_register_application(app_dtmfmode, sip_dtmfmode, synopsis_dtmfmode, descrip_dtmfmode);
18597    ast_register_application(app_sipaddheader, sip_addheader, synopsis_sipaddheader, descrip_sipaddheader);
18598 
18599    /* Register dialplan functions */
18600    ast_custom_function_register(&sip_header_function);
18601    ast_custom_function_register(&sippeer_function);
18602    ast_custom_function_register(&sipchaninfo_function);
18603    ast_custom_function_register(&checksipdomain_function);
18604 
18605    /* Register manager commands */
18606    ast_manager_register2("SIPpeers", EVENT_FLAG_SYSTEM, manager_sip_show_peers,
18607          "List SIP peers (text format)", mandescr_show_peers);
18608    ast_manager_register2("SIPshowpeer", EVENT_FLAG_SYSTEM, manager_sip_show_peer,
18609          "Show SIP peer (text format)", mandescr_show_peer);
18610 
18611    sip_poke_all_peers();   
18612    sip_send_all_registers();
18613    
18614    /* And start the monitor for the first time */
18615    restart_monitor();
18616 
18617    return AST_MODULE_LOAD_SUCCESS;
18618 }

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

14685 {
14686    struct sip_dual target;    /* Chan 1: Call from tranferer to Asterisk */
14687                /* Chan 2: Call from Asterisk to target */
14688    int res = 0;
14689    struct sip_pvt *targetcall_pvt;
14690 
14691    /* Check if the call ID of the replaces header does exist locally */
14692    if (!(targetcall_pvt = get_sip_pvt_byid_locked(transferer->refer->replaces_callid, transferer->refer->replaces_callid_totag, 
14693       transferer->refer->replaces_callid_fromtag))) {
14694       if (transferer->refer->localtransfer) {
14695          /* We did not find the refered call. Sorry, can't accept then */
14696          transmit_response(transferer, "202 Accepted", req);
14697          /* Let's fake a response from someone else in order
14698             to follow the standard */
14699          transmit_notify_with_sipfrag(transferer, seqno, "481 Call leg/transaction does not exist", TRUE);
14700          append_history(transferer, "Xfer", "Refer failed");
14701          ast_clear_flag(&transferer->flags[0], SIP_GOTREFER);  
14702          transferer->refer->status = REFER_FAILED;
14703          return -1;
14704       }
14705       /* Fall through for remote transfers that we did not find locally */
14706       if (option_debug > 2)
14707          ast_log(LOG_DEBUG, "SIP attended transfer: Not our call - generating INVITE with replaces\n");
14708       return 0;
14709    }
14710 
14711    /* Ok, we can accept this transfer */
14712    transmit_response(transferer, "202 Accepted", req);
14713    append_history(transferer, "Xfer", "Refer accepted");
14714    if (!targetcall_pvt->owner) { /* No active channel */
14715       if (option_debug > 3)
14716          ast_log(LOG_DEBUG, "SIP attended transfer: Error: No owner of target call\n");
14717       /* Cancel transfer */
14718       transmit_notify_with_sipfrag(transferer, seqno, "503 Service Unavailable", TRUE);
14719       append_history(transferer, "Xfer", "Refer failed");
14720       ast_clear_flag(&transferer->flags[0], SIP_GOTREFER);
14721       transferer->refer->status = REFER_FAILED;
14722       ast_mutex_unlock(&targetcall_pvt->lock);
14723       ast_channel_unlock(current->chan1);
14724       return -1;
14725    }
14726 
14727    /* We have a channel, find the bridge */
14728    target.chan1 = targetcall_pvt->owner;           /* Transferer to Asterisk */
14729    target.chan2 = ast_bridged_channel(targetcall_pvt->owner);  /* Asterisk to target */
14730 
14731    if (!target.chan2 || !(target.chan2->_state == AST_STATE_UP || target.chan2->_state == AST_STATE_RINGING) ) {
14732       /* Wrong state of new channel */
14733       if (option_debug > 3) {
14734          if (target.chan2) 
14735             ast_log(LOG_DEBUG, "SIP attended transfer: Error: Wrong state of target call: %s\n", ast_state2str(target.chan2->_state));
14736          else if (target.chan1->_state != AST_STATE_RING)
14737             ast_log(LOG_DEBUG, "SIP attended transfer: Error: No target channel\n");
14738          else
14739             ast_log(LOG_DEBUG, "SIP attended transfer: Attempting transfer in ringing state\n");
14740       }
14741    }
14742 
14743    /* Transfer */
14744    if (option_debug > 3 && sipdebug) {
14745       if (current->chan2)  /* We have two bridges */
14746          ast_log(LOG_DEBUG, "SIP attended transfer: trying to bridge %s and %s\n", target.chan1->name, current->chan2->name);
14747       else        /* One bridge, propably transfer of IVR/voicemail etc */
14748          ast_log(LOG_DEBUG, "SIP attended transfer: trying to make %s take over (masq) %s\n", target.chan1->name, current->chan1->name);
14749    }
14750 
14751    ast_set_flag(&transferer->flags[0], SIP_DEFER_BYE_ON_TRANSFER);   /* Delay hangup */
14752 
14753    /* Perform the transfer */
14754    res = attempt_transfer(current, &target);
14755    ast_mutex_unlock(&targetcall_pvt->lock);
14756    if (res) {
14757       /* Failed transfer */
14758       transmit_notify_with_sipfrag(transferer, seqno, "486 Busy Here", TRUE);
14759       append_history(transferer, "Xfer", "Refer failed");
14760       transferer->refer->status = REFER_FAILED;
14761       if (targetcall_pvt->owner)
14762          ast_channel_unlock(targetcall_pvt->owner);
14763       /* Right now, we have to hangup, sorry. Bridge is destroyed */
14764       if (res != -2)
14765          ast_hangup(transferer->owner);
14766       else
14767          ast_clear_flag(&transferer->flags[0], SIP_DEFER_BYE_ON_TRANSFER);
14768    } else {
14769       /* Transfer succeeded! */
14770 
14771       /* Tell transferer that we're done. */
14772       transmit_notify_with_sipfrag(transferer, seqno, "200 OK", TRUE);
14773       append_history(transferer, "Xfer", "Refer succeeded");
14774       transferer->refer->status = REFER_200OK;
14775       if (targetcall_pvt->owner) {
14776          if (option_debug)
14777             ast_log(LOG_DEBUG, "SIP attended transfer: Unlocking channel %s\n", targetcall_pvt->owner->name);
14778          ast_channel_unlock(targetcall_pvt->owner);
14779       }
14780    }
14781    return 1;
14782 }

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

References t.

Referenced by sipsock_read().

04768 {
04769    int h = 0, t = 0; 
04770    int lws = 0; 
04771 
04772    for (; h < len;) { 
04773       /* Eliminate all CRs */ 
04774       if (msgbuf[h] == '\r') { 
04775          h++; 
04776          continue; 
04777       } 
04778       /* Check for end-of-line */ 
04779       if (msgbuf[h] == '\n') { 
04780          /* Check for end-of-message */ 
04781          if (h + 1 == len) 
04782             break; 
04783          /* Check for a continuation line */ 
04784          if (msgbuf[h + 1] == ' ' || msgbuf[h + 1] == '\t') { 
04785             /* Merge continuation line */ 
04786             h++; 
04787             continue; 
04788          } 
04789          /* Propagate LF and start new line */ 
04790          msgbuf[t++] = msgbuf[h++]; 
04791          lws = 0;
04792          continue; 
04793       } 
04794       if (msgbuf[h] == ' ' || msgbuf[h] == '\t') { 
04795          if (lws) { 
04796             h++; 
04797             continue; 
04798          } 
04799          msgbuf[t++] = msgbuf[h++]; 
04800          lws = 1; 
04801          continue; 
04802       } 
04803       msgbuf[t++] = msgbuf[h++]; 
04804       if (lws) 
04805          lws = 0; 
04806    } 
04807    msgbuf[t] = '\0'; 
04808    return t; 
04809 }

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

Make our SIP dialog tag.

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

04439 {
04440    snprintf(tagbuf, len, "as%08lx", ast_random());
04441 }

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

Show SIP peers in the manager API.

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

10471 {
10472    const char *a[4];
10473    const char *peer;
10474    int ret;
10475 
10476    peer = astman_get_header(m,"Peer");
10477    if (ast_strlen_zero(peer)) {
10478       astman_send_error(s, m, "Peer: <name> missing.\n");
10479       return 0;
10480    }
10481    a[0] = "sip";
10482    a[1] = "show";
10483    a[2] = "peer";
10484    a[3] = peer;
10485 
10486    ret = _sip_show_peer(1, -1, s, m, 4, a);
10487    astman_append(s, "\r\n\r\n" );
10488    return ret;
10489 }

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

Show SIP peers in the manager API.

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

10022 {
10023    const char *id = astman_get_header(m,"ActionID");
10024    const char *a[] = {"sip", "show", "peers"};
10025    char idtext[256] = "";
10026    int total = 0;
10027 
10028    if (!ast_strlen_zero(id))
10029       snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
10030 
10031    astman_send_ack(s, m, "Peer status list will follow");
10032    /* List the peers in separate manager events */
10033    _sip_show_peers(-1, &total, s, m, 3, a);
10034    /* Send final confirmation */
10035    astman_append(s,
10036    "Event: PeerlistComplete\r\n"
10037    "ListItems: %d\r\n"
10038    "%s"
10039    "\r\n", total, idtext);
10040    return 0;
10041 }

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

References len, sip_methods, and text.

Referenced by __sip_semi_ack(), and find_sip_method().

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

static char * nat2str ( int  nat  )  [static]

Convert NAT setting to text string.

Definition at line 9924 of file chan_sip.c.

References SIP_NAT_ALWAYS, SIP_NAT_NEVER, SIP_NAT_RFC3581, and SIP_NAT_ROUTE.

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

09925 {
09926    switch(nat) {
09927    case SIP_NAT_NEVER:
09928       return "No";
09929    case SIP_NAT_ROUTE:
09930       return "Route";
09931    case SIP_NAT_ALWAYS:
09932       return "Always";
09933    case SIP_NAT_RFC3581:
09934       return "RFC3581";
09935    default:
09936       return "Unknown";
09937    }
09938 }

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

Copy SIP request, parse it.

Definition at line 2240 of file chan_sip.c.

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

Referenced by send_request(), and send_response().

02241 {
02242    memset(dst, 0, sizeof(*dst));
02243    memcpy(dst->data, src->data, sizeof(dst->data));
02244    dst->len = src->len;
02245    parse_request(dst);
02246 }

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

Parse 302 Moved temporalily response.

Definition at line 12110 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, SIPBUFSIZE, and t.

Referenced by handle_response().

12111 {
12112    char tmp[SIPBUFSIZE];
12113    char *s, *e, *uri, *t;
12114    char *domain;
12115 
12116    ast_copy_string(tmp, get_header(req, "Contact"), sizeof(tmp));
12117    if ((t = strchr(tmp, ',')))
12118       *t = '\0';
12119    s = get_in_brackets(tmp);
12120    uri = ast_strdupa(s);
12121    if (ast_test_flag(&p->flags[0], SIP_PROMISCREDIR)) {
12122       if (!strncasecmp(s, "sip:", 4))
12123          s += 4;
12124       e = strchr(s, ';');
12125       if (e)
12126          *e = '\0';
12127       if (option_debug)
12128          ast_log(LOG_DEBUG, "Found promiscuous redirection to 'SIP/%s'\n", s);
12129       if (p->owner)
12130          ast_string_field_build(p->owner, call_forward, "SIP/%s", s);
12131    } else {
12132       e = strchr(tmp, '@');
12133       if (e) {
12134          *e++ = '\0';
12135          domain = e;
12136       } else {
12137          /* No username part */
12138          domain = tmp;
12139       }
12140       e = strchr(s, ';');  /* Strip of parameters in the username part */
12141       if (e)
12142          *e = '\0';
12143       e = strchr(domain, ';');   /* Strip of parameters in the domain part */
12144       if (e)
12145          *e = '\0';
12146    
12147       if (!strncasecmp(s, "sip:", 4))
12148          s += 4;
12149       if (option_debug > 1)
12150          ast_log(LOG_DEBUG, "Received 302 Redirect to extension '%s' (domain %s)\n", s, domain);
12151       if (p->owner) {
12152          pbx_builtin_setvar_helper(p->owner, "SIPREDIRECTURI", uri);
12153          pbx_builtin_setvar_helper(p->owner, "SIPDOMAIN", domain);
12154          ast_string_field_set(p->owner, call_forward, s);
12155       }
12156    }
12157 }

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

References ast_string_field_set, sip_peer::fullcontact, get_header(), get_in_brackets(), SIPBUFSIZE, and TRUE.

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

08030 {
08031    char contact[SIPBUFSIZE]; 
08032    char *c;
08033 
08034    /* Look for brackets */
08035    ast_copy_string(contact, get_header(req, "Contact"), sizeof(contact));
08036    c = get_in_brackets(contact);
08037 
08038    /* Save full contact to call pvt for later bye or re-invite */
08039    ast_string_field_set(pvt, fullcontact, c);
08040 
08041    /* Save URI for later ACKs, BYE or RE-invites */
08042    ast_string_field_set(pvt, okcontacturi, c);
08043 
08044    /* We should return false for URI:s we can't handle,
08045       like sips:, tel:, mailto:,ldap: etc */
08046    return TRUE;      
08047 }

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 8113 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(), ASTOBJ_REF, ASTOBJ_UNREF, 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_destroy_peer(), SIP_NAT_ROUTE, SIP_PAGE2_RT_FROMCONTACT, sip_poke_peer(), SIP_REALTIME, SIPBUFSIZE, 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().

08114 {
08115    char contact[SIPBUFSIZE]; 
08116    char data[SIPBUFSIZE];
08117    const char *expires = get_header(req, "Expires");
08118    int expiry = atoi(expires);
08119    char *curi, *n, *pt;
08120    int port;
08121    const char *useragent;
08122    struct hostent *hp;
08123    struct ast_hostent ahp;
08124    struct sockaddr_in oldsin;
08125 
08126    ast_copy_string(contact, get_header(req, "Contact"), sizeof(contact));
08127 
08128    if (ast_strlen_zero(expires)) {  /* No expires header */
08129       expires = strcasestr(contact, ";expires=");
08130       if (expires) {
08131          /* XXX bug here, we overwrite the string */
08132          expires = strsep((char **) &expires, ";"); /* trim ; and beyond */
08133          if (sscanf(expires + 9, "%d", &expiry) != 1)
08134             expiry = default_expiry;
08135       } else {
08136          /* Nothing has been specified */
08137          expiry = default_expiry;
08138       }
08139    }
08140 
08141    /* Look for brackets */
08142    curi = contact;
08143    if (strchr(contact, '<') == NULL)   /* No <, check for ; and strip it */
08144       strsep(&curi, ";");  /* This is Header options, not URI options */
08145    curi = get_in_brackets(contact);
08146 
08147    /* if they did not specify Contact: or Expires:, they are querying
08148       what we currently have stored as their contact address, so return
08149       it
08150    */
08151    if (ast_strlen_zero(curi) && ast_strlen_zero(expires)) {
08152       /* If we have an active registration, tell them when the registration is going to expire */
08153       if (peer->expire > -1 && !ast_strlen_zero(peer->fullcontact))
08154          pvt->expiry = ast_sched_when(sched, peer->expire);
08155       return PARSE_REGISTER_QUERY;
08156    } else if (!strcasecmp(curi, "*") || !expiry) { /* Unregister this peer */
08157       /* This means remove all registrations and return OK */
08158       memset(&peer->addr, 0, sizeof(peer->addr));
08159       if (!AST_SCHED_DEL(sched, peer->expire)) {
08160          struct sip_peer *peer_ptr = peer;
08161          ASTOBJ_UNREF(peer_ptr, sip_destroy_peer);
08162       }
08163 
08164       destroy_association(peer);
08165       
08166       register_peer_exten(peer, 0); /* Add extension from regexten= setting in sip.conf */
08167       peer->fullcontact[0] = '\0';
08168       peer->useragent[0] = '\0';
08169       peer->sipoptions = 0;
08170       peer->lastms = 0;
08171 
08172       if (option_verbose > 2)
08173          ast_verbose(VERBOSE_PREFIX_3 "Unregistered SIP '%s'\n", peer->name);
08174          manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unregistered\r\n", peer->name);
08175       return PARSE_REGISTER_UPDATE;
08176    }
08177 
08178    /* Store whatever we got as a contact from the client */
08179    ast_copy_string(peer->fullcontact, curi, sizeof(peer->fullcontact));
08180 
08181    /* For the 200 OK, we should use the received contact */
08182    ast_string_field_build(pvt, our_contact, "<%s>", curi);
08183 
08184    /* Make sure it's a SIP URL */
08185    if (strncasecmp(curi, "sip:", 4)) {
08186       ast_log(LOG_NOTICE, "'%s' is not a valid SIP contact (missing sip:) trying to use anyway\n", curi);
08187    } else
08188       curi += 4;
08189    /* Ditch q */
08190    curi = strsep(&curi, ";");
08191    /* Grab host */
08192    n = strchr(curi, '@');
08193    if (!n) {
08194       n = curi;
08195       curi = NULL;
08196    } else
08197       *n++ = '\0';
08198    pt = strchr(n, ':');
08199    if (pt) {
08200       *pt++ = '\0';
08201       port = atoi(pt);
08202    } else
08203       port = STANDARD_SIP_PORT;
08204    oldsin = peer->addr;
08205    if (!ast_test_flag(&peer->flags[0], SIP_NAT_ROUTE)) {
08206       /* XXX This could block for a long time XXX */
08207       hp = ast_gethostbyname(n, &ahp);
08208       if (!hp)  {
08209          ast_log(LOG_WARNING, "Invalid host '%s'\n", n);
08210          return PARSE_REGISTER_FAILED;
08211       }
08212       peer->addr.sin_family = AF_INET;
08213       memcpy(&peer->addr.sin_addr, hp->h_addr, sizeof(peer->addr.sin_addr));
08214       peer->addr.sin_port = htons(port);
08215    } else {
08216       /* Don't trust the contact field.  Just use what they came to us
08217          with */
08218       peer->addr = pvt->recv;
08219    }
08220 
08221    /* Save SIP options profile */
08222    peer->sipoptions = pvt->sipoptions;
08223 
08224    if (curi && ast_strlen_zero(peer->username))
08225       ast_copy_string(peer->username, curi, sizeof(peer->username));
08226 
08227    if (!AST_SCHED_DEL(sched, peer->expire)) {
08228       struct sip_peer *peer_ptr = peer;
08229       ASTOBJ_UNREF(peer_ptr, sip_destroy_peer);
08230    }
08231    if (expiry > max_expiry)
08232       expiry = max_expiry;
08233    if (expiry < min_expiry)
08234       expiry = min_expiry;
08235    if (ast_test_flag(&peer->flags[0], SIP_REALTIME)) {
08236       peer->expire = -1;
08237    } else {
08238       peer->expire = ast_sched_add(sched, (expiry + 10) * 1000, expire_register, ASTOBJ_REF(peer));
08239       if (peer->expire == -1) {
08240          struct sip_peer *peer_ptr = peer;
08241          ASTOBJ_UNREF(peer_ptr, sip_destroy_peer);
08242       }
08243    }
08244    pvt->expiry = expiry;
08245    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);
08246    if (!ast_test_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT)) 
08247       ast_db_put("SIP/Registry", peer->name, data);
08248    manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Registered\r\n", peer->name);
08249 
08250    /* Is this a new IP address for us? */
08251    if (inaddrcmp(&peer->addr, &oldsin)) {
08252       sip_poke_peer(peer);
08253       if (option_verbose > 2)
08254          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);
08255       register_peer_exten(peer, 1);
08256    }
08257    
08258    /* Save User agent */
08259    useragent = get_header(req, "User-Agent");
08260    if (strcasecmp(useragent, peer->useragent)) {   /* XXX copy if they are different ? */
08261       ast_copy_string(peer->useragent, useragent, sizeof(peer->useragent));
08262       if (option_verbose > 3)
08263          ast_verbose(VERBOSE_PREFIX_3 "Saved useragent \"%s\" for peer %s\n", peer->useragent, peer->name);  
08264    }
08265    return PARSE_REGISTER_UPDATE;
08266 }

static int 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 4814 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().

04815 {
04816    /* Divide fields by NULL's */
04817    char *c;
04818    int f = 0;
04819 
04820    c = req->data;
04821 
04822    /* First header starts immediately */
04823    req->header[f] = c;
04824    while(*c) {
04825       if (*c == '\n') {
04826          /* We've got a new header */
04827          *c = 0;
04828 
04829          if (sipdebug && option_debug > 3)
04830             ast_log(LOG_DEBUG, "Header %d: %s (%d)\n", f, req->header[f], (int) strlen(req->header[f]));
04831          if (ast_strlen_zero(req->header[f])) {
04832             /* Line by itself means we're now in content */
04833             c++;
04834             break;
04835          }
04836          if (f >= SIP_MAX_HEADERS - 1) {
04837             ast_log(LOG_WARNING, "Too many SIP headers. Ignoring.\n");
04838          } else
04839             f++;
04840          req->header[f] = c + 1;
04841       } else if (*c == '\r') {
04842          /* Ignore but eliminate \r's */
04843          *c = 0;
04844       }
04845       c++;
04846    }
04847    /* Check for last header */
04848    if (!ast_strlen_zero(req->header[f])) {
04849       if (sipdebug && option_debug > 3)
04850          ast_log(LOG_DEBUG, "Header %d: %s (%d)\n", f, req->header[f], (int) strlen(req->header[f]));
04851       f++;
04852    }
04853    req->headers = f;
04854    /* Now we process any mime content */
04855    f = 0;
04856    req->line[f] = c;
04857    while(*c) {
04858       if (*c == '\n') {
04859          /* We've got a new line */
04860          *c = 0;
04861          if (sipdebug && option_debug > 3)
04862             ast_log(LOG_DEBUG, "Line: %s (%d)\n", req->line[f], (int) strlen(req->line[f]));
04863          if (f >= SIP_MAX_LINES - 1) {
04864             ast_log(LOG_WARNING, "Too many SDP lines. Ignoring.\n");
04865          } else
04866             f++;
04867          req->line[f] = c + 1;
04868       } else if (*c == '\r') {
04869          /* Ignore and eliminate \r's */
04870          *c = 0;
04871       }
04872       c++;
04873    }
04874    /* Check for last line */
04875    if (!ast_strlen_zero(req->line[f])) 
04876       f++;
04877    req->lines = f;
04878    if (*c) 
04879       ast_log(LOG_WARNING, "Odd content, extra stuff left over ('%s')\n", c);
04880    /* Split up the first line parts */
04881    return determine_firstline_parts(req);
04882 }

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

Parse supported header in incoming packet.

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

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

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

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

09944 {
09945    int res = 0;
09946    if (peer->maxms) {
09947       if (peer->lastms < 0) {
09948          ast_copy_string(status, "UNREACHABLE", statuslen);
09949       } else if (peer->lastms > peer->maxms) {
09950          snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms);
09951          res = 1;
09952       } else if (peer->lastms) {
09953          snprintf(status, statuslen, "OK (%d ms)", peer->lastms);
09954          res = 1;
09955       } else {
09956          ast_copy_string(status, "UNKNOWN", statuslen);
09957       }
09958    } else { 
09959       ast_copy_string(status, "Unmonitored", statuslen);
09960       /* Checking if port is 0 */
09961       res = -1;
09962    }
09963    return res;
09964 }

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

10412 {
10413    int x, codec;
10414 
10415    for(x = 0; x < 32 ; x++) {
10416       codec = ast_codec_pref_index(pref, x);
10417       if (!codec)
10418          break;
10419       ast_cli(fd, "%s", ast_getformatname(codec));
10420       ast_cli(fd, ":%d", pref->framing[x]);
10421       if (x < 31 && ast_codec_pref_index(pref, x + 1))
10422          ast_cli(fd, ",");
10423    }
10424    if (!x)
10425       ast_cli(fd, "none");
10426 }

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

Print call group and pickup group.

Definition at line 10202 of file chan_sip.c.

References ast_cli(), and ast_print_group().

Referenced by _sip_show_peer(), and sip_show_user().

10203 {
10204    char buf[256];
10205    ast_cli(fd, crlf ? "%s\r\n" : "%s\n", ast_print_group(buf, sizeof(buf), group) );
10206 }

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 5015 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_get_peer(), 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, MAX_RTP_PT, 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_NAT, SIP_NOVIDEO, SIP_PAGE2_CALL_ONHOLD, SIP_PAGE2_RFC2833_COMPENSATE, SIP_PAGE2_UDPTL_DESTINATION, SIPBUFSIZE, 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.

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

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

References ast_category_browse(), ast_category_root(), ast_config_destroy(), ast_copy_flags, ast_gethostbyname(), 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, ASTOBJ_REF, ASTOBJ_UNREF, build_peer(), sip_peer::expire, expire_register(), sip_peer::flags, hp, LOG_WARNING, ast_variable::name, ast_variable::next, peerl, set_insecure_flags(), sip_destroy_peer(), SIP_INSECURE_PORT, SIP_PAGE2_RTAUTOCLEAR, SIP_PAGE2_RTCACHEFRIENDS, SIP_REALTIME, ast_variable::value, and var.

02506 {
02507    struct sip_peer *peer=NULL;
02508    struct ast_variable *var = NULL;
02509    struct ast_config *peerlist = NULL;
02510    struct ast_variable *tmp;
02511    struct ast_flags flags = {0};
02512    const char *iabuf = NULL;
02513    char portstring[6]; /*up to five digits plus null terminator*/
02514    const char *insecure; 
02515    char *cat = NULL;
02516    unsigned short portnum;
02517 
02518    /* First check on peer name */
02519    if (newpeername) {
02520       var = ast_load_realtime("sippeers", "name", newpeername, "host", "dynamic", NULL);
02521       if (!var && sin)
02522          var = ast_load_realtime("sippeers", "name", newpeername, "host", ast_inet_ntoa(sin->sin_addr), NULL);
02523       if (!var) {
02524          var = ast_load_realtime("sippeers", "name", newpeername, NULL);
02525          /*!\note
02526           * If this one loaded something, then we need to ensure that the host
02527           * field matched.  The only reason why we can't have this as a criteria
02528           * is because we only have the IP address and the host field might be
02529           * set as a name (and the reverse PTR might not match).
02530           */
02531          if (var && sin) {
02532             for (tmp = var; tmp; tmp = tmp->next) {
02533                if (!strcasecmp(tmp->name, "host")) {
02534                   struct hostent *hp;
02535                   struct ast_hostent ahp;
02536                   if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(&hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) {
02537                      /* No match */
02538                      ast_variables_destroy(var);
02539                      var = NULL;
02540                   }
02541                   break;
02542                }
02543             }
02544          }
02545       }
02546    }
02547 
02548    if (!var && sin) {   /* Then check on IP address */
02549       iabuf = ast_inet_ntoa(sin->sin_addr);
02550       portnum = ntohs(sin->sin_port);
02551       sprintf(portstring, "%d", portnum);
02552       var = ast_load_realtime("sippeers", "host", iabuf, "port", portstring, NULL); /* First check for fixed IP hosts */
02553       if (!var)
02554          var = ast_load_realtime("sippeers", "ipaddr", iabuf, "port", portstring, NULL);  /* Then check for registered hosts */
02555       if (!var) { 
02556          peerlist = ast_load_realtime_multientry("sippeers", "host", iabuf, NULL); /*No exact match, see if port is insecure, try host match first*/
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          if(!var) {
02569             ast_config_destroy(peerlist);
02570             peerlist = NULL; /*for safety's sake*/
02571             cat = NULL;
02572             peerlist = ast_load_realtime_multientry("sippeers", "ipaddr", iabuf, NULL); /*No exact match, see if port is insecure, now try ip address match*/
02573             if(peerlist) {
02574                while((cat = ast_category_browse(peerlist, cat)))
02575                {
02576                   insecure = ast_variable_retrieve(peerlist, cat, "insecure");
02577                   set_insecure_flags(&flags, insecure, -1);
02578                   if(ast_test_flag(&flags, SIP_INSECURE_PORT)) {
02579                      var = ast_category_root(peerlist, cat);
02580                      break;
02581                   }
02582                }
02583             }
02584          }
02585       }
02586    }
02587 
02588    if (!var) {
02589       if(peerlist)
02590          ast_config_destroy(peerlist);
02591       return NULL;
02592    }
02593 
02594    for (tmp = var; tmp; tmp = tmp->next) {
02595       /* If this is type=user, then skip this object. */
02596       if (!strcasecmp(tmp->name, "type") &&
02597           !strcasecmp(tmp->value, "user")) {
02598          ast_variables_destroy(var);
02599          return NULL;
02600       } else if (!newpeername && !strcasecmp(tmp->name, "name")) {
02601          newpeername = tmp->value;
02602       }
02603    }
02604    
02605    if (!newpeername) {  /* Did not find peer in realtime */
02606       ast_log(LOG_WARNING, "Cannot Determine peer name ip=%s\n", iabuf);
02607       if(peerlist)
02608          ast_config_destroy(peerlist);
02609       else
02610          ast_variables_destroy(var);
02611       return NULL;
02612    }
02613 
02614    /* Peer found in realtime, now build it in memory */
02615    peer = build_peer(newpeername, var, NULL, 1);
02616    if (!peer) {
02617       if(peerlist)
02618          ast_config_destroy(peerlist);
02619       else
02620          ast_variables_destroy(var);
02621       return NULL;
02622    }
02623 
02624    if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) {
02625       /* Cache peer */
02626       ast_copy_flags(&peer->flags[1],&global_flags[1], SIP_PAGE2_RTAUTOCLEAR|SIP_PAGE2_RTCACHEFRIENDS);
02627       if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTAUTOCLEAR)) {
02628          if (!AST_SCHED_DEL(sched, peer->expire)) {
02629             struct sip_peer *peer_ptr = peer;
02630             ASTOBJ_UNREF(peer_ptr, sip_destroy_peer);
02631          }
02632          peer->expire = ast_sched_add(sched, (global_rtautoclear) * 1000, expire_register, ASTOBJ_REF(peer));
02633          if (peer->expire == -1) {
02634             struct sip_peer *peer_ptr = peer;
02635             ASTOBJ_UNREF(peer_ptr, sip_destroy_peer);
02636          }
02637       }
02638       ASTOBJ_CONTAINER_LINK(&peerl,peer);
02639    } else {
02640       ast_set_flag(&peer->flags[0], SIP_REALTIME);
02641    }
02642    if(peerlist)
02643       ast_config_destroy(peerlist);
02644    else
02645       ast_variables_destroy(var);
02646    return peer;
02647 }

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

02395 {
02396    char port[10];
02397    char ipaddr[INET_ADDRSTRLEN];
02398    char regseconds[20];
02399 
02400    char *sysname = ast_config_AST_SYSTEM_NAME;
02401    char *syslabel = NULL;
02402 
02403    time_t nowtime = time(NULL) + expirey;
02404    const char *fc = fullcontact ? "fullcontact" : NULL;
02405    
02406    snprintf(regseconds, sizeof(regseconds), "%d", (int)nowtime);  /* Expiration time */
02407    ast_copy_string(ipaddr, ast_inet_ntoa(sin->sin_addr), sizeof(ipaddr));
02408    snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port));
02409    
02410    if (ast_strlen_zero(sysname)) /* No system name, disable this */
02411       sysname = NULL;
02412    else if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTSAVE_SYSNAME))
02413       syslabel = "regserver";
02414 
02415    if (fc)
02416       ast_update_realtime("sippeers", "name", peername, "ipaddr", ipaddr,
02417          "port", port, "regseconds", regseconds,
02418          "username", username, fc, fullcontact, syslabel, sysname, NULL); /* note fc and syslabel _can_ be NULL */
02419    else
02420       ast_update_realtime("sippeers", "name", peername, "ipaddr", ipaddr,
02421          "port", port, "regseconds", regseconds,
02422          "username", username, syslabel, sysname, NULL); /* note syslabel _can_ be NULL */
02423 }

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

02698 {
02699    struct ast_variable *var;
02700    struct ast_variable *tmp;
02701    struct sip_user *user = NULL;
02702 
02703    var = ast_load_realtime("sipusers", "name", username, NULL);
02704 
02705    if (!var)
02706       return NULL;
02707 
02708    for (tmp = var; tmp; tmp = tmp->next) {
02709       if (!strcasecmp(tmp->name, "type") &&
02710          !strcasecmp(tmp->value, "peer")) {
02711          ast_variables_destroy(var);
02712          return NULL;
02713       }
02714    }
02715 
02716    user = build_user(username, var, NULL, !ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS));
02717    
02718    if (!user) {   /* No user found */
02719       ast_variables_destroy(var);
02720       return NULL;
02721    }
02722 
02723    if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) {
02724       ast_set_flag(&user->flags[1], SIP_PAGE2_RTCACHEFRIENDS);
02725       suserobjs++;
02726       ASTOBJ_CONTAINER_LINK(&userl,user);
02727    } else {
02728       /* Move counter from s to r... */
02729       suserobjs--;
02730       ruserobjs++;
02731       ast_set_flag(&user->flags[0], SIP_REALTIME);
02732    }
02733    ast_variables_destroy(var);
02734    return user;
02735 }

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

09827 {
09828    char buf[1024];
09829    struct ast_frame f;
09830    const char *content_type = get_header(req, "Content-Type");
09831 
09832    if (strncmp(content_type, "text/plain", strlen("text/plain"))) { /* No text/plain attachment */
09833       transmit_response(p, "415 Unsupported Media Type", req); /* Good enough, or? */
09834       if (!p->owner)
09835          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
09836       return;
09837    }
09838 
09839    if (get_msg_text(buf, sizeof(buf), req)) {
09840       ast_log(LOG_WARNING, "Unable to retrieve text from %s\n", p->callid);
09841       transmit_response(p, "202 Accepted", req);
09842       if (!p->owner)
09843          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
09844       return;
09845    }
09846 
09847    if (p->owner) {
09848       if (sip_debug_test_pvt(p))
09849          ast_verbose("Message received: '%s'\n", buf);
09850       memset(&f, 0, sizeof(f));
09851       f.frametype = AST_FRAME_TEXT;
09852       f.subclass = 0;
09853       f.offset = 0;
09854       f.data = buf;
09855       f.datalen = strlen(buf);
09856       ast_queue_frame(p->owner, &f);
09857       transmit_response(p, "202 Accepted", req); /* We respond 202 accepted, since we relay the message */
09858    } else { /* Message outside of a call, we do not support that */
09859       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);
09860       transmit_response(p, "405 Method Not Allowed", req); /* Good enough, or? */
09861       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
09862    }
09863    return;
09864 }

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

Convert transfer status to string.

Definition at line 1627 of file chan_sip.c.

References referstatusstrings, and c_referstatusstring::text.

Referenced by __sip_show_channels().

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

static void reg_source_db ( struct sip_peer peer  )  [static]

Get registration details from Asterisk DB.

Definition at line 7957 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, ASTOBJ_REF, ASTOBJ_UNREF, sip_peer::expire, expire_register(), sip_peer::flags, sip_peer::fullcontact, LOG_DEBUG, option_debug, sip_peer::pokeexpire, register_peer_exten(), sip_destroy_peer(), SIP_PAGE2_RT_FROMCONTACT, sip_poke_peer(), sip_poke_peer_s(), sipsock, strsep(), TRUE, sip_peer::username, and username.

07958 {
07959    char data[256];
07960    struct in_addr in;
07961    int expiry;
07962    int port;
07963    char *scan, *addr, *port_str, *expiry_str, *username, *contact;
07964 
07965    if (ast_test_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT)) 
07966       return;
07967    if (ast_db_get("SIP/Registry", peer->name, data, sizeof(data)))
07968       return;
07969 
07970    scan = data;
07971    addr = strsep(&scan, ":");
07972    port_str = strsep(&scan, ":");
07973    expiry_str = strsep(&scan, ":");
07974    username = strsep(&scan, ":");
07975    contact = scan;   /* Contact include sip: and has to be the last part of the database entry as long as we use : as a separator */
07976 
07977    if (!inet_aton(addr, &in))
07978       return;
07979 
07980    if (port_str)
07981       port = atoi(port_str);
07982    else
07983       return;
07984 
07985    if (expiry_str)
07986       expiry = atoi(expiry_str);
07987    else
07988       return;
07989 
07990    if (username)
07991       ast_copy_string(peer->username, username, sizeof(peer->username));
07992    if (contact)
07993       ast_copy_string(peer->fullcontact, contact, sizeof(peer->fullcontact));
07994 
07995    if (option_debug > 1)
07996       ast_log(LOG_DEBUG, "SIP Seeding peer from astdb: '%s' at %s@%s:%d for %d\n",
07997              peer->name, peer->username, ast_inet_ntoa(in), port, expiry);
07998 
07999    memset(&peer->addr, 0, sizeof(peer->addr));
08000    peer->addr.sin_family = AF_INET;
08001    peer->addr.sin_addr = in;
08002    peer->addr.sin_port = htons(port);
08003    if (sipsock < 0) {
08004       /* SIP isn't up yet, so schedule a poke only, pretty soon */
08005       if (!AST_SCHED_DEL(sched, peer->pokeexpire)) {
08006          struct sip_peer *peer_ptr = peer;
08007          ASTOBJ_UNREF(peer_ptr, sip_destroy_peer);
08008       }
08009       peer->pokeexpire = ast_sched_add(sched, ast_random() % 5000 + 1, sip_poke_peer_s, ASTOBJ_REF(peer));
08010       if (peer->pokeexpire == -1) {
08011          struct sip_peer *peer_ptr = peer;
08012          ASTOBJ_UNREF(peer_ptr, sip_destroy_peer);
08013       }
08014    } else
08015       sip_poke_peer(peer);
08016    if (!AST_SCHED_DEL(sched, peer->expire)) {
08017       struct sip_peer *peer_ptr = peer;
08018       ASTOBJ_UNREF(peer_ptr, sip_destroy_peer);
08019    }
08020    peer->expire = ast_sched_add(sched, (expiry + 10) * 1000, expire_register, ASTOBJ_REF(peer));
08021    if (peer->expire == -1) {
08022       struct sip_peer *peer_ptr = peer;
08023       ASTOBJ_UNREF(peer_ptr, sip_destroy_peer);
08024    }
08025    register_peer_exten(peer, TRUE);
08026 }

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

Automatically add peer extension to dial plan.

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

02427 {
02428    char multi[256];
02429    char *stringp, *ext, *context;
02430 
02431    /* XXX note that global_regcontext is both a global 'enable' flag and
02432     * the name of the global regexten context, if not specified
02433     * individually.
02434     */
02435    if (ast_strlen_zero(global_regcontext))
02436       return;
02437 
02438    ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi));
02439    stringp = multi;
02440    while ((ext = strsep(&stringp, "&"))) {
02441       if ((context = strchr(ext, '@'))) {
02442          *context++ = '\0';   /* split ext@context */
02443          if (!ast_context_find(context)) {
02444             ast_log(LOG_WARNING, "Context %s must exist in regcontext= in sip.conf!\n", context);
02445             continue;
02446          }
02447       } else {
02448          context = global_regcontext;
02449       }
02450       if (onoff)
02451          ast_add_extension(context, 1, ext, 1, NULL, NULL, "Noop",
02452              ast_strdup(peer->name), ast_free, "SIP");
02453       else
02454          ast_context_remove_extension(context, ext, 1, NULL);
02455    }
02456 }

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

08742 {
08743    enum check_auth_result res = AUTH_NOT_FOUND;
08744    struct sip_peer *peer;
08745    char tmp[256];
08746    char *name, *c;
08747    char *t;
08748    char *domain;
08749 
08750    /* Terminate URI */
08751    t = uri;
08752    while(*t && (*t > 32) && (*t != ';'))
08753       t++;
08754    *t = '\0';
08755    
08756    ast_copy_string(tmp, get_header(req, "To"), sizeof(tmp));
08757    if (pedanticsipchecking)
08758       ast_uri_decode(tmp);
08759 
08760    c = get_in_brackets(tmp);
08761    c = strsep(&c, ";"); /* Ditch ;user=phone */
08762 
08763    if (!strncasecmp(c, "sip:", 4)) {
08764       name = c + 4;
08765    } else {
08766       name = c;
08767       ast_log(LOG_NOTICE, "Invalid to address: '%s' from %s (missing sip:) trying to use anyway...\n", c, ast_inet_ntoa(sin->sin_addr));
08768    }
08769 
08770    /* Strip off the domain name */
08771    if ((c = strchr(name, '@'))) {
08772       *c++ = '\0';
08773       domain = c;
08774       if ((c = strchr(domain, ':')))   /* Remove :port */
08775          *c = '\0';
08776       if (!AST_LIST_EMPTY(&domain_list)) {
08777          if (!check_sip_domain(domain, NULL, 0)) {
08778             transmit_response(p, "404 Not found (unknown domain)", &p->initreq);
08779             return AUTH_UNKNOWN_DOMAIN;
08780          }
08781       }
08782    }
08783 
08784    ast_string_field_set(p, exten, name);
08785    build_contact(p);
08786    peer = find_peer(name, NULL, 1);
08787    if (!(peer && ast_apply_ha(peer->ha, sin))) {
08788       /* Peer fails ACL check */
08789       if (peer) {
08790          ASTOBJ_UNREF(peer, sip_destroy_peer);
08791          res = AUTH_ACL_FAILED;
08792       } else
08793          res = AUTH_NOT_FOUND;
08794    }
08795    if (peer) {
08796       /* Set Frame packetization */
08797       if (p->rtp) {
08798          ast_rtp_codec_setpref(p->rtp, &peer->prefs);
08799          p->autoframing = peer->autoframing;
08800       }
08801       if (!ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)) {
08802          ast_log(LOG_ERROR, "Peer '%s' is trying to register, but not configured as host=dynamic\n", peer->name);
08803          res = AUTH_PEER_NOT_DYNAMIC;
08804       } else {
08805          ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_NAT);
08806          transmit_response(p, "100 Trying", req);
08807          if (!(res = check_auth(p, req, peer->name, peer->secret, peer->md5secret, SIP_REGISTER, uri, XMIT_UNRELIABLE, ast_test_flag(req, SIP_PKT_IGNORE)))) {
08808             if (sip_cancel_destroy(p))
08809                ast_log(LOG_WARNING, "Unable to cancel SIP destruction.  Expect bad things.\n");
08810 
08811             /* We have a succesful registration attemp with proper authentication,
08812                now, update the peer */
08813             switch (parse_register_contact(p, peer, req)) {
08814             case PARSE_REGISTER_FAILED:
08815                ast_log(LOG_WARNING, "Failed to parse contact info\n");
08816                transmit_response_with_date(p, "400 Bad Request", req);
08817                peer->lastmsgssent = -1;
08818                res = 0;
08819                break;
08820             case PARSE_REGISTER_QUERY:
08821                transmit_response_with_date(p, "200 OK", req);
08822                peer->lastmsgssent = -1;
08823                res = 0;
08824                break;
08825             case PARSE_REGISTER_UPDATE:
08826                update_peer(peer, p->expiry);
08827                /* Say OK and ask subsystem to retransmit msg counter */
08828                transmit_response_with_date(p, "200 OK", req);
08829                if (!ast_test_flag((&peer->flags[1]), SIP_PAGE2_SUBSCRIBEMWIONLY))
08830                   peer->lastmsgssent = -1;
08831                res = 0;
08832                break;
08833             }
08834          } 
08835       }
08836    }
08837    if (!peer && autocreatepeer) {
08838       /* Create peer if we have autocreate mode enabled */
08839       peer = temp_peer(name);
08840       if (peer) {
08841          ASTOBJ_CONTAINER_LINK(&peerl, peer);
08842          if (sip_cancel_destroy(p))
08843             ast_log(LOG_WARNING, "Unable to cancel SIP destruction.  Expect bad things.\n");
08844          switch (parse_register_contact(p, peer, req)) {
08845          case PARSE_REGISTER_FAILED:
08846             ast_log(LOG_WARNING, "Failed to parse contact info\n");
08847             transmit_response_with_date(p, "400 Bad Request", req);
08848             peer->lastmsgssent = -1;
08849             res = 0;
08850             break;
08851          case PARSE_REGISTER_QUERY:
08852             transmit_response_with_date(p, "200 OK", req);
08853             peer->lastmsgssent = -1;
08854             res = 0;
08855             break;
08856          case PARSE_REGISTER_UPDATE:
08857             /* Say OK and ask subsystem to retransmit msg counter */
08858             transmit_response_with_date(p, "200 OK", req);
08859             manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Registered\r\n", peer->name);
08860             peer->lastmsgssent = -1;
08861             res = 0;
08862             break;
08863          }
08864       }
08865    }
08866    if (!peer && global_alwaysauthreject) {
08867       /* If we found a peer, we transmit a 100 Trying.  Therefore, if we're
08868        * trying to avoid leaking information, we MUST also transmit the same
08869        * response when we DON'T find a peer. */
08870       transmit_response(p, "100 Trying", req);
08871       /* Insert a fake delay between the 100 and the subsequent failure. */
08872       sched_yield();
08873    }
08874    if (!res) {
08875       ast_device_state_changed("SIP/%s", peer->name);
08876    }
08877    if (res < 0) {
08878       switch (res) {
08879       case AUTH_SECRET_FAILED:
08880          /* Wrong password in authentication. Go away, don't try again until you fixed it */
08881          transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq);
08882          break;
08883       case AUTH_USERNAME_MISMATCH:
08884          /* Username and digest username does not match.
08885             Asterisk uses the From: username for authentication. We need the
08886             users to use the same authentication user name until we support
08887             proper authentication by digest auth name */
08888       case AUTH_NOT_FOUND:
08889       case AUTH_PEER_NOT_DYNAMIC:
08890       case AUTH_ACL_FAILED:
08891          if (global_alwaysauthreject) {
08892             transmit_fake_auth_response(p, SIP_REGISTER, &p->initreq, XMIT_UNRELIABLE);
08893          } else {
08894             /* URI not found */
08895             if (res == AUTH_PEER_NOT_DYNAMIC)
08896                transmit_response(p, "403 Forbidden", &p->initreq);
08897             else
08898                transmit_response(p, "404 Not found", &p->initreq);
08899          }
08900          break;
08901       default:
08902          break;
08903       }
08904    }
08905    if (peer)
08906       ASTOBJ_UNREF(peer, sip_destroy_peer);
08907 
08908    return res;
08909 }

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

Convert registration state status to string.

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

07447 {
07448    switch(regstate) {
07449    case REG_STATE_FAILED:
07450       return "Failed";
07451    case REG_STATE_UNREGISTERED:
07452       return "Unregistered";
07453    case REG_STATE_REGSENT:
07454       return "Request Sent";
07455    case REG_STATE_AUTHSENT:
07456       return "Auth. Sent";
07457    case REG_STATE_REGISTERED:
07458       return "Registered";
07459    case REG_STATE_REJECTED:
07460       return "Rejected";
07461    case REG_STATE_TIMEOUT:
07462       return "Timeout";
07463    case REG_STATE_NOAUTH:
07464       return "No Authentication";
07465    default:
07466       return "Unknown";
07467    }
07468 }

static int reload ( void   )  [static]

Part of Asterisk module interface.

Definition at line 18442 of file chan_sip.c.

References sip_reload().

18443 {
18444    return sip_reload(0, 0, NULL);
18445 }

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

< Default to nat=yes

Definition at line 17322 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, display_nat_warning(), errno, EVENT_FLAG_SYSTEM, externexpire, externhost, externip, externrefresh, FALSE, sip_peer::flags, sip_user::flags, 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_ALWAYS, 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.

17323 {
17324    struct ast_config *cfg, *ucfg;
17325    struct ast_variable *v;
17326    struct sip_peer *peer;
17327    struct sip_user *user;
17328    struct ast_hostent ahp;
17329    char *cat, *stringp, *context, *oldregcontext;
17330    char newcontexts[AST_MAX_CONTEXT], oldcontexts[AST_MAX_CONTEXT];
17331    struct hostent *hp;
17332    int format;
17333    struct ast_flags dummy[2];
17334    int auto_sip_domains = FALSE;
17335    struct sockaddr_in old_bindaddr = bindaddr;
17336    int registry_count = 0, peer_count = 0, user_count = 0;
17337    unsigned int temp_tos = 0;
17338    struct ast_flags debugflag = {0};
17339 
17340    cfg = ast_config_load(config);
17341 
17342    /* We *must* have a config file otherwise stop immediately */
17343    if (!cfg) {
17344       ast_log(LOG_NOTICE, "Unable to load config %s\n", config);
17345       return -1;
17346    }
17347    
17348    if (option_debug > 3)
17349       ast_log(LOG_DEBUG, "--------------- SIP reload started\n");
17350 
17351    clear_realm_authentication(authl);
17352    clear_sip_domains();
17353    authl = NULL;
17354 
17355    /* First, destroy all outstanding registry calls */
17356    /* This is needed, since otherwise active registry entries will not be destroyed */
17357    ASTOBJ_CONTAINER_TRAVERSE(&regl, 1, do {
17358       ASTOBJ_RDLOCK(iterator);
17359       if (iterator->call) {
17360          if (option_debug > 2)
17361             ast_log(LOG_DEBUG, "Destroying active SIP dialog for registry %s@%s\n", iterator->username, iterator->hostname);
17362          /* This will also remove references to the registry */
17363          sip_destroy(iterator->call);
17364       }
17365       ASTOBJ_UNLOCK(iterator);
17366    
17367    } while(0));
17368 
17369    /* Then, actually destroy users and registry */
17370    ASTOBJ_CONTAINER_DESTROYALL(&userl, sip_destroy_user);
17371    if (option_debug > 3)
17372       ast_log(LOG_DEBUG, "--------------- Done destroying user list\n");
17373    ASTOBJ_CONTAINER_DESTROYALL(&regl, sip_registry_destroy);
17374    if (option_debug > 3)
17375       ast_log(LOG_DEBUG, "--------------- Done destroying registry list\n");
17376    ASTOBJ_CONTAINER_MARKALL(&peerl);
17377 
17378    /* Initialize copy of current global_regcontext for later use in removing stale contexts */
17379    ast_copy_string(oldcontexts, global_regcontext, sizeof(oldcontexts));
17380    oldregcontext = oldcontexts;
17381 
17382    /* Clear all flags before setting default values */
17383    /* Preserve debugging settings for console */
17384    ast_copy_flags(&debugflag, &global_flags[1], SIP_PAGE2_DEBUG_CONSOLE);
17385    ast_clear_flag(&global_flags[0], AST_FLAGS_ALL);
17386    ast_clear_flag(&global_flags[1], AST_FLAGS_ALL);
17387    ast_copy_flags(&global_flags[1], &debugflag, SIP_PAGE2_DEBUG_CONSOLE);
17388 
17389    /* Reset IP addresses  */
17390    memset(&bindaddr, 0, sizeof(bindaddr));
17391    ast_free_ha(localaddr);
17392    memset(&localaddr, 0, sizeof(localaddr));
17393    memset(&externip, 0, sizeof(externip));
17394    memset(&default_prefs, 0 , sizeof(default_prefs));
17395    outboundproxyip.sin_port = htons(STANDARD_SIP_PORT);
17396    outboundproxyip.sin_family = AF_INET;  /* Type of address: IPv4 */
17397    ourport = STANDARD_SIP_PORT;
17398    srvlookup = DEFAULT_SRVLOOKUP;
17399    global_tos_sip = DEFAULT_TOS_SIP;
17400    global_tos_audio = DEFAULT_TOS_AUDIO;
17401    global_tos_video = DEFAULT_TOS_VIDEO;
17402    externhost[0] = '\0';         /* External host name (for behind NAT DynDNS support) */
17403    externexpire = 0;       /* Expiration for DNS re-issuing */
17404    externrefresh = 10;
17405    memset(&outboundproxyip, 0, sizeof(outboundproxyip));
17406 
17407    /* Reset channel settings to default before re-configuring */
17408    allow_external_domains = DEFAULT_ALLOW_EXT_DOM;          /* Allow external invites */
17409    global_regcontext[0] = '\0';
17410    expiry = DEFAULT_EXPIRY;
17411    global_notifyringing = DEFAULT_NOTIFYRINGING;
17412    global_limitonpeers = FALSE;
17413    global_directrtpsetup = FALSE;      /* Experimental feature, disabled by default */
17414    global_notifyhold = FALSE;
17415    global_alwaysauthreject = 0;
17416    global_allowsubscribe = FALSE;
17417    ast_copy_string(global_useragent, DEFAULT_USERAGENT, sizeof(global_useragent));
17418    ast_copy_string(default_notifymime, DEFAULT_NOTIFYMIME, sizeof(default_notifymime));
17419    if (ast_strlen_zero(ast_config_AST_SYSTEM_NAME))
17420       ast_copy_string(global_realm, DEFAULT_REALM, sizeof(global_realm));
17421    else
17422       ast_copy_string(global_realm, ast_config_AST_SYSTEM_NAME, sizeof(global_realm));
17423    ast_copy_string(default_callerid, DEFAULT_CALLERID, sizeof(default_callerid));
17424    compactheaders = DEFAULT_COMPACTHEADERS;
17425    global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT;
17426    global_regattempts_max = 0;
17427    pedanticsipchecking = DEFAULT_PEDANTIC;
17428    global_mwitime = DEFAULT_MWITIME;
17429    autocreatepeer = DEFAULT_AUTOCREATEPEER;
17430    global_autoframing = 0;
17431    global_allowguest = DEFAULT_ALLOWGUEST;
17432    global_rtptimeout = 0;
17433    global_rtpholdtimeout = 0;
17434    global_rtpkeepalive = 0;
17435    global_allowtransfer = TRANSFER_OPENFORALL;  /* Merrily accept all transfers by default */
17436    global_rtautoclear = 120;
17437    ast_set_flag(&global_flags[1], SIP_PAGE2_ALLOWSUBSCRIBE);   /* Default for peers, users: TRUE */
17438    ast_set_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP);     /* Default for peers, users: TRUE */
17439    ast_set_flag(&global_flags[1], SIP_PAGE2_RTUPDATE);
17440 
17441    /* Initialize some reasonable defaults at SIP reload (used both for channel and as default for peers and users */
17442    ast_copy_string(default_context, DEFAULT_CONTEXT, sizeof(default_context));
17443    default_subscribecontext[0] = '\0';
17444    default_language[0] = '\0';
17445    default_fromdomain[0] = '\0';
17446    default_qualify = DEFAULT_QUALIFY;
17447    default_maxcallbitrate = DEFAULT_MAX_CALL_BITRATE;
17448    ast_copy_string(default_mohinterpret, DEFAULT_MOHINTERPRET, sizeof(default_mohinterpret));
17449    ast_copy_string(default_mohsuggest, DEFAULT_MOHSUGGEST, sizeof(default_mohsuggest));
17450    ast_copy_string(default_vmexten, DEFAULT_VMEXTEN, sizeof(default_vmexten));
17451    ast_set_flag(&global_flags[0], SIP_DTMF_RFC2833); /*!< Default DTMF setting: RFC2833 */
17452    ast_set_flag(&global_flags[0], SIP_NAT_RFC3581);  /*!< NAT support if requested by device with rport */
17453    ast_set_flag(&global_flags[0], SIP_CAN_REINVITE); /*!< Allow re-invites */
17454    ast_set_flag(&global_flags[0], SIP_NAT_ALWAYS);   /*!< Default to nat=yes */
17455 
17456    /* Debugging settings, always default to off */
17457    dumphistory = FALSE;
17458    recordhistory = FALSE;
17459    ast_clear_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONFIG);
17460 
17461    /* Misc settings for the channel */
17462    global_relaxdtmf = FALSE;
17463    global_callevents = FALSE;
17464    global_t1min = DEFAULT_T1MIN;    
17465 
17466    global_matchexterniplocally = FALSE;
17467 
17468    /* Copy the default jb config over global_jbconf */
17469    memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf));
17470 
17471    ast_clear_flag(&global_flags[1], SIP_PAGE2_VIDEOSUPPORT);
17472 
17473    /* Read the [general] config section of sip.conf (or from realtime config) */
17474    for (v = ast_variable_browse(cfg, "general"); v; v = v->next) {
17475       if (handle_common_options(&global_flags[0], &dummy[0], v))
17476          continue;
17477       /* handle jb conf */
17478       if (!ast_jb_read_conf(&global_jbconf, v->name, v->value))
17479          continue;
17480 
17481       /* Create the interface list */
17482       if (!strcasecmp(v->name, "context")) {
17483          ast_copy_string(default_context, v->value, sizeof(default_context));
17484       } else if (!strcasecmp(v->name, "subscribecontext")) {
17485          ast_copy_string(default_subscribecontext, v->value, sizeof(default_subscribecontext));
17486       } else if (!strcasecmp(v->name, "allowguest")) {
17487          global_allowguest = ast_true(v->value) ? 1 : 0;
17488       } else if (!strcasecmp(v->name, "realm")) {
17489          ast_copy_string(global_realm, v->value, sizeof(global_realm));
17490       } else if (!strcasecmp(v->name, "useragent")) {
17491          ast_copy_string(global_useragent, v->value, sizeof(global_useragent));
17492          if (option_debug)
17493             ast_log(LOG_DEBUG, "Setting SIP channel User-Agent Name to %s\n", global_useragent);
17494       } else if (!strcasecmp(v->name, "allowtransfer")) {
17495          global_allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED;
17496       } else if (!strcasecmp(v->name, "rtcachefriends")) {
17497          ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_RTCACHEFRIENDS);   
17498       } else if (!strcasecmp(v->name, "rtsavesysname")) {
17499          ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_RTSAVE_SYSNAME);   
17500       } else if (!strcasecmp(v->name, "rtupdate")) {
17501          ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_RTUPDATE);   
17502       } else if (!strcasecmp(v->name, "ignoreregexpire")) {
17503          ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_IGNOREREGEXPIRE);  
17504       } else if (!strcasecmp(v->name, "t1min")) {
17505          global_t1min = atoi(v->value);
17506       } else if (!strcasecmp(v->name, "rtautoclear")) {
17507          int i = atoi(v->value);
17508          if (i > 0)
17509             global_rtautoclear = i;
17510          else
17511             i = 0;
17512          ast_set2_flag(&global_flags[1], i || ast_true(v->value), SIP_PAGE2_RTAUTOCLEAR);
17513       } else if (!strcasecmp(v->name, "usereqphone")) {
17514          ast_set2_flag(&global_flags[0], ast_true(v->value), SIP_USEREQPHONE);   
17515       } else if (!strcasecmp(v->name, "relaxdtmf")) {
17516          global_relaxdtmf = ast_true(v->value);
17517       } else if (!strcasecmp(v->name, "checkmwi")) {
17518          if ((sscanf(v->value, "%d", &global_mwitime) != 1) || (global_mwitime < 0)) {
17519             ast_log(LOG_WARNING, "'%s' is not a valid MWI time setting at line %d.  Using default (10).\n", v->value, v->lineno);
17520             global_mwitime = DEFAULT_MWITIME;
17521          }
17522       } else if (!strcasecmp(v->name, "vmexten")) {
17523          ast_copy_string(default_vmexten, v->value, sizeof(default_vmexten));
17524       } else if (!strcasecmp(v->name, "rtptimeout")) {
17525          if ((sscanf(v->value, "%d", &global_rtptimeout) != 1) || (global_rtptimeout < 0)) {
17526             ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d.  Using default.\n", v->value, v->lineno);
17527             global_rtptimeout = 0;
17528          }
17529       } else if (!strcasecmp(v->name, "rtpholdtimeout")) {
17530          if ((sscanf(v->value, "%d", &global_rtpholdtimeout) != 1) || (global_rtpholdtimeout < 0)) {
17531             ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d.  Using default.\n", v->value, v->lineno);
17532             global_rtpholdtimeout = 0;
17533          }
17534       } else if (!strcasecmp(v->name, "rtpkeepalive")) {
17535          if ((sscanf(v->value, "%d", &global_rtpkeepalive) != 1) || (global_rtpkeepalive < 0)) {
17536             ast_log(LOG_WARNING, "'%s' is not a valid RTP keepalive time at line %d.  Using default.\n", v->value, v->lineno);
17537             global_rtpkeepalive = 0;
17538          }
17539       } else if (!strcasecmp(v->name, "compactheaders")) {
17540          compactheaders = ast_true(v->value);
17541       } else if (!strcasecmp(v->name, "notifymimetype")) {
17542          ast_copy_string(default_notifymime, v->value, sizeof(default_notifymime));
17543       } else if (!strncasecmp(v->name, "limitonpeer", 11)) {
17544          global_limitonpeers = ast_true(v->value);
17545       } else if (!strcasecmp(v->name, "directrtpsetup")) {
17546          global_directrtpsetup = ast_true(v->value);
17547       } else if (!strcasecmp(v->name, "notifyringing")) {
17548          global_notifyringing = ast_true(v->value);
17549       } else if (!strcasecmp(v->name, "notifyhold")) {
17550          global_notifyhold = ast_true(v->value);
17551       } else if (!strcasecmp(v->name, "alwaysauthreject")) {
17552          global_alwaysauthreject = ast_true(v->value);
17553       } else if (!strcasecmp(v->name, "mohinterpret") 
17554          || !strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) {
17555          ast_copy_string(default_mohinterpret, v->value, sizeof(default_mohinterpret));
17556       } else if (!strcasecmp(v->name, "mohsuggest")) {
17557          ast_copy_string(default_mohsuggest, v->value, sizeof(default_mohsuggest));
17558       } else if (!strcasecmp(v->name, "language")) {
17559          ast_copy_string(default_language, v->value, sizeof(default_language));
17560       } else if (!strcasecmp(v->name, "regcontext")) {
17561          ast_copy_string(newcontexts, v->value, sizeof(newcontexts));
17562          stringp = newcontexts;
17563          /* Let's remove any contexts that are no longer defined in regcontext */
17564          cleanup_stale_contexts(stringp, oldregcontext);
17565          /* Create contexts if they don't exist already */
17566          while ((context = strsep(&stringp, "&"))) {
17567             if (!ast_context_find(context))
17568                ast_context_create(NULL, context,"SIP");
17569          }
17570          ast_copy_string(global_regcontext, v->value, sizeof(global_regcontext));
17571       } else if (!strcasecmp(v->name, "callerid")) {
17572          ast_copy_string(default_callerid, v->value, sizeof(default_callerid));
17573       } else if (!strcasecmp(v->name, "fromdomain")) {
17574          ast_copy_string(default_fromdomain, v->value, sizeof(default_fromdomain));
17575       } else if (!strcasecmp(v->name, "outboundproxy")) {
17576          if (ast_get_ip_or_srv(&outboundproxyip, v->value, srvlookup ? "_sip._udp" : NULL) < 0)
17577             ast_log(LOG_WARNING, "Unable to locate host '%s'\n", v->value);
17578       } else if (!strcasecmp(v->name, "outboundproxyport")) {
17579          /* Port needs to be after IP */
17580          sscanf(v->value, "%d", &format);
17581          outboundproxyip.sin_port = htons(format);
17582       } else if (!strcasecmp(v->name, "autocreatepeer")) {
17583          autocreatepeer = ast_true(v->value);
17584       } else if (!strcasecmp(v->name, "srvlookup")) {
17585          srvlookup = ast_true(v->value);
17586       } else if (!strcasecmp(v->name, "pedantic")) {
17587          pedanticsipchecking = ast_true(v->value);
17588       } else if (!strcasecmp(v->name, "maxexpirey") || !strcasecmp(v->name, "maxexpiry")) {
17589          max_expiry = atoi(v->value);
17590          if (max_expiry < 1)
17591             max_expiry = DEFAULT_MAX_EXPIRY;
17592       } else if (!strcasecmp(v->name, "minexpirey") || !strcasecmp(v->name, "minexpiry")) {
17593          min_expiry = atoi(v->value);
17594          if (min_expiry < 1)
17595             min_expiry = DEFAULT_MIN_EXPIRY;
17596       } else if (!strcasecmp(v->name, "defaultexpiry") || !strcasecmp(v->name, "defaultexpirey")) {
17597          default_expiry = atoi(v->value);
17598          if (default_expiry < 1)
17599             default_expiry = DEFAULT_DEFAULT_EXPIRY;
17600       } else if (!strcasecmp(v->name, "sipdebug")) {  /* XXX maybe ast_set2_flags ? */
17601          if (ast_true(v->value))
17602             ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONFIG);
17603       } else if (!strcasecmp(v->name, "dumphistory")) {
17604          dumphistory = ast_true(v->value);
17605       } else if (!strcasecmp(v->name, "recordhistory")) {
17606          recordhistory = ast_true(v->value);
17607       } else if (!strcasecmp(v->name, "registertimeout")) {
17608          global_reg_timeout = atoi(v->value);
17609          if (global_reg_timeout < 1)
17610             global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT;
17611       } else if (!strcasecmp(v->name, "registerattempts")) {
17612          global_regattempts_max = atoi(v->value);
17613       } else if (!strcasecmp(v->name, "bindaddr")) {
17614          if (!(hp = ast_gethostbyname(v->value, &ahp))) {
17615             ast_log(LOG_WARNING, "Invalid address: %s\n", v->value);
17616          } else {
17617             memcpy(&bindaddr.sin_addr, hp->h_addr, sizeof(bindaddr.sin_addr));
17618          }
17619       } else if (!strcasecmp(v->name, "localnet")) {
17620          struct ast_ha *na;
17621          if (!(na = ast_append_ha("d", v->value, localaddr)))
17622             ast_log(LOG_WARNING, "Invalid localnet value: %s\n", v->value);
17623          else
17624             localaddr = na;
17625       } else if (!strcasecmp(v->name, "localmask")) {
17626          ast_log(LOG_WARNING, "Use of localmask is no long supported -- use localnet with mask syntax\n");
17627       } else if (!strcasecmp(v->name, "externip")) {
17628          if (!(hp = ast_gethostbyname(v->value, &ahp))) 
17629             ast_log(LOG_WARNING, "Invalid address for externip keyword: %s\n", v->value);
17630          else
17631             memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr));
17632          externexpire = 0;
17633       } else if (!strcasecmp(v->name, "externhost")) {
17634          ast_copy_string(externhost, v->value, sizeof(externhost));
17635          if (!(hp = ast_gethostbyname(externhost, &ahp))) 
17636             ast_log(LOG_WARNING, "Invalid address for externhost keyword: %s\n", externhost);
17637          else
17638             memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr));
17639          externexpire = time(NULL);
17640       } else if (!strcasecmp(v->name, "externrefresh")) {
17641          if (sscanf(v->value, "%d", &externrefresh) != 1) {
17642             ast_log(LOG_WARNING, "Invalid externrefresh value '%s', must be an integer >0 at line %d\n", v->value, v->lineno);
17643             externrefresh = 10;
17644          }
17645       } else if (!strcasecmp(v->name, "allow")) {
17646          ast_parse_allow_disallow(&default_prefs, &global_capability, v->value, 1);
17647       } else if (!strcasecmp(v->name, "disallow")) {
17648          ast_parse_allow_disallow(&default_prefs, &global_capability, v->value, 0);
17649       } else if (!strcasecmp(v->name, "autoframing")) {
17650          global_autoframing = ast_true(v->value);
17651       } else if (!strcasecmp(v->name, "allowexternaldomains")) {
17652          allow_external_domains = ast_true(v->value);
17653       } else if (!strcasecmp(v->name, "autodomain")) {
17654          auto_sip_domains = ast_true(v->value);
17655       } else if (!strcasecmp(v->name, "domain")) {
17656          char *domain = ast_strdupa(v->value);
17657          char *context = strchr(domain, ',');
17658 
17659          if (context)
17660             *context++ = '\0';
17661 
17662          if (option_debug && ast_strlen_zero(context))
17663             ast_log(LOG_DEBUG, "No context specified at line %d for domain '%s'\n", v->lineno, domain);
17664          if (ast_strlen_zero(domain))
17665             ast_log(LOG_WARNING, "Empty domain specified at line %d\n", v->lineno);
17666          else
17667             add_sip_domain(ast_strip(domain), SIP_DOMAIN_CONFIG, context ? ast_strip(context) : "");
17668       } else if (!strcasecmp(v->name, "register")) {
17669          if (sip_register(v->value, v->lineno) == 0)
17670             registry_count++;
17671       } else if (!strcasecmp(v->name, "tos")) {
17672          if (!ast_str2tos(v->value, &temp_tos)) {
17673             global_tos_sip = temp_tos;
17674             global_tos_audio = temp_tos;
17675             global_tos_video = temp_tos;
17676             ast_log(LOG_WARNING, "tos value at line %d is deprecated.  See doc/ip-tos.txt for more information.\n", v->lineno);
17677          } else
17678             ast_log(LOG_WARNING, "Invalid tos value at line %d, See doc/ip-tos.txt for more information.\n", v->lineno);
17679       } else if (!strcasecmp(v->name, "tos_sip")) {
17680          if (ast_str2tos(v->value, &global_tos_sip))
17681             ast_log(LOG_WARNING, "Invalid tos_sip value at line %d, recommended value is 'cs3'. See doc/ip-tos.txt.\n", v->lineno);
17682       } else if (!strcasecmp(v->name, "tos_audio")) {
17683          if (ast_str2tos(v->value, &global_tos_audio))
17684             ast_log(LOG_WARNING, "Invalid tos_audio value at line %d, recommended value is 'ef'. See doc/ip-tos.txt.\n", v->lineno);
17685       } else if (!strcasecmp(v->name, "tos_video")) {
17686          if (ast_str2tos(v->value, &global_tos_video))
17687             ast_log(LOG_WARNING, "Invalid tos_video value at line %d, recommended value is 'af41'. See doc/ip-tos.txt.\n", v->lineno);
17688       } else if (!strcasecmp(v->name, "bindport")) {
17689          if (sscanf(v->value, "%d", &ourport) == 1) {
17690             bindaddr.sin_port = htons(ourport);
17691          } else {
17692             ast_log(LOG_WARNING, "Invalid port number '%s' at line %d of %s\n", v->value, v->lineno, config);
17693          }
17694       } else if (!strcasecmp(v->name, "qualify")) {
17695          if (!strcasecmp(v->value, "no")) {
17696             default_qualify = 0;
17697          } else if (!strcasecmp(v->value, "yes")) {
17698             default_qualify = DEFAULT_MAXMS;
17699          } else if (sscanf(v->value, "%d", &default_qualify) != 1) {
17700             ast_log(LOG_WARNING, "Qualification default should be 'yes', 'no', or a number of milliseconds at line %d of sip.conf\n", v->lineno);
17701             default_qualify = 0;
17702          }
17703       } else if (!strcasecmp(v->name, "callevents")) {
17704          global_callevents = ast_true(v->value);
17705       } else if (!strcasecmp(v->name, "maxcallbitrate")) {
17706          default_maxcallbitrate = atoi(v->value);
17707          if (default_maxcallbitrate < 0)
17708             default_maxcallbitrate = DEFAULT_MAX_CALL_BITRATE;
17709       } else if (!strcasecmp(v->name, "matchexterniplocally")) {
17710          global_matchexterniplocally = ast_true(v->value);
17711       }
17712    }
17713 
17714    if (!allow_external_domains && AST_LIST_EMPTY(&domain_list)) {
17715       ast_log(LOG_WARNING, "To disallow external domains, you need to configure local SIP domains.\n");
17716       allow_external_domains = 1;
17717    }
17718    
17719    /* Build list of authentication to various SIP realms, i.e. service providers */
17720    for (v = ast_variable_browse(cfg, "authentication"); v ; v = v->next) {
17721       /* Format for authentication is auth = username:password@realm */
17722       if (!strcasecmp(v->name, "auth"))
17723          authl = add_realm_authentication(authl, v->value, v->lineno);
17724    }
17725    
17726    ucfg = ast_config_load("users.conf");
17727    if (ucfg) {
17728       struct ast_variable *gen;
17729       int genhassip, genregistersip;
17730       const char *hassip, *registersip;
17731       
17732       genhassip = ast_true(ast_variable_retrieve(ucfg, "general", "hassip"));
17733       genregistersip = ast_true(ast_variable_retrieve(ucfg, "general", "registersip"));
17734       gen = ast_variable_browse(ucfg, "general");
17735       cat = ast_category_browse(ucfg, NULL);
17736       while (cat) {
17737          if (strcasecmp(cat, "general")) {
17738             hassip = ast_variable_retrieve(ucfg, cat, "hassip");
17739             registersip = ast_variable_retrieve(ucfg, cat, "registersip");
17740             if (ast_true(hassip) || (!hassip && genhassip)) {
17741                user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0);
17742                if (user) {
17743                   ASTOBJ_CONTAINER_LINK(&userl,user);
17744                   ASTOBJ_UNREF(user, sip_destroy_user);
17745                   user_count++;
17746                }
17747                peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0);
17748                if (peer) {
17749                   ast_device_state_changed("SIP/%s", peer->name);
17750                   ASTOBJ_CONTAINER_LINK(&peerl,peer);
17751                   ASTOBJ_UNREF(peer, sip_destroy_peer);
17752                   peer_count++;
17753                }
17754             }
17755             if (ast_true(registersip) || (!registersip && genregistersip)) {
17756                char tmp[256];
17757                const char *host = ast_variable_retrieve(ucfg, cat, "host");
17758                const char *username = ast_variable_retrieve(ucfg, cat, "username");
17759                const char *secret = ast_variable_retrieve(ucfg, cat, "secret");
17760                const char *contact = ast_variable_retrieve(ucfg, cat, "contact");
17761                if (!host)
17762                   host = ast_variable_retrieve(ucfg, "general", "host");
17763                if (!username)
17764                   username = ast_variable_retrieve(ucfg, "general", "username");
17765                if (!secret)
17766                   secret = ast_variable_retrieve(ucfg, "general", "secret");
17767                if (!contact)
17768                   contact = "s";
17769                if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) {
17770                   if (!ast_strlen_zero(secret))
17771                      snprintf(tmp, sizeof(tmp), "%s:%s@%s/%s", username, secret, host, contact);
17772                   else
17773                      snprintf(tmp, sizeof(tmp), "%s@%s/%s", username, host, contact);
17774                   if (sip_register(tmp, 0) == 0)
17775                      registry_count++;
17776                }
17777             }
17778          }
17779          cat = ast_category_browse(ucfg, cat);
17780       }
17781       ast_config_destroy(ucfg);
17782    }
17783    
17784 
17785    /* Load peers, users and friends */
17786    cat = NULL;
17787    while ( (cat = ast_category_browse(cfg, cat)) ) {
17788       const char *utype;
17789       if (!strcasecmp(cat, "general") || !strcasecmp(cat, "authentication"))
17790          continue;
17791       utype = ast_variable_retrieve(cfg, cat, "type");
17792       if (!utype) {
17793          ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat);
17794          continue;
17795       } else {
17796          int is_user = 0, is_peer = 0;
17797          if (!strcasecmp(utype, "user"))
17798             is_user = 1;
17799          else if (!strcasecmp(utype, "friend"))
17800             is_user = is_peer = 1;
17801          else if (!strcasecmp(utype, "peer"))
17802             is_peer = 1;
17803          else {
17804             ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, "sip.conf");
17805             continue;
17806          }
17807          if (is_user) {
17808             user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0);
17809             if (user) {
17810                display_nat_warning(cat, reason, &user->flags[0]);
17811                ASTOBJ_CONTAINER_LINK(&userl,user);
17812                ASTOBJ_UNREF(user, sip_destroy_user);
17813                user_count++;
17814             }
17815          }
17816          if (is_peer) {
17817             peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0);
17818             if (peer) {
17819                if (!is_user) {
17820                   display_nat_warning(cat, reason, &peer->flags[0]);
17821                }
17822                ASTOBJ_CONTAINER_LINK(&peerl,peer);
17823                ASTOBJ_UNREF(peer, sip_destroy_peer);
17824                peer_count++;
17825             }
17826          }
17827       }
17828    }
17829 
17830    if (ast_find_ourip(&__ourip, bindaddr)) {
17831       ast_log(LOG_WARNING, "Unable to get own IP address, SIP disabled\n");
17832       ast_config_destroy(cfg);
17833       return 0;
17834    }
17835    if (!ntohs(bindaddr.sin_port))
17836       bindaddr.sin_port = ntohs(STANDARD_SIP_PORT);
17837    bindaddr.sin_family = AF_INET;
17838    ast_mutex_lock(&netlock);
17839    if ((sipsock > -1) && (memcmp(&old_bindaddr, &bindaddr, sizeof(struct sockaddr_in)))) {
17840       close(sipsock);
17841       sipsock = -1;
17842    }
17843    if (sipsock < 0) {
17844       sipsock = socket(AF_INET, SOCK_DGRAM, 0);
17845       if (sipsock < 0) {
17846          ast_log(LOG_WARNING, "Unable to create SIP socket: %s\n", strerror(errno));
17847          ast_config_destroy(cfg);
17848          return -1;
17849       } else {
17850          /* Allow SIP clients on the same host to access us: */
17851          const int reuseFlag = 1;
17852 
17853          setsockopt(sipsock, SOL_SOCKET, SO_REUSEADDR,
17854                (const char*)&reuseFlag,
17855                sizeof reuseFlag);
17856 
17857          ast_enable_packet_fragmentation(sipsock);
17858 
17859          if (bind(sipsock, (struct sockaddr *)&bindaddr, sizeof(bindaddr)) < 0) {
17860             ast_log(LOG_WARNING, "Failed to bind to %s:%d: %s\n",
17861             ast_inet_ntoa(bindaddr.sin_addr), ntohs(bindaddr.sin_port),
17862             strerror(errno));
17863             close(sipsock);
17864             sipsock = -1;
17865          } else {
17866             if (option_verbose > 1) { 
17867                ast_verbose(VERBOSE_PREFIX_2 "SIP Listening on %s:%d\n", 
17868                ast_inet_ntoa(bindaddr.sin_addr), ntohs(bindaddr.sin_port));
17869                ast_verbose(VERBOSE_PREFIX_2 "Using SIP TOS: %s\n", ast_tos2str(global_tos_sip));
17870             }
17871             if (setsockopt(sipsock, IPPROTO_IP, IP_TOS, &global_tos_sip, sizeof(global_tos_sip))) 
17872                ast_log(LOG_WARNING, "Unable to set SIP TOS to %s\n", ast_tos2str(global_tos_sip));
17873          }
17874       }
17875    }
17876    ast_mutex_unlock(&netlock);
17877 
17878    /* Add default domains - host name, IP address and IP:port */
17879    /* Only do this if user added any sip domain with "localdomains" */
17880    /* In order to *not* break backwards compatibility */
17881    /*    Some phones address us at IP only, some with additional port number */
17882    if (auto_sip_domains) {
17883       char temp[MAXHOSTNAMELEN];
17884 
17885       /* First our default IP address */
17886       if (bindaddr.sin_addr.s_addr)
17887          add_sip_domain(ast_inet_ntoa(bindaddr.sin_addr), SIP_DOMAIN_AUTO, NULL);
17888       else
17889          ast_log(LOG_NOTICE, "Can't add wildcard IP address to domain list, please add IP address to domain manually.\n");
17890 
17891       /* Our extern IP address, if configured */
17892       if (externip.sin_addr.s_addr)
17893          add_sip_domain(ast_inet_ntoa(externip.sin_addr), SIP_DOMAIN_AUTO, NULL);
17894 
17895       /* Extern host name (NAT traversal support) */
17896       if (!ast_strlen_zero(externhost))
17897          add_sip_domain(externhost, SIP_DOMAIN_AUTO, NULL);
17898       
17899       /* Our host name */
17900       if (!gethostname(temp, sizeof(temp)))
17901          add_sip_domain(temp, SIP_DOMAIN_AUTO, NULL);
17902    }
17903 
17904    /* Release configuration from memory */
17905    ast_config_destroy(cfg);
17906 
17907    /* Load the list of manual NOTIFY types to support */
17908    if (notify_types)
17909       ast_config_destroy(notify_types);
17910    notify_types = ast_config_load(notify_config);
17911 
17912    /* Done, tell the manager */
17913    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);
17914 
17915    return 0;
17916 }

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 11618 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(), keys, LOG_WARNING, sip_registry::noncecount, sip_pvt::noncecount, sip_pvt::registry, and strsep().

Referenced by do_proxy_auth(), and do_register_auth().

11619 {
11620    char tmp[512];
11621    char *c;
11622    char oldnonce[256];
11623 
11624    /* table of recognised keywords, and places where they should be copied */
11625    const struct x {
11626       const char *key;
11627       int field_index;
11628    } *i, keys[] = {
11629       { "realm=", ast_string_field_index(p, realm) },
11630       { "nonce=", ast_string_field_index(p, nonce) },
11631       { "opaque=", ast_string_field_index(p, opaque) },
11632       { "qop=", ast_string_field_index(p, qop) },
11633       { "domain=", ast_string_field_index(p, domain) },
11634       { NULL, 0 },
11635    };
11636 
11637    ast_copy_string(tmp, get_header(req, header), sizeof(tmp));
11638    if (ast_strlen_zero(tmp)) 
11639       return -1;
11640    if (strncasecmp(tmp, "Digest ", strlen("Digest "))) {
11641       ast_log(LOG_WARNING, "missing Digest.\n");
11642       return -1;
11643    }
11644    c = tmp + strlen("Digest ");
11645    ast_copy_string(oldnonce, p->nonce, sizeof(oldnonce));
11646    while (c && *(c = ast_skip_blanks(c))) {  /* lookup for keys */
11647       for (i = keys; i->key != NULL; i++) {
11648          char *src, *separator;
11649          if (strncasecmp(c, i->key, strlen(i->key)) != 0)
11650             continue;
11651          /* Found. Skip keyword, take text in quotes or up to the separator. */
11652          c += strlen(i->key);
11653          if (*c == '"') {
11654             src = ++c;
11655             separator = "\"";
11656          } else {
11657             src = c;
11658             separator = ",";
11659          }
11660          strsep(&c, separator); /* clear separator and move ptr */
11661          ast_string_field_index_set(p, i->field_index, src);
11662          break;
11663       }
11664       if (i->key == NULL) /* not found, try ',' */
11665          strsep(&c, ",");
11666    }
11667    /* Reset nonce count */
11668    if (strcmp(p->nonce, oldnonce)) 
11669       p->noncecount = 0;
11670 
11671    /* Save auth data for following registrations */
11672    if (p->registry) {
11673       struct sip_registry *r = p->registry;
11674 
11675       if (strcmp(r->nonce, p->nonce)) {
11676          ast_string_field_set(r, realm, p->realm);
11677          ast_string_field_set(r, nonce, p->nonce);
11678          ast_string_field_set(r, domain, p->domain);
11679          ast_string_field_set(r, opaque, p->opaque);
11680          ast_string_field_set(r, qop, p->qop);
11681          r->noncecount = 0;
11682       }
11683    }
11684    return build_reply_digest(p, sipmethod, digest, digest_len); 
11685 }

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

05930 {
05931    struct sip_request *orig = &p->initreq;
05932    char stripped[80];
05933    char tmp[80];
05934    char newto[256];
05935    const char *c;
05936    const char *ot, *of;
05937    int is_strict = FALSE;     /*!< Strict routing flag */
05938 
05939    memset(req, 0, sizeof(struct sip_request));
05940    
05941    snprintf(p->lastmsg, sizeof(p->lastmsg), "Tx: %s", sip_methods[sipmethod].text);
05942    
05943    if (!seqno) {
05944       p->ocseq++;
05945       seqno = p->ocseq;
05946    }
05947    
05948    if (newbranch) {
05949       p->branch ^= ast_random();
05950       build_via(p);
05951    }
05952 
05953    /* Check for strict or loose router */
05954    if (p->route && !ast_strlen_zero(p->route->hop) && strstr(p->route->hop,";lr") == NULL) {
05955       is_strict = TRUE;
05956       if (sipdebug)
05957          ast_log(LOG_DEBUG, "Strict routing enforced for session %s\n", p->callid);
05958    }
05959 
05960    if (sipmethod == SIP_CANCEL)
05961       c = p->initreq.rlPart2; /* Use original URI */
05962    else if (sipmethod == SIP_ACK) {
05963       /* Use URI from Contact: in 200 OK (if INVITE) 
05964       (we only have the contacturi on INVITEs) */
05965       if (!ast_strlen_zero(p->okcontacturi))
05966          c = is_strict ? p->route->hop : p->okcontacturi;
05967       else
05968          c = p->initreq.rlPart2;
05969    } else if (!ast_strlen_zero(p->okcontacturi)) 
05970       c = is_strict ? p->route->hop : p->okcontacturi; /* Use for BYE or REINVITE */
05971    else if (!ast_strlen_zero(p->uri)) 
05972       c = p->uri;
05973    else {
05974       char *n;
05975       /* We have no URI, use To: or From:  header as URI (depending on direction) */
05976       ast_copy_string(stripped, get_header(orig, (ast_test_flag(&p->flags[0], SIP_OUTGOING)) ? "To" : "From"),
05977             sizeof(stripped));
05978       n = get_in_brackets(stripped);
05979       c = strsep(&n, ";"); /* trim ; and beyond */
05980    }  
05981    init_req(req, sipmethod, c);
05982 
05983    snprintf(tmp, sizeof(tmp), "%d %s", seqno, sip_methods[sipmethod].text);
05984 
05985    add_header(req, "Via", p->via);
05986    if (p->route) {
05987       set_destination(p, p->route->hop);
05988       add_route(req, is_strict ? p->route->next : p->route);
05989    }
05990 
05991    ot = get_header(orig, "To");
05992    of = get_header(orig, "From");
05993 
05994    /* Add tag *unless* this is a CANCEL, in which case we need to send it exactly
05995       as our original request, including tag (or presumably lack thereof) */
05996    if (!strcasestr(ot, "tag=") && sipmethod != SIP_CANCEL) {
05997       /* Add the proper tag if we don't have it already.  If they have specified
05998          their tag, use it.  Otherwise, use our own tag */
05999       if (ast_test_flag(&p->flags[0], SIP_OUTGOING) && !ast_strlen_zero(p->theirtag))
06000          snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->theirtag);
06001       else if (!ast_test_flag(&p->flags[0], SIP_OUTGOING))
06002          snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->tag);
06003       else
06004          snprintf(newto, sizeof(newto), "%s", ot);
06005       ot = newto;
06006    }
06007 
06008    if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
06009       add_header(req, "From", of);
06010       add_header(req, "To", ot);
06011    } else {
06012       add_header(req, "From", ot);
06013       add_header(req, "To", of);
06014    }
06015    /* Do not add Contact for MESSAGE, BYE and Cancel requests */
06016    if (sipmethod != SIP_BYE && sipmethod != SIP_CANCEL && sipmethod != SIP_MESSAGE)
06017       add_header(req, "Contact", p->our_contact);
06018 
06019    copy_header(req, orig, "Call-ID");
06020    add_header(req, "CSeq", tmp);
06021 
06022    if (!ast_strlen_zero(global_useragent))
06023       add_header(req, "User-Agent", global_useragent);
06024    add_header(req, "Max-Forwards", DEFAULT_MAX_FORWARDS);
06025 
06026    if (!ast_strlen_zero(p->rpid))
06027       add_header(req, "Remote-Party-ID", p->rpid);
06028 
06029    return 0;
06030 }

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 5881 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, SIPBUFSIZE, strcasestr(), SUPPORTED_EXTENSIONS, and sip_pvt::tag.

05882 {
05883    char newto[256];
05884    const char *ot;
05885 
05886    init_resp(resp, msg);
05887    copy_via_headers(p, resp, req, "Via");
05888    if (msg[0] == '1' || msg[0] == '2')
05889       copy_all_header(resp, req, "Record-Route");
05890    copy_header(resp, req, "From");
05891    ot = get_header(req, "To");
05892    if (!strcasestr(ot, "tag=") && strncmp(msg, "100", 3)) {
05893       /* Add the proper tag if we don't have it already.  If they have specified
05894          their tag, use it.  Otherwise, use our own tag */
05895       if (!ast_strlen_zero(p->theirtag) && ast_test_flag(&p->flags[0], SIP_OUTGOING))
05896          snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->theirtag);
05897       else if (p->tag && !ast_test_flag(&p->flags[0], SIP_OUTGOING))
05898          snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->tag);
05899       else
05900          ast_copy_string(newto, ot, sizeof(newto));
05901       ot = newto;
05902    }
05903    add_header(resp, "To", ot);
05904    copy_header(resp, req, "Call-ID");
05905    copy_header(resp, req, "CSeq");
05906    if (!ast_strlen_zero(global_useragent))
05907       add_header(resp, "User-Agent", global_useragent);
05908    add_header(resp, "Allow", ALLOWED_METHODS);
05909    add_header(resp, "Supported", SUPPORTED_EXTENSIONS);
05910    if (msg[0] == '2' && (p->method == SIP_SUBSCRIBE || p->method == SIP_REGISTER)) {
05911       /* For registration responses, we also need expiry and
05912          contact info */
05913       char tmp[256];
05914 
05915       snprintf(tmp, sizeof(tmp), "%d", p->expiry);
05916       add_header(resp, "Expires", tmp);
05917       if (p->expiry) {  /* Only add contact if we have an expiry time */
05918          char contact[SIPBUFSIZE];
05919          snprintf(contact, sizeof(contact), "%s;expires=%d", p->our_contact, p->expiry);
05920          add_header(resp, "Contact", contact);  /* Not when we unregister */
05921       }
05922    } else if (msg[0] != '4' && !ast_strlen_zero(p->our_contact)) {
05923       add_header(resp, "Contact", p->our_contact);
05924    }
05925    return 0;
05926 }

static int restart_monitor ( void   )  [static]

Start the channel monitor thread.

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

16226 {
16227    /* If we're supposed to be stopped -- stay stopped */
16228    if (monitor_thread == AST_PTHREADT_STOP)
16229       return 0;
16230    ast_mutex_lock(&monlock);
16231    if (monitor_thread == pthread_self()) {
16232       ast_mutex_unlock(&monlock);
16233       ast_log(LOG_WARNING, "Cannot kill myself\n");
16234       return -1;
16235    }
16236    if (monitor_thread != AST_PTHREADT_NULL) {
16237       /* Wake up the thread */
16238       pthread_kill(monitor_thread, SIGURG);
16239    } else {
16240       /* Start a new monitor */
16241       if (ast_pthread_create_background(&monitor_thread, NULL, do_monitor, NULL) < 0) {
16242          ast_mutex_unlock(&monlock);
16243          ast_log(LOG_ERROR, "Unable to start monitor thread.\n");
16244          return -1;
16245       }
16246    }
16247    ast_mutex_unlock(&monlock);
16248    return 0;
16249 }

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

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

Definition at line 1896 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, DEADLOCK_AVOIDANCE, 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.

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

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

02288 {
02289    int res;
02290 
02291    add_blank(req);
02292    if (sip_debug_test_pvt(p)) {
02293       if (ast_test_flag(&p->flags[0], SIP_NAT_ROUTE))
02294          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);
02295       else
02296          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);
02297    }
02298    if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) {
02299       struct sip_request tmp;
02300       parse_copy(&tmp, req);
02301       append_history(p, reliable ? "TxReqRel" : "TxReq", "%s / %s - %s", tmp.data, get_header(&tmp, "CSeq"), sip_methods[tmp.method].text);
02302    }
02303    res = (reliable) ?
02304       __sip_reliable_xmit(p, seqno, 0, req->data, req->len, (reliable == XMIT_CRITICAL), req->method) :
02305       __sip_xmit(p, req->data, req->len);
02306    return res;
02307 }

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

02260 {
02261    int res;
02262 
02263    add_blank(req);
02264    if (sip_debug_test_pvt(p)) {
02265       const struct sockaddr_in *dst = sip_real_dst(p);
02266 
02267       ast_verbose("\n<--- %sTransmitting (%s) to %s:%d --->\n%s\n<------------>\n",
02268          reliable ? "Reliably " : "", sip_nat_mode(p),
02269          ast_inet_ntoa(dst->sin_addr),
02270          ntohs(dst->sin_port), req->data);
02271    }
02272    if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) {
02273       struct sip_request tmp;
02274       parse_copy(&tmp, req);
02275       append_history(p, reliable ? "TxRespRel" : "TxResp", "%s / %s - %s", tmp.data, get_header(&tmp, "CSeq"), 
02276          (tmp.method == SIP_RESPONSE || tmp.method == SIP_UNKNOWN) ? tmp.rlPart2 : sip_methods[tmp.method].text);
02277    }
02278    res = (reliable) ?
02279        __sip_reliable_xmit(p, seqno, 1, req->data, req->len, (reliable == XMIT_CRITICAL), req->method) :
02280       __sip_xmit(p, req->data, req->len);
02281    if (res > 0)
02282       return 0;
02283    return res;
02284 }

static int set_address_from_contact ( struct sip_pvt pvt  )  [static]

Change the other partys IP address based on given contact.

Definition at line 8050 of file chan_sip.c.

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

08051 {
08052    struct hostent *hp;
08053    struct ast_hostent ahp;
08054    int port;
08055    char *c, *host, *pt;
08056    char contact_buf[256];
08057    char *contact;
08058 
08059    if (ast_test_flag(&pvt->flags[0], SIP_NAT_ROUTE)) {
08060       /* NAT: Don't trust the contact field.  Just use what they came to us
08061          with. */
08062       pvt->sa = pvt->recv;
08063       return 0;
08064    }
08065 
08066    /* Work on a copy */
08067    ast_copy_string(contact_buf, pvt->fullcontact, sizeof(contact_buf));
08068    contact = contact_buf;
08069 
08070    /* Make sure it's a SIP URL */
08071    if (strncasecmp(contact, "sip:", 4)) {
08072       ast_log(LOG_NOTICE, "'%s' is not a valid SIP contact (missing sip:) trying to use anyway\n", contact);
08073    } else
08074       contact += 4;
08075 
08076    /* Ditch arguments */
08077    /* XXX this code is replicated also shortly below */
08078 
08079    /* Grab host */
08080    host = strchr(contact, '@');
08081    if (!host) {   /* No username part */
08082       host = contact;
08083       c = NULL;
08084    } else {
08085       *host++ = '\0';
08086    }
08087    pt = strchr(host, ':');
08088    if (pt) {
08089       *pt++ = '\0';
08090       port = atoi(pt);
08091    } else
08092       port = STANDARD_SIP_PORT;
08093 
08094    contact = strsep(&contact, ";"); /* trim ; and beyond in username part */
08095    host = strsep(&host, ";");    /* trim ; and beyond in host/domain part */
08096 
08097    /* XXX This could block for a long time XXX */
08098    /* We should only do this if it's a name, not an IP */
08099    hp = ast_gethostbyname(host, &ahp);
08100    if (!hp)  {
08101       ast_log(LOG_WARNING, "Invalid host name in Contact: (can't resolve in DNS) : '%s'\n", host);
08102       return -1;
08103    }
08104    pvt->sa.sin_family = AF_INET;
08105    memcpy(&pvt->sa.sin_addr, hp->h_addr, sizeof(pvt->sa.sin_addr));
08106    pvt->sa.sin_port = htons(port);
08107 
08108    return 0;
08109 }

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

Set destination from SIP URI.

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

05791 {
05792    char *h, *maddr, hostname[256];
05793    int port, hn;
05794    struct hostent *hp;
05795    struct ast_hostent ahp;
05796    int debug=sip_debug_test_pvt(p);
05797 
05798    /* Parse uri to h (host) and port - uri is already just the part inside the <> */
05799    /* general form we are expecting is sip[s]:username[:password]@host[:port][;...] */
05800 
05801    if (debug)
05802       ast_verbose("set_destination: Parsing <%s> for address/port to send to\n", uri);
05803 
05804    /* Find and parse hostname */
05805    h = strchr(uri, '@');
05806    if (h)
05807       ++h;
05808    else {
05809       h = uri;
05810       if (strncasecmp(h, "sip:", 4) == 0)
05811          h += 4;
05812       else if (strncasecmp(h, "sips:", 5) == 0)
05813          h += 5;
05814    }
05815    hn = strcspn(h, ":;>") + 1;
05816    if (hn > sizeof(hostname)) 
05817       hn = sizeof(hostname);
05818    ast_copy_string(hostname, h, hn);
05819    /* XXX bug here if string has been trimmed to sizeof(hostname) */
05820    h += hn - 1;
05821 
05822    /* Is "port" present? if not default to STANDARD_SIP_PORT */
05823    if (*h == ':') {
05824       /* Parse port */
05825       ++h;
05826       port = strtol(h, &h, 10);
05827    }
05828    else
05829       port = STANDARD_SIP_PORT;
05830 
05831    /* Got the hostname:port - but maybe there's a "maddr=" to override address? */
05832    maddr = strstr(h, "maddr=");
05833    if (maddr) {
05834       maddr += 6;
05835       hn = strspn(maddr, "0123456789.") + 1;
05836       if (hn > sizeof(hostname))
05837          hn = sizeof(hostname);
05838       ast_copy_string(hostname, maddr, hn);
05839    }
05840    
05841    hp = ast_gethostbyname(hostname, &ahp);
05842    if (hp == NULL)  {
05843       ast_log(LOG_WARNING, "Can't find address for host '%s'\n", hostname);
05844       return;
05845    }
05846    p->sa.sin_family = AF_INET;
05847    memcpy(&p->sa.sin_addr, hp->h_addr, sizeof(p->sa.sin_addr));
05848    p->sa.sin_port = htons(port);
05849    if (debug)
05850       ast_verbose("set_destination: set destination to %s, port %d\n", ast_inet_ntoa(p->sa.sin_addr), port);
05851 }

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

16553 {
16554    static int dep_insecure_very = 0;
16555    static int dep_insecure_yes = 0;
16556 
16557    if (ast_strlen_zero(value))
16558       return;
16559 
16560    if (!strcasecmp(value, "very")) {
16561       ast_set_flag(flags, SIP_INSECURE_PORT | SIP_INSECURE_INVITE);
16562       if(!dep_insecure_very) {
16563          if(lineno != -1)
16564             ast_log(LOG_WARNING, "insecure=very at line %d is deprecated; use insecure=port,invite instead\n", lineno);
16565          else
16566             ast_log(LOG_WARNING, "insecure=very is deprecated; use insecure=port,invite instead\n");
16567          dep_insecure_very = 1;
16568       }
16569    }
16570    else if (ast_true(value)) {
16571       ast_set_flag(flags, SIP_INSECURE_PORT);
16572       if(!dep_insecure_yes) {
16573          if(lineno != -1)
16574             ast_log(LOG_WARNING, "insecure=%s at line %d is deprecated; use insecure=port instead\n", value, lineno);
16575          else
16576             ast_log(LOG_WARNING, "insecure=%s is deprecated; use insecure=port instead\n", value);
16577          dep_insecure_yes = 1;
16578       }
16579    }
16580    else if (!ast_false(value)) {
16581       char buf[64];
16582       char *word, *next;
16583       ast_copy_string(buf, value, sizeof(buf));
16584       next = buf;
16585       while ((word = strsep(&next, ","))) {
16586          if (!strcasecmp(word, "port"))
16587             ast_set_flag(flags, SIP_INSECURE_PORT);
16588          else if (!strcasecmp(word, "invite"))
16589             ast_set_flag(flags, SIP_INSECURE_INVITE);
16590          else
16591             ast_log(LOG_WARNING, "Unknown insecure mode '%s' on line %d\n", value, lineno);
16592       }
16593    }
16594 }

static void set_peer_defaults ( struct sip_peer peer  )  [static]

Set peer defaults before configuring specific configurations.

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

16983 {
16984    if (peer->expire == 0) {
16985       /* Don't reset expire or port time during reload 
16986          if we have an active registration 
16987       */
16988       peer->expire = -1;
16989       peer->pokeexpire = -1;
16990       peer->addr.sin_port = htons(STANDARD_SIP_PORT);
16991    }
16992    ast_copy_flags(&peer->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY);
16993    ast_copy_flags(&peer->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY);
16994    strcpy(peer->context, default_context);
16995    strcpy(peer->subscribecontext, default_subscribecontext);
16996    strcpy(peer->language, default_language);
16997    strcpy(peer->mohinterpret, default_mohinterpret);
16998    strcpy(peer->mohsuggest, default_mohsuggest);
16999    peer->addr.sin_family = AF_INET;
17000    peer->defaddr.sin_family = AF_INET;
17001    peer->capability = global_capability;
17002    peer->maxcallbitrate = default_maxcallbitrate;
17003    peer->rtptimeout = global_rtptimeout;
17004    peer->rtpholdtimeout = global_rtpholdtimeout;
17005    peer->rtpkeepalive = global_rtpkeepalive;
17006    peer->allowtransfer = global_allowtransfer;
17007    peer->autoframing = global_autoframing;
17008    strcpy(peer->vmexten, default_vmexten);
17009    peer->secret[0] = '\0';
17010    peer->md5secret[0] = '\0';
17011    peer->cid_num[0] = '\0';
17012    peer->cid_name[0] = '\0';
17013    peer->fromdomain[0] = '\0';
17014    peer->fromuser[0] = '\0';
17015    peer->regexten[0] = '\0';
17016    peer->mailbox[0] = '\0';
17017    peer->callgroup = 0;
17018    peer->pickupgroup = 0;
17019    peer->maxms = default_qualify;
17020    peer->prefs = default_prefs;
17021 }

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

Add a SIP header to an outbound INVITE.

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

18256 {
18257    int no = 0;
18258    int ok = FALSE;
18259    char varbuf[30];
18260    char *inbuf = (char *) data;
18261    
18262    if (ast_strlen_zero(inbuf)) {
18263       ast_log(LOG_WARNING, "This application requires the argument: Header\n");
18264       return 0;
18265    }
18266    ast_channel_lock(chan);
18267 
18268    /* Check for headers */
18269    while (!ok && no <= 50) {
18270       no++;
18271       snprintf(varbuf, sizeof(varbuf), "_SIPADDHEADER%.2d", no);
18272 
18273       /* Compare without the leading underscore */
18274       if( (pbx_builtin_getvar_helper(chan, (const char *) varbuf + 1) == (const char *) NULL) )
18275          ok = TRUE;
18276    }
18277    if (ok) {
18278       pbx_builtin_setvar_helper (chan, varbuf, inbuf);
18279       if (sipdebug)
18280          ast_log(LOG_DEBUG,"SIP Header added \"%s\" as %s\n", inbuf, varbuf);
18281    } else {
18282       ast_log(LOG_WARNING, "Too many SIP headers added, max 50\n");
18283    }
18284    ast_channel_unlock(chan);
18285    return 0;
18286 }

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

Support routine for find_peer.

Definition at line 2650 of file chan_sip.c.

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

Referenced by find_peer().

02651 {
02652    /* We know name is the first field, so we can cast */
02653    struct sip_peer *p = (struct sip_peer *) name;
02654    return   !(!inaddrcmp(&p->addr, sin) || 
02655                (ast_test_flag(&p->flags[0], SIP_INSECURE_PORT) &&
02656                (p->addr.sin_addr.s_addr == sin->sin_addr.s_addr)));
02657 }

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 4444 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_codec_setpref(), 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::autoframing, 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().

04446 {
04447    struct sip_pvt *p;
04448 
04449    if (!(p = ast_calloc(1, sizeof(*p))))
04450       return NULL;
04451 
04452    if (ast_string_field_init(p, 512)) {
04453       free(p);
04454       return NULL;
04455    }
04456 
04457    ast_mutex_init(&p->lock);
04458 
04459    p->method = intended_method;
04460    p->initid = -1;
04461    p->waitid = -1;
04462    p->autokillid = -1;
04463    p->subscribed = NONE;
04464    p->stateid = -1;
04465    p->prefs = default_prefs;     /* Set default codecs for this call */
04466 
04467    if (intended_method != SIP_OPTIONS) /* Peerpoke has it's own system */
04468       p->timer_t1 = 500;   /* Default SIP retransmission timer T1 (RFC 3261) */
04469 
04470    if (sin) {
04471       p->sa = *sin;
04472       if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
04473          p->ourip = __ourip;
04474    } else
04475       p->ourip = __ourip;
04476 
04477    /* Copy global flags to this PVT at setup. */
04478    ast_copy_flags(&p->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY);
04479    ast_copy_flags(&p->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY);
04480 
04481    ast_set2_flag(&p->flags[0], !recordhistory, SIP_NO_HISTORY);
04482 
04483    p->branch = ast_random();  
04484    make_our_tag(p->tag, sizeof(p->tag));
04485    p->ocseq = INITIAL_CSEQ;
04486 
04487    if (sip_methods[intended_method].need_rtp) {
04488       p->rtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr.sin_addr);
04489       /* If the global videosupport flag is on, we always create a RTP interface for video */
04490       if (ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT))
04491          p->vrtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr.sin_addr);
04492       if (ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT))
04493          p->udptl = ast_udptl_new_with_bindaddr(sched, io, 0, bindaddr.sin_addr);
04494       if (!p->rtp || (ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) && !p->vrtp)) {
04495          ast_log(LOG_WARNING, "Unable to create RTP audio %s session: %s\n",
04496             ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) ? "and video" : "", strerror(errno));
04497          ast_mutex_destroy(&p->lock);
04498          if (p->chanvars) {
04499             ast_variables_destroy(p->chanvars);
04500             p->chanvars = NULL;
04501          }
04502          free(p);
04503          return NULL;
04504       }
04505       ast_rtp_setdtmf(p->rtp, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833);
04506       ast_rtp_setdtmfcompensate(p->rtp, ast_test_flag(&p->flags[1], SIP_PAGE2_RFC2833_COMPENSATE));
04507       ast_rtp_settos(p->rtp, global_tos_audio);
04508       ast_rtp_set_rtptimeout(p->rtp, global_rtptimeout);
04509       ast_rtp_set_rtpholdtimeout(p->rtp, global_rtpholdtimeout);
04510       ast_rtp_set_rtpkeepalive(p->rtp, global_rtpkeepalive);
04511       if (p->vrtp) {
04512          ast_rtp_settos(p->vrtp, global_tos_video);
04513          ast_rtp_setdtmf(p->vrtp, 0);
04514          ast_rtp_setdtmfcompensate(p->vrtp, 0);
04515          ast_rtp_set_rtptimeout(p->vrtp, global_rtptimeout);
04516          ast_rtp_set_rtpholdtimeout(p->vrtp, global_rtpholdtimeout);
04517          ast_rtp_set_rtpkeepalive(p->vrtp, global_rtpkeepalive);
04518       }
04519       if (p->udptl)
04520          ast_udptl_settos(p->udptl, global_tos_audio);
04521       p->maxcallbitrate = default_maxcallbitrate;
04522       p->autoframing = global_autoframing;
04523       ast_rtp_codec_setpref(p->rtp, &p->prefs);
04524    }
04525 
04526    if (useglobal_nat && sin) {
04527       /* Setup NAT structure according to global settings if we have an address */
04528       ast_copy_flags(&p->flags[0], &global_flags[0], SIP_NAT);
04529       p->recv = *sin;
04530       do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE);
04531    }
04532 
04533    if (p->method != SIP_REGISTER)
04534       ast_string_field_set(p, fromdomain, default_fromdomain);
04535    build_via(p);
04536    if (!callid)
04537       build_callid_pvt(p);
04538    else
04539       ast_string_field_set(p, callid, callid);
04540    /* Assign default music on hold class */
04541    ast_string_field_set(p, mohinterpret, default_mohinterpret);
04542    ast_string_field_set(p, mohsuggest, default_mohsuggest);
04543    p->capability = global_capability;
04544    p->allowtransfer = global_allowtransfer;
04545    if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) ||
04546        (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO))
04547       p->noncodeccapability |= AST_RTP_DTMF;
04548    if (p->udptl) {
04549       p->t38.capability = global_t38_capability;
04550       if (ast_udptl_get_error_correction_scheme(p->udptl) == UDPTL_ERROR_CORRECTION_REDUNDANCY)
04551          p->t38.capability |= T38FAX_UDP_EC_REDUNDANCY;
04552       else if (ast_udptl_get_error_correction_scheme(p->udptl) == UDPTL_ERROR_CORRECTION_FEC)
04553          p->t38.capability |= T38FAX_UDP_EC_FEC;
04554       else if (ast_udptl_get_error_correction_scheme(p->udptl) == UDPTL_ERROR_CORRECTION_NONE)
04555          p->t38.capability |= T38FAX_UDP_EC_NONE;
04556       p->t38.capability |= T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF;
04557       p->t38.jointcapability = p->t38.capability;
04558    }
04559    ast_string_field_set(p, context, default_context);
04560 
04561    /* Add to active dialog list */
04562    ast_mutex_lock(&iflock);
04563    p->next = iflist;
04564    iflist = p;
04565    ast_mutex_unlock(&iflock);
04566    if (option_debug)
04567       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");
04568    return p;
04569 }

static void sip_alreadygone ( struct sip_pvt dialog  )  [static]

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

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

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

03673 {
03674    int res = 0;
03675    struct sip_pvt *p = ast->tech_pvt;
03676 
03677    ast_mutex_lock(&p->lock);
03678    if (ast->_state != AST_STATE_UP) {
03679       try_suggested_sip_codec(p);   
03680 
03681       ast_setstate(ast, AST_STATE_UP);
03682       if (option_debug)
03683          ast_log(LOG_DEBUG, "SIP answering channel: %s\n", ast->name);
03684       if (p->t38.state == T38_PEER_DIRECT) {
03685          p->t38.state = T38_ENABLED;
03686          if (option_debug > 1)
03687             ast_log(LOG_DEBUG,"T38State change to %d on channel %s\n", p->t38.state, ast->name);
03688          res = transmit_response_with_t38_sdp(p, "200 OK", &p->initreq, XMIT_CRITICAL);
03689       } else {
03690          res = transmit_response_with_sdp(p, "200 OK", &p->initreq, XMIT_CRITICAL);
03691       }
03692    }
03693    ast_mutex_unlock(&p->lock);
03694    return res;
03695 }

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 2954 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, SIPBUFSIZE, 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.

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

static int sip_cancel_destroy ( struct sip_pvt p  )  [static]

Cancel destruction of SIP dialog.

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

02130 {
02131    int res = 0;
02132    if (p->autokillid > -1) {
02133       if (!(res = ast_sched_del(sched, p->autokillid))) {
02134          append_history(p, "CancelDestroy", "");
02135          p->autokillid = -1;
02136       }
02137    }
02138    return res;
02139 }

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

See if we pass debug IP filter.

Definition at line 1736 of file chan_sip.c.

References debugaddr, and sipdebug.

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

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

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

03316 {
03317    ast_mutex_lock(&iflock);
03318    if (option_debug > 2)
03319       ast_log(LOG_DEBUG, "Destroying SIP dialog %s\n", p->callid);
03320    __sip_destroy(p, 1);
03321    ast_mutex_unlock(&iflock);
03322 }

static void sip_destroy_peer ( struct sip_peer peer  )  [static]

Destroy peer object from memory.

Definition at line 2459 of file chan_sip.c.

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

Referenced by __sip_autodestruct(), __sip_destroy(), _sip_show_peer(), build_peer(), check_user_full(), create_addr(), do_monitor(), expire_register(), function_sippeer(), handle_request_subscribe(), handle_response_peerpoke(), parse_register_contact(), realtime_peer(), reg_source_db(), register_verify(), reload_config(), sip_devicestate(), sip_do_debug_peer(), sip_do_reload(), sip_poke_all_peers(), sip_poke_noanswer(), sip_poke_peer(), sip_poke_peer_s(), sip_prune_realtime(), unload_module(), and update_call_counter().

02460 {
02461    if (option_debug > 2)
02462       ast_log(LOG_DEBUG, "Destroying SIP peer %s\n", peer->name);
02463 
02464    /* Delete it, it needs to disappear */
02465    if (peer->call)
02466       sip_destroy(peer->call);
02467 
02468    if (peer->mwipvt)    /* We have an active subscription, delete it */
02469       sip_destroy(peer->mwipvt);
02470 
02471    if (peer->chanvars) {
02472       ast_variables_destroy(peer->chanvars);
02473       peer->chanvars = NULL;
02474    }
02475 
02476    register_peer_exten(peer, FALSE);
02477    ast_free_ha(peer->ha);
02478    if (ast_test_flag(&peer->flags[1], SIP_PAGE2_SELFDESTRUCT))
02479       apeerobjs--;
02480    else if (ast_test_flag(&peer->flags[0], SIP_REALTIME))
02481       rpeerobjs--;
02482    else
02483       speerobjs--;
02484    clear_realm_authentication(peer->auth);
02485    peer->auth = NULL;
02486    free(peer);
02487 }

static void sip_destroy_user ( struct sip_user user  )  [static]

Remove user object from in-memory storage.

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

02679 {
02680    if (option_debug > 2)
02681       ast_log(LOG_DEBUG, "Destroying user object from memory: %s\n", user->name);
02682    ast_free_ha(user->ha);
02683    if (user->chanvars) {
02684       ast_variables_destroy(user->chanvars);
02685       user->chanvars = NULL;
02686    }
02687    if (ast_test_flag(&user->flags[0], SIP_REALTIME))
02688       ruserobjs--;
02689    else
02690       suserobjs--;
02691    free(user);
02692 }

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

16395 {
16396    char *host;
16397    char *tmp;
16398 
16399    struct hostent *hp;
16400    struct ast_hostent ahp;
16401    struct sip_peer *p;
16402 
16403    int res = AST_DEVICE_INVALID;
16404 
16405    /* make sure data is not null. Maybe unnecessary, but better be safe */
16406    host = ast_strdupa(data ? data : "");
16407    if ((tmp = strchr(host, '@')))
16408       host = tmp + 1;
16409 
16410    if (option_debug > 2) 
16411       ast_log(LOG_DEBUG, "Checking device state for peer %s\n", host);
16412 
16413    if ((p = find_peer(host, NULL, 1))) {
16414       if (p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) {
16415          /* we have an address for the peer */
16416       
16417          /* Check status in this order
16418             - Hold
16419             - Ringing
16420             - Busy (enforced only by call limit)
16421             - Inuse (we have a call)
16422             - Unreachable (qualify)
16423             If we don't find any of these state, report AST_DEVICE_NOT_INUSE
16424             for registered devices */
16425 
16426          if (p->onHold)
16427             /* First check for hold or ring states */
16428             res = AST_DEVICE_ONHOLD;
16429          else if (p->inRinging) {
16430             if (p->inRinging == p->inUse)
16431                res = AST_DEVICE_RINGING;
16432             else
16433                res = AST_DEVICE_RINGINUSE;
16434          } else if (p->call_limit && (p->inUse == p->call_limit))
16435             /* check call limit */
16436             res = AST_DEVICE_BUSY;
16437          else if (p->call_limit && p->inUse)
16438             /* Not busy, but we do have a call */
16439             res = AST_DEVICE_INUSE;
16440          else if (p->maxms && ((p->lastms > p->maxms) || (p->lastms < 0))) 
16441             /* We don't have a call. Are we reachable at all? Requires qualify= */
16442             res = AST_DEVICE_UNAVAILABLE;
16443          else  /* Default reply if we're registered and have no other data */
16444             res = AST_DEVICE_NOT_INUSE;
16445       } else {
16446          /* there is no address, it's unavailable */
16447          res = AST_DEVICE_UNAVAILABLE;
16448       }
16449       ASTOBJ_UNREF(p,sip_destroy_peer);
16450    } else {
16451       char *port = strchr(host, ':');
16452       if (port)
16453          *port = '\0';
16454       hp = ast_gethostbyname(host, &ahp);
16455       if (hp)
16456          res = AST_DEVICE_UNKNOWN;
16457    }
16458 
16459    return res;
16460 }

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

Turn on SIP debugging (CLI command).

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

11432 {
11433    int oldsipdebug = sipdebug_console;
11434    if (argc != 3) {
11435       if (argc != 5) 
11436          return RESULT_SHOWUSAGE;
11437       else if (strcmp(argv[3], "ip") == 0)
11438          return sip_do_debug_ip(fd, argc, argv);
11439       else if (strcmp(argv[3], "peer") == 0)
11440          return sip_do_debug_peer(fd, argc, argv);
11441       else
11442          return RESULT_SHOWUSAGE;
11443    }
11444    ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE);
11445    memset(&debugaddr, 0, sizeof(debugaddr));
11446    ast_cli(fd, "SIP Debugging %senabled\n", oldsipdebug ? "re-" : "");
11447    return RESULT_SUCCESS;
11448 }

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

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

11451 {
11452    int oldsipdebug = sipdebug_console;
11453    char *newargv[6] = { "sip", "set", "debug", NULL };
11454    if (argc != 2) {
11455       if (argc != 4) 
11456          return RESULT_SHOWUSAGE;
11457       else if (strcmp(argv[2], "ip") == 0) {
11458          newargv[3] = argv[2];
11459          newargv[4] = argv[3];
11460          return sip_do_debug_ip(fd, argc + 1, newargv);
11461       } else if (strcmp(argv[2], "peer") == 0) {
11462          newargv[3] = argv[2];
11463          newargv[4] = argv[3];
11464          return sip_do_debug_peer(fd, argc + 1, newargv);
11465       } else
11466          return RESULT_SHOWUSAGE;
11467    }
11468    ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE);
11469    memset(&debugaddr, 0, sizeof(debugaddr));
11470    ast_cli(fd, "SIP Debugging %senabled\n", oldsipdebug ? "re-" : "");
11471    return RESULT_SUCCESS;
11472 }

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

Enable SIP Debugging in CLI.

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

11378 {
11379    struct hostent *hp;
11380    struct ast_hostent ahp;
11381    int port = 0;
11382    char *p, *arg;
11383 
11384    /* sip set debug ip <ip> */
11385    if (argc != 5)
11386       return RESULT_SHOWUSAGE;
11387    p = arg = argv[4];
11388    strsep(&p, ":");
11389    if (p)
11390       port = atoi(p);
11391    hp = ast_gethostbyname(arg, &ahp);
11392    if (hp == NULL)
11393       return RESULT_SHOWUSAGE;
11394 
11395    debugaddr.sin_family = AF_INET;
11396    memcpy(&debugaddr.sin_addr, hp->h_addr, sizeof(debugaddr.sin_addr));
11397    debugaddr.sin_port = htons(port);
11398    if (port == 0)
11399       ast_cli(fd, "SIP Debugging Enabled for IP: %s\n", ast_inet_ntoa(debugaddr.sin_addr));
11400    else
11401       ast_cli(fd, "SIP Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(debugaddr.sin_addr), port);
11402 
11403    ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE);
11404 
11405    return RESULT_SUCCESS;
11406 }

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

11410 {
11411    struct sip_peer *peer;
11412    if (argc != 5)
11413       return RESULT_SHOWUSAGE;
11414    peer = find_peer(argv[4], NULL, 1);
11415    if (peer) {
11416       if (peer->addr.sin_addr.s_addr) {
11417          debugaddr.sin_family = AF_INET;
11418          debugaddr.sin_addr = peer->addr.sin_addr;
11419          debugaddr.sin_port = peer->addr.sin_port;
11420          ast_cli(fd, "SIP Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(debugaddr.sin_addr), ntohs(debugaddr.sin_port));
11421          ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE);
11422       } else
11423          ast_cli(fd, "Unable to get IP address of peer '%s'\n", argv[4]);
11424       ASTOBJ_UNREF(peer,sip_destroy_peer);
11425    } else
11426       ast_cli(fd, "No such peer '%s'\n", argv[4]);
11427    return RESULT_SUCCESS;
11428 }

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

Enable SIP History logging (CLI).

Definition at line 11550 of file chan_sip.c.

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

11551 {
11552    if (argc != 2) {
11553       return RESULT_SHOWUSAGE;
11554    }
11555    recordhistory = TRUE;
11556    ast_cli(fd, "SIP History Recording Enabled (use 'sip show history')\n");
11557    return RESULT_SUCCESS;
11558 }

static int sip_do_reload ( enum channelreloadreason  reason  )  [static]

Reload module.

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

18402 {
18403    reload_config(reason);
18404 
18405    /* Prune peers who still are supposed to be deleted */
18406    ASTOBJ_CONTAINER_PRUNE_MARKED(&peerl, sip_destroy_peer);
18407    if (option_debug > 3)
18408       ast_log(LOG_DEBUG, "--------------- Done destroying pruned peers\n");
18409 
18410    /* Send qualify (OPTIONS) to all peers */
18411    sip_poke_all_peers();
18412 
18413    /* Register with all services */
18414    sip_send_all_registers();
18415 
18416    if (option_debug > 3)
18417       ast_log(LOG_DEBUG, "--------------- SIP reload done\n");
18418 
18419    return 0;
18420 }

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

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

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

18201 {
18202    struct sip_pvt *p;
18203    char *mode;
18204    if (data)
18205       mode = (char *)data;
18206    else {
18207       ast_log(LOG_WARNING, "This application requires the argument: info, inband, rfc2833\n");
18208       return 0;
18209    }
18210    ast_channel_lock(chan);
18211    if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) {
18212       ast_log(LOG_WARNING, "Call this application only on SIP incoming calls\n");
18213       ast_channel_unlock(chan);
18214       return 0;
18215    }
18216    p = chan->tech_pvt;
18217    if (!p) {
18218       ast_channel_unlock(chan);
18219       return 0;
18220    }
18221    ast_mutex_lock(&p->lock);
18222    if (!strcasecmp(mode,"info")) {
18223       ast_clear_flag(&p->flags[0], SIP_DTMF);
18224       ast_set_flag(&p->flags[0], SIP_DTMF_INFO);
18225       p->jointnoncodeccapability &= ~AST_RTP_DTMF;
18226    } else if (!strcasecmp(mode,"rfc2833")) {
18227       ast_clear_flag(&p->flags[0], SIP_DTMF);
18228       ast_set_flag(&p->flags[0], SIP_DTMF_RFC2833);
18229       p->jointnoncodeccapability |= AST_RTP_DTMF;
18230    } else if (!strcasecmp(mode,"inband")) { 
18231       ast_clear_flag(&p->flags[0], SIP_DTMF);
18232       ast_set_flag(&p->flags[0], SIP_DTMF_INBAND);
18233       p->jointnoncodeccapability &= ~AST_RTP_DTMF;
18234    } else
18235       ast_log(LOG_WARNING, "I don't know about this dtmf mode: %s\n",mode);
18236    if (p->rtp)
18237       ast_rtp_setdtmf(p->rtp, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833);
18238    if (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) {
18239       if (!p->vad) {
18240          p->vad = ast_dsp_new();
18241          ast_dsp_set_features(p->vad, DSP_FEATURE_DTMF_DETECT);
18242       }
18243    } else {
18244       if (p->vad) {
18245          ast_dsp_free(p->vad);
18246          p->vad = NULL;
18247       }
18248    }
18249    ast_mutex_unlock(&p->lock);
18250    ast_channel_unlock(chan);
18251    return 0;
18252 }

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

11243 {
11244    int x = 0;
11245    struct sip_history *hist;
11246    static int errmsg = 0;
11247 
11248    if (!dialog)
11249       return;
11250 
11251    if (!option_debug && !sipdebug) {
11252       if (!errmsg) {
11253          ast_log(LOG_NOTICE, "You must have debugging enabled (SIP or Asterisk) in order to dump SIP history.\n");
11254          errmsg = 1;
11255       }
11256       return;
11257    }
11258 
11259    ast_log(LOG_DEBUG, "\n---------- SIP HISTORY for '%s' \n", dialog->callid);
11260    if (dialog->subscribed)
11261       ast_log(LOG_DEBUG, "  * Subscription\n");
11262    else
11263       ast_log(LOG_DEBUG, "  * SIP Call\n");
11264    if (dialog->history)
11265       AST_LIST_TRAVERSE(dialog->history, hist, list)
11266          ast_log(LOG_DEBUG, "  %-3.3d. %s\n", ++x, hist->event);
11267    if (!x)
11268       ast_log(LOG_DEBUG, "Call '%s' has no history\n", dialog->callid);
11269    ast_log(LOG_DEBUG, "\n---------- END SIP HISTORY for '%s' \n", dialog->callid);
11270 }

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 3776 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, sip_set_rtp_peer(), and ast_channel::tech_pvt.

03777 {
03778    int ret = -1;
03779    struct sip_pvt *p;
03780 
03781    if (newchan && ast_test_flag(newchan, AST_FLAG_ZOMBIE) && option_debug)
03782       ast_log(LOG_DEBUG, "New channel is zombie\n");
03783    if (oldchan && ast_test_flag(oldchan, AST_FLAG_ZOMBIE) && option_debug)
03784       ast_log(LOG_DEBUG, "Old channel is zombie\n");
03785 
03786    if (!newchan || !newchan->tech_pvt) {
03787       if (!newchan)
03788          ast_log(LOG_WARNING, "No new channel! Fixup of %s failed.\n", oldchan->name);
03789       else
03790          ast_log(LOG_WARNING, "No SIP tech_pvt! Fixup of %s failed.\n", oldchan->name);
03791       return -1;
03792    }
03793    p = newchan->tech_pvt;
03794 
03795    if (!p) {
03796       ast_log(LOG_WARNING, "No pvt after masquerade. Strange things may happen\n");
03797       return -1;
03798    }
03799 
03800    ast_mutex_lock(&p->lock);
03801    append_history(p, "Masq", "Old channel: %s\n", oldchan->name);
03802    append_history(p, "Masq (cont)", "...new owner: %s\n", newchan->name);
03803    if (p->owner != oldchan)
03804       ast_log(LOG_WARNING, "old channel wasn't %p but was %p\n", oldchan, p->owner);
03805    else {
03806       p->owner = newchan;
03807       /* Re-invite RTP back to Asterisk. Needed if channel is masqueraded out of a native
03808          RTP bridge (i.e., RTP not going through Asterisk): RTP bridge code might not be
03809          able to do this if the masquerade happens before the bridge breaks (e.g., AMI
03810          redirect of both channels). Note that a channel can not be masqueraded *into*
03811          a native bridge. So there is no danger that this breaks a native bridge that
03812          should stay up. */
03813       sip_set_rtp_peer(newchan, NULL, NULL, 0, 0);
03814       ret = 0;
03815    }
03816    if (option_debug > 2)
03817       ast_log(LOG_DEBUG, "SIP Fixup: New owner for dialogue %s: %s (Old parent: %s)\n", p->callid, p->owner->name, oldchan->name);
03818 
03819    ast_mutex_unlock(&p->lock);
03820    return ret;
03821 }

static int sip_get_codec ( struct ast_channel chan  )  [static]

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

Definition at line 18345 of file chan_sip.c.

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

18346 {
18347    struct sip_pvt *p = chan->tech_pvt;
18348    return p->peercapability ? p->peercapability : p->capability;  
18349 }

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

18054 {
18055    struct sip_pvt *p = NULL;
18056    enum ast_rtp_get_result res = AST_RTP_TRY_PARTIAL;
18057 
18058    if (!(p = chan->tech_pvt))
18059       return AST_RTP_GET_FAILED;
18060 
18061    ast_mutex_lock(&p->lock);
18062    if (!(p->rtp)) {
18063       ast_mutex_unlock(&p->lock);
18064       return AST_RTP_GET_FAILED;
18065    }
18066 
18067    *rtp = p->rtp;
18068 
18069    if (ast_rtp_getnat(*rtp) && !ast_test_flag(&p->flags[0], SIP_CAN_REINVITE_NAT))
18070       res = AST_RTP_TRY_PARTIAL;
18071    else if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE))
18072       res = AST_RTP_TRY_NATIVE;
18073    else if (ast_test_flag(&global_jbconf, AST_JB_FORCED))
18074       res = AST_RTP_GET_FAILED;
18075 
18076    ast_mutex_unlock(&p->lock);
18077 
18078    return res;
18079 }

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

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

17919 {
17920    struct sip_pvt *p;
17921    struct ast_udptl *udptl = NULL;
17922    
17923    p = chan->tech_pvt;
17924    if (!p)
17925       return NULL;
17926    
17927    ast_mutex_lock(&p->lock);
17928    if (p->udptl && ast_test_flag(&p->flags[0], SIP_CAN_REINVITE))
17929       udptl = p->udptl;
17930    ast_mutex_unlock(&p->lock);
17931    return udptl;
17932 }

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

18083 {
18084    struct sip_pvt *p = NULL;
18085    enum ast_rtp_get_result res = AST_RTP_TRY_PARTIAL;
18086    
18087    if (!(p = chan->tech_pvt))
18088       return AST_RTP_GET_FAILED;
18089 
18090    ast_mutex_lock(&p->lock);
18091    if (!(p->vrtp)) {
18092       ast_mutex_unlock(&p->lock);
18093       return AST_RTP_GET_FAILED;
18094    }
18095 
18096    *rtp = p->vrtp;
18097 
18098    if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE))
18099       res = AST_RTP_TRY_NATIVE;
18100 
18101    ast_mutex_unlock(&p->lock);
18102 
18103    return res;
18104 }

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

17971 {
17972    struct sip_pvt *p;
17973    int flag = 0;
17974    
17975    p = chan->tech_pvt;
17976    if (!p || !pvt->udptl)
17977       return -1;
17978    
17979    /* Setup everything on the other side like offered/responded from first side */
17980    ast_mutex_lock(&p->lock);
17981 
17982    /*! \todo check if this is not set earlier when setting up the PVT. If not
17983       maybe it should move there. */
17984    p->t38.jointcapability = p->t38.peercapability = pvt->t38.jointcapability;
17985 
17986    ast_udptl_set_far_max_datagram(p->udptl, ast_udptl_get_local_max_datagram(pvt->udptl));
17987    ast_udptl_set_local_max_datagram(p->udptl, ast_udptl_get_local_max_datagram(pvt->udptl));
17988    ast_udptl_set_error_correction_scheme(p->udptl, ast_udptl_get_error_correction_scheme(pvt->udptl));
17989    
17990    if (reinvite) {      /* If we are handling sending re-invite to the other side of the bridge */
17991       /*! \note The SIP_CAN_REINVITE flag is for RTP media redirects,
17992          not really T38 re-invites which are different. In this
17993          case it's used properly, to see if we can reinvite over
17994          NAT 
17995       */
17996       if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE) && ast_test_flag(&pvt->flags[0], SIP_CAN_REINVITE)) {
17997          ast_udptl_get_peer(pvt->udptl, &p->udptlredirip);
17998          flag =1;
17999       } else {
18000          memset(&p->udptlredirip, 0, sizeof(p->udptlredirip));
18001       }
18002       if (!ast_test_flag(&p->flags[0], SIP_GOTREFER)) {
18003          if (!p->pendinginvite) {
18004             if (option_debug > 2) {
18005                if (flag)
18006                   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));
18007                else
18008                   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));
18009             }
18010             transmit_reinvite_with_t38_sdp(p);
18011          } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) {
18012             if (option_debug > 2) {
18013                if (flag)
18014                   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));
18015                else
18016                   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));
18017             }
18018             ast_set_flag(&p->flags[0], SIP_NEEDREINVITE);
18019          }
18020       }
18021       /* Reset lastrtprx timer */
18022       p->lastrtprx = p->lastrtptx = time(NULL);
18023       ast_mutex_unlock(&p->lock);
18024       return 0;
18025    } else { /* If we are handling sending 200 OK to the other side of the bridge */
18026       if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE) && ast_test_flag(&pvt->flags[0], SIP_CAN_REINVITE)) {
18027          ast_udptl_get_peer(pvt->udptl, &p->udptlredirip);
18028          flag = 1;
18029       } else {
18030          memset(&p->udptlredirip, 0, sizeof(p->udptlredirip));
18031       }
18032       if (option_debug > 2) {
18033          if (flag)
18034             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));
18035          else
18036             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));
18037       }
18038       pvt->t38.state = T38_ENABLED;
18039       p->t38.state = T38_ENABLED;
18040       if (option_debug > 1) {
18041          ast_log(LOG_DEBUG, "T38 changed state to %d on channel %s\n", pvt->t38.state, pvt->owner ? pvt->owner->name : "<none>");
18042          ast_log(LOG_DEBUG, "T38 changed state to %d on channel %s\n", p->t38.state, chan ? chan->name : "<none>");
18043       }
18044       transmit_response_with_t38_sdp(p, "200 OK", &p->initreq, XMIT_CRITICAL);
18045       p->lastrtprx = p->lastrtptx = time(NULL);
18046       ast_mutex_unlock(&p->lock);
18047       return 0;
18048    }
18049 }

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 3487 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::lastinvite, sip_pvt::lock, LOG_DEBUG, LOG_WARNING, 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.

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

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 3892 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_SRCUPDATE, AST_CONTROL_UNHOLD, AST_CONTROL_VIDUPDATE, ast_log(), ast_moh_start(), ast_moh_stop(), ast_mutex_lock(), ast_mutex_unlock(), ast_rtp_new_source(), 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_pvt::rtp, 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.

03893 {
03894    struct sip_pvt *p = ast->tech_pvt;
03895    int res = 0;
03896 
03897    ast_mutex_lock(&p->lock);
03898    switch(condition) {
03899    case AST_CONTROL_RINGING:
03900       if (ast->_state == AST_STATE_RING) {
03901          p->invitestate = INV_EARLY_MEDIA;
03902          if (!ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) ||
03903              (ast_test_flag(&p->flags[0], SIP_PROG_INBAND) == SIP_PROG_INBAND_NEVER)) {            
03904             /* Send 180 ringing if out-of-band seems reasonable */
03905             transmit_response(p, "180 Ringing", &p->initreq);
03906             ast_set_flag(&p->flags[0], SIP_RINGING);
03907             if (ast_test_flag(&p->flags[0], SIP_PROG_INBAND) != SIP_PROG_INBAND_YES)
03908                break;
03909          } else {
03910             /* Well, if it's not reasonable, just send in-band */
03911          }
03912       }
03913       res = -1;
03914       break;
03915    case AST_CONTROL_BUSY:
03916       if (ast->_state != AST_STATE_UP) {
03917          transmit_response(p, "486 Busy Here", &p->initreq);
03918          p->invitestate = INV_COMPLETED;
03919          sip_alreadygone(p);
03920          ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV);
03921          break;
03922       }
03923       res = -1;
03924       break;
03925    case AST_CONTROL_CONGESTION:
03926       if (ast->_state != AST_STATE_UP) {
03927          transmit_response(p, "503 Service Unavailable", &p->initreq);
03928          p->invitestate = INV_COMPLETED;
03929          sip_alreadygone(p);
03930          ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV);
03931          break;
03932       }
03933       res = -1;
03934       break;
03935    case AST_CONTROL_PROCEEDING:
03936       if ((ast->_state != AST_STATE_UP) &&
03937           !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) &&
03938           !ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
03939          transmit_response(p, "100 Trying", &p->initreq);
03940          p->invitestate = INV_PROCEEDING;  
03941          break;
03942       }
03943       res = -1;
03944       break;
03945    case AST_CONTROL_PROGRESS:
03946       if ((ast->_state != AST_STATE_UP) &&
03947           !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) &&
03948           !ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
03949          p->invitestate = INV_EARLY_MEDIA;
03950          transmit_response_with_sdp(p, "183 Session Progress", &p->initreq, XMIT_UNRELIABLE);
03951          ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT);  
03952          break;
03953       }
03954       res = -1;
03955       break;
03956    case AST_CONTROL_HOLD:
03957       ast_rtp_new_source(p->rtp);
03958       ast_moh_start(ast, data, p->mohinterpret);
03959       break;
03960    case AST_CONTROL_UNHOLD:
03961       ast_rtp_new_source(p->rtp);
03962       ast_moh_stop(ast);
03963       break;
03964    case AST_CONTROL_VIDUPDATE:   /* Request a video frame update */
03965       if (p->vrtp && !ast_test_flag(&p->flags[0], SIP_NOVIDEO)) {
03966          transmit_info_with_vidupdate(p);
03967          /* ast_rtcp_send_h261fur(p->vrtp); */
03968       } else
03969          res = -1;
03970       break;
03971    case AST_CONTROL_SRCUPDATE:
03972       ast_rtp_new_source(p->rtp);
03973       break;
03974    case -1:
03975       res = -1;
03976       break;
03977    default:
03978       ast_log(LOG_WARNING, "Don't know how to indicate condition %d\n", condition);
03979       res = -1;
03980       break;
03981    }
03982    ast_mutex_unlock(&p->lock);
03983    return res;
03984 }

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

Display SIP nat mode.

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

01757 {
01758    return ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE ? "NAT" : "no NAT";
01759 }

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 3992 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, SIPBUFSIZE, 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().

03993 {
03994    struct ast_channel *tmp;
03995    struct ast_variable *v = NULL;
03996    int fmt;
03997    int what;
03998    int needvideo = 0, video = 0;
03999    char *decoded_exten;
04000    {
04001       const char *my_name;    /* pick a good name */
04002 
04003       if (title)
04004          my_name = title;
04005       else if ( (my_name = strchr(i->fromdomain,':')) )
04006          my_name++;      /* skip ':' */
04007       else
04008          my_name = i->fromdomain;
04009 
04010       ast_mutex_unlock(&i->lock);
04011       /* Don't hold a sip pvt lock while we allocate a channel */
04012       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);
04013 
04014    }
04015    if (!tmp) {
04016       ast_log(LOG_WARNING, "Unable to allocate AST channel structure for SIP channel\n");
04017       ast_mutex_lock(&i->lock);
04018       return NULL;
04019    }
04020    ast_mutex_lock(&i->lock);
04021 
04022    if (ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_INFO)
04023       tmp->tech = &sip_tech_info;
04024    else
04025       tmp->tech = &sip_tech;
04026 
04027    /* Select our native format based on codec preference until we receive
04028       something from another device to the contrary. */
04029    if (i->jointcapability) {     /* The joint capabilities of us and peer */
04030       what = i->jointcapability;
04031       video = i->jointcapability & AST_FORMAT_VIDEO_MASK;
04032    } else if (i->capability)  {  /* Our configured capability for this peer */
04033       what = i->capability;
04034       video = i->capability & AST_FORMAT_VIDEO_MASK;
04035    } else {
04036       what = global_capability;  /* Global codec support */
04037       video = global_capability & AST_FORMAT_VIDEO_MASK;
04038    }
04039 
04040    /* Set the native formats for audio  and merge in video */
04041    tmp->nativeformats = ast_codec_choose(&i->prefs, what, 1) | video;
04042    if (option_debug > 2) {
04043       char buf[SIPBUFSIZE];
04044       ast_log(LOG_DEBUG, "*** Our native formats are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, tmp->nativeformats));
04045       ast_log(LOG_DEBUG, "*** Joint capabilities are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, i->jointcapability));
04046       ast_log(LOG_DEBUG, "*** Our capabilities are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, i->capability));
04047       ast_log(LOG_DEBUG, "*** AST_CODEC_CHOOSE formats are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, ast_codec_choose(&i->prefs, what, 1)));
04048       if (i->prefcodec)
04049          ast_log(LOG_DEBUG, "*** Our preferred formats from the incoming channel are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, i->prefcodec));
04050    }
04051 
04052    /* XXX Why are we choosing a codec from the native formats?? */
04053    fmt = ast_best_codec(tmp->nativeformats);
04054 
04055    /* If we have a prefcodec setting, we have an inbound channel that set a 
04056       preferred format for this call. Otherwise, we check the jointcapability
04057       We also check for vrtp. If it's not there, we are not allowed do any video anyway.
04058     */
04059    if (i->vrtp) {
04060       if (i->prefcodec)
04061          needvideo = i->prefcodec & AST_FORMAT_VIDEO_MASK;  /* Outbound call */
04062       else
04063          needvideo = i->jointcapability & AST_FORMAT_VIDEO_MASK;  /* Inbound call */
04064    }
04065 
04066    if (option_debug > 2) {
04067       if (needvideo) 
04068          ast_log(LOG_DEBUG, "This channel can handle video! HOLLYWOOD next!\n");
04069       else
04070          ast_log(LOG_DEBUG, "This channel will not be able to handle video.\n");
04071    }
04072 
04073 
04074 
04075    if (ast_test_flag(&i->flags[0], SIP_DTMF) ==  SIP_DTMF_INBAND) {
04076       i->vad = ast_dsp_new();
04077       ast_dsp_set_features(i->vad, DSP_FEATURE_DTMF_DETECT);
04078       if (global_relaxdtmf)
04079          ast_dsp_digitmode(i->vad, DSP_DIGITMODE_DTMF | DSP_DIGITMODE_RELAXDTMF);
04080    }
04081    if (i->rtp) {
04082       tmp->fds[0] = ast_rtp_fd(i->rtp);
04083       tmp->fds[1] = ast_rtcp_fd(i->rtp);
04084    }
04085    if (needvideo && i->vrtp) {
04086       tmp->fds[2] = ast_rtp_fd(i->vrtp);
04087       tmp->fds[3] = ast_rtcp_fd(i->vrtp);
04088    }
04089    if (i->udptl) {
04090       tmp->fds[5] = ast_udptl_fd(i->udptl);
04091    }
04092    if (state == AST_STATE_RING)
04093       tmp->rings = 1;
04094    tmp->adsicpe = AST_ADSI_UNAVAILABLE;
04095    tmp->writeformat = fmt;
04096    tmp->rawwriteformat = fmt;
04097    tmp->readformat = fmt;
04098    tmp->rawreadformat = fmt;
04099    tmp->tech_pvt = i;
04100 
04101    tmp->callgroup = i->callgroup;
04102    tmp->pickupgroup = i->pickupgroup;
04103    tmp->cid.cid_pres = i->callingpres;
04104    if (!ast_strlen_zero(i->accountcode))
04105       ast_string_field_set(tmp, accountcode, i->accountcode);
04106    if (i->amaflags)
04107       tmp->amaflags = i->amaflags;
04108    if (!ast_strlen_zero(i->language))
04109       ast_string_field_set(tmp, language, i->language);
04110    i->owner = tmp;
04111    ast_module_ref(ast_module_info->self);
04112    ast_copy_string(tmp->context, i->context, sizeof(tmp->context));
04113    /*Since it is valid to have extensions in the dialplan that have unescaped characters in them
04114     * we should decode the uri before storing it in the channel, but leave it encoded in the sip_pvt
04115     * structure so that there aren't issues when forming URI's
04116     */
04117    decoded_exten = ast_strdupa(i->exten);
04118    ast_uri_decode(decoded_exten);
04119    ast_copy_string(tmp->exten, decoded_exten, sizeof(tmp->exten));
04120 
04121    /* Don't use ast_set_callerid() here because it will
04122     * generate an unnecessary NewCallerID event  */
04123    tmp->cid.cid_ani = ast_strdup(i->cid_num);
04124    if (!ast_strlen_zero(i->rdnis))
04125       tmp->cid.cid_rdnis = ast_strdup(i->rdnis);
04126    
04127    if (!ast_strlen_zero(i->exten) && strcmp(i->exten, "s"))
04128       tmp->cid.cid_dnid = ast_strdup(i->exten);
04129 
04130    tmp->priority = 1;
04131    if (!ast_strlen_zero(i->uri))
04132       pbx_builtin_setvar_helper(tmp, "SIPURI", i->uri);
04133    if (!ast_strlen_zero(i->domain))
04134       pbx_builtin_setvar_helper(tmp, "SIPDOMAIN", i->domain);
04135    if (!ast_strlen_zero(i->useragent))
04136       pbx_builtin_setvar_helper(tmp, "SIPUSERAGENT", i->useragent);
04137    if (!ast_strlen_zero(i->callid))
04138       pbx_builtin_setvar_helper(tmp, "SIPCALLID", i->callid);
04139    if (i->rtp)
04140       ast_jb_configure(tmp, &global_jbconf);
04141 
04142    /* If the INVITE contains T.38 SDP information set the proper channel variable so a created outgoing call will also have T.38 */
04143    if (i->udptl && i->t38.state == T38_PEER_DIRECT)
04144       pbx_builtin_setvar_helper(tmp, "_T38CALL", "1");
04145 
04146    /* Set channel variables for this call from configuration */
04147    for (v = i->chanvars ; v ; v = v->next)
04148       pbx_builtin_setvar_helper(tmp, v->name, v->value);
04149 
04150    if (state != AST_STATE_DOWN && ast_pbx_start(tmp)) {
04151       ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
04152       tmp->hangupcause = AST_CAUSE_SWITCH_CONGESTION;
04153       ast_hangup(tmp);
04154       tmp = NULL;
04155    }
04156 
04157    if (!ast_test_flag(&i->flags[0], SIP_NO_HISTORY))
04158       append_history(i, "NewChan", "Channel %s - from %s", tmp->name, i->callid);
04159 
04160    return tmp;
04161 }

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

Disable SIP Debugging in CLI.

Definition at line 11531 of file chan_sip.c.

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

11532 {
11533    if (argc != 4)
11534       return RESULT_SHOWUSAGE;
11535    ast_clear_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE);
11536    ast_cli(fd, "SIP Debugging Disabled\n");
11537    return RESULT_SUCCESS;
11538 }

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

Definition at line 11540 of file chan_sip.c.

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

11541 {
11542    if (argc != 3)
11543       return RESULT_SHOWUSAGE;
11544    ast_clear_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE);
11545    ast_cli(fd, "SIP Debugging Disabled\n");
11546    return RESULT_SUCCESS;
11547 }

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

Disable SIP History logging (CLI).

Definition at line 11561 of file chan_sip.c.

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

11562 {
11563    if (argc != 3) {
11564       return RESULT_SHOWUSAGE;
11565    }
11566    recordhistory = FALSE;
11567    ast_cli(fd, "SIP History Recording Disabled\n");
11568    return RESULT_SUCCESS;
11569 }

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

Cli command to send SIP notify to peer.

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

11476 {
11477    struct ast_variable *varlist;
11478    int i;
11479 
11480    if (argc < 4)
11481       return RESULT_SHOWUSAGE;
11482 
11483    if (!notify_types) {
11484       ast_cli(fd, "No %s file found, or no types listed there\n", notify_config);
11485       return RESULT_FAILURE;
11486    }
11487 
11488    varlist = ast_variable_browse(notify_types, argv[2]);
11489 
11490    if (!varlist) {
11491       ast_cli(fd, "Unable to find notify type '%s'\n", argv[2]);
11492       return RESULT_FAILURE;
11493    }
11494 
11495    for (i = 3; i < argc; i++) {
11496       struct sip_pvt *p;
11497       struct sip_request req;
11498       struct ast_variable *var;
11499 
11500       if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY))) {
11501          ast_log(LOG_WARNING, "Unable to build sip pvt data for notify (memory/socket error)\n");
11502          return RESULT_FAILURE;
11503       }
11504 
11505       if (create_addr(p, argv[i])) {
11506          /* Maybe they're not registered, etc. */
11507          sip_destroy(p);
11508          ast_cli(fd, "Could not create address for '%s'\n", argv[i]);
11509          continue;
11510       }
11511 
11512       initreqprep(&req, p, SIP_NOTIFY);
11513 
11514       for (var = varlist; var; var = var->next)
11515          add_header(&req, var->name, ast_unescape_semicolon(var->value));
11516 
11517       /* Recalculate our side, and recalculate Call ID */
11518       if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
11519          p->ourip = __ourip;
11520       build_via(p);
11521       build_callid_pvt(p);
11522       ast_cli(fd, "Sending NOTIFY of type '%s' to '%s'\n", argv[2], argv[i]);
11523       transmit_sip_request(p, &req);
11524       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
11525    }
11526 
11527    return RESULT_SUCCESS;
11528 }

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 13291 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_pthread_create_background, AST_STATE_DOWN, sip_dual::chan1, sip_dual::chan2, ast_channel::context, copy_request(), DEADLOCK_AVOIDANCE, 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().

13292 {
13293    struct sip_dual *d;
13294    struct ast_channel *transferee, *transferer;
13295       /* Chan2m: The transferer, chan1m: The transferee */
13296    pthread_t th;
13297 
13298    transferee = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan1->accountcode, chan1->exten, chan1->context, chan1->amaflags, "Parking/%s", chan1->name);
13299    transferer = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->amaflags, "SIPPeer/%s", chan2->name);
13300    if ((!transferer) || (!transferee)) {
13301       if (transferee) {
13302          transferee->hangupcause = AST_CAUSE_SWITCH_CONGESTION;
13303          ast_hangup(transferee);
13304       }
13305       if (transferer) {
13306          transferer->hangupcause = AST_CAUSE_SWITCH_CONGESTION;
13307          ast_hangup(transferer);
13308       }
13309       return -1;
13310    }
13311 
13312    /* Make formats okay */
13313    transferee->readformat = chan1->readformat;
13314    transferee->writeformat = chan1->writeformat;
13315 
13316    /* Prepare for taking over the channel */
13317    ast_channel_masquerade(transferee, chan1);
13318 
13319    /* Setup the extensions and such */
13320    ast_copy_string(transferee->context, chan1->context, sizeof(transferee->context));
13321    ast_copy_string(transferee->exten, chan1->exten, sizeof(transferee->exten));
13322    transferee->priority = chan1->priority;
13323       
13324    /* We make a clone of the peer channel too, so we can play
13325       back the announcement */
13326 
13327    /* Make formats okay */
13328    transferer->readformat = chan2->readformat;
13329    transferer->writeformat = chan2->writeformat;
13330 
13331    /* Prepare for taking over the channel.  Go ahead and grab this channel
13332     * lock here to avoid a deadlock with callbacks into the channel driver
13333     * that hold the channel lock and want the pvt lock.  */
13334    while (ast_channel_trylock(chan2)) {
13335       struct sip_pvt *pvt = chan2->tech_pvt;
13336       DEADLOCK_AVOIDANCE(&pvt->lock);
13337    }
13338    ast_channel_masquerade(transferer, chan2);
13339    ast_channel_unlock(chan2);
13340 
13341    /* Setup the extensions and such */
13342    ast_copy_string(transferer->context, chan2->context, sizeof(transferer->context));
13343    ast_copy_string(transferer->exten, chan2->exten, sizeof(transferer->exten));
13344    transferer->priority = chan2->priority;
13345 
13346    ast_channel_lock(transferer);
13347    if (ast_do_masquerade(transferer)) {
13348       ast_log(LOG_WARNING, "Masquerade failed :(\n");
13349       ast_channel_unlock(transferer);
13350       transferer->hangupcause = AST_CAUSE_SWITCH_CONGESTION;
13351       ast_hangup(transferer);
13352       return -1;
13353    }
13354    ast_channel_unlock(transferer);
13355    if (!transferer || !transferee) {
13356       if (!transferer) { 
13357          if (option_debug)
13358             ast_log(LOG_DEBUG, "No transferer channel, giving up parking\n");
13359       }
13360       if (!transferee) {
13361          if (option_debug)
13362             ast_log(LOG_DEBUG, "No transferee channel, giving up parking\n");
13363       }
13364       return -1;
13365    }
13366    if ((d = ast_calloc(1, sizeof(*d)))) {
13367       pthread_attr_t attr;
13368 
13369       pthread_attr_init(&attr);
13370       pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);   
13371 
13372       /* Save original request for followup */
13373       copy_request(&d->req, req);
13374       d->chan1 = transferee;  /* Transferee */
13375       d->chan2 = transferer;  /* Transferer */
13376       d->seqno = seqno;
13377       if (ast_pthread_create_background(&th, &attr, sip_park_thread, d) < 0) {
13378          /* Could not start thread */
13379          free(d); /* We don't need it anymore. If thread is created, d will be free'd
13380                   by sip_park_thread() */
13381          pthread_attr_destroy(&attr);
13382          return 0;
13383       }
13384       pthread_attr_destroy(&attr);
13385    } 
13386    return -1;
13387 }

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

13225 {
13226    struct ast_channel *transferee, *transferer; /* Chan1: The transferee, Chan2: The transferer */
13227    struct sip_dual *d;
13228    struct sip_request req;
13229    int ext;
13230    int res;
13231 
13232    d = stuff;
13233    transferee = d->chan1;
13234    transferer = d->chan2;
13235    copy_request(&req, &d->req);
13236    free(d);
13237 
13238    if (!transferee || !transferer) {
13239       ast_log(LOG_ERROR, "Missing channels for parking! Transferer %s Transferee %s\n", transferer ? "<available>" : "<missing>", transferee ? "<available>" : "<missing>" );
13240       return NULL;
13241    }
13242    if (option_debug > 3) 
13243       ast_log(LOG_DEBUG, "SIP Park: Transferer channel %s, Transferee %s\n", transferer->name, transferee->name);
13244 
13245    ast_channel_lock(transferee);
13246    if (ast_do_masquerade(transferee)) {
13247       ast_log(LOG_WARNING, "Masquerade failed.\n");
13248       transmit_response(transferer->tech_pvt, "503 Internal error", &req);
13249       ast_channel_unlock(transferee);
13250       return NULL;
13251    } 
13252    ast_channel_unlock(transferee);
13253 
13254    res = ast_park_call(transferee, transferer, 0, &ext);
13255    
13256 
13257 #ifdef WHEN_WE_KNOW_THAT_THE_CLIENT_SUPPORTS_MESSAGE
13258    if (!res) {
13259       transmit_message_with_text(transferer->tech_pvt, "Unable to park call.\n");
13260    } else {
13261       /* Then tell the transferer what happened */
13262       sprintf(buf, "Call parked on extension '%d'", ext);
13263       transmit_message_with_text(transferer->tech_pvt, buf);
13264    }
13265 #endif
13266 
13267    /* Any way back to the current call??? */
13268    /* Transmit response to the REFER request */
13269    transmit_response(transferer->tech_pvt, "202 Accepted", &req);
13270    if (!res)   {
13271       /* Transfer succeeded */
13272       append_history(transferer->tech_pvt, "SIPpark","Parked call on %d", ext);
13273       transmit_notify_with_sipfrag(transferer->tech_pvt, d->seqno, "200 OK", TRUE);
13274       transferer->hangupcause = AST_CAUSE_NORMAL_CLEARING;
13275       ast_hangup(transferer); /* This will cause a BYE */
13276       if (option_debug)
13277          ast_log(LOG_DEBUG, "SIP Call parked on extension '%d'\n", ext);
13278    } else {
13279       transmit_notify_with_sipfrag(transferer->tech_pvt, d->seqno, "503 Service Unavailable", TRUE);
13280       append_history(transferer->tech_pvt, "SIPpark","Parking failed\n");
13281       if (option_debug)
13282          ast_log(LOG_DEBUG, "SIP Call parked failed \n");
13283       /* Do not hangup call */
13284    }
13285    return NULL;
13286 }

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

08579 {
08580    struct sip_peer *peer = find_peer(p->peername, NULL, 1);
08581 
08582    if (!peer)
08583       return;
08584 
08585    /* If they put someone on hold, increment the value... otherwise decrement it */
08586    if (hold)
08587       peer->onHold++;
08588    else
08589       peer->onHold--;
08590 
08591    /* Request device state update */
08592    ast_device_state_changed("SIP/%s", peer->name);
08593 
08594    return;
08595 }

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

References ast_sched_add(), AST_SCHED_DEL, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_REF, ASTOBJ_UNLOCK, ASTOBJ_UNREF, ASTOBJ_WRLOCK, peerl, sip_destroy_peer(), and sip_poke_peer_s().

Referenced by load_module(), and sip_do_reload().

18356 {
18357    int ms = 0;
18358    
18359    if (!speerobjs)   /* No peers, just give up */
18360       return;
18361 
18362    ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do {
18363       ASTOBJ_WRLOCK(iterator);
18364       if (!AST_SCHED_DEL(sched, iterator->pokeexpire)) {
18365          struct sip_peer *peer_ptr = iterator;
18366          ASTOBJ_UNREF(peer_ptr, sip_destroy_peer);
18367       }
18368       ms += 100;
18369       iterator->pokeexpire = ast_sched_add(sched, ms, sip_poke_peer_s, ASTOBJ_REF(iterator));
18370       if (iterator->pokeexpire == -1) {
18371          struct sip_peer *peer_ptr = iterator;
18372          ASTOBJ_UNREF(peer_ptr, sip_destroy_peer);
18373       }
18374       ASTOBJ_UNLOCK(iterator);
18375    } while (0)
18376    );
18377 }

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

React to lack of answer to Qualify poke.

Definition at line 16252 of file chan_sip.c.

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

Referenced by sip_poke_peer().

16253 {
16254    struct sip_peer *peer = (struct sip_peer *)data;
16255    
16256    peer->pokeexpire = -1;
16257    if (peer->lastms > -1) {
16258       ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE!  Last qualify: %d\n", peer->name, peer->lastms);
16259       manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, -1);
16260    }
16261    if (peer->call)
16262       sip_destroy(peer->call);
16263    peer->call = NULL;
16264    peer->lastms = -1;
16265    ast_device_state_changed("SIP/%s", peer->name);
16266 
16267    /* This function gets called one place outside of the scheduler ... */
16268    if (!AST_SCHED_DEL(sched, peer->pokeexpire)) {
16269       struct sip_peer *peer_ptr = peer;
16270       ASTOBJ_UNREF(peer_ptr, sip_destroy_peer);
16271    }
16272 
16273    /* There is no need to ASTOBJ_REF() here.  Just let the scheduled callback
16274     * inherit the reference that the current callback already has. */
16275    peer->pokeexpire = ast_sched_add(sched, DEFAULT_FREQ_NOTOK, sip_poke_peer_s, peer);
16276    if (peer->pokeexpire == -1) {
16277       ASTOBJ_UNREF(peer, sip_destroy_peer);
16278    }
16279 
16280    return 0;
16281 }

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 16286 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(), ASTOBJ_REF, ASTOBJ_UNREF, 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_destroy_peer(), 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().

16287 {
16288    struct sip_pvt *p;
16289    int xmitres = 0;
16290 
16291    if (!peer->maxms || !peer->addr.sin_addr.s_addr) {
16292       /* IF we have no IP, or this isn't to be monitored, return
16293         imeediately after clearing things out */
16294       if (!AST_SCHED_DEL(sched, peer->pokeexpire)) {
16295          struct sip_peer *peer_ptr = peer;
16296          ASTOBJ_UNREF(peer_ptr, sip_destroy_peer);
16297       }
16298       peer->lastms = 0;
16299       peer->call = NULL;
16300       return 0;
16301    }
16302    if (peer->call) {
16303       if (sipdebug)
16304          ast_log(LOG_NOTICE, "Still have a QUALIFY dialog active, deleting\n");
16305       sip_destroy(peer->call);
16306    }
16307    if (!(p = peer->call = sip_alloc(NULL, NULL, 0, SIP_OPTIONS)))
16308       return -1;
16309    
16310    p->sa = peer->addr;
16311    p->recv = peer->addr;
16312    ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY);
16313    ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY);
16314 
16315    /* Send OPTIONs to peer's fullcontact */
16316    if (!ast_strlen_zero(peer->fullcontact))
16317       ast_string_field_set(p, fullcontact, peer->fullcontact);
16318 
16319    if (!ast_strlen_zero(peer->tohost))
16320       ast_string_field_set(p, tohost, peer->tohost);
16321    else
16322       ast_string_field_set(p, tohost, ast_inet_ntoa(peer->addr.sin_addr));
16323 
16324    /* Recalculate our side, and recalculate Call ID */
16325    if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
16326       p->ourip = __ourip;
16327    build_via(p);
16328    build_callid_pvt(p);
16329 
16330    if (!AST_SCHED_DEL(sched, peer->pokeexpire)) {
16331       struct sip_peer *peer_ptr = peer;
16332       ASTOBJ_UNREF(peer_ptr, sip_destroy_peer);
16333    }
16334 
16335    p->relatedpeer = ASTOBJ_REF(peer);
16336    ast_set_flag(&p->flags[0], SIP_OUTGOING);
16337 #ifdef VOCAL_DATA_HACK
16338    ast_copy_string(p->username, "__VOCAL_DATA_SHOULD_READ_THE_SIP_SPEC__", sizeof(p->username));
16339    xmitres = transmit_invite(p, SIP_INVITE, 0, 2);
16340 #else
16341    xmitres = transmit_invite(p, SIP_OPTIONS, 0, 2);
16342 #endif
16343    gettimeofday(&peer->ps, NULL);
16344    if (xmitres == XMIT_ERROR) {
16345       sip_poke_noanswer(ASTOBJ_REF(peer));   /* Immediately unreachable, network problems */
16346    } else {
16347       if (!AST_SCHED_DEL(sched, peer->pokeexpire)) {
16348          struct sip_peer *peer_ptr = peer;
16349          ASTOBJ_UNREF(peer_ptr, sip_destroy_peer);
16350       }
16351       peer->pokeexpire = ast_sched_add(sched, peer->maxms * 2, sip_poke_noanswer, ASTOBJ_REF(peer));
16352       if (peer->pokeexpire == -1) {
16353          struct sip_peer *peer_ptr = peer;
16354          ASTOBJ_UNREF(peer_ptr, sip_destroy_peer);
16355       }
16356    }
16357 
16358    return 0;
16359 }

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

References ASTOBJ_UNREF, sip_peer::pokeexpire, sip_destroy_peer(), and sip_poke_peer().

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

07944 {
07945    struct sip_peer *peer = (struct sip_peer *) data;
07946 
07947    peer->pokeexpire = -1;
07948 
07949    sip_poke_peer(peer);
07950 
07951    ASTOBJ_UNREF(peer, sip_destroy_peer);
07952 
07953    return 0;
07954 }

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

Remove temporary realtime objects from memory (CLI).

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

10265 {
10266    struct sip_peer *peer;
10267    struct sip_user *user;
10268    int pruneuser = FALSE;
10269    int prunepeer = FALSE;
10270    int multi = FALSE;
10271    char *name = NULL;
10272    regex_t regexbuf;
10273 
10274    switch (argc) {
10275    case 4:
10276       if (!strcasecmp(argv[3], "user"))
10277          return RESULT_SHOWUSAGE;
10278       if (!strcasecmp(argv[3], "peer"))
10279          return RESULT_SHOWUSAGE;
10280       if (!strcasecmp(argv[3], "like"))
10281          return RESULT_SHOWUSAGE;
10282       if (!strcasecmp(argv[3], "all")) {
10283          multi = TRUE;
10284          pruneuser = prunepeer = TRUE;
10285       } else {
10286          pruneuser = prunepeer = TRUE;
10287          name = argv[3];
10288       }
10289       break;
10290    case 5:
10291       if (!strcasecmp(argv[4], "like"))
10292          return RESULT_SHOWUSAGE;
10293       if (!strcasecmp(argv[3], "all"))
10294          return RESULT_SHOWUSAGE;
10295       if (!strcasecmp(argv[3], "like")) {
10296          multi = TRUE;
10297          name = argv[4];
10298          pruneuser = prunepeer = TRUE;
10299       } else if (!strcasecmp(argv[3], "user")) {
10300          pruneuser = TRUE;
10301          if (!strcasecmp(argv[4], "all"))
10302             multi = TRUE;
10303          else
10304             name = argv[4];
10305       } else if (!strcasecmp(argv[3], "peer")) {
10306          prunepeer = TRUE;
10307          if (!strcasecmp(argv[4], "all"))
10308             multi = TRUE;
10309          else
10310             name = argv[4];
10311       } else
10312          return RESULT_SHOWUSAGE;
10313       break;
10314    case 6:
10315       if (strcasecmp(argv[4], "like"))
10316          return RESULT_SHOWUSAGE;
10317       if (!strcasecmp(argv[3], "user")) {
10318          pruneuser = TRUE;
10319          name = argv[5];
10320       } else if (!strcasecmp(argv[3], "peer")) {
10321          prunepeer = TRUE;
10322          name = argv[5];
10323       } else
10324          return RESULT_SHOWUSAGE;
10325       break;
10326    default:
10327       return RESULT_SHOWUSAGE;
10328    }
10329 
10330    if (multi && name) {
10331       if (regcomp(&regexbuf, name, REG_EXTENDED | REG_NOSUB))
10332          return RESULT_SHOWUSAGE;
10333    }
10334 
10335    if (multi) {
10336       if (prunepeer) {
10337          int pruned = 0;
10338 
10339          ASTOBJ_CONTAINER_WRLOCK(&peerl);
10340          ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do {
10341             ASTOBJ_RDLOCK(iterator);
10342             if (name && regexec(&regexbuf, iterator->name, 0, NULL, 0)) {
10343                ASTOBJ_UNLOCK(iterator);
10344                continue;
10345             };
10346             if (ast_test_flag(&iterator->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) {
10347                ASTOBJ_MARK(iterator);
10348                pruned++;
10349             }
10350             ASTOBJ_UNLOCK(iterator);
10351          } while (0) );
10352          if (pruned) {
10353             ASTOBJ_CONTAINER_PRUNE_MARKED(&peerl, sip_destroy_peer);
10354             ast_cli(fd, "%d peers pruned.\n", pruned);
10355          } else
10356             ast_cli(fd, "No peers found to prune.\n");
10357          ASTOBJ_CONTAINER_UNLOCK(&peerl);
10358       }
10359       if (pruneuser) {
10360          int pruned = 0;
10361 
10362          ASTOBJ_CONTAINER_WRLOCK(&userl);
10363          ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do {
10364             ASTOBJ_RDLOCK(iterator);
10365             if (name && regexec(&regexbuf, iterator->name, 0, NULL, 0)) {
10366                ASTOBJ_UNLOCK(iterator);
10367                continue;
10368             };
10369             if (ast_test_flag(&iterator->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) {
10370                ASTOBJ_MARK(iterator);
10371                pruned++;
10372             }
10373             ASTOBJ_UNLOCK(iterator);
10374          } while (0) );
10375          if (pruned) {
10376             ASTOBJ_CONTAINER_PRUNE_MARKED(&userl, sip_destroy_user);
10377             ast_cli(fd, "%d users pruned.\n", pruned);
10378          } else
10379             ast_cli(fd, "No users found to prune.\n");
10380          ASTOBJ_CONTAINER_UNLOCK(&userl);
10381       }
10382    } else {
10383       if (prunepeer) {
10384          if ((peer = ASTOBJ_CONTAINER_FIND_UNLINK(&peerl, name))) {
10385             if (!ast_test_flag(&peer->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) {
10386                ast_cli(fd, "Peer '%s' is not a Realtime peer, cannot be pruned.\n", name);
10387                ASTOBJ_CONTAINER_LINK(&peerl, peer);
10388             } else
10389                ast_cli(fd, "Peer '%s' pruned.\n", name);
10390             ASTOBJ_UNREF(peer, sip_destroy_peer);
10391          } else
10392             ast_cli(fd, "Peer '%s' not found.\n", name);
10393       }
10394       if (pruneuser) {
10395          if ((user = ASTOBJ_CONTAINER_FIND_UNLINK(&userl, name))) {
10396             if (!ast_test_flag(&user->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) {
10397                ast_cli(fd, "User '%s' is not a Realtime user, cannot be pruned.\n", name);
10398                ASTOBJ_CONTAINER_LINK(&userl, user);
10399             } else
10400                ast_cli(fd, "User '%s' pruned.\n", name);
10401             ASTOBJ_UNREF(user, sip_destroy_user);
10402          } else
10403             ast_cli(fd, "User '%s' not found.\n", name);
10404       }
10405    }
10406 
10407    return RESULT_SUCCESS;
10408 }

static struct ast_frame * sip_read ( struct ast_channel ast  )  [static, read]

Read SIP RTP from channel.

Definition at line 4364 of file chan_sip.c.

References ast_channel::_state, ast_bridged_channel(), AST_FRAME_VOICE, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_null_frame, ast_set_flag, AST_STATE_UP, ast_test_flag, FALSE, sip_pvt::flags, ast_frame::frametype, INV_EARLY_MEDIA, sip_pvt::invitestate, 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().

04365 {
04366    struct ast_frame *fr;
04367    struct sip_pvt *p = ast->tech_pvt;
04368    int faxdetected = FALSE;
04369 
04370    ast_mutex_lock(&p->lock);
04371    fr = sip_rtp_read(ast, p, &faxdetected);
04372    p->lastrtprx = time(NULL);
04373 
04374    /* If we are NOT bridged to another channel, and we have detected fax tone we issue T38 re-invite to a peer */
04375    /* 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 */
04376    if (faxdetected && ast_test_flag(&p->t38.t38support, SIP_PAGE2_T38SUPPORT_UDPTL) && (p->t38.state == T38_DISABLED) && !(ast_bridged_channel(ast))) {
04377       if (!ast_test_flag(&p->flags[0], SIP_GOTREFER)) {
04378          if (!p->pendinginvite) {
04379             if (option_debug > 2)
04380                ast_log(LOG_DEBUG, "Sending reinvite on SIP (%s) for T.38 negotiation.\n",ast->name);
04381             p->t38.state = T38_LOCAL_REINVITE;
04382             transmit_reinvite_with_t38_sdp(p);
04383             if (option_debug > 1)
04384                ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, ast->name);
04385          }
04386       } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) {
04387          if (option_debug > 2)
04388             ast_log(LOG_DEBUG, "Deferring reinvite on SIP (%s) - it will be re-negotiated for T.38\n", ast->name);
04389          ast_set_flag(&p->flags[0], SIP_NEEDREINVITE);
04390       }
04391    }
04392 
04393    /* Only allow audio through if they sent progress with SDP, or if the channel is actually answered */
04394    if (fr->frametype == AST_FRAME_VOICE && p->invitestate != INV_EARLY_MEDIA && ast->_state != AST_STATE_UP) {
04395       fr = &ast_null_frame;
04396    }
04397 
04398    ast_mutex_unlock(&p->lock);
04399    return fr;
04400 }

static struct sockaddr_in * sip_real_dst ( const struct sip_pvt p  )  [static, read]

The real destination address for a write.

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

01751 {
01752    return ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE ? &p->recv : &p->sa;
01753 }

static int sip_refer_allocate ( struct sip_pvt p  )  [static]

Allocate SIP refer structure.

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

07749 {
07750    p->refer = ast_calloc(1, sizeof(struct sip_refer)); 
07751    return p->refer ? 1 : 0;
07752 }

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

Registration timeout, register again.

Definition at line 7503 of file chan_sip.c.

References __sip_pretend_ack(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ASTOBJ_REF, ASTOBJ_UNREF, sip_registry::call, EVENT_FLAG_SYSTEM, sip_pvt::flags, sip_pvt::lock, 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().

07504 {
07505 
07506    /* if we are here, our registration timed out, so we'll just do it over */
07507    struct sip_registry *r = ASTOBJ_REF((struct sip_registry *) data);
07508    struct sip_pvt *p;
07509    int res;
07510 
07511    /* if we couldn't get a reference to the registry object, punt */
07512    if (!r)
07513       return 0;
07514 
07515    ast_log(LOG_NOTICE, "   -- Registration for '%s@%s' timed out, trying again (Attempt #%d)\n", r->username, r->hostname, r->regattempts); 
07516    if (r->call) {
07517       /* Unlink us, destroy old call.  Locking is not relevant here because all this happens
07518          in the single SIP manager thread. */
07519       p = r->call;
07520       ast_mutex_lock(&p->lock);
07521       if (p->registry)
07522          ASTOBJ_UNREF(p->registry, sip_registry_destroy);
07523       r->call = NULL;
07524       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
07525       /* Pretend to ACK anything just in case */
07526       __sip_pretend_ack(p);
07527       ast_mutex_unlock(&p->lock);
07528    }
07529    /* If we have a limit, stop registration and give up */
07530    if (global_regattempts_max && (r->regattempts > global_regattempts_max)) {
07531       /* Ok, enough is enough. Don't try any more */
07532       /* We could add an external notification here... 
07533          steal it from app_voicemail :-) */
07534       ast_log(LOG_NOTICE, "   -- Giving up forever trying to register '%s@%s'\n", r->username, r->hostname);
07535       r->regstate = REG_STATE_FAILED;
07536    } else {
07537       r->regstate = REG_STATE_UNREGISTERED;
07538       r->timeout = -1;
07539       res=transmit_register(r, SIP_REGISTER, NULL, NULL);
07540    }
07541    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));
07542    ASTOBJ_UNREF(r, sip_registry_destroy);
07543    return 0;
07544 }

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

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

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

04690 {
04691    struct sip_registry *reg;
04692    int portnum = 0;
04693    char username[256] = "";
04694    char *hostname=NULL, *secret=NULL, *authuser=NULL;
04695    char *porta=NULL;
04696    char *contact=NULL;
04697 
04698    if (!value)
04699       return -1;
04700    ast_copy_string(username, value, sizeof(username));
04701    /* First split around the last '@' then parse the two components. */
04702    hostname = strrchr(username, '@'); /* allow @ in the first part */
04703    if (hostname)
04704       *hostname++ = '\0';
04705    if (ast_strlen_zero(username) || ast_strlen_zero(hostname)) {
04706       ast_log(LOG_WARNING, "Format for registration is user[:secret[:authuser]]@host[:port][/contact] at line %d\n", lineno);
04707       return -1;
04708    }
04709    /* split user[:secret[:authuser]] */
04710    secret = strchr(username, ':');
04711    if (secret) {
04712       *secret++ = '\0';
04713       authuser = strchr(secret, ':');
04714       if (authuser)
04715          *authuser++ = '\0';
04716    }
04717    /* split host[:port][/contact] */
04718    contact = strchr(hostname, '/');
04719    if (contact)
04720       *contact++ = '\0';
04721    if (ast_strlen_zero(contact))
04722       contact = "s";
04723    porta = strchr(hostname, ':');
04724    if (porta) {
04725       *porta++ = '\0';
04726       portnum = atoi(porta);
04727       if (portnum == 0) {
04728          ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno);
04729          return -1;
04730       }
04731    }
04732    if (!(reg = ast_calloc(1, sizeof(*reg)))) {
04733       ast_log(LOG_ERROR, "Out of memory. Can't allocate SIP registry entry\n");
04734       return -1;
04735    }
04736 
04737    if (ast_string_field_init(reg, 256)) {
04738       ast_log(LOG_ERROR, "Out of memory. Can't allocate SIP registry strings\n");
04739       free(reg);
04740       return -1;
04741    }
04742 
04743    regobjs++;
04744    ASTOBJ_INIT(reg);
04745    ast_string_field_set(reg, contact, contact);
04746    if (!ast_strlen_zero(username))
04747       ast_string_field_set(reg, username, username);
04748    if (hostname)
04749       ast_string_field_set(reg, hostname, hostname);
04750    if (authuser)
04751       ast_string_field_set(reg, authuser, authuser);
04752    if (secret)
04753       ast_string_field_set(reg, secret, secret);
04754    reg->expire = -1;
04755    reg->timeout =  -1;
04756    reg->refresh = default_expiry;
04757    reg->portno = portnum;
04758    reg->callid_valid = FALSE;
04759    reg->ocseq = INITIAL_CSEQ;
04760    ASTOBJ_CONTAINER_LINK(&regl, reg);  /* Add the new registry entry to the list */
04761    ASTOBJ_UNREF(reg,sip_registry_destroy);
04762    return 0;
04763 }

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

03047 {
03048    /* Really delete */
03049    if (option_debug > 2)
03050       ast_log(LOG_DEBUG, "Destroying registry entry for %s@%s\n", reg->username, reg->hostname);
03051 
03052    if (reg->call) {
03053       /* Clear registry before destroying to ensure
03054          we don't get reentered trying to grab the registry lock */
03055       reg->call->registry = NULL;
03056       if (option_debug > 2)
03057          ast_log(LOG_DEBUG, "Destroying active SIP dialog for registry %s@%s\n", reg->username, reg->hostname);
03058       sip_destroy(reg->call);
03059    }
03060    AST_SCHED_DEL(sched, reg->expire);
03061    AST_SCHED_DEL(sched, reg->timeout);
03062    ast_string_field_free_memory(reg);
03063    regobjs--;
03064    free(reg);
03065    
03066 }

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

References ast_set_flag, sip_pvt::flags, SIP_NEEDREINVITE, and sip_pvt::waitid.

Referenced by handle_response_invite().

12199 {
12200    struct sip_pvt *p = (struct sip_pvt *) data;
12201 
12202    ast_set_flag(&p->flags[0], SIP_NEEDREINVITE);   
12203    p->waitid = -1;
12204    return 0;
12205 }

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

Force reload of module from cli.

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

18424 {
18425    ast_mutex_lock(&sip_reload_lock);
18426    if (sip_reloading) 
18427       ast_verbose("Previous SIP reload not yet done\n");
18428    else {
18429       sip_reloading = TRUE;
18430       if (fd)
18431          sip_reloadreason = CHANNEL_CLI_RELOAD;
18432       else
18433          sip_reloadreason = CHANNEL_MODULE_RELOAD;
18434    }
18435    ast_mutex_unlock(&sip_reload_lock);
18436    restart_monitor();
18437 
18438    return 0;
18439 }

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

16465 {
16466    int oldformat;
16467    struct sip_pvt *p;
16468    struct ast_channel *tmpc = NULL;
16469    char *ext, *host;
16470    char tmp[256];
16471    char *dest = data;
16472 
16473    oldformat = format;
16474    if (!(format &= ((AST_FORMAT_MAX_AUDIO << 1) - 1))) {
16475       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));
16476       *cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;   /* Can't find codec to connect to host */
16477       return NULL;
16478    }
16479    if (option_debug)
16480       ast_log(LOG_DEBUG, "Asked to create a SIP channel with formats: %s\n", ast_getformatname_multiple(tmp, sizeof(tmp), oldformat));
16481 
16482    if (!(p = sip_alloc(NULL, NULL, 0, SIP_INVITE))) {
16483       ast_log(LOG_ERROR, "Unable to build sip pvt data for '%s' (Out of memory or socket error)\n", (char *)data);
16484       *cause = AST_CAUSE_SWITCH_CONGESTION;
16485       return NULL;
16486    }
16487 
16488    ast_set_flag(&p->flags[1], SIP_PAGE2_OUTGOING_CALL);
16489 
16490    if (!(p->options = ast_calloc(1, sizeof(*p->options)))) {
16491       sip_destroy(p);
16492       ast_log(LOG_ERROR, "Unable to build option SIP data structure - Out of memory\n");
16493       *cause = AST_CAUSE_SWITCH_CONGESTION;
16494       return NULL;
16495    }
16496 
16497    ast_copy_string(tmp, dest, sizeof(tmp));
16498    host = strchr(tmp, '@');
16499    if (host) {
16500       *host++ = '\0';
16501       ext = tmp;
16502    } else {
16503       ext = strchr(tmp, '/');
16504       if (ext) 
16505          *ext++ = '\0';
16506       host = tmp;
16507    }
16508 
16509    if (create_addr(p, host)) {
16510       *cause = AST_CAUSE_UNREGISTERED;
16511       if (option_debug > 2)
16512          ast_log(LOG_DEBUG, "Cant create SIP call - target device not registred\n");
16513       sip_destroy(p);
16514       return NULL;
16515    }
16516    if (ast_strlen_zero(p->peername) && ext)
16517       ast_string_field_set(p, peername, ext);
16518    /* Recalculate our side, and recalculate Call ID */
16519    if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
16520       p->ourip = __ourip;
16521    build_via(p);
16522    build_callid_pvt(p);
16523    
16524    /* We have an extension to call, don't use the full contact here */
16525    /* This to enable dialing registered peers with extension dialling,
16526       like SIP/peername/extension   
16527       SIP/peername will still use the full contact */
16528    if (ext) {
16529       ast_string_field_set(p, username, ext);
16530       ast_string_field_free(p, fullcontact);
16531    }
16532 #if 0
16533    printf("Setting up to call extension '%s' at '%s'\n", ext ? ext : "<none>", host);
16534 #endif
16535    p->prefcodec = oldformat;           /* Format for this call */
16536    ast_mutex_lock(&p->lock);
16537    tmpc = sip_new(p, AST_STATE_DOWN, host);  /* Place the call */
16538    ast_mutex_unlock(&p->lock);
16539    if (!tmpc)
16540       sip_destroy(p);
16541    ast_update_use_count();
16542    restart_monitor();
16543    return tmpc;
16544 }

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

Update registration with SIP Proxy.

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

07472 {
07473    /* if we are here, we know that we need to reregister. */
07474    struct sip_registry *r= ASTOBJ_REF((struct sip_registry *) data);
07475 
07476    /* if we couldn't get a reference to the registry object, punt */
07477    if (!r)
07478       return 0;
07479 
07480    if (r->call && !ast_test_flag(&r->call->flags[0], SIP_NO_HISTORY))
07481       append_history(r->call, "RegistryRenew", "Account: %s@%s", r->username, r->hostname);
07482    /* Since registry's are only added/removed by the the monitor thread, this
07483       may be overkill to reference/dereference at all here */
07484    if (sipdebug)
07485       ast_log(LOG_NOTICE, "   -- Re-registration for  %s@%s\n", r->username, r->hostname);
07486 
07487    r->expire = -1;
07488    __sip_do_register(r);
07489    ASTOBJ_UNREF(r, sip_registry_destroy);
07490    return 0;
07491 }

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

04295 {
04296    /* Retrieve audio/etc from channel.  Assumes p->lock is already held. */
04297    struct ast_frame *f;
04298    
04299    if (!p->rtp) {
04300       /* We have no RTP allocated for this channel */
04301       return &ast_null_frame;
04302    }
04303 
04304    switch(ast->fdno) {
04305    case 0:
04306       f = ast_rtp_read(p->rtp);  /* RTP Audio */
04307       break;
04308    case 1:
04309       f = ast_rtcp_read(p->rtp); /* RTCP Control Channel */
04310       break;
04311    case 2:
04312       f = ast_rtp_read(p->vrtp); /* RTP Video */
04313       break;
04314    case 3:
04315       f = ast_rtcp_read(p->vrtp);   /* RTCP Control Channel for video */
04316       break;
04317    case 5:
04318       f = ast_udptl_read(p->udptl); /* UDPTL for T.38 */
04319       break;
04320    default:
04321       f = &ast_null_frame;
04322    }
04323    /* Don't forward RFC2833 if we're not supposed to */
04324    if (f && (f->frametype == AST_FRAME_DTMF) &&
04325        (ast_test_flag(&p->flags[0], SIP_DTMF) != SIP_DTMF_RFC2833))
04326       return &ast_null_frame;
04327 
04328       /* We already hold the channel lock */
04329    if (!p->owner || (f && f->frametype != AST_FRAME_VOICE))
04330       return f;
04331 
04332    if (f && f->subclass != (p->owner->nativeformats & AST_FORMAT_AUDIO_MASK)) {
04333       if (!(f->subclass & p->jointcapability)) {
04334          if (option_debug) {
04335             ast_log(LOG_DEBUG, "Bogus frame of format '%s' received from '%s'!\n",
04336                ast_getformatname(f->subclass), p->owner->name);
04337          }
04338          return &ast_null_frame;
04339       }
04340       if (option_debug)
04341          ast_log(LOG_DEBUG, "Oooh, format changed to %d\n", f->subclass);
04342       p->owner->nativeformats = (p->owner->nativeformats & AST_FORMAT_VIDEO_MASK) | f->subclass;
04343       ast_set_read_format(p->owner, p->owner->readformat);
04344       ast_set_write_format(p->owner, p->owner->writeformat);
04345    }
04346 
04347    if (f && (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) && p->vad) {
04348       f = ast_dsp_process(p->owner, p->vad, f);
04349       if (f && f->frametype == AST_FRAME_DTMF) {
04350          if (ast_test_flag(&p->t38.t38support, SIP_PAGE2_T38SUPPORT_UDPTL) && f->subclass == 'f') {
04351             if (option_debug)
04352                ast_log(LOG_DEBUG, "Fax CNG detected on %s\n", ast->name);
04353             *faxdetect = 1;
04354          } else if (option_debug) {
04355             ast_log(LOG_DEBUG, "* Detected inband DTMF '%c'\n", f->subclass);
04356          }
04357       }
04358    }
04359    
04360    return f;
04361 }

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

18381 {
18382    int ms;
18383    int regspacing;
18384    if (!regobjs)
18385       return;
18386    regspacing = default_expiry * 1000/regobjs;
18387    if (regspacing > 100)
18388       regspacing = 100;
18389    ms = regspacing;
18390    ASTOBJ_CONTAINER_TRAVERSE(&regl, 1, do {
18391       ASTOBJ_WRLOCK(iterator);
18392       AST_SCHED_DEL(sched, iterator->expire);
18393       ms += regspacing;
18394       iterator->expire = ast_sched_add(sched, ms, sip_reregister, iterator);
18395       ASTOBJ_UNLOCK(iterator);
18396    } while (0)
18397    );
18398 }

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

15987 {
15988    /* Called with peerl lock, but releases it */
15989    struct sip_pvt *p;
15990    int newmsgs, oldmsgs;
15991 
15992    /* Do we have an IP address? If not, skip this peer */
15993    if (!peer->addr.sin_addr.s_addr && !peer->defaddr.sin_addr.s_addr) 
15994       return 0;
15995 
15996    /* Check for messages */
15997    ast_app_inboxcount(peer->mailbox, &newmsgs, &oldmsgs);
15998    
15999    peer->lastmsgcheck = time(NULL);
16000    
16001    /* Return now if it's the same thing we told them last time */
16002    if (((newmsgs > 0x7fff ? 0x7fff0000 : (newmsgs << 16)) | (oldmsgs > 0xffff ? 0xffff : oldmsgs)) == peer->lastmsgssent) {
16003       return 0;
16004    }
16005    
16006    
16007    peer->lastmsgssent = ((newmsgs > 0x7fff ? 0x7fff0000 : (newmsgs << 16)) | (oldmsgs > 0xffff ? 0xffff : oldmsgs));
16008 
16009    if (peer->mwipvt) {
16010       /* Base message on subscription */
16011       p = peer->mwipvt;
16012    } else {
16013       /* Build temporary dialog for this message */
16014       if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY))) 
16015          return -1;
16016       if (create_addr_from_peer(p, peer)) {
16017          /* Maybe they're not registered, etc. */
16018          sip_destroy(p);
16019          return 0;
16020       }
16021       /* Recalculate our side, and recalculate Call ID */
16022       if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
16023          p->ourip = __ourip;
16024       build_via(p);
16025       build_callid_pvt(p);
16026       /* Destroy this session after 32 secs */
16027       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
16028    }
16029    /* Send MWI */
16030    ast_set_flag(&p->flags[0], SIP_OUTGOING);
16031    transmit_notify_with_mwi(p, newmsgs, oldmsgs, peer->vmexten);
16032    return 0;
16033 }

static int sip_senddigit_begin ( struct ast_channel ast,
char  digit 
) [static]

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

03824 {
03825    struct sip_pvt *p = ast->tech_pvt;
03826    int res = 0;
03827 
03828    ast_mutex_lock(&p->lock);
03829    switch (ast_test_flag(&p->flags[0], SIP_DTMF)) {
03830    case SIP_DTMF_INBAND:
03831       res = -1; /* Tell Asterisk to generate inband indications */
03832       break;
03833    case SIP_DTMF_RFC2833:
03834       if (p->rtp)
03835          ast_rtp_senddigit_begin(p->rtp, digit);
03836       break;
03837    default:
03838       break;
03839    }
03840    ast_mutex_unlock(&p->lock);
03841 
03842    return res;
03843 }

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

03848 {
03849    struct sip_pvt *p = ast->tech_pvt;
03850    int res = 0;
03851 
03852    ast_mutex_lock(&p->lock);
03853    switch (ast_test_flag(&p->flags[0], SIP_DTMF)) {
03854    case SIP_DTMF_INFO:
03855       transmit_info_with_digit(p, digit, duration);
03856       break;
03857    case SIP_DTMF_RFC2833:
03858       if (p->rtp)
03859          ast_rtp_senddigit_end(p->rtp, digit);
03860       break;
03861    case SIP_DTMF_INBAND:
03862       res = -1; /* Tell Asterisk to stop inband indications */
03863       break;
03864    }
03865    ast_mutex_unlock(&p->lock);
03866 
03867    return res;
03868 }

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

Send SIP MESSAGE text within a call Called from PBX core sendtext() application.

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

02373 {
02374    struct sip_pvt *p = ast->tech_pvt;
02375    int debug = sip_debug_test_pvt(p);
02376 
02377    if (debug)
02378       ast_verbose("Sending text %s on %s\n", text, ast->name);
02379    if (!p)
02380       return -1;
02381    if (ast_strlen_zero(text))
02382       return 0;
02383    if (debug)
02384       ast_verbose("Really sending text %s on %s\n", text, ast->name);
02385    transmit_message_with_text(p, text);
02386    return 0;   
02387 }

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

Referenced by sip_fixup().

18108 {
18109    struct sip_pvt *p;
18110    int changed = 0;
18111 
18112    p = chan->tech_pvt;
18113    if (!p) 
18114       return -1;
18115 
18116    /* Disable early RTP bridge  */
18117    if (chan->_state != AST_STATE_UP && !global_directrtpsetup)    /* We are in early state */
18118       return 0;
18119 
18120    ast_mutex_lock(&p->lock);
18121    if (ast_test_flag(&p->flags[0], SIP_ALREADYGONE)) {
18122       /* If we're destroyed, don't bother */
18123       ast_mutex_unlock(&p->lock);
18124       return 0;
18125    }
18126 
18127    /* if this peer cannot handle reinvites of the media stream to devices
18128       that are known to be behind a NAT, then stop the process now
18129    */
18130    if (nat_active && !ast_test_flag(&p->flags[0], SIP_CAN_REINVITE_NAT)) {
18131       ast_mutex_unlock(&p->lock);
18132       return 0;
18133    }
18134 
18135    if (rtp) {
18136       changed |= ast_rtp_get_peer(rtp, &p->redirip);
18137    } else if (p->redirip.sin_addr.s_addr || ntohs(p->redirip.sin_port) != 0) {
18138       memset(&p->redirip, 0, sizeof(p->redirip));
18139       changed = 1;
18140    }
18141    if (vrtp) {
18142       changed |= ast_rtp_get_peer(vrtp, &p->vredirip);
18143    } else if (p->vredirip.sin_addr.s_addr || ntohs(p->vredirip.sin_port) != 0) {
18144       memset(&p->vredirip, 0, sizeof(p->vredirip));
18145       changed = 1;
18146    }
18147    if (codecs) {
18148       if ((p->redircodecs != codecs)) {
18149          p->redircodecs = codecs;
18150          changed = 1;
18151       }
18152       if ((p->capability & codecs) != p->capability) {
18153          p->jointcapability &= codecs;
18154          p->capability &= codecs;
18155          changed = 1;
18156       }
18157    }
18158    if (changed && !ast_test_flag(&p->flags[0], SIP_GOTREFER) && !ast_test_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER)) {
18159       if (chan->_state != AST_STATE_UP) { /* We are in early state */
18160          if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY))
18161             append_history(p, "ExtInv", "Initial invite sent with remote bridge proposal.");
18162          if (option_debug)
18163             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));
18164       } else if (!p->pendinginvite) {     /* We are up, and have no outstanding invite */
18165          if (option_debug > 2) {
18166             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));
18167          }
18168          transmit_reinvite_with_sdp(p);
18169       } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) {
18170          if (option_debug > 2) {
18171             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));
18172          }
18173          /* We have a pending Invite. Send re-invite when we're done with the invite */
18174          ast_set_flag(&p->flags[0], SIP_NEEDREINVITE);   
18175       }
18176    }
18177    /* Reset lastrtprx timer */
18178    p->lastrtprx = p->lastrtptx = time(NULL);
18179    ast_mutex_unlock(&p->lock);
18180    return 0;
18181 }

static int sip_set_udptl_peer ( struct ast_channel chan,
struct ast_udptl udptl 
) [static]

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

17935 {
17936    struct sip_pvt *p;
17937    
17938    p = chan->tech_pvt;
17939    if (!p)
17940       return -1;
17941    ast_mutex_lock(&p->lock);
17942    if (udptl)
17943       ast_udptl_get_peer(udptl, &p->udptlredirip);
17944    else
17945       memset(&p->udptlredirip, 0, sizeof(p->udptlredirip));
17946    if (!ast_test_flag(&p->flags[0], SIP_GOTREFER)) {
17947       if (!p->pendinginvite) {
17948          if (option_debug > 2) {
17949             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);
17950          }
17951          transmit_reinvite_with_t38_sdp(p);
17952       } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) {
17953          if (option_debug > 2) {
17954             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);
17955          }
17956          ast_set_flag(&p->flags[0], SIP_NEEDREINVITE);
17957       }
17958    }
17959    /* Reset lastrtprx timer */
17960    p->lastrtprx = p->lastrtptx = time(NULL);
17961    ast_mutex_unlock(&p->lock);
17962    return 0;
17963 }

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

Show details of one active dialog.

Definition at line 11137 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, SIPBUFSIZE, sip_pvt::sipoptions, sip_pvt::subscribed, subscription_type2str(), sip_pvt::tag, text, and transfermode2str().

11138 {
11139    struct sip_pvt *cur;
11140    size_t len;
11141    int found = 0;
11142 
11143    if (argc != 4)
11144       return RESULT_SHOWUSAGE;
11145    len = strlen(argv[3]);
11146    ast_mutex_lock(&iflock);
11147    for (cur = iflist; cur; cur = cur->next) {
11148       if (!strncasecmp(cur->callid, argv[3], len)) {
11149          char formatbuf[SIPBUFSIZE/2];
11150          ast_cli(fd,"\n");
11151          if (cur->subscribed != NONE)
11152             ast_cli(fd, "  * Subscription (type: %s)\n", subscription_type2str(cur->subscribed));
11153          else
11154             ast_cli(fd, "  * SIP Call\n");
11155          ast_cli(fd, "  Curr. trans. direction:  %s\n", ast_test_flag(&cur->flags[0], SIP_OUTGOING) ? "Outgoing" : "Incoming");
11156          ast_cli(fd, "  Call-ID:                %s\n", cur->callid);
11157          ast_cli(fd, "  Owner channel ID:       %s\n", cur->owner ? cur->owner->name : "<none>");
11158          ast_cli(fd, "  Our Codec Capability:   %d\n", cur->capability);
11159          ast_cli(fd, "  Non-Codec Capability (DTMF):   %d\n", cur->noncodeccapability);
11160          ast_cli(fd, "  Their Codec Capability:   %d\n", cur->peercapability);
11161          ast_cli(fd, "  Joint Codec Capability:   %d\n", cur->jointcapability);
11162          ast_cli(fd, "  Format:                 %s\n", ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->owner ? cur->owner->nativeformats : 0) );
11163          ast_cli(fd, "  MaxCallBR:              %d kbps\n", cur->maxcallbitrate);
11164          ast_cli(fd, "  Theoretical Address:    %s:%d\n", ast_inet_ntoa(cur->sa.sin_addr), ntohs(cur->sa.sin_port));
11165          ast_cli(fd, "  Received Address:       %s:%d\n", ast_inet_ntoa(cur->recv.sin_addr), ntohs(cur->recv.sin_port));
11166          ast_cli(fd, "  SIP Transfer mode:      %s\n", transfermode2str(cur->allowtransfer));
11167          ast_cli(fd, "  NAT Support:            %s\n", nat2str(ast_test_flag(&cur->flags[0], SIP_NAT)));
11168          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)" );
11169          ast_cli(fd, "  Our Tag:                %s\n", cur->tag);
11170          ast_cli(fd, "  Their Tag:              %s\n", cur->theirtag);
11171          ast_cli(fd, "  SIP User agent:         %s\n", cur->useragent);
11172          if (!ast_strlen_zero(cur->username))
11173             ast_cli(fd, "  Username:               %s\n", cur->username);
11174          if (!ast_strlen_zero(cur->peername))
11175             ast_cli(fd, "  Peername:               %s\n", cur->peername);
11176          if (!ast_strlen_zero(cur->uri))
11177             ast_cli(fd, "  Original uri:           %s\n", cur->uri);
11178          if (!ast_strlen_zero(cur->cid_num))
11179             ast_cli(fd, "  Caller-ID:              %s\n", cur->cid_num);
11180          ast_cli(fd, "  Need Destroy:           %d\n", ast_test_flag(&cur->flags[0], SIP_NEEDDESTROY));
11181          ast_cli(fd, "  Last Message:           %s\n", cur->lastmsg);
11182          ast_cli(fd, "  Promiscuous Redir:      %s\n", ast_test_flag(&cur->flags[0], SIP_PROMISCREDIR) ? "Yes" : "No");
11183          ast_cli(fd, "  Route:                  %s\n", cur->route ? cur->route->hop : "N/A");
11184          ast_cli(fd, "  DTMF Mode:              %s\n", dtmfmode2str(ast_test_flag(&cur->flags[0], SIP_DTMF)));
11185          ast_cli(fd, "  SIP Options:            ");
11186          if (cur->sipoptions) {
11187             int x;
11188             for (x=0 ; (x < (sizeof(sip_options) / sizeof(sip_options[0]))); x++) {
11189                if (cur->sipoptions & sip_options[x].id)
11190                   ast_cli(fd, "%s ", sip_options[x].text);
11191             }
11192          } else
11193             ast_cli(fd, "(none)\n");
11194          ast_cli(fd, "\n\n");
11195          found++;
11196       }
11197    }
11198    ast_mutex_unlock(&iflock);
11199    if (!found) 
11200       ast_cli(fd, "No such SIP Call ID starting with '%s'\n", argv[3]);
11201    return RESULT_SUCCESS;
11202 }

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

Show active SIP channels.

Definition at line 10930 of file chan_sip.c.

References __sip_show_channels().

10931 {
10932         return __sip_show_channels(fd, argc, argv, 0);
10933 }

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

CLI command to list local domains.

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

10443 {
10444    struct domain *d;
10445 #define FORMAT "%-40.40s %-20.20s %-16.16s\n"
10446 
10447    if (AST_LIST_EMPTY(&domain_list)) {
10448       ast_cli(fd, "SIP Domain support not enabled.\n\n");
10449       return RESULT_SUCCESS;
10450    } else {
10451       ast_cli(fd, FORMAT, "Our local SIP domains:", "Context", "Set by");
10452       AST_LIST_LOCK(&domain_list);
10453       AST_LIST_TRAVERSE(&domain_list, d, list)
10454          ast_cli(fd, FORMAT, d->domain, S_OR(d->context, "(default)"),
10455             domain_mode_to_text(d->mode));
10456       AST_LIST_UNLOCK(&domain_list);
10457       ast_cli(fd, "\n");
10458       return RESULT_SUCCESS;
10459    }
10460 }

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

Show history details of one dialog.

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

11206 {
11207    struct sip_pvt *cur;
11208    size_t len;
11209    int found = 0;
11210 
11211    if (argc != 4)
11212       return RESULT_SHOWUSAGE;
11213    if (!recordhistory)
11214       ast_cli(fd, "\n***Note: History recording is currently DISABLED.  Use 'sip history' to ENABLE.\n");
11215    len = strlen(argv[3]);
11216    ast_mutex_lock(&iflock);
11217    for (cur = iflist; cur; cur = cur->next) {
11218       if (!strncasecmp(cur->callid, argv[3], len)) {
11219          struct sip_history *hist;
11220          int x = 0;
11221 
11222          ast_cli(fd,"\n");
11223          if (cur->subscribed != NONE)
11224             ast_cli(fd, "  * Subscription\n");
11225          else
11226             ast_cli(fd, "  * SIP Call\n");
11227          if (cur->history)
11228             AST_LIST_TRAVERSE(cur->history, hist, list)
11229                ast_cli(fd, "%d. %s\n", ++x, hist->event);
11230          if (x == 0)
11231             ast_cli(fd, "Call '%s' has no history\n", cur->callid);
11232          found++;
11233       }
11234    }
11235    ast_mutex_unlock(&iflock);
11236    if (!found) 
11237       ast_cli(fd, "No such SIP Call ID starting with '%s'\n", argv[3]);
11238    return RESULT_SUCCESS;
11239 }

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

09868 {
09869 #define FORMAT  "%-25.25s %-15.15s %-15.15s \n"
09870 #define FORMAT2 "%-25.25s %-15.15s %-15.15s \n"
09871    char ilimits[40];
09872    char iused[40];
09873    int showall = FALSE;
09874 
09875    if (argc < 3) 
09876       return RESULT_SHOWUSAGE;
09877 
09878    if (argc == 4 && !strcmp(argv[3],"all")) 
09879          showall = TRUE;
09880    
09881    ast_cli(fd, FORMAT, "* User name", "In use", "Limit");
09882    ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do {
09883       ASTOBJ_RDLOCK(iterator);
09884       if (iterator->call_limit)
09885          snprintf(ilimits, sizeof(ilimits), "%d", iterator->call_limit);
09886       else 
09887          ast_copy_string(ilimits, "N/A", sizeof(ilimits));
09888       snprintf(iused, sizeof(iused), "%d", iterator->inUse);
09889       if (showall || iterator->call_limit)
09890          ast_cli(fd, FORMAT2, iterator->name, iused, ilimits);
09891       ASTOBJ_UNLOCK(iterator);
09892    } while (0) );
09893 
09894    ast_cli(fd, FORMAT, "* Peer name", "In use", "Limit");
09895 
09896    ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do {
09897       ASTOBJ_RDLOCK(iterator);
09898       if (iterator->call_limit)
09899          snprintf(ilimits, sizeof(ilimits), "%d", iterator->call_limit);
09900       else 
09901          ast_copy_string(ilimits, "N/A", sizeof(ilimits));
09902       snprintf(iused, sizeof(iused), "%d/%d", iterator->inUse, iterator->inRinging);
09903       if (showall || iterator->call_limit)
09904          ast_cli(fd, FORMAT2, iterator->name, iused, ilimits);
09905       ASTOBJ_UNLOCK(iterator);
09906    } while (0) );
09907 
09908    return RESULT_SUCCESS;
09909 #undef FORMAT
09910 #undef FORMAT2
09911 }

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

List all allocated SIP Objects (realtime or static).

Definition at line 10188 of file chan_sip.c.

References ast_cli(), ASTOBJ_CONTAINER_DUMP, peerl, regl, RESULT_SHOWUSAGE, RESULT_SUCCESS, and userl.

10189 {
10190    char tmp[256];
10191    if (argc != 3)
10192       return RESULT_SHOWUSAGE;
10193    ast_cli(fd, "-= User objects: %d static, %d realtime =-\n\n", suserobjs, ruserobjs);
10194    ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), &userl);
10195    ast_cli(fd, "-= Peer objects: %d static, %d realtime, %d autocreate =-\n\n", speerobjs, rpeerobjs, apeerobjs);
10196    ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), &peerl);
10197    ast_cli(fd, "-= Registry objects: %d =-\n\n", regobjs);
10198    ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), &regl);
10199    return RESULT_SUCCESS;
10200 }

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

Show one peer in detail.

Definition at line 10494 of file chan_sip.c.

References _sip_show_peer().

10495 {
10496    return _sip_show_peer(0, fd, NULL, NULL, argc, (const char **) argv);
10497 }

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

CLI Show Peers command.

Definition at line 10044 of file chan_sip.c.

References _sip_show_peers().

10045 {
10046    return _sip_show_peers(fd, NULL, NULL, NULL, argc, (const char **) argv);
10047 }

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

Show SIP Registry (registrations with other SIP proxies.

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

10768 {
10769 #define FORMAT2 "%-30.30s  %-12.12s  %8.8s %-20.20s %-25.25s\n"
10770 #define FORMAT  "%-30.30s  %-12.12s  %8d %-20.20s %-25.25s\n"
10771    char host[80];
10772    char tmpdat[256];
10773    struct tm tm;
10774 
10775 
10776    if (argc != 3)
10777       return RESULT_SHOWUSAGE;
10778    ast_cli(fd, FORMAT2, "Host", "Username", "Refresh", "State", "Reg.Time");
10779    ASTOBJ_CONTAINER_TRAVERSE(&regl, 1, do {
10780       ASTOBJ_RDLOCK(iterator);
10781       snprintf(host, sizeof(host), "%s:%d", iterator->hostname, iterator->portno ? iterator->portno : STANDARD_SIP_PORT);
10782       if (iterator->regtime) {
10783          ast_localtime(&iterator->regtime, &tm, NULL);
10784          strftime(tmpdat, sizeof(tmpdat), "%a, %d %b %Y %T", &tm);
10785       } else {
10786          tmpdat[0] = 0;
10787       }
10788       ast_cli(fd, FORMAT, host, iterator->username, iterator->refresh, regstate2str(iterator->regstate), tmpdat);
10789       ASTOBJ_UNLOCK(iterator);
10790    } while(0));
10791    return RESULT_SUCCESS;
10792 #undef FORMAT
10793 #undef FORMAT2
10794 }

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

List global settings for the SIP channel.

Definition at line 10797 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, SIPBUFSIZE, and transfermode2str().

10798 {
10799    int realtimepeers;
10800    int realtimeusers;
10801    char codec_buf[SIPBUFSIZE];
10802 
10803    realtimepeers = ast_check_realtime("sippeers");
10804    realtimeusers = ast_check_realtime("sipusers");
10805 
10806    if (argc != 3)
10807       return RESULT_SHOWUSAGE;
10808    ast_cli(fd, "\n\nGlobal Settings:\n");
10809    ast_cli(fd, "----------------\n");
10810    ast_cli(fd, "  SIP Port:               %d\n", ntohs(bindaddr.sin_port));
10811    ast_cli(fd, "  Bindaddress:            %s\n", ast_inet_ntoa(bindaddr.sin_addr));
10812    ast_cli(fd, "  Videosupport:           %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_VIDEOSUPPORT) ? "Yes" : "No");
10813    ast_cli(fd, "  AutoCreatePeer:         %s\n", autocreatepeer ? "Yes" : "No");
10814    ast_cli(fd, "  Allow unknown access:   %s\n", global_allowguest ? "Yes" : "No");
10815    ast_cli(fd, "  Allow subscriptions:    %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWSUBSCRIBE) ? "Yes" : "No");
10816    ast_cli(fd, "  Allow overlap dialing:  %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP) ? "Yes" : "No");
10817    ast_cli(fd, "  Promsic. redir:         %s\n", ast_test_flag(&global_flags[0], SIP_PROMISCREDIR) ? "Yes" : "No");
10818    ast_cli(fd, "  SIP domain support:     %s\n", AST_LIST_EMPTY(&domain_list) ? "No" : "Yes");
10819    ast_cli(fd, "  Call to non-local dom.: %s\n", allow_external_domains ? "Yes" : "No");
10820    ast_cli(fd, "  URI user is phone no:   %s\n", ast_test_flag(&global_flags[0], SIP_USEREQPHONE) ? "Yes" : "No");
10821    ast_cli(fd, "  Our auth realm          %s\n", global_realm);
10822    ast_cli(fd, "  Realm. auth:            %s\n", authl ? "Yes": "No");
10823    ast_cli(fd, "  Always auth rejects:    %s\n", global_alwaysauthreject ? "Yes" : "No");
10824    ast_cli(fd, "  Call limit peers only:  %s\n", global_limitonpeers ? "Yes" : "No");
10825    ast_cli(fd, "  Direct RTP setup:       %s\n", global_directrtpsetup ? "Yes" : "No");
10826    ast_cli(fd, "  User Agent:             %s\n", global_useragent);
10827    ast_cli(fd, "  MWI checking interval:  %d secs\n", global_mwitime);
10828    ast_cli(fd, "  Reg. context:           %s\n", S_OR(global_regcontext, "(not set)"));
10829    ast_cli(fd, "  Caller ID:              %s\n", default_callerid);
10830    ast_cli(fd, "  From: Domain:           %s\n", default_fromdomain);
10831    ast_cli(fd, "  Record SIP history:     %s\n", recordhistory ? "On" : "Off");
10832    ast_cli(fd, "  Call Events:            %s\n", global_callevents ? "On" : "Off");
10833    ast_cli(fd, "  IP ToS SIP:             %s\n", ast_tos2str(global_tos_sip));
10834    ast_cli(fd, "  IP ToS RTP audio:       %s\n", ast_tos2str(global_tos_audio));
10835    ast_cli(fd, "  IP ToS RTP video:       %s\n", ast_tos2str(global_tos_video));
10836    ast_cli(fd, "  T38 fax pt UDPTL:       %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT_UDPTL) ? "Yes" : "No");
10837 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS
10838    ast_cli(fd, "  T38 fax pt RTP:         %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT_RTP) ? "Yes" : "No");
10839    ast_cli(fd, "  T38 fax pt TCP:         %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT_TCP) ? "Yes" : "No");
10840 #endif
10841    ast_cli(fd, "  RFC2833 Compensation:   %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RFC2833_COMPENSATE) ? "Yes" : "No");
10842    if (!realtimepeers && !realtimeusers)
10843       ast_cli(fd, "  SIP realtime:           Disabled\n" );
10844    else
10845       ast_cli(fd, "  SIP realtime:           Enabled\n" );
10846 
10847    ast_cli(fd, "\nGlobal Signalling Settings:\n");
10848    ast_cli(fd, "---------------------------\n");
10849    ast_cli(fd, "  Codecs:                 ");
10850    ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, global_capability);
10851    ast_cli(fd, "%s\n", codec_buf);
10852    ast_cli(fd, "  Codec Order:            ");
10853    print_codec_to_cli(fd, &default_prefs);
10854    ast_cli(fd, "\n");
10855    ast_cli(fd, "  T1 minimum:             %d\n", global_t1min);
10856    ast_cli(fd, "  Relax DTMF:             %s\n", global_relaxdtmf ? "Yes" : "No");
10857    ast_cli(fd, "  Compact SIP headers:    %s\n", compactheaders ? "Yes" : "No");
10858    ast_cli(fd, "  RTP Keepalive:          %d %s\n", global_rtpkeepalive, global_rtpkeepalive ? "" : "(Disabled)" );
10859    ast_cli(fd, "  RTP Timeout:            %d %s\n", global_rtptimeout, global_rtptimeout ? "" : "(Disabled)" );
10860    ast_cli(fd, "  RTP Hold Timeout:       %d %s\n", global_rtpholdtimeout, global_rtpholdtimeout ? "" : "(Disabled)");
10861    ast_cli(fd, "  MWI NOTIFY mime type:   %s\n", default_notifymime);
10862    ast_cli(fd, "  DNS SRV lookup:         %s\n", srvlookup ? "Yes" : "No");
10863    ast_cli(fd, "  Pedantic SIP support:   %s\n", pedanticsipchecking ? "Yes" : "No");
10864    ast_cli(fd, "  Reg. min duration       %d secs\n", min_expiry);
10865    ast_cli(fd, "  Reg. max duration:      %d secs\n", max_expiry);
10866    ast_cli(fd, "  Reg. default duration:  %d secs\n", default_expiry);
10867    ast_cli(fd, "  Outbound reg. timeout:  %d secs\n", global_reg_timeout);
10868    ast_cli(fd, "  Outbound reg. attempts: %d\n", global_regattempts_max);
10869    ast_cli(fd, "  Notify ringing state:   %s\n", global_notifyringing ? "Yes" : "No");
10870    ast_cli(fd, "  Notify hold state:      %s\n", global_notifyhold ? "Yes" : "No");
10871    ast_cli(fd, "  SIP Transfer mode:      %s\n", transfermode2str(global_allowtransfer));
10872    ast_cli(fd, "  Max Call Bitrate:       %d kbps\r\n", default_maxcallbitrate);
10873    ast_cli(fd, "  Auto-Framing:           %s \r\n", global_autoframing ? "Yes" : "No");
10874    ast_cli(fd, "\nDefault Settings:\n");
10875    ast_cli(fd, "-----------------\n");
10876    ast_cli(fd, "  Context:                %s\n", default_context);
10877    ast_cli(fd, "  Nat:                    %s\n", nat2str(ast_test_flag(&global_flags[0], SIP_NAT)));
10878    ast_cli(fd, "  DTMF:                   %s\n", dtmfmode2str(ast_test_flag(&global_flags[0], SIP_DTMF)));
10879    ast_cli(fd, "  Qualify:                %d\n", default_qualify);
10880    ast_cli(fd, "  Use ClientCode:         %s\n", ast_test_flag(&global_flags[0], SIP_USECLIENTCODE) ? "Yes" : "No");
10881    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" );
10882    ast_cli(fd, "  Language:               %s\n", S_OR(default_language, "(Defaults to English)"));
10883    ast_cli(fd, "  MOH Interpret:          %s\n", default_mohinterpret);
10884    ast_cli(fd, "  MOH Suggest:            %s\n", default_mohsuggest);
10885    ast_cli(fd, "  Voice Mail Extension:   %s\n", default_vmexten);
10886 
10887    
10888    if (realtimepeers || realtimeusers) {
10889       ast_cli(fd, "\nRealtime SIP Settings:\n");
10890       ast_cli(fd, "----------------------\n");
10891       ast_cli(fd, "  Realtime Peers:         %s\n", realtimepeers ? "Yes" : "No");
10892       ast_cli(fd, "  Realtime Users:         %s\n", realtimeusers ? "Yes" : "No");
10893       ast_cli(fd, "  Cache Friends:          %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS) ? "Yes" : "No");
10894       ast_cli(fd, "  Update:                 %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RTUPDATE) ? "Yes" : "No");
10895       ast_cli(fd, "  Ignore Reg. Expire:     %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_IGNOREREGEXPIRE) ? "Yes" : "No");
10896       ast_cli(fd, "  Save sys. name:         %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RTSAVE_SYSNAME) ? "Yes" : "No");
10897       ast_cli(fd, "  Auto Clear:             %d\n", global_rtautoclear);
10898    }
10899    ast_cli(fd, "\n----\n");
10900    return RESULT_SUCCESS;
10901 }

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

Show active SIP subscriptions.

Definition at line 10936 of file chan_sip.c.

References __sip_show_channels().

10937 {
10938         return __sip_show_channels(fd, argc, argv, 1);
10939 }

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

Show one user in detail.

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

10713 {
10714    char cbuf[256];
10715    struct sip_user *user;
10716    struct ast_variable *v;
10717    int load_realtime;
10718 
10719    if (argc < 4)
10720       return RESULT_SHOWUSAGE;
10721 
10722    /* Load from realtime storage? */
10723    load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? TRUE : FALSE;
10724 
10725    user = find_user(argv[3], load_realtime);
10726    if (user) {
10727       ast_cli(fd,"\n\n");
10728       ast_cli(fd, "  * Name       : %s\n", user->name);
10729       ast_cli(fd, "  Secret       : %s\n", ast_strlen_zero(user->secret)?"<Not set>":"<Set>");
10730       ast_cli(fd, "  MD5Secret    : %s\n", ast_strlen_zero(user->md5secret)?"<Not set>":"<Set>");
10731       ast_cli(fd, "  Context      : %s\n", user->context);
10732       ast_cli(fd, "  Language     : %s\n", user->language);
10733       if (!ast_strlen_zero(user->accountcode))
10734          ast_cli(fd, "  Accountcode  : %s\n", user->accountcode);
10735       ast_cli(fd, "  AMA flags    : %s\n", ast_cdr_flags2str(user->amaflags));
10736       ast_cli(fd, "  Transfer mode: %s\n", transfermode2str(user->allowtransfer));
10737       ast_cli(fd, "  MaxCallBR    : %d kbps\n", user->maxcallbitrate);
10738       ast_cli(fd, "  CallingPres  : %s\n", ast_describe_caller_presentation(user->callingpres));
10739       ast_cli(fd, "  Call limit   : %d\n", user->call_limit);
10740       ast_cli(fd, "  Callgroup    : ");
10741       print_group(fd, user->callgroup, 0);
10742       ast_cli(fd, "  Pickupgroup  : ");
10743       print_group(fd, user->pickupgroup, 0);
10744       ast_cli(fd, "  Callerid     : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), user->cid_name, user->cid_num, "<unspecified>"));
10745       ast_cli(fd, "  ACL          : %s\n", (user->ha?"Yes":"No"));
10746       ast_cli(fd, "  Codec Order  : (");
10747       print_codec_to_cli(fd, &user->prefs);
10748       ast_cli(fd, ")\n");
10749 
10750       ast_cli(fd, "  Auto-Framing:  %s \n", user->autoframing ? "Yes" : "No");
10751       if (user->chanvars) {
10752          ast_cli(fd, "  Variables    :\n");
10753          for (v = user->chanvars ; v ; v = v->next)
10754             ast_cli(fd, "                 %s = %s\n", v->name, v->value);
10755       }
10756       ast_cli(fd,"\n");
10757       ASTOBJ_UNREF(user,sip_destroy_user);
10758    } else {
10759       ast_cli(fd,"User %s not found.\n", argv[3]);
10760       ast_cli(fd,"\n");
10761    }
10762 
10763    return RESULT_SUCCESS;
10764 }

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

CLI Command 'SIP Show Users'.

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

09968 {
09969    regex_t regexbuf;
09970    int havepattern = FALSE;
09971 
09972 #define FORMAT  "%-25.25s  %-15.15s  %-15.15s  %-15.15s  %-5.5s%-10.10s\n"
09973 
09974    switch (argc) {
09975    case 5:
09976       if (!strcasecmp(argv[3], "like")) {
09977          if (regcomp(&regexbuf, argv[4], REG_EXTENDED | REG_NOSUB))
09978             return RESULT_SHOWUSAGE;
09979          havepattern = TRUE;
09980       } else
09981          return RESULT_SHOWUSAGE;
09982    case 3:
09983       break;
09984    default:
09985       return RESULT_SHOWUSAGE;
09986    }
09987 
09988    ast_cli(fd, FORMAT, "Username", "Secret", "Accountcode", "Def.Context", "ACL", "NAT");
09989    ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do {
09990       ASTOBJ_RDLOCK(iterator);
09991 
09992       if (havepattern && regexec(&regexbuf, iterator->name, 0, NULL, 0)) {
09993          ASTOBJ_UNLOCK(iterator);
09994          continue;
09995       }
09996 
09997       ast_cli(fd, FORMAT, iterator->name, 
09998          iterator->secret, 
09999          iterator->accountcode,
10000          iterator->context,
10001          iterator->ha ? "Yes" : "No",
10002          nat2str(ast_test_flag(&iterator->flags[0], SIP_NAT)));
10003       ASTOBJ_UNLOCK(iterator);
10004    } while (0)
10005    );
10006 
10007    if (havepattern)
10008       regfree(&regexbuf);
10009 
10010    return RESULT_SUCCESS;
10011 #undef FORMAT
10012 }

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

18295 {
18296    char *cdest;
18297    char *extension, *host, *port;
18298    char tmp[80];
18299    
18300    cdest = ast_strdupa(dest);
18301    
18302    extension = strsep(&cdest, "@");
18303    host = strsep(&cdest, ":");
18304    port = strsep(&cdest, ":");
18305    if (ast_strlen_zero(extension)) {
18306       ast_log(LOG_ERROR, "Missing mandatory argument: extension\n");
18307       return 0;
18308    }
18309 
18310    /* we'll issue the redirect message here */
18311    if (!host) {
18312       char *localtmp;
18313       ast_copy_string(tmp, get_header(&p->initreq, "To"), sizeof(tmp));
18314       if (ast_strlen_zero(tmp)) {
18315          ast_log(LOG_ERROR, "Cannot retrieve the 'To' header from the original SIP request!\n");
18316          return 0;
18317       }
18318       if ((localtmp = strcasestr(tmp, "sip:")) && (localtmp = strchr(localtmp, '@'))) {
18319          char lhost[80], lport[80];
18320          memset(lhost, 0, sizeof(lhost));
18321          memset(lport, 0, sizeof(lport));
18322          localtmp++;
18323          /* This is okey because lhost and lport are as big as tmp */
18324          sscanf(localtmp, "%[^<>:; ]:%[^<>:; ]", lhost, lport);
18325          if (ast_strlen_zero(lhost)) {
18326             ast_log(LOG_ERROR, "Can't find the host address\n");
18327             return 0;
18328          }
18329          host = ast_strdupa(lhost);
18330          if (!ast_strlen_zero(lport)) {
18331             port = ast_strdupa(lport);
18332          }
18333       }
18334    }
18335 
18336    ast_string_field_build(p, our_contact, "Transfer <sip:%s@%s%s%s>", extension, host, port ? ":" : "", port ? port : "");
18337    transmit_response_reliable(p, "302 Moved Temporarily", &p->initreq);
18338 
18339    sip_scheddestroy(p, SIP_TRANS_TIMEOUT);   /* Make sure we stop send this reply. */
18340    sip_alreadygone(p);
18341    return 0;
18342 }

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

Transfer SIP call.

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

03872 {
03873    struct sip_pvt *p = ast->tech_pvt;
03874    int res;
03875 
03876    if (dest == NULL) /* functions below do not take a NULL */
03877       dest = "";
03878    ast_mutex_lock(&p->lock);
03879    if (ast->_state == AST_STATE_RING)
03880       res = sip_sipredirect(p, dest);
03881    else
03882       res = transmit_refer(p, dest);
03883    ast_mutex_unlock(&p->lock);
03884    return res;
03885 }

static int sip_uri_cmp ( const char *  input1,
const char *  input2 
) [static]

Definition at line 14033 of file chan_sip.c.

References ast_strdupa, S_OR, sip_uri_headers_cmp(), sip_uri_params_cmp(), and strsep().

Referenced by handle_request_invite().

14034 {
14035    char *uri1 = ast_strdupa(input1);
14036    char *uri2 = ast_strdupa(input2);
14037    char *host1;
14038    char *host2;
14039    char *params1;
14040    char *params2;
14041    char *headers1;
14042    char *headers2;
14043 
14044    /* Strip off "sip:" from the URI. We know this is present
14045     * because it was checked back in parse_request()
14046     */
14047    strsep(&uri1, ":");
14048    strsep(&uri2, ":");
14049 
14050    if ((host1 = strchr(uri1, '@'))) {
14051       *host1++ = '\0';
14052    }
14053    if ((host2 = strchr(uri2, '@'))) {
14054       *host2++ = '\0';
14055    }
14056 
14057    /* Check for mismatched username and passwords. This is the
14058     * only case-sensitive comparison of a SIP URI
14059     */
14060    if ((host1 && !host2) ||
14061          (host2 && !host1) ||
14062          (host1 && host2 && strcmp(uri1, uri2))) {
14063       return 1;
14064    }
14065 
14066    if (!host1)
14067       host1 = uri1;
14068    if (!host2)
14069       host2 = uri2;
14070 
14071    /* Strip off the parameters and headers so we can compare
14072     * host and port
14073     */
14074 
14075    if ((params1 = strchr(host1, ';'))) {
14076       *params1++ = '\0';
14077    }
14078    if ((params2 = strchr(host2, ';'))) {
14079       *params2++ = '\0';
14080    }
14081 
14082    /* Headers come after parameters, but there may be headers without
14083     * parameters, thus the S_OR
14084     */
14085    if ((headers1 = strchr(S_OR(params1, host1), '?'))) {
14086       *headers1++ = '\0';
14087    }
14088    if ((headers2 = strchr(S_OR(params2, host2), '?'))) {
14089       *headers2++ = '\0';
14090    }
14091 
14092    /* Now the host/port are properly isolated. We can get by with a string comparison
14093     * because the SIP URI checking rules have some interesting exceptions that make
14094     * this possible. I will note 2 in particular
14095     * 1. hostnames which resolve to the same IP address as well as a hostname and its
14096     *    IP address are not considered a match with SIP URI's.
14097     * 2. If one URI specifies a port and the other does not, then the URIs do not match.
14098     *    This includes if one URI explicitly contains port 5060 and the other implies it
14099     *    by not having a port specified.
14100     */
14101 
14102    if (strcasecmp(host1, host2)) {
14103       return 1;
14104    }
14105 
14106    /* Headers have easier rules to follow, so do those first */
14107    if (sip_uri_headers_cmp(headers1, headers2)) {
14108       return 1;
14109    }
14110 
14111    /* And now the parameters. Ugh */
14112    return sip_uri_params_cmp(params1, params2);
14113 }

static int sip_uri_headers_cmp ( const char *  input1,
const char *  input2 
) [static]

helper routine for sip_uri_cmp

This takes the "headers" from two SIP URIs and determines if the URIs match. The rules for headers is simple. If a header appears in one URI, then it must also appear in the other URI. The order in which the headers appear does not matter.

Parameters:
input1 Headers from URI 1
input2 Headers from URI 2
Returns:
Return 0 if the URIs' headers match, 1 if they do not

Definition at line 13987 of file chan_sip.c.

References ast_strdupa, ast_strlen_zero(), strcasestr(), and strsep().

Referenced by sip_uri_cmp().

13988 {
13989    char *headers1 = NULL;
13990    char *headers2 = NULL;
13991    int zerolength1 = 0;
13992    int zerolength2 = 0;
13993    int different = 0;
13994    char *header1;
13995 
13996    if (ast_strlen_zero(input1)) {
13997       zerolength1 = 1;
13998    } else {
13999       headers1 = ast_strdupa(input1);
14000    }
14001    
14002    if (ast_strlen_zero(input2)) {
14003       zerolength2 = 1;
14004    } else {
14005       headers2 = ast_strdupa(input2);
14006    }
14007 
14008    if ((zerolength1 && !zerolength2) ||
14009          (zerolength2 && !zerolength1))
14010       return 1;
14011 
14012    if (zerolength1 && zerolength2)
14013       return 0;
14014 
14015    /* At this point, we can definitively state that both inputs are
14016     * not zero-length. First, one more optimization. If the length
14017     * of the headers is not equal, then we definitely have no match
14018     */
14019    if (strlen(headers1) != strlen(headers2)) {
14020       return 1;
14021    }
14022 
14023    for (header1 = strsep(&headers1, "&"); header1; header1 = strsep(&headers1, "&")) {
14024       if (!strcasestr(headers2, header1)) {
14025          different = 1;
14026          break;
14027       }
14028    }
14029 
14030    return different;
14031 }

static int sip_uri_params_cmp ( const char *  input1,
const char *  input2 
) [static]

helper routine for sip_uri_cmp

This takes the parameters from two SIP URIs and determines if the URIs match. The rules for parameters *suck*. Here's a breakdown 1. If a parameter appears in both URIs, then they must have the same value in order for the URIs to match 2. If one URI has a user, maddr, ttl, or method parameter, then the other URI must also have that parameter and must have the same value in order for the URIs to match 3. All other headers appearing in only one URI are not considered when determining if URIs match

Parameters:
input1 Parameters from URI 1
input2 Parameters from URI 2
Returns:
Return 0 if the URIs' parameters match, 1 if they do not

Definition at line 13849 of file chan_sip.c.

References ast_strdupa, and ast_strlen_zero().

Referenced by sip_uri_cmp().

13850 {
13851    char *params1 = NULL;
13852    char *params2 = NULL;
13853    char *pos1;
13854    char *pos2;
13855    int zerolength1 = 0;
13856    int zerolength2 = 0;
13857    int maddrmatch = 0;
13858    int ttlmatch = 0;
13859    int usermatch = 0;
13860    int methodmatch = 0;
13861 
13862    if (ast_strlen_zero(input1)) {
13863       zerolength1 = 1;
13864    } else {
13865       params1 = ast_strdupa(input1);
13866    }
13867    if (ast_strlen_zero(input2)) {
13868       zerolength2 = 1;
13869    } else {
13870       params2 = ast_strdupa(input2);
13871    }
13872 
13873    /*Quick optimization. If both params are zero-length, then
13874     * they match
13875     */
13876    if (zerolength1 && zerolength2) {
13877       return 0;
13878    }
13879 
13880    pos1 = params1;
13881    while (!ast_strlen_zero(pos1)) {
13882       char *name1 = pos1;
13883       char *value1 = strchr(pos1, '=');
13884       char *semicolon1 = strchr(pos1, ';');
13885       int matched = 0;
13886       if (semicolon1) {
13887          *semicolon1++ = '\0';
13888       }
13889       if (!value1) {
13890          goto fail;
13891       }
13892       *value1++ = '\0';
13893       /* Checkpoint reached. We have the name and value parsed for param1 
13894        * We have to duplicate params2 each time through the second loop
13895        * or else we can't search and replace the semicolons with \0 each
13896        * time
13897        */
13898       pos2 = ast_strdupa(params2);
13899       while (!ast_strlen_zero(pos2)) {
13900          char *name2 = pos2;
13901          char *value2 = strchr(pos2, '=');
13902          char *semicolon2 = strchr(pos2, ';');
13903          if (semicolon2) {
13904             *semicolon2++ = '\0';
13905          }
13906          if (!value2) {
13907             goto fail;
13908          }
13909          if (!strcasecmp(name1, name2)) {
13910             if (strcasecmp(value1, value2)) {
13911                goto fail;
13912             } else {
13913                matched = 1;
13914                break;
13915             }
13916          }
13917          pos2 = semicolon2;
13918       }
13919       /* Need to see if the parameter we're looking at is one of the 'must-match' parameters */
13920       if (!strcasecmp(name1, "maddr")) {
13921          if (matched) {
13922             maddrmatch = 1;
13923          } else {
13924             goto fail;
13925          }
13926       } else if (!strcasecmp(name1, "ttl")) {
13927          if (matched) {
13928             ttlmatch = 1;
13929          } else {
13930             goto fail;
13931          }
13932       } else if (!strcasecmp(name1, "user")) {
13933          if (matched) {
13934             usermatch = 1;
13935          } else {
13936             goto fail;
13937          }
13938       } else if (!strcasecmp(name1, "method")) {
13939          if (matched) {
13940             methodmatch = 1;
13941          } else {
13942             goto fail;
13943          }
13944       }
13945       pos1 = semicolon1;
13946    }
13947 
13948    /* We've made it out of that horrible O(m*n) construct and there are no
13949     * failures yet. We're not done yet, though, because params2 could have
13950     * an maddr, ttl, user, or method header and params1 did not.
13951     */
13952    pos2 = params2;
13953    while (!ast_strlen_zero(pos2)) {
13954       char *name2 = pos2;
13955       char *value2 = strchr(pos2, '=');
13956       char *semicolon2 = strchr(pos2, ';');
13957       if (semicolon2) {
13958          *semicolon2++ = '\0';
13959       }
13960       if (!value2) {
13961          goto fail;
13962       }
13963       if ((!strcasecmp(name2, "maddr") && !maddrmatch) ||
13964             (!strcasecmp(name2, "ttl") && !ttlmatch) ||
13965             (!strcasecmp(name2, "user") && !usermatch) ||
13966             (!strcasecmp(name2, "method") && !methodmatch)) {
13967          goto fail;
13968       }
13969    }
13970    return 0;
13971 
13972 fail:
13973    return 1;
13974 }

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

Send frame to media channel (rtp).

Definition at line 3698 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_new_source(), 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.

03699 {
03700    struct sip_pvt *p = ast->tech_pvt;
03701    int res = 0;
03702 
03703    switch (frame->frametype) {
03704    case AST_FRAME_VOICE:
03705       if (!(frame->subclass & ast->nativeformats)) {
03706          char s1[512], s2[512], s3[512];
03707          ast_log(LOG_WARNING, "Asked to transmit frame type %d, while native formats is %s(%d) read/write = %s(%d)/%s(%d)\n",
03708             frame->subclass, 
03709             ast_getformatname_multiple(s1, sizeof(s1) - 1, ast->nativeformats & AST_FORMAT_AUDIO_MASK),
03710             ast->nativeformats & AST_FORMAT_AUDIO_MASK,
03711             ast_getformatname_multiple(s2, sizeof(s2) - 1, ast->readformat),
03712             ast->readformat,
03713             ast_getformatname_multiple(s3, sizeof(s3) - 1, ast->writeformat),
03714             ast->writeformat);
03715          return 0;
03716       }
03717       if (p) {
03718          ast_mutex_lock(&p->lock);
03719          if (p->rtp) {
03720             /* If channel is not up, activate early media session */
03721             if ((ast->_state != AST_STATE_UP) &&
03722                 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) &&
03723                 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
03724                ast_rtp_new_source(p->rtp);
03725                transmit_response_with_sdp(p, "183 Session Progress", &p->initreq, XMIT_UNRELIABLE);
03726                ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT);  
03727             }
03728             p->lastrtptx = time(NULL);
03729             res = ast_rtp_write(p->rtp, frame);
03730          }
03731          ast_mutex_unlock(&p->lock);
03732       }
03733       break;
03734    case AST_FRAME_VIDEO:
03735       if (p) {
03736          ast_mutex_lock(&p->lock);
03737          if (p->vrtp) {
03738             /* Activate video early media */
03739             if ((ast->_state != AST_STATE_UP) &&
03740                 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) &&
03741                 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
03742                transmit_response_with_sdp(p, "183 Session Progress", &p->initreq, XMIT_UNRELIABLE);
03743                ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT);  
03744             }
03745             p->lastrtptx = time(NULL);
03746             res = ast_rtp_write(p->vrtp, frame);
03747          }
03748          ast_mutex_unlock(&p->lock);
03749       }
03750       break;
03751    case AST_FRAME_IMAGE:
03752       return 0;
03753       break;
03754    case AST_FRAME_MODEM:
03755       if (p) {
03756          ast_mutex_lock(&p->lock);
03757          /* UDPTL requires two-way communication, so early media is not needed here.
03758             we simply forget the frames if we get modem frames before the bridge is up.
03759             Fax will re-transmit.
03760          */
03761          if (p->udptl && ast->_state == AST_STATE_UP) 
03762             res = ast_udptl_write(p->udptl, frame);
03763          ast_mutex_unlock(&p->lock);
03764       }
03765       break;
03766    default: 
03767       ast_log(LOG_WARNING, "Can't send %d type frames with SIP write\n", frame->frametype);
03768       return 0;
03769    }
03770 
03771    return res;
03772 }

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

15884 {
15885    struct sip_request req;
15886    struct sockaddr_in sin = { 0, };
15887    struct sip_pvt *p;
15888    int res;
15889    socklen_t len = sizeof(sin);
15890    int nounlock;
15891    int recount = 0;
15892    int lockretry;
15893 
15894    memset(&req, 0, sizeof(req));
15895    res = recvfrom(sipsock, req.data, sizeof(req.data) - 1, 0, (struct sockaddr *)&sin, &len);
15896    if (res < 0) {
15897 #if !defined(__FreeBSD__)
15898       if (errno == EAGAIN)
15899          ast_log(LOG_NOTICE, "SIP: Received packet with bad UDP checksum\n");
15900       else 
15901 #endif
15902       if (errno != ECONNREFUSED)
15903          ast_log(LOG_WARNING, "Recv error: %s\n", strerror(errno));
15904       return 1;
15905    }
15906    if (option_debug && res == sizeof(req.data) - 1)
15907       ast_log(LOG_DEBUG, "Received packet exceeds buffer. Data is possibly lost\n");
15908 
15909    req.data[res] = '\0';
15910    /* req.data will have the correct length in case of nulls */
15911    req.len = strlen(req.data);
15912    if(sip_debug_test_addr(&sin)) /* Set the debug flag early on packet level */
15913       ast_set_flag(&req, SIP_PKT_DEBUG);
15914    if (pedanticsipchecking)
15915       req.len = lws2sws(req.data, req.len);  /* Fix multiline headers */
15916    if (ast_test_flag(&req, SIP_PKT_DEBUG))
15917       ast_verbose("\n<--- SIP read from %s:%d --->\n%s\n<------------->\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port), req.data);
15918 
15919    if(parse_request(&req) == -1) /* Bad packet, can't parse */
15920       return 1;
15921 
15922    req.method = find_sip_method(req.rlPart1);
15923 
15924    if (ast_test_flag(&req, SIP_PKT_DEBUG))
15925       ast_verbose("--- (%d headers %d lines)%s ---\n", req.headers, req.lines, (req.headers + req.lines == 0) ? " Nat keepalive" : "");
15926 
15927    if (req.headers < 2) /* Must have at least two headers */
15928       return 1;
15929 
15930    /* Process request, with netlock held, and with usual deadlock avoidance */
15931    for (lockretry = 100; lockretry > 0; lockretry--) {
15932       ast_mutex_lock(&netlock);
15933 
15934       /* Find the active SIP dialog or create a new one */
15935       p = find_call(&req, &sin, req.method); /* returns p locked */
15936       if (p == NULL) {
15937          if (option_debug)
15938             ast_log(LOG_DEBUG, "Invalid SIP message - rejected , no callid, len %d\n", req.len);
15939          ast_mutex_unlock(&netlock);
15940          return 1;
15941       }
15942       /* Go ahead and lock the owner if it has one -- we may need it */
15943       /* becaues this is deadlock-prone, we need to try and unlock if failed */
15944       if (!p->owner || !ast_channel_trylock(p->owner))
15945          break;   /* locking succeeded */
15946       if (option_debug)
15947          ast_log(LOG_DEBUG, "Failed to grab owner channel lock, trying again. (SIP call %s)\n", p->callid);
15948       ast_mutex_unlock(&p->lock);
15949       ast_mutex_unlock(&netlock);
15950       /* Sleep for a very short amount of time */
15951       usleep(1);
15952    }
15953    p->recv = sin;
15954 
15955    if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) /* This is a request or response, note what it was for */
15956       append_history(p, "Rx", "%s / %s / %s", req.data, get_header(&req, "CSeq"), req.rlPart2);
15957 
15958    if (!lockretry) {
15959       if (p->owner)
15960          ast_log(LOG_ERROR, "We could NOT get the channel lock for %s! \n", S_OR(p->owner->name, "- no channel name ??? - "));
15961       ast_log(LOG_ERROR, "SIP transaction failed: %s \n", p->callid);
15962       if (req.method != SIP_ACK)
15963          transmit_response(p, "503 Server error", &req); /* We must respond according to RFC 3261 sec 12.2 */
15964       /* XXX We could add retry-after to make sure they come back */
15965       append_history(p, "LockFail", "Owner lock failed, transaction failed.");
15966       return 1;
15967    }
15968    nounlock = 0;
15969    if (handle_request(p, &req, &sin, &recount, &nounlock) == -1) {
15970       /* Request failed */
15971       if (option_debug)
15972          ast_log(LOG_DEBUG, "SIP message could not be handled, bad request: %-70.70s\n", p->callid[0] ? p->callid : "<no callid>");
15973    }
15974       
15975    if (p->owner && !nounlock)
15976       ast_channel_unlock(p->owner);
15977    ast_mutex_unlock(&p->lock);
15978    ast_mutex_unlock(&netlock);
15979    if (recount)
15980       ast_update_use_count();
15981 
15982    return 1;
15983 }

static void stop_media_flows ( struct sip_pvt p  )  [static]

Immediately stop RTP, VRTP and UDPTL as applicable.

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

12786 {
12787    /* Immediately stop RTP, VRTP and UDPTL as applicable */
12788    if (p->rtp)
12789       ast_rtp_stop(p->rtp);
12790    if (p->vrtp)
12791       ast_rtp_stop(p->vrtp);
12792    if (p->udptl)
12793       ast_udptl_stop(p->udptl);
12794 }

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

Show subscription type in string format.

Definition at line 10904 of file chan_sip.c.

References subscription_types, cfsubscription_types::text, and type.

Referenced by __sip_show_channels(), and sip_show_channel().

10905 {
10906    int i;
10907 
10908    for (i = 1; (i < (sizeof(subscription_types) / sizeof(subscription_types[0]))); i++) {
10909       if (subscription_types[i].type == subtype) {
10910          return subscription_types[i].text;
10911       }
10912    }
10913    return subscription_types[0].text;
10914 }

static int t38_get_rate ( int  t38cap  )  [static]

Get Max T.38 Transmission rate from T38 capabilities.

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

06282 {
06283    int maxrate = (t38cap & (T38FAX_RATE_14400 | T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400));
06284    
06285    if (maxrate & T38FAX_RATE_14400) {
06286       if (option_debug > 1)
06287          ast_log(LOG_DEBUG, "T38MaxFaxRate 14400 found\n");
06288       return 14400;
06289    } else if (maxrate & T38FAX_RATE_12000) {
06290       if (option_debug > 1)
06291          ast_log(LOG_DEBUG, "T38MaxFaxRate 12000 found\n");
06292       return 12000;
06293    } else if (maxrate & T38FAX_RATE_9600) {
06294       if (option_debug > 1)
06295          ast_log(LOG_DEBUG, "T38MaxFaxRate 9600 found\n");
06296       return 9600;
06297    } else if (maxrate & T38FAX_RATE_7200) {
06298       if (option_debug > 1)
06299          ast_log(LOG_DEBUG, "T38MaxFaxRate 7200 found\n");
06300       return 7200;
06301    } else if (maxrate & T38FAX_RATE_4800) {
06302       if (option_debug > 1)
06303          ast_log(LOG_DEBUG, "T38MaxFaxRate 4800 found\n");
06304       return 4800;
06305    } else if (maxrate & T38FAX_RATE_2400) {
06306       if (option_debug > 1)
06307          ast_log(LOG_DEBUG, "T38MaxFaxRate 2400 found\n");
06308       return 2400;
06309    } else {
06310       if (option_debug > 1)
06311          ast_log(LOG_DEBUG, "Strange, T38MaxFaxRate NOT found in peers T38 SDP.\n");
06312       return 0;
06313    }
06314 }

static struct sip_peer * temp_peer ( const char *  name  )  [static, read]

Create temporary peer (used in autocreatepeer mode).

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

17025 {
17026    struct sip_peer *peer;
17027 
17028    if (!(peer = ast_calloc(1, sizeof(*peer))))
17029       return NULL;
17030 
17031    apeerobjs++;
17032    ASTOBJ_INIT(peer);
17033    set_peer_defaults(peer);
17034 
17035    ast_copy_string(peer->name, name, sizeof(peer->name));
17036 
17037    ast_set_flag(&peer->flags[1], SIP_PAGE2_SELFDESTRUCT);
17038    ast_set_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC);
17039    peer->prefs = default_prefs;
17040    reg_source_db(peer);
17041 
17042    return peer;
17043 }

static void temp_pvt_cleanup ( void *  data  )  [static]

Definition at line 6056 of file chan_sip.c.

References ast_string_field_free_memory, and free.

06057 {
06058    struct sip_pvt *p = data;
06059 
06060    ast_string_field_free_memory(p);
06061 
06062    free(data);
06063 }

static char * transfermode2str ( enum transfermodes  mode  )  [static]

Convert transfer mode to text string.

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

09915 {
09916    if (mode == TRANSFER_OPENFORALL)
09917       return "open";
09918    else if (mode == TRANSFER_CLOSED)
09919       return "closed";
09920    return "strict";
09921 }

static void transmit_fake_auth_response ( struct sip_pvt p,
int  sipmethod,
struct sip_request req,
enum xmittype  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 8643 of file chan_sip.c.

References ast_random(), ast_string_field_build, ast_strlen_zero(), ast_test_flag, CHECK_AUTH_BUF_INITLEN, DEFAULT_TRANS_TIMEOUT, FALSE, get_header(), sip_pvt::initreq, keys, s, SIP_PKT_IGNORE, SIP_REGISTER, sip_scheddestroy(), SIP_SUBSCRIBE, strsep(), transmit_response(), and transmit_response_with_auth().

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

08644 {
08645    /* We have to emulate EXACTLY what we'd get with a good peer
08646     * and a bad password, or else we leak information. */
08647    const char *response = "407 Proxy Authentication Required";
08648    const char *reqheader = "Proxy-Authorization";
08649    const char *respheader = "Proxy-Authenticate";
08650    const char *authtoken;
08651    struct ast_dynamic_str *buf;
08652    char *c;
08653 
08654    /* table of recognised keywords, and their value in the digest */
08655    enum keys { K_NONCE, K_LAST };
08656    struct x {
08657       const char *key;
08658       const char *s;
08659    } *i, keys[] = {
08660       [K_NONCE] = { "nonce=", "" },
08661       [K_LAST] = { NULL, NULL}
08662    };
08663 
08664    if (sipmethod == SIP_REGISTER || sipmethod == SIP_SUBSCRIBE) {
08665       response = "401 Unauthorized";
08666       reqheader = "Authorization";
08667       respheader = "WWW-Authenticate";
08668    }
08669    authtoken = get_header(req, reqheader);
08670    if (ast_test_flag(req, SIP_PKT_IGNORE) && !ast_strlen_zero(p->randdata) && ast_strlen_zero(authtoken)) {
08671       /* This is a retransmitted invite/register/etc, don't reconstruct authentication
08672        * information */
08673       transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0);
08674       /* Schedule auto destroy in 32 seconds (according to RFC 3261) */
08675       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
08676       return;
08677    } else if (ast_strlen_zero(p->randdata) || ast_strlen_zero(authtoken)) {
08678       /* We have no auth, so issue challenge and request authentication */
08679       ast_string_field_build(p, randdata, "%08lx", ast_random()); /* Create nonce for challenge */
08680       transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0);
08681       /* Schedule auto destroy in 32 seconds */
08682       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
08683       return;
08684    }
08685 
08686    if (!(buf = ast_dynamic_str_thread_get(&check_auth_buf, CHECK_AUTH_BUF_INITLEN))) {
08687       transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq);
08688       return;
08689    }
08690 
08691    /* Make a copy of the response and parse it */
08692    if (ast_dynamic_str_thread_set(&buf, 0, &check_auth_buf, "%s", authtoken) == AST_DYNSTR_BUILD_FAILED) {
08693       transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq);
08694       return;
08695    }
08696 
08697    c = buf->str;
08698 
08699    while (c && *(c = ast_skip_blanks(c))) { /* lookup for keys */
08700       for (i = keys; i->key != NULL; i++) {
08701          const char *separator = ",";  /* default */
08702 
08703          if (strncasecmp(c, i->key, strlen(i->key)) != 0) {
08704             continue;
08705          }
08706          /* Found. Skip keyword, take text in quotes or up to the separator. */
08707          c += strlen(i->key);
08708          if (*c == '"') { /* in quotes. Skip first and look for last */
08709             c++;
08710             separator = "\"";
08711          }
08712          i->s = c;
08713          strsep(&c, separator);
08714          break;
08715       }
08716       if (i->key == NULL) { /* not found, jump after space or comma */
08717          strsep(&c, " ,");
08718       }
08719    }
08720 
08721    /* Verify nonce from request matches our nonce.  If not, send 401 with new nonce */
08722    if (strcasecmp(p->randdata, keys[K_NONCE].s)) {
08723       if (!ast_test_flag(req, SIP_PKT_IGNORE)) {
08724          ast_string_field_build(p, randdata, "%08lx", ast_random());
08725       }
08726       transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, FALSE);
08727 
08728       /* Schedule auto destroy in 32 seconds */
08729       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
08730    } else {
08731       transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq);
08732    }
08733 }

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

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

Referenced by sip_senddigit_end().

07830 {
07831    struct sip_request req;
07832 
07833    reqprep(&req, p, SIP_INFO, 0, 1);
07834    add_digit(&req, digit, duration);
07835    return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
07836 }

static int transmit_info_with_vidupdate ( struct sip_pvt p  )  [static]

Send SIP INFO with video update request.

Definition at line 7839 of file chan_sip.c.

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

Referenced by sip_indicate().

07840 {
07841    struct sip_request req;
07842 
07843    reqprep(&req, p, SIP_INFO, 0, 1);
07844    add_vidupdate(&req);
07845    return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
07846 }

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 7088 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, SIPBUFSIZE, sipdebug, t38properties::state, SUPPORTED_EXTENSIONS, sip_pvt::t38, T38_LOCAL_DIRECT, T38_LOCAL_REINVITE, sip_pvt::udptl, ast_channel::varshead, XMIT_CRITICAL, and XMIT_RELIABLE.

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

07089 {
07090    struct sip_request req;
07091    
07092    req.method = sipmethod;
07093    if (init) {    /* Seems like init always is 2 */
07094       /* Bump branch even on initial requests */
07095       p->branch ^= ast_random();
07096       build_via(p);
07097       if (init > 1)
07098          initreqprep(&req, p, sipmethod);
07099       else
07100          reqprep(&req, p, sipmethod, 0, 1);
07101    } else
07102       reqprep(&req, p, sipmethod, 0, 1);
07103       
07104    if (p->options && p->options->auth)
07105       add_header(&req, p->options->authheader, p->options->auth);
07106    append_date(&req);
07107    if (sipmethod == SIP_REFER) { /* Call transfer */
07108       if (p->refer) {
07109          char buf[SIPBUFSIZE];
07110          if (!ast_strlen_zero(p->refer->refer_to))
07111             add_header(&req, "Refer-To", p->refer->refer_to);
07112          if (!ast_strlen_zero(p->refer->referred_by)) {
07113             snprintf(buf, sizeof(buf), "%s <%s>", p->refer->referred_by_name, p->refer->referred_by);
07114             add_header(&req, "Referred-By", buf);
07115          }
07116       }
07117    }
07118    /* This new INVITE is part of an attended transfer. Make sure that the
07119    other end knows and replace the current call with this new call */
07120    if (p->options && p->options->replaces && !ast_strlen_zero(p->options->replaces)) {
07121       add_header(&req, "Replaces", p->options->replaces);
07122       add_header(&req, "Require", "replaces");
07123    }
07124 
07125    add_header(&req, "Allow", ALLOWED_METHODS);
07126    add_header(&req, "Supported", SUPPORTED_EXTENSIONS);
07127    if (p->options && p->options->addsipheaders && p->owner) {
07128       struct ast_channel *chan = p->owner; /* The owner channel */
07129       struct varshead *headp;
07130    
07131       ast_channel_lock(chan);
07132 
07133       headp = &chan->varshead;
07134 
07135       if (!headp)
07136          ast_log(LOG_WARNING,"No Headp for the channel...ooops!\n");
07137       else {
07138          const struct ast_var_t *current;
07139          AST_LIST_TRAVERSE(headp, current, entries) {  
07140             /* SIPADDHEADER: Add SIP header to outgoing call */
07141             if (!strncasecmp(ast_var_name(current), "SIPADDHEADER", strlen("SIPADDHEADER"))) {
07142                char *content, *end;
07143                const char *header = ast_var_value(current);
07144                char *headdup = ast_strdupa(header);
07145 
07146                /* Strip of the starting " (if it's there) */
07147                if (*headdup == '"')
07148                   headdup++;
07149                if ((content = strchr(headdup, ':'))) {
07150                   *content++ = '\0';
07151                   content = ast_skip_blanks(content); /* Skip white space */
07152                   /* Strip the ending " (if it's there) */
07153                   end = content + strlen(content) -1; 
07154                   if (*end == '"')
07155                      *end = '\0';
07156                
07157                   add_header(&req, headdup, content);
07158                   if (sipdebug)
07159                      ast_log(LOG_DEBUG, "Adding SIP Header \"%s\" with content :%s: \n", headdup, content);
07160                }
07161             }
07162          }
07163       }
07164 
07165       ast_channel_unlock(chan);
07166    }
07167    if (sdp) {
07168       if (p->udptl && (p->t38.state == T38_LOCAL_DIRECT || p->t38.state == T38_LOCAL_REINVITE)) {
07169          ast_udptl_offered_from_local(p->udptl, 1);
07170          if (option_debug)
07171             ast_log(LOG_DEBUG, "T38 is in state %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>");
07172          add_t38_sdp(&req, p);
07173       } else if (p->rtp) 
07174          add_sdp(&req, p);
07175    } else {
07176       add_header_contentLength(&req, 0);
07177    }
07178 
07179    if (!p->initreq.headers || init > 2)
07180       initialize_initreq(p, &req);
07181    p->lastinvite = p->ocseq;
07182    return send_request(p, &req, init ? XMIT_CRITICAL : XMIT_RELIABLE, p->ocseq);
07183 }

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

Transmit text with SIP MESSAGE method.

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

07739 {
07740    struct sip_request req;
07741 
07742    reqprep(&req, p, SIP_MESSAGE, 0, 1);
07743    add_text(&req, text);
07744    return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
07745 }

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

07375 {
07376    struct sip_request req;
07377    char tmp[500];
07378    char *t = tmp;
07379    size_t maxbytes = sizeof(tmp);
07380 
07381    initreqprep(&req, p, SIP_NOTIFY);
07382    add_header(&req, "Event", "message-summary");
07383    add_header(&req, "Content-Type", default_notifymime);
07384 
07385    ast_build_string(&t, &maxbytes, "Messages-Waiting: %s\r\n", newmsgs ? "yes" : "no");
07386    ast_build_string(&t, &maxbytes, "Message-Account: sip:%s@%s\r\n",
07387       S_OR(vmexten, default_vmexten), S_OR(p->fromdomain, ast_inet_ntoa(p->ourip)));
07388    /* Cisco has a bug in the SIP stack where it can't accept the
07389       (0/0) notification. This can temporarily be disabled in
07390       sip.conf with the "buggymwi" option */
07391    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)"));
07392 
07393    if (p->subscribed) {
07394       if (p->expiry)
07395          add_header(&req, "Subscription-State", "active");
07396       else  /* Expired */
07397          add_header(&req, "Subscription-State", "terminated;reason=timeout");
07398    }
07399 
07400    if (t > tmp + sizeof(tmp))
07401       ast_log(LOG_WARNING, "Buffer overflow detected!!  (Please file a bug report)\n");
07402 
07403    add_header_contentLength(&req, strlen(tmp));
07404    add_line(&req, tmp);
07405 
07406    if (!p->initreq.headers) 
07407       initialize_initreq(p, &req);
07408    return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
07409 }

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 7420 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, SIPBUFSIZE, SUPPORTED_EXTENSIONS, and XMIT_RELIABLE.

Referenced by handle_request_refer(), local_attended_transfer(), and sip_park_thread().

07421 {
07422    struct sip_request req;
07423    char tmp[SIPBUFSIZE/2];
07424 
07425    reqprep(&req, p, SIP_NOTIFY, 0, 1);
07426    snprintf(tmp, sizeof(tmp), "refer;id=%d", cseq);
07427    add_header(&req, "Event", tmp);
07428    add_header(&req, "Subscription-state", terminate ? "terminated;reason=noresource" : "active");
07429    add_header(&req, "Content-Type", "message/sipfrag;version=2.0");
07430    add_header(&req, "Allow", ALLOWED_METHODS);
07431    add_header(&req, "Supported", SUPPORTED_EXTENSIONS);
07432 
07433    snprintf(tmp, sizeof(tmp), "SIP/2.0 %s\r\n", message);
07434    add_header_contentLength(&req, strlen(tmp));
07435    add_line(&req, tmp);
07436 
07437    if (!p->initreq.headers)
07438       initialize_initreq(p, &req);
07439 
07440    p->lastnoninvite = p->ocseq;
07441 
07442    return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
07443 }

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

References add_header(), ALLOWED_METHODS, ast_log(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, 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().

07760 {
07761    struct sip_request req = { 
07762       .headers = 0,  
07763    };
07764    char from[256];
07765    const char *of;
07766    char *c;
07767    char referto[256];
07768    char *ttag, *ftag;
07769    char *theirtag = ast_strdupa(p->theirtag);
07770 
07771    if (option_debug || sipdebug)
07772       ast_log(LOG_DEBUG, "SIP transfer of %s to %s\n", p->callid, dest);
07773 
07774    /* Are we transfering an inbound or outbound call ? */
07775    if (ast_test_flag(&p->flags[0], SIP_OUTGOING))  {
07776       of = get_header(&p->initreq, "To");
07777       ttag = theirtag;
07778       ftag = p->tag;
07779    } else {
07780       of = get_header(&p->initreq, "From");
07781       ftag = theirtag;
07782       ttag = p->tag;
07783    }
07784 
07785    ast_copy_string(from, of, sizeof(from));
07786    of = get_in_brackets(from);
07787    ast_string_field_set(p, from, of);
07788    if (strncasecmp(of, "sip:", 4))
07789       ast_log(LOG_NOTICE, "From address missing 'sip:', using it anyway\n");
07790    else
07791       of += 4;
07792    /* Get just the username part */
07793    if ((c = strchr(dest, '@')))
07794       c = NULL;
07795    else if ((c = strchr(of, '@')))
07796       *c++ = '\0';
07797    if (c) 
07798       snprintf(referto, sizeof(referto), "<sip:%s@%s>", dest, c);
07799    else
07800       snprintf(referto, sizeof(referto), "<sip:%s>", dest);
07801 
07802    /* save in case we get 407 challenge */
07803    sip_refer_allocate(p);
07804    ast_copy_string(p->refer->refer_to, referto, sizeof(p->refer->refer_to));
07805    ast_copy_string(p->refer->referred_by, p->our_contact, sizeof(p->refer->referred_by));
07806    p->refer->status = REFER_SENT;   /* Set refer status */
07807 
07808    reqprep(&req, p, SIP_REFER, 0, 1);
07809 
07810    add_header(&req, "Refer-To", referto);
07811    add_header(&req, "Allow", ALLOWED_METHODS);
07812    add_header(&req, "Supported", SUPPORTED_EXTENSIONS);
07813    if (!ast_strlen_zero(p->our_contact))
07814       add_header(&req, "Referred-By", p->our_contact);
07815 
07816    return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
07817    /* We should propably wait for a NOTIFY here until we ack the transfer */
07818    /* Maybe fork a new thread and wait for a STATUS of REFER_200OK on the refer status before returning to app_transfer */
07819 
07820    /*! \todo In theory, we should hang around and wait for a reply, before
07821    returning to the dial plan here. Don't know really how that would
07822    affect the transfer() app or the pbx, but, well, to make this
07823    useful we should have a STATUS code on transfer().
07824    */
07825 }

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

07548 {
07549    struct sip_request req;
07550    char from[256];
07551    char to[256];
07552    char tmp[80];
07553    char addr[80];
07554    struct sip_pvt *p;
07555 
07556    /* exit if we are already in process with this registrar ?*/
07557    if ( r == NULL || ((auth==NULL) && (r->regstate==REG_STATE_REGSENT || r->regstate==REG_STATE_AUTHSENT))) {
07558       ast_log(LOG_NOTICE, "Strange, trying to register %s@%s when registration already pending\n", r->username, r->hostname);
07559       return 0;
07560    }
07561 
07562    if (r->call) { /* We have a registration */
07563       if (!auth) {
07564          ast_log(LOG_WARNING, "Already have a REGISTER going on to %s@%s?? \n", r->username, r->hostname);
07565          return 0;
07566       } else {
07567          p = r->call;
07568          make_our_tag(p->tag, sizeof(p->tag));  /* create a new local tag for every register attempt */
07569          ast_string_field_free(p, theirtag); /* forget their old tag, so we don't match tags when getting response */
07570       }
07571    } else {
07572       /* Build callid for registration if we haven't registered before */
07573       if (!r->callid_valid) {
07574          build_callid_registry(r, __ourip, default_fromdomain);
07575          r->callid_valid = TRUE;
07576       }
07577       /* Allocate SIP packet for registration */
07578       if (!(p = sip_alloc( r->callid, NULL, 0, SIP_REGISTER))) {
07579          ast_log(LOG_WARNING, "Unable to allocate registration transaction (memory or socket error)\n");
07580          return 0;
07581       }
07582       if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY))
07583          append_history(p, "RegistryInit", "Account: %s@%s", r->username, r->hostname);
07584       /* Find address to hostname */
07585       if (create_addr(p, r->hostname)) {
07586          /* we have what we hope is a temporary network error,
07587           * probably DNS.  We need to reschedule a registration try */
07588          sip_destroy(p);
07589 
07590          if (r->timeout > -1)
07591             ast_log(LOG_WARNING, "Still have a registration timeout for %s@%s (create_addr() error), %d\n", r->username, r->hostname, r->timeout);
07592          else
07593             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);
07594 
07595          AST_SCHED_DEL(sched, r->timeout);
07596          r->timeout = ast_sched_add(sched, global_reg_timeout * 1000, sip_reg_timeout, r);
07597          r->regattempts++;
07598          return 0;
07599       }
07600       /* Copy back Call-ID in case create_addr changed it */
07601       ast_string_field_set(r, callid, p->callid);
07602       if (r->portno) {
07603          p->sa.sin_port = htons(r->portno);
07604          p->recv.sin_port = htons(r->portno);
07605       } else   /* Set registry port to the port set from the peer definition/srv or default */
07606          r->portno = ntohs(p->sa.sin_port);
07607       ast_set_flag(&p->flags[0], SIP_OUTGOING); /* Registration is outgoing call */
07608       r->call=p;        /* Save pointer to SIP packet */
07609       p->registry = ASTOBJ_REF(r);  /* Add pointer to registry in packet */
07610       if (!ast_strlen_zero(r->secret)) /* Secret (password) */
07611          ast_string_field_set(p, peersecret, r->secret);
07612       if (!ast_strlen_zero(r->md5secret))
07613          ast_string_field_set(p, peermd5secret, r->md5secret);
07614       /* User name in this realm  
07615       - if authuser is set, use that, otherwise use username */
07616       if (!ast_strlen_zero(r->authuser)) {   
07617          ast_string_field_set(p, peername, r->authuser);
07618          ast_string_field_set(p, authname, r->authuser);
07619       } else if (!ast_strlen_zero(r->username)) {
07620          ast_string_field_set(p, peername, r->username);
07621          ast_string_field_set(p, authname, r->username);
07622          ast_string_field_set(p, fromuser, r->username);
07623       }
07624       if (!ast_strlen_zero(r->username))
07625          ast_string_field_set(p, username, r->username);
07626       /* Save extension in packet */
07627       ast_string_field_set(p, exten, r->contact);
07628 
07629       /*
07630         check which address we should use in our contact header 
07631         based on whether the remote host is on the external or
07632         internal network so we can register through nat
07633        */
07634       if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
07635          p->ourip = bindaddr.sin_addr;
07636       build_contact(p);
07637    }
07638 
07639    /* set up a timeout */
07640    if (auth == NULL)  {
07641       if (r->timeout > -1)
07642          ast_log(LOG_WARNING, "Still have a registration timeout, #%d - deleting it\n", r->timeout);
07643       AST_SCHED_DEL(sched, r->timeout);
07644       r->timeout = ast_sched_add(sched, global_reg_timeout * 1000, sip_reg_timeout, r);
07645       if (option_debug)
07646          ast_log(LOG_DEBUG, "Scheduled a registration timeout for %s id  #%d \n", r->hostname, r->timeout);
07647    }
07648 
07649    if (strchr(r->username, '@')) {
07650       snprintf(from, sizeof(from), "<sip:%s>;tag=%s", r->username, p->tag);
07651       if (!ast_strlen_zero(p->theirtag))
07652          snprintf(to, sizeof(to), "<sip:%s>;tag=%s", r->username, p->theirtag);
07653       else
07654          snprintf(to, sizeof(to), "<sip:%s>", r->username);
07655    } else {
07656       snprintf(from, sizeof(from), "<sip:%s@%s>;tag=%s", r->username, p->tohost, p->tag);
07657       if (!ast_strlen_zero(p->theirtag))
07658          snprintf(to, sizeof(to), "<sip:%s@%s>;tag=%s", r->username, p->tohost, p->theirtag);
07659       else
07660          snprintf(to, sizeof(to), "<sip:%s@%s>", r->username, p->tohost);
07661    }
07662    
07663    /* Fromdomain is what we are registering to, regardless of actual
07664       host name from SRV */
07665    if (!ast_strlen_zero(p->fromdomain)) {
07666       if (r->portno && r->portno != STANDARD_SIP_PORT)
07667          snprintf(addr, sizeof(addr), "sip:%s:%d", p->fromdomain, r->portno);
07668       else
07669          snprintf(addr, sizeof(addr), "sip:%s", p->fromdomain);
07670    } else {
07671       if (r->portno && r->portno != STANDARD_SIP_PORT)
07672          snprintf(addr, sizeof(addr), "sip:%s:%d", r->hostname, r->portno);
07673       else
07674          snprintf(addr, sizeof(addr), "sip:%s", r->hostname);
07675    }
07676    ast_string_field_set(p, uri, addr);
07677 
07678    p->branch ^= ast_random();
07679 
07680    init_req(&req, sipmethod, addr);
07681 
07682    /* Add to CSEQ */
07683    snprintf(tmp, sizeof(tmp), "%u %s", ++r->ocseq, sip_methods[sipmethod].text);
07684    p->ocseq = r->ocseq;
07685 
07686    build_via(p);
07687    add_header(&req, "Via", p->via);
07688    add_header(&req, "From", from);
07689    add_header(&req, "To", to);
07690    add_header(&req, "Call-ID", p->callid);
07691    add_header(&req, "CSeq", tmp);
07692    if (!ast_strlen_zero(global_useragent))
07693       add_header(&req, "User-Agent", global_useragent);
07694    add_header(&req, "Max-Forwards", DEFAULT_MAX_FORWARDS);
07695 
07696    
07697    if (auth)   /* Add auth header */
07698       add_header(&req, authheader, auth);
07699    else if (!ast_strlen_zero(r->nonce)) {
07700       char digest[1024];
07701 
07702       /* We have auth data to reuse, build a digest header! */
07703       if (sipdebug)
07704          ast_log(LOG_DEBUG, "   >>> Re-using Auth data for %s@%s\n", r->username, r->hostname);
07705       ast_string_field_set(p, realm, r->realm);
07706       ast_string_field_set(p, nonce, r->nonce);
07707       ast_string_field_set(p, domain, r->domain);
07708       ast_string_field_set(p, opaque, r->opaque);
07709       ast_string_field_set(p, qop, r->qop);
07710       r->noncecount++;
07711       p->noncecount = r->noncecount;
07712 
07713       memset(digest,0,sizeof(digest));
07714       if(!build_reply_digest(p, sipmethod, digest, sizeof(digest)))
07715          add_header(&req, "Authorization", digest);
07716       else
07717          ast_log(LOG_NOTICE, "No authorization available for authentication of registration to %s@%s\n", r->username, r->hostname);
07718    
07719    }
07720 
07721    snprintf(tmp, sizeof(tmp), "%d", default_expiry);
07722    add_header(&req, "Expires", tmp);
07723    add_header(&req, "Contact", p->our_contact);
07724    add_header(&req, "Event", "registration");
07725    add_header_contentLength(&req, 0);
07726 
07727    initialize_initreq(p, &req);
07728    if (sip_debug_test_pvt(p))
07729       ast_verbose("REGISTER %d headers, %d lines\n", p->initreq.headers, p->initreq.lines);
07730    r->regstate = auth ? REG_STATE_AUTHSENT : REG_STATE_REGSENT;
07731    r->regattempts++; /* Another attempt */
07732    if (option_debug > 3)
07733       ast_verbose("REGISTER attempt %d to %s@%s\n", r->regattempts, r->username, r->hostname);
07734    return send_request(p, &req, XMIT_CRITICAL, p->ocseq);
07735 }

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

06809 {
06810    struct sip_request req;
06811 
06812    reqprep(&req, p, ast_test_flag(&p->flags[0], SIP_REINVITE_UPDATE) ?  SIP_UPDATE : SIP_INVITE, 0, 1);
06813    
06814    add_header(&req, "Allow", ALLOWED_METHODS);
06815    add_header(&req, "Supported", SUPPORTED_EXTENSIONS);
06816    if (sipdebug)
06817       add_header(&req, "X-asterisk-Info", "SIP re-invite (External RTP bridge)");
06818    if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY))
06819       append_history(p, "ReInv", "Re-invite sent");
06820    add_sdp(&req, p);
06821    /* Use this as the basis */
06822    initialize_initreq(p, &req);
06823    p->lastinvite = p->ocseq;
06824    ast_set_flag(&p->flags[0], SIP_OUTGOING);    /* Change direction of this dialog */
06825    return send_request(p, &req, XMIT_CRITICAL, p->ocseq);
06826 }

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

06833 {
06834    struct sip_request req;
06835 
06836    reqprep(&req, p, ast_test_flag(&p->flags[0], SIP_REINVITE_UPDATE) ?  SIP_UPDATE : SIP_INVITE, 0, 1);
06837    
06838    add_header(&req, "Allow", ALLOWED_METHODS);
06839    add_header(&req, "Supported", SUPPORTED_EXTENSIONS);
06840    if (sipdebug)
06841       add_header(&req, "X-asterisk-info", "SIP re-invite (T38 switchover)");
06842    ast_udptl_offered_from_local(p->udptl, 1);
06843    add_t38_sdp(&req, p);
06844    /* Use this as the basis */
06845    initialize_initreq(p, &req);
06846    ast_set_flag(&p->flags[0], SIP_OUTGOING);    /* Change direction of this dialog */
06847    p->lastinvite = p->ocseq;
06848    return send_request(p, &req, XMIT_CRITICAL, p->ocseq);
06849 }

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

07852 {
07853    struct sip_request resp;
07854 
07855    if (sipmethod == SIP_ACK)
07856       p->invitestate = INV_CONFIRMED;
07857 
07858    reqprep(&resp, p, sipmethod, seqno, newbranch);
07859    add_header_contentLength(&resp, 0);
07860    return send_request(p, &resp, reliable, seqno ? seqno : p->ocseq);
07861 }

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

07865 {
07866    struct sip_request resp;
07867 
07868    reqprep(&resp, p, sipmethod, seqno, newbranch);
07869    if (!ast_strlen_zero(p->realm)) {
07870       char digest[1024];
07871 
07872       memset(digest, 0, sizeof(digest));
07873       if(!build_reply_digest(p, sipmethod, digest, sizeof(digest))) {
07874          if (p->options && p->options->auth_type == PROXY_AUTH)
07875             add_header(&resp, "Proxy-Authorization", digest);
07876          else if (p->options && p->options->auth_type == WWW_AUTH)
07877             add_header(&resp, "Authorization", digest);
07878          else  /* Default, to be backwards compatible (maybe being too careful, but leaving it for now) */
07879             add_header(&resp, "Proxy-Authorization", digest);
07880       } else
07881          ast_log(LOG_WARNING, "No authentication available for call %s\n", p->callid);
07882    }
07883    /* If we are hanging up and know a cause for that, send it in clear text to make
07884       debugging easier. */
07885    if (sipmethod == SIP_BYE && p->owner && p->owner->hangupcause) {
07886       char buf[10];
07887 
07888       add_header(&resp, "X-Asterisk-HangupCause", ast_cause2str(p->owner->hangupcause));
07889       snprintf(buf, sizeof(buf), "%d", p->owner->hangupcause);
07890       add_header(&resp, "X-Asterisk-HangupCauseCode", buf);
07891    }
07892 
07893    add_header_contentLength(&resp, 0);
07894    return send_request(p, &resp, reliable, seqno ? seqno : p->ocseq);   
07895 }

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

Transmit response, no retransmits.

Definition at line 6117 of file chan_sip.c.

References __transmit_response(), and XMIT_UNRELIABLE.

06118 {
06119    return __transmit_response(p, msg, req, XMIT_UNRELIABLE);
06120 }

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

06137 {
06138    return __transmit_response(p, msg, req, XMIT_CRITICAL);
06139 }

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 6066 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(), check_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().

06067 {
06068    struct sip_pvt *p = NULL;
06069 
06070    if (!(p = ast_threadstorage_get(&ts_temp_pvt, sizeof(*p)))) {
06071       ast_log(LOG_NOTICE, "Failed to get temporary pvt\n");
06072       return -1;
06073    }
06074 
06075    /* if the structure was just allocated, initialize it */
06076    if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) {
06077       ast_set_flag(&p->flags[0], SIP_NO_HISTORY);
06078       if (ast_string_field_init(p, 512))
06079          return -1;
06080    }
06081 
06082    /* Initialize the bare minimum */
06083    p->method = intended_method;
06084 
06085    if (sin) {
06086       p->sa = *sin;
06087       if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
06088          p->ourip = __ourip;
06089    } else
06090       p->ourip = __ourip;
06091 
06092    p->branch = ast_random();
06093    make_our_tag(p->tag, sizeof(p->tag));
06094    p->ocseq = INITIAL_CSEQ;
06095 
06096    if (useglobal_nat && sin) {
06097       ast_copy_flags(&p->flags[0], &global_flags[0], SIP_NAT);
06098       p->recv = *sin;
06099       do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE);
06100    }
06101    check_via(p, req);
06102 
06103    ast_string_field_set(p, fromdomain, default_fromdomain);
06104    build_via(p);
06105    ast_string_field_set(p, callid, callid);
06106 
06107    /* Use this temporary pvt structure to send the message */
06108    __transmit_response(p, msg, req, XMIT_UNRELIABLE);
06109 
06110    /* Free the string fields, but not the pool space */
06111    ast_string_field_reset_all(p);
06112 
06113    return 0;
06114 }

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

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

Referenced by handle_request(), and handle_request_options().

06165 {
06166    struct sip_request resp;
06167    respprep(&resp, p, msg, req);
06168    add_header(&resp, "Accept", "application/sdp");
06169    add_header_contentLength(&resp, 0);
06170    return send_response(p, &resp, reliable, 0);
06171 }

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

06175 {
06176    struct sip_request resp;
06177    char tmp[512];
06178    int seqno = 0;
06179 
06180    if (reliable && (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1)) {
06181       ast_log(LOG_WARNING, "Unable to determine sequence number from '%s'\n", get_header(req, "CSeq"));
06182       return -1;
06183    }
06184    /* Stale means that they sent us correct authentication, but 
06185       based it on an old challenge (nonce) */
06186    snprintf(tmp, sizeof(tmp), "Digest algorithm=MD5, realm=\"%s\", nonce=\"%s\"%s", global_realm, randdata, stale ? ", stale=true" : "");
06187    respprep(&resp, p, msg, req);
06188    add_header(&resp, header, tmp);
06189    add_header_contentLength(&resp, 0);
06190    append_history(p, "AuthChal", "Auth challenge sent for %s - nc %d", p->username, p->noncecount);
06191    return send_response(p, &resp, reliable, seqno);
06192 }

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

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

Referenced by register_verify().

06155 {
06156    struct sip_request resp;
06157    respprep(&resp, p, msg, req);
06158    append_date(&resp);
06159    add_header_contentLength(&resp, 0);
06160    return send_response(p, &resp, XMIT_UNRELIABLE, 0);
06161 }

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

06738 {
06739    struct sip_request resp;
06740    int seqno;
06741    if (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1) {
06742       ast_log(LOG_WARNING, "Unable to get seqno from '%s'\n", get_header(req, "CSeq"));
06743       return -1;
06744    }
06745    respprep(&resp, p, msg, req);
06746    if (p->rtp) {
06747       if (!p->autoframing && !ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
06748          if (option_debug)
06749             ast_log(LOG_DEBUG, "Setting framing from config on incoming call\n");
06750          ast_rtp_codec_setpref(p->rtp, &p->prefs);
06751       }
06752       try_suggested_sip_codec(p);   
06753       add_sdp(&resp, p);
06754    } else 
06755       ast_log(LOG_ERROR, "Can't add SDP to response, since we have no RTP session allocated. Call-ID %s\n", p->callid);
06756    if (reliable && !p->pendinginvite)
06757       p->pendinginvite = seqno;     /* Buggy clients sends ACK on RINGING too */
06758    return send_response(p, &resp, reliable, seqno);
06759 }

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

06698 {
06699    struct sip_request resp;
06700    int seqno;
06701    
06702    if (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1) {
06703       ast_log(LOG_WARNING, "Unable to get seqno from '%s'\n", get_header(req, "CSeq"));
06704       return -1;
06705    }
06706    respprep(&resp, p, msg, req);
06707    if (p->udptl) {
06708       ast_udptl_offered_from_local(p->udptl, 0);
06709       add_t38_sdp(&resp, p);
06710    } else 
06711       ast_log(LOG_ERROR, "Can't add SDP to response, since we have no UDPTL session allocated. Call-ID %s\n", p->callid);
06712    if (retrans && !p->pendinginvite)
06713       p->pendinginvite = seqno;     /* Buggy clients sends ACK on RINGING too */
06714    return send_response(p, &resp, retrans, seqno);
06715 }

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

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

Referenced by handle_request_invite().

06124 {
06125    struct sip_request resp;
06126    respprep(&resp, p, msg, req);
06127    append_date(&resp);
06128    add_header(&resp, "Unsupported", unsupported);
06129    add_header_contentLength(&resp, 0);
06130    return send_response(p, &resp, XMIT_UNRELIABLE, 0);
06131 }

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

07413 {
07414    if (!p->initreq.headers)   /* Initialize first request before sending */
07415       initialize_initreq(p, req);
07416    return send_request(p, req, XMIT_UNRELIABLE, p->ocseq);
07417 }

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 7186 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, sip_pvt::pendinginvite, 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().

07187 {
07188    char tmp[4000], from[256], to[256];
07189    char *t = tmp, *c, *mfrom, *mto;
07190    size_t maxbytes = sizeof(tmp);
07191    struct sip_request req;
07192    char hint[AST_MAX_EXTENSION];
07193    char *statestring = "terminated";
07194    const struct cfsubscription_types *subscriptiontype;
07195    enum state { NOTIFY_OPEN, NOTIFY_INUSE, NOTIFY_CLOSED } local_state = NOTIFY_OPEN;
07196    char *pidfstate = "--";
07197    char *pidfnote= "Ready";
07198 
07199    memset(from, 0, sizeof(from));
07200    memset(to, 0, sizeof(to));
07201    memset(tmp, 0, sizeof(tmp));
07202 
07203    switch (state) {
07204    case (AST_EXTENSION_RINGING | AST_EXTENSION_INUSE):
07205       statestring = (global_notifyringing) ? "early" : "confirmed";
07206       local_state = NOTIFY_INUSE;
07207       pidfstate = "busy";
07208       pidfnote = "Ringing";
07209       break;
07210    case AST_EXTENSION_RINGING:
07211       statestring = "early";
07212       local_state = NOTIFY_INUSE;
07213       pidfstate = "busy";
07214       pidfnote = "Ringing";
07215       break;
07216    case AST_EXTENSION_INUSE:
07217       statestring = "confirmed";
07218       local_state = NOTIFY_INUSE;
07219       pidfstate = "busy";
07220       pidfnote = "On the phone";
07221       break;
07222    case AST_EXTENSION_BUSY:
07223       statestring = "confirmed";
07224       local_state = NOTIFY_CLOSED;
07225       pidfstate = "busy";
07226       pidfnote = "On the phone";
07227       break;
07228    case AST_EXTENSION_UNAVAILABLE:
07229       statestring = "terminated";
07230       local_state = NOTIFY_CLOSED;
07231       pidfstate = "away";
07232       pidfnote = "Unavailable";
07233       break;
07234    case AST_EXTENSION_ONHOLD:
07235       statestring = "confirmed";
07236       local_state = NOTIFY_CLOSED;
07237       pidfstate = "busy";
07238       pidfnote = "On Hold";
07239       break;
07240    case AST_EXTENSION_NOT_INUSE:
07241    default:
07242       /* Default setting */
07243       break;
07244    }
07245 
07246    subscriptiontype = find_subscription_type(p->subscribed);
07247    
07248    /* Check which device/devices we are watching  and if they are registered */
07249    if (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, p->context, p->exten)) {
07250       char *hint2 = hint, *individual_hint = NULL;
07251       int hint_count = 0, unavailable_count = 0;
07252 
07253       while ((individual_hint = strsep(&hint2, "&"))) {
07254          hint_count++;
07255 
07256          if (ast_device_state(individual_hint) == AST_DEVICE_UNAVAILABLE)
07257             unavailable_count++;
07258       }
07259 
07260       /* If none of the hinted devices are registered, we will
07261        * override notification and show no availability.
07262        */
07263       if (hint_count > 0 && hint_count == unavailable_count) {
07264          local_state = NOTIFY_CLOSED;
07265          pidfstate = "away";
07266          pidfnote = "Not online";
07267       }
07268    }
07269 
07270    ast_copy_string(from, get_header(&p->initreq, "From"), sizeof(from));
07271    c = get_in_brackets(from);
07272    if (strncasecmp(c, "sip:", 4)) {
07273       ast_log(LOG_WARNING, "Huh?  Not a SIP header (%s)?\n", c);
07274       return -1;
07275    }
07276    mfrom = strsep(&c, ";");   /* trim ; and beyond */
07277 
07278    ast_copy_string(to, get_header(&p->initreq, "To"), sizeof(to));
07279    c = get_in_brackets(to);
07280    if (strncasecmp(c, "sip:", 4)) {
07281       ast_log(LOG_WARNING, "Huh?  Not a SIP header (%s)?\n", c);
07282       return -1;
07283    }
07284    mto = strsep(&c, ";");  /* trim ; and beyond */
07285 
07286    reqprep(&req, p, SIP_NOTIFY, 0, 1);
07287 
07288    
07289    add_header(&req, "Event", subscriptiontype->event);
07290    add_header(&req, "Content-Type", subscriptiontype->mediatype);
07291    switch(state) {
07292    case AST_EXTENSION_DEACTIVATED:
07293       if (timeout)
07294          add_header(&req, "Subscription-State", "terminated;reason=timeout");
07295       else {
07296          add_header(&req, "Subscription-State", "terminated;reason=probation");
07297          add_header(&req, "Retry-After", "60");
07298       }
07299       break;
07300    case AST_EXTENSION_REMOVED:
07301       add_header(&req, "Subscription-State", "terminated;reason=noresource");
07302       break;
07303    default:
07304       if (p->expiry)
07305          add_header(&req, "Subscription-State", "active");
07306       else  /* Expired */
07307          add_header(&req, "Subscription-State", "terminated;reason=timeout");
07308    }
07309    switch (p->subscribed) {
07310    case XPIDF_XML:
07311    case CPIM_PIDF_XML:
07312       ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\"?>\n");
07313       ast_build_string(&t, &maxbytes, "<!DOCTYPE presence PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n");
07314       ast_build_string(&t, &maxbytes, "<presence>\n");
07315       ast_build_string(&t, &maxbytes, "<presentity uri=\"%s;method=SUBSCRIBE\" />\n", mfrom);
07316       ast_build_string(&t, &maxbytes, "<atom id=\"%s\">\n", p->exten);
07317       ast_build_string(&t, &maxbytes, "<address uri=\"%s;user=ip\" priority=\"0.800000\">\n", mto);
07318       ast_build_string(&t, &maxbytes, "<status status=\"%s\" />\n", (local_state ==  NOTIFY_OPEN) ? "open" : (local_state == NOTIFY_INUSE) ? "inuse" : "closed");
07319       ast_build_string(&t, &maxbytes, "<msnsubstatus substatus=\"%s\" />\n", (local_state == NOTIFY_OPEN) ? "online" : (local_state == NOTIFY_INUSE) ? "onthephone" : "offline");
07320       ast_build_string(&t, &maxbytes, "</address>\n</atom>\n</presence>\n");
07321       break;
07322    case PIDF_XML: /* Eyebeam supports this format */
07323       ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n");
07324       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);
07325       ast_build_string(&t, &maxbytes, "<pp:person><status>\n");
07326       if (pidfstate[0] != '-')
07327          ast_build_string(&t, &maxbytes, "<ep:activities><ep:%s/></ep:activities>\n", pidfstate);
07328       ast_build_string(&t, &maxbytes, "</status></pp:person>\n");
07329       ast_build_string(&t, &maxbytes, "<note>%s</note>\n", pidfnote); /* Note */
07330       ast_build_string(&t, &maxbytes, "<tuple id=\"%s\">\n", p->exten); /* Tuple start */
07331       ast_build_string(&t, &maxbytes, "<contact priority=\"1\">%s</contact>\n", mto);
07332       if (pidfstate[0] == 'b') /* Busy? Still open ... */
07333          ast_build_string(&t, &maxbytes, "<status><basic>open</basic></status>\n");
07334       else
07335          ast_build_string(&t, &maxbytes, "<status><basic>%s</basic></status>\n", (local_state != NOTIFY_CLOSED) ? "open" : "closed");
07336       ast_build_string(&t, &maxbytes, "</tuple>\n</presence>\n");
07337       break;
07338    case DIALOG_INFO_XML: /* SNOM subscribes in this format */
07339       ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\"?>\n");
07340       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);
07341       if ((state & AST_EXTENSION_RINGING) && global_notifyringing)
07342          ast_build_string(&t, &maxbytes, "<dialog id=\"%s\" direction=\"recipient\">\n", p->exten);
07343       else
07344          ast_build_string(&t, &maxbytes, "<dialog id=\"%s\">\n", p->exten);
07345       ast_build_string(&t, &maxbytes, "<state>%s</state>\n", statestring);
07346       if (state == AST_EXTENSION_ONHOLD) {
07347          ast_build_string(&t, &maxbytes, "<local>\n<target uri=\"%s\">\n"
07348                                          "<param pname=\"+sip.rendering\" pvalue=\"no\">\n"
07349                                          "</target>\n</local>\n", mto);
07350       }
07351       ast_build_string(&t, &maxbytes, "</dialog>\n</dialog-info>\n");
07352       break;
07353    case NONE:
07354    default:
07355       break;
07356    }
07357 
07358    if (t > tmp + sizeof(tmp))
07359       ast_log(LOG_WARNING, "Buffer overflow detected!!  (Please file a bug report)\n");
07360 
07361    add_header_contentLength(&req, strlen(tmp));
07362    add_line(&req, tmp);
07363    p->pendinginvite = p->ocseq;  /* Remember that we have a pending NOTIFY in order not to confuse the NOTIFY subsystem */
07364 
07365    return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
07366 }

static void try_suggested_sip_codec ( struct sip_pvt p  )  [static]

Try setting codec suggested by the SIP_CODEC channel variable.

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

03649 {
03650    int fmt;
03651    const char *codec;
03652 
03653    codec = pbx_builtin_getvar_helper(p->owner, "SIP_CODEC");
03654    if (!codec) 
03655       return;
03656 
03657    fmt = ast_getformatbyname(codec);
03658    if (fmt) {
03659       ast_log(LOG_NOTICE, "Changing codec to '%s' for this call because of ${SIP_CODEC} variable\n", codec);
03660       if (p->jointcapability & fmt) {
03661          p->jointcapability &= fmt;
03662          p->capability &= fmt;
03663       } else
03664          ast_log(LOG_NOTICE, "Ignoring ${SIP_CODEC} variable because it is not shared by both ends.\n");
03665    } else
03666       ast_log(LOG_NOTICE, "Ignoring ${SIP_CODEC} variable because of unrecognized/not configured codec (check allow/disallow in sip.conf): %s\n", codec);
03667    return;  
03668 }

static int unload_module ( void   )  [static]

PBX unload module API.

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

18622 {
18623    struct sip_pvt *p, *pl;
18624    
18625    /* First, take us out of the channel type list */
18626    ast_channel_unregister(&sip_tech);
18627 
18628    /* Unregister dial plan functions */
18629    ast_custom_function_unregister(&sipchaninfo_function);
18630    ast_custom_function_unregister(&sippeer_function);
18631    ast_custom_function_unregister(&sip_header_function);
18632    ast_custom_function_unregister(&checksipdomain_function);
18633 
18634    /* Unregister dial plan applications */
18635    ast_unregister_application(app_dtmfmode);
18636    ast_unregister_application(app_sipaddheader);
18637 
18638    /* Unregister CLI commands */
18639    ast_cli_unregister_multiple(cli_sip, sizeof(cli_sip) / sizeof(struct ast_cli_entry));
18640 
18641    /* Disconnect from the RTP subsystem */
18642    ast_rtp_proto_unregister(&sip_rtp);
18643 
18644    /* Disconnect from UDPTL */
18645    ast_udptl_proto_unregister(&sip_udptl);
18646 
18647    /* Unregister AMI actions */
18648    ast_manager_unregister("SIPpeers");
18649    ast_manager_unregister("SIPshowpeer");
18650 
18651    ast_mutex_lock(&iflock);
18652    /* Hangup all interfaces if they have an owner */
18653    for (p = iflist; p ; p = p->next) {
18654       if (p->owner)
18655          ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD);
18656    }
18657    ast_mutex_unlock(&iflock);
18658 
18659    ast_mutex_lock(&monlock);
18660    if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP) && (monitor_thread != AST_PTHREADT_NULL)) {
18661       pthread_cancel(monitor_thread);
18662       pthread_kill(monitor_thread, SIGURG);
18663       pthread_join(monitor_thread, NULL);
18664    }
18665    monitor_thread = AST_PTHREADT_STOP;
18666    ast_mutex_unlock(&monlock);
18667 
18668 restartdestroy:
18669    ast_mutex_lock(&iflock);
18670    /* Destroy all the interfaces and free their memory */
18671    p = iflist;
18672    while (p) {
18673       pl = p;
18674       p = p->next;
18675       if (__sip_destroy(pl, TRUE) < 0) {
18676          /* Something is still bridged, let it react to getting a hangup */
18677          iflist = p;
18678          ast_mutex_unlock(&iflock);
18679          usleep(1);
18680          goto restartdestroy;
18681       }
18682    }
18683    iflist = NULL;
18684    ast_mutex_unlock(&iflock);
18685 
18686    /* Free memory for local network address mask */
18687    ast_free_ha(localaddr);
18688 
18689    ASTOBJ_CONTAINER_DESTROYALL(&userl, sip_destroy_user);
18690    ASTOBJ_CONTAINER_DESTROY(&userl);
18691    ASTOBJ_CONTAINER_DESTROYALL(&peerl, sip_destroy_peer);
18692    ASTOBJ_CONTAINER_DESTROY(&peerl);
18693    ASTOBJ_CONTAINER_DESTROYALL(&regl, sip_registry_destroy);
18694    ASTOBJ_CONTAINER_DESTROY(&regl);
18695 
18696    clear_realm_authentication(authl);
18697    clear_sip_domains();
18698    close(sipsock);
18699    sched_context_destroy(sched);
18700       
18701    return 0;
18702 }

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 3201 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_peer::flags, 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().

03202 {
03203    char name[256];
03204    int *inuse = NULL, *call_limit = NULL, *inringing = NULL;
03205    int outgoing = ast_test_flag(&fup->flags[1], SIP_PAGE2_OUTGOING_CALL);
03206    struct sip_user *u = NULL;
03207    struct sip_peer *p = NULL;
03208 
03209    if (option_debug > 2)
03210       ast_log(LOG_DEBUG, "Updating call counter for %s call\n", outgoing ? "outgoing" : "incoming");
03211 
03212    /* Test if we need to check call limits, in order to avoid 
03213       realtime lookups if we do not need it */
03214    if (!ast_test_flag(&fup->flags[0], SIP_CALL_LIMIT) && !ast_test_flag(&fup->flags[1], SIP_PAGE2_CALL_ONHOLD))
03215       return 0;
03216 
03217    ast_copy_string(name, fup->username, sizeof(name));
03218 
03219    /* Check the list of users only for incoming calls */
03220    if (global_limitonpeers == FALSE && !outgoing && (u = find_user(name, 1)))  {
03221       inuse = &u->inUse;
03222       call_limit = &u->call_limit;
03223       inringing = NULL;
03224    } else if ( (p = find_peer(ast_strlen_zero(fup->peername) ? name : fup->peername, NULL, 1) ) ) { /* Try to find peer */
03225       inuse = &p->inUse;
03226       call_limit = &p->call_limit;
03227       inringing = &p->inRinging;
03228       ast_copy_string(name, fup->peername, sizeof(name));
03229    } 
03230    if (!p && !u) {
03231       if (option_debug > 1)
03232          ast_log(LOG_DEBUG, "%s is not a local device, no call limit\n", name);
03233       return 0;
03234    }
03235 
03236    switch(event) {
03237    /* incoming and outgoing affects the inUse counter */
03238    case DEC_CALL_LIMIT:
03239       if ( *inuse > 0 ) {
03240          if (ast_test_flag(&fup->flags[0], SIP_INC_COUNT)) {
03241             (*inuse)--;
03242             ast_clear_flag(&fup->flags[0], SIP_INC_COUNT);
03243          }
03244       } else {
03245          *inuse = 0;
03246       }
03247       if (inringing) {
03248          if (ast_test_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING)) {
03249             if (*inringing > 0)
03250                (*inringing)--;
03251             else if (!ast_test_flag(&p->flags[0], SIP_REALTIME) || ast_test_flag(&p->flags[1], SIP_PAGE2_RTCACHEFRIENDS))
03252                ast_log(LOG_WARNING, "Inringing for peer '%s' < 0?\n", fup->peername);
03253             ast_clear_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING);
03254          }
03255       }
03256       if (ast_test_flag(&fup->flags[1], SIP_PAGE2_CALL_ONHOLD) && global_notifyhold) {
03257          ast_clear_flag(&fup->flags[1], SIP_PAGE2_CALL_ONHOLD);
03258          sip_peer_hold(fup, 0);
03259       }
03260       if (option_debug > 1 || sipdebug) {
03261          ast_log(LOG_DEBUG, "Call %s %s '%s' removed from call limit %d\n", outgoing ? "to" : "from", u ? "user":"peer", name, *call_limit);
03262       }
03263       break;
03264 
03265    case INC_CALL_RINGING:
03266    case INC_CALL_LIMIT:
03267       if (*call_limit > 0 ) {
03268          if (*inuse >= *call_limit) {
03269             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);
03270             if (u)
03271                ASTOBJ_UNREF(u, sip_destroy_user);
03272             else
03273                ASTOBJ_UNREF(p, sip_destroy_peer);
03274             return -1; 
03275          }
03276       }
03277       if (inringing && (event == INC_CALL_RINGING)) {
03278          if (!ast_test_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING)) {
03279             (*inringing)++;
03280             ast_set_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING);
03281          }
03282       }
03283       /* Continue */
03284       (*inuse)++;
03285       ast_set_flag(&fup->flags[0], SIP_INC_COUNT);
03286       if (option_debug > 1 || sipdebug) {
03287          ast_log(LOG_DEBUG, "Call %s %s '%s' is %d out of %d\n", outgoing ? "to" : "from", u ? "user":"peer", name, *inuse, *call_limit);
03288       }
03289       break;
03290 
03291    case DEC_CALL_RINGING:
03292       if (inringing) {
03293          if (ast_test_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING)) {
03294             if (*inringing > 0)
03295                (*inringing)--;
03296             else if (!ast_test_flag(&p->flags[0], SIP_REALTIME) || ast_test_flag(&p->flags[1], SIP_PAGE2_RTCACHEFRIENDS))
03297                ast_log(LOG_WARNING, "Inringing for peer '%s' < 0?\n", p->name);
03298             ast_clear_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING);
03299          }
03300       }
03301       break;
03302 
03303    default:
03304       ast_log(LOG_ERROR, "update_call_counter(%s, %d) called with no event!\n", name, event);
03305    }
03306    if (p) {
03307       ast_device_state_changed("SIP/%s", p->name);
03308       ASTOBJ_UNREF(p, sip_destroy_peer);
03309    } else /* u must be set */
03310       ASTOBJ_UNREF(u, sip_destroy_user);
03311    return 0;
03312 }

static void update_peer ( struct sip_peer p,
int  expiry 
) [static]

Update peer data in database (if used).

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

02491 {
02492    int rtcachefriends = ast_test_flag(&p->flags[1], SIP_PAGE2_RTCACHEFRIENDS);
02493    if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTUPDATE) &&
02494        (ast_test_flag(&p->flags[0], SIP_REALTIME) || rtcachefriends)) {
02495       realtime_update_peer(p->name, &p->addr, p->username, rtcachefriends ? p->fullcontact : NULL, expiry);
02496    }
02497 }


Variable Documentation

struct in_addr __ourip [static]

Definition at line 1209 of file chan_sip.c.

int allow_external_domains [static]

Accept calls to external SIP domains?

Definition at line 566 of file chan_sip.c.

int apeerobjs = 0 [static]

Autocreated peer objects

Definition at line 582 of file chan_sip.c.

char* app_dtmfmode = "SIPDtmfMode" [static]

Definition at line 18185 of file chan_sip.c.

char* app_sipaddheader = "SIPAddHeader" [static]

Definition at line 18187 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 1198 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 546 of file chan_sip.c.

struct sockaddr_in bindaddr = { 0, } [static]

The address we bind to

Definition at line 1203 of file chan_sip.c.

Definition at line 11939 of file chan_sip.c.

struct ast_cli_entry cli_sip[] [static]

Definition at line 18457 of file chan_sip.c.

Initial value:

   { { "sip", "debug", NULL },
   sip_do_debug_deprecated, "Enable SIP debugging",
   debug_usage }

Definition at line 18447 of file chan_sip.c.

Initial value:

   { { "sip", "no", "debug", NULL },
   sip_no_debug_deprecated, "Disable SIP debugging",
   debug_usage }

Definition at line 18452 of file chan_sip.c.

int compactheaders [static]

send compact sip headers

Definition at line 560 of file chan_sip.c.

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

Definition at line 232 of file chan_sip.c.

char debug_usage[] [static]

Definition at line 11823 of file chan_sip.c.

struct sockaddr_in debugaddr [static]

char default_callerid[AST_MAX_EXTENSION] [static]

Definition at line 526 of file chan_sip.c.

char default_context[AST_MAX_CONTEXT] [static]

Definition at line 523 of file chan_sip.c.

int default_expiry = DEFAULT_DEFAULT_EXPIRY [static]

Definition at line 193 of file chan_sip.c.

char default_fromdomain[AST_MAX_EXTENSION] [static]

Definition at line 527 of file chan_sip.c.

struct ast_jb_conf default_jbconf [static]

Global jitterbuffer configuration - by default, jb is disabled.

Definition at line 223 of file chan_sip.c.

char default_language[MAX_LANGUAGE] [static]

Definition at line 525 of file chan_sip.c.

int default_maxcallbitrate [static]

Maximum bitrate for call

Definition at line 534 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 531 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 532 of file chan_sip.c.

char default_notifymime[AST_MAX_EXTENSION] [static]

Definition at line 528 of file chan_sip.c.

struct ast_codec_pref default_prefs [static]

Default codec prefs

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

char default_subscribecontext[AST_MAX_CONTEXT] [static]

Definition at line 524 of file chan_sip.c.

char default_vmexten[AST_MAX_EXTENSION] [static]

Definition at line 530 of file chan_sip.c.

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

Definition at line 18184 of file chan_sip.c.

char* descrip_sipaddheader [static]

Definition at line 18190 of file chan_sip.c.

int dumphistory [static]

Dump history to verbose before destroying SIP dialog

Definition at line 562 of file chan_sip.c.

int expiry = DEFAULT_EXPIRY [static]

Definition at line 194 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 1206 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 1205 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 1204 of file chan_sip.c.

int externrefresh = 10 [static]

Definition at line 1207 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 553 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 554 of file chan_sip.c.

SIP Refer restriction scheme

Definition at line 570 of file chan_sip.c.

Send 401 Unauthorized for all failing requests

Definition at line 543 of file chan_sip.c.

int global_autoframing [static]

Turn autoframing on or off.

Definition at line 569 of file chan_sip.c.

int global_callevents [static]

Whether we send manager events or not

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

int global_directrtpsetup [static]

Enable support for Direct RTP setup (no re-invites)

Definition at line 538 of file chan_sip.c.

struct ast_flags global_flags[2] = {{0}} [static]

global SIP_ flags

Definition at line 585 of file chan_sip.c.

struct ast_jb_conf global_jbconf [static]

Definition at line 230 of file chan_sip.c.

int global_limitonpeers [static]

Match call limit on peers only

Definition at line 539 of file chan_sip.c.

Match externip/externhost setting against localnet setting

Definition at line 572 of file chan_sip.c.

int global_mwitime [static]

Time between MWI checks for peers

Definition at line 556 of file chan_sip.c.

int global_notifyhold [static]

Send notifications on hold

Definition at line 542 of file chan_sip.c.

int global_notifyringing [static]

Send notifications on ringing

Definition at line 541 of file chan_sip.c.

char global_realm[MAXHOSTNAMELEN] [static]

Default realm

Definition at line 563 of file chan_sip.c.

int global_reg_timeout [static]

Definition at line 551 of file chan_sip.c.

int global_regattempts_max [static]

Registration attempts before giving up

Definition at line 552 of file chan_sip.c.

char global_regcontext[AST_MAX_CONTEXT] [static]

Context for auto-extensions

Definition at line 564 of file chan_sip.c.

int global_relaxdtmf [static]

Relax DTMF

Definition at line 547 of file chan_sip.c.

int global_rtautoclear [static]

Definition at line 540 of file chan_sip.c.

int global_rtpholdtimeout [static]

Definition at line 549 of file chan_sip.c.

int global_rtpkeepalive [static]

Send RTP keepalives

Definition at line 550 of file chan_sip.c.

int global_rtptimeout [static]

Time out call if no RTP

Definition at line 548 of file chan_sip.c.

int global_t1min [static]

T1 roundtrip time minimum

Definition at line 568 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 835 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 558 of file chan_sip.c.

unsigned int global_tos_sip [static]

IP type of service for SIP packets

Definition at line 557 of file chan_sip.c.

unsigned int global_tos_video [static]

IP type of service for video RTP packets

Definition at line 559 of file chan_sip.c.

char global_useragent[AST_MAX_EXTENSION] [static]

Useragent for the SIP channel

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

struct sip_pvt * iflist [static]

sip_pvt: PVT structures are used for each SIP dialog, ie. a call, a registration, a subscribe

struct io_context* io [static]

The IO context

Definition at line 606 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 1208 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 10463 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 10014 of file chan_sip.c.

Referenced by load_module().

int max_expiry = DEFAULT_MAX_EXPIRY [static]

Maximum accepted registration time

Definition at line 192 of file chan_sip.c.

int min_expiry = DEFAULT_MIN_EXPIRY [static]

Minimum accepted registration time

Definition at line 191 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 600 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 11832 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 11836 of file chan_sip.c.

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

Definition at line 233 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 1214 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 11772 of file chan_sip.c.

int ourport [static]

Definition at line 1211 of file chan_sip.c.

struct sockaddr_in outboundproxyip [static]

Definition at line 1210 of file chan_sip.c.

Referenced by reload_config().

int pedanticsipchecking [static]

Extra checking ? Default off

Definition at line 545 of file chan_sip.c.

struct ast_peer_list peerl [static]

The peer list: Peers and Friends.

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

int recordhistory [static]

Record SIP history. Off by default

Definition at line 561 of file chan_sip.c.

Referenced by referstatus2str().

struct ast_register_list regl [static]

The register list: Other SIP proxys we register with and place calls to.

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

int regobjs = 0 [static]

Registry objects

Definition at line 583 of file chan_sip.c.

int rpeerobjs = 0 [static]

Realtime peers

Definition at line 581 of file chan_sip.c.

int ruserobjs = 0 [static]

Realtime users

Definition at line 579 of file chan_sip.c.

struct sched_context* sched [static]

The scheduling context

Definition at line 605 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 11796 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 11792 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 11767 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 11800 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 11787 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 11853 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 11809 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 11804 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 11819 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 11857 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 11849 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 11782 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 11777 of file chan_sip.c.

Definition at line 11915 of file chan_sip.c.

struct cfsip_methods sip_methods[] [static]

struct cfsip_options sip_options[] [static]

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

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

char sip_reload_usage[] [static]

Initial value:

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

Definition at line 11845 of file chan_sip.c.

int sip_reloading = FALSE [static]

Flag for avoiding multiple reloads at the same time

Definition at line 602 of file chan_sip.c.

Reason for last reload/load of configuration

Definition at line 603 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 1611 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 1553 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 1579 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 1620 of file chan_sip.c.

Referenced by load_module(), and unload_module().

Structure to declare a dialplan function: SIPCHANINFO.

Definition at line 12094 of file chan_sip.c.

Structure to declare a dialplan function: SIPPEER.

Definition at line 12014 of file chan_sip.c.

int sipsock = -1 [static]

Main socket for SIP network communication

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

int speerobjs = 0 [static]

Statis peers

Definition at line 580 of file chan_sip.c.

int srvlookup [static]

SRV Lookup on or off. Default is on

Definition at line 544 of file chan_sip.c.

int suserobjs = 0 [static]

Static users

Definition at line 578 of file chan_sip.c.

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

Definition at line 18183 of file chan_sip.c.

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

Definition at line 18188 of file chan_sip.c.

struct ast_user_list userl [static]

The user list: Users and friends.


Generated on Sun Dec 18 20:55:48 2011 for Asterisk - the Open Source PBX by  doxygen 1.5.6