Thu Oct 8 21:57:41 2009

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 * 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_write (struct ast_channel *ast, struct ast_frame *frame)
 Send frame to media channel (rtp).
static int sipsock_read (int *id, int fd, short events, void *ignore)
 Read data from SIP socket.
static void stop_media_flows (struct sip_pvt *p)
 Immediately stop RTP, VRTP and UDPTL as applicable.
static const char * subscription_type2str (enum subscriptiontype subtype)
 Show subscription type in string format.
static int t38_get_rate (int t38cap)
 Get Max T.38 Transmission rate from T38 capabilities.
static struct sip_peertemp_peer (const char *name)
 Create temporary peer (used in autocreatepeer mode).
static void temp_pvt_cleanup (void *)
static char * transfermode2str (enum transfermodes mode)
 Convert transfer mode to text string.
static void transmit_fake_auth_response (struct sip_pvt *p, struct sip_request *req, int reliable)
 Send a fake 401 Unauthorized response when the administrator wants to hide the names of local users/peers from fishers.
static int transmit_info_with_digit (struct sip_pvt *p, const char digit, unsigned int duration)
 Send SIP INFO dtmf message, see Cisco documentation on cisco.com.
static int transmit_info_with_vidupdate (struct sip_pvt *p)
 Send SIP INFO with video update request.
static int transmit_invite (struct sip_pvt *p, int sipmethod, int sdp, int init)
 Build REFER/INVITE/OPTIONS message and transmit it.
static int transmit_message_with_text (struct sip_pvt *p, const char *text)
 Transmit text with SIP MESSAGE method.
static int transmit_notify_with_mwi (struct sip_pvt *p, int newmsgs, int oldmsgs, char *vmexten)
 Notify user of messages waiting in voicemail.
static int transmit_notify_with_sipfrag (struct sip_pvt *p, int cseq, char *message, int terminate)
 Notify a transferring party of the status of transfer.
static int transmit_refer (struct sip_pvt *p, const char *dest)
 Transmit SIP REFER message (initiated by the transfer() dialplan application.
static int transmit_register (struct sip_registry *r, int sipmethod, const char *auth, const char *authheader)
 Transmit register to SIP proxy or UA.
static int transmit_reinvite_with_sdp (struct sip_pvt *p)
 Transmit reinvite with SDP.
static int transmit_reinvite_with_t38_sdp (struct sip_pvt *p)
 Transmit reinvite with T38 SDP We reinvite so that the T38 processing can take place. SIP Signalling stays with * in the path.
static int transmit_request (struct sip_pvt *p, int sipmethod, int seqno, enum xmittype reliable, int newbranch)
 Transmit generic SIP request returns XMIT_ERROR if transmit failed with a critical error (don't retry).
static int transmit_request_with_auth (struct sip_pvt *p, int sipmethod, int seqno, enum xmittype reliable, int newbranch)
 Transmit SIP request, auth added.
static int transmit_response (struct sip_pvt *p, const char *msg, const struct sip_request *req)
 Transmit response, no retransmits.
static int transmit_response_reliable (struct sip_pvt *p, const char *msg, const struct sip_request *req)
 Transmit response, Make sure you get an ACK This is only used for responses to INVITEs, where we need to make sure we get an ACK.
static int transmit_response_using_temp (ast_string_field callid, struct sockaddr_in *sin, int useglobal_nat, const int intended_method, const struct sip_request *req, const char *msg)
 Transmit response, no retransmits, using a temporary pvt structure.
static int transmit_response_with_allow (struct sip_pvt *p, const char *msg, const struct sip_request *req, enum xmittype reliable)
 Append Accept header, content length before transmitting response.
static int transmit_response_with_auth (struct sip_pvt *p, const char *msg, const struct sip_request *req, const char *randdata, enum xmittype reliable, const char *header, int stale)
 Respond with authorization request.
static int transmit_response_with_date (struct sip_pvt *p, const char *msg, const struct sip_request *req)
 Append date and content length before transmitting response.
static int transmit_response_with_sdp (struct sip_pvt *p, const char *msg, const struct sip_request *req, enum xmittype reliable)
 Used for 200 OK and 183 early media.
static int transmit_response_with_t38_sdp (struct sip_pvt *p, char *msg, struct sip_request *req, int retrans)
 Used for 200 OK and 183 early media.
static int transmit_response_with_unsupported (struct sip_pvt *p, const char *msg, const struct sip_request *req, const char *unsupported)
 Transmit response, no retransmits.
static int transmit_sip_request (struct sip_pvt *p, struct sip_request *req)
 Transmit SIP request unreliably (only used in sip_notify subsystem).
static int transmit_state_notify (struct sip_pvt *p, int state, int full, int timeout)
 Used in the SUBSCRIBE notification subsystem.
static void try_suggested_sip_codec (struct sip_pvt *p)
 Try setting codec suggested by the SIP_CODEC channel variable.
static int unload_module (void)
 PBX unload module API.
static int update_call_counter (struct sip_pvt *fup, int event)
 update_call_counter: Handle call_limit for SIP users Setting a call-limit will cause calls above the limit not to be accepted.
static void update_peer (struct sip_peer *p, int expiry)
 Update peer data in database (if used).

Variables

static struct in_addr __ourip
static int allow_external_domains
static int apeerobjs = 0
static char * app_dtmfmode = "SIPDtmfMode"
static char * app_sipaddheader = "SIPAddHeader"
static struct sip_authauthl = NULL
static int autocreatepeer
static struct sockaddr_in bindaddr = { 0, }
static struct ast_custom_function checksipdomain_function
static struct ast_cli_entry cli_sip []
static struct ast_cli_entry cli_sip_debug_deprecated
static struct ast_cli_entry cli_sip_no_debug_deprecated
static int compactheaders
static const char config [] = "sip.conf"
static char debug_usage []
static struct sockaddr_in debugaddr
static char default_callerid [AST_MAX_EXTENSION]
static char default_context [AST_MAX_CONTEXT]
static int default_expiry = DEFAULT_DEFAULT_EXPIRY
static char default_fromdomain [AST_MAX_EXTENSION]
static struct ast_jb_conf default_jbconf
 Global jitterbuffer configuration - by default, jb is disabled.
static char default_language [MAX_LANGUAGE]
static int default_maxcallbitrate
static char default_mohinterpret [MAX_MUSICCLASS]
static char default_mohsuggest [MAX_MUSICCLASS]
static char default_notifymime [AST_MAX_EXTENSION]
static struct ast_codec_pref default_prefs
static int default_qualify
static char default_subscribecontext [AST_MAX_CONTEXT]
static char default_vmexten [AST_MAX_EXTENSION]
static char * descrip_dtmfmode = "SIPDtmfMode(inband|info|rfc2833): Changes the dtmfmode for a SIP call\n"
static char * descrip_sipaddheader
static int dumphistory
static int expiry = DEFAULT_EXPIRY
static time_t externexpire = 0
static char externhost [MAXHOSTNAMELEN]
static struct sockaddr_in externip
static int externrefresh = 10
static int global_allowguest
static int global_allowsubscribe
static enum transfermodes global_allowtransfer
static int global_alwaysauthreject
static int global_autoframing
static int global_callevents
static int global_capability = AST_FORMAT_ULAW | AST_FORMAT_ALAW | AST_FORMAT_GSM | AST_FORMAT_H263
 Codecs that we support by default:.
static int global_directrtpsetup
static struct ast_flags global_flags [2] = {{0}}
static struct ast_jb_conf global_jbconf
static int global_limitonpeers
static int global_matchexterniplocally
static int global_mwitime
static int global_notifyhold
static int global_notifyringing
static char global_realm [MAXHOSTNAMELEN]
static int global_reg_timeout
static int global_regattempts_max
static char global_regcontext [AST_MAX_CONTEXT]
static int global_relaxdtmf
static int global_rtautoclear
static int global_rtpholdtimeout
static int global_rtpkeepalive
static int global_rtptimeout
static int global_t1min
static int global_t38_capability = T38FAX_VERSION_0 | T38FAX_RATE_2400 | T38FAX_RATE_4800 | T38FAX_RATE_7200 | T38FAX_RATE_9600
static unsigned int global_tos_audio
static unsigned int global_tos_sip
static unsigned int global_tos_video
static char global_useragent [AST_MAX_EXTENSION]
static char history_usage []
static struct sip_pvtiflist
 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

SIP over TLS

Better support of forking

VIA branch tag transaction checking

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

Referenced by check_auth().

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

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

References SIP_REGISTER, and transmit_register().

Referenced by sip_reregister().

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

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

10853 {
10854 #define FORMAT3 "%-15.15s  %-10.10s  %-11.11s  %-15.15s  %-13.13s  %-15.15s %-10.10s\n"
10855 #define FORMAT2 "%-15.15s  %-10.10s  %-11.11s  %-11.11s  %-15.15s  %-7.7s  %-15.15s\n"
10856 #define FORMAT  "%-15.15s  %-10.10s  %-11.11s  %5.5d/%5.5d  %-15.15s  %-3.3s %-3.3s  %-15.15s %-10.10s\n"
10857    struct sip_pvt *cur;
10858    int numchans = 0;
10859    char *referstatus = NULL;
10860 
10861    if (argc != 3)
10862       return RESULT_SHOWUSAGE;
10863    ast_mutex_lock(&iflock);
10864    cur = iflist;
10865    if (!subscriptions)
10866       ast_cli(fd, FORMAT2, "Peer", "User/ANR", "Call ID", "Seq (Tx/Rx)", "Format", "Hold", "Last Message");
10867    else 
10868       ast_cli(fd, FORMAT3, "Peer", "User", "Call ID", "Extension", "Last state", "Type", "Mailbox");
10869    for (; cur; cur = cur->next) {
10870       referstatus = "";
10871       if (cur->refer) { /* SIP transfer in progress */
10872          referstatus = referstatus2str(cur->refer->status);
10873       }
10874       if (cur->subscribed == NONE && !subscriptions) {
10875          char formatbuf[SIPBUFSIZE/2];
10876          ast_cli(fd, FORMAT, ast_inet_ntoa(cur->sa.sin_addr), 
10877             S_OR(cur->username, S_OR(cur->cid_num, "(None)")),
10878             cur->callid, 
10879             cur->ocseq, cur->icseq,
10880             ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->owner ? cur->owner->nativeformats : 0),
10881             ast_test_flag(&cur->flags[1], SIP_PAGE2_CALL_ONHOLD) ? "Yes" : "No",
10882             ast_test_flag(&cur->flags[0], SIP_NEEDDESTROY) ? "(d)" : "",
10883             cur->lastmsg ,
10884             referstatus
10885          );
10886          numchans++;
10887       }
10888       if (cur->subscribed != NONE && subscriptions) {
10889          ast_cli(fd, FORMAT3, ast_inet_ntoa(cur->sa.sin_addr),
10890             S_OR(cur->username, S_OR(cur->cid_num, "(None)")), 
10891                cur->callid,
10892             /* the 'complete' exten/context is hidden in the refer_to field for subscriptions */
10893             cur->subscribed == MWI_NOTIFICATION ? "--" : cur->subscribeuri,
10894             cur->subscribed == MWI_NOTIFICATION ? "<none>" : ast_extension_state2str(cur->laststate), 
10895             subscription_type2str(cur->subscribed),
10896             cur->subscribed == MWI_NOTIFICATION ? (cur->relatedpeer ? cur->relatedpeer->mailbox : "<none>") : "<none>"
10897 );
10898          numchans++;
10899       }
10900    }
10901    ast_mutex_unlock(&iflock);
10902    if (!subscriptions)
10903       ast_cli(fd, "%d active SIP channel%s\n", numchans, (numchans != 1) ? "s" : "");
10904    else
10905       ast_cli(fd, "%d active SIP subscription%s\n", numchans, (numchans != 1) ? "s" : "");
10906    return RESULT_SUCCESS;
10907 #undef FORMAT
10908 #undef FORMAT2
10909 #undef FORMAT3
10910 }

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

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

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

10411 {
10412    char status[30] = "";
10413    char cbuf[256];
10414    struct sip_peer *peer;
10415    char codec_buf[512];
10416    struct ast_codec_pref *pref;
10417    struct ast_variable *v;
10418    struct sip_auth *auth;
10419    int x = 0, codec = 0, load_realtime;
10420    int realtimepeers;
10421 
10422    realtimepeers = ast_check_realtime("sippeers");
10423 
10424    if (argc < 4)
10425       return RESULT_SHOWUSAGE;
10426 
10427    load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? TRUE : FALSE;
10428    peer = find_peer(argv[3], NULL, load_realtime);
10429    if (s) {    /* Manager */
10430       if (peer) {
10431          const char *id = astman_get_header(m,"ActionID");
10432 
10433          astman_append(s, "Response: Success\r\n");
10434          if (!ast_strlen_zero(id))
10435             astman_append(s, "ActionID: %s\r\n",id);
10436       } else {
10437          snprintf (cbuf, sizeof(cbuf), "Peer %s not found.\n", argv[3]);
10438          astman_send_error(s, m, cbuf);
10439          return 0;
10440       }
10441    }
10442    if (peer && type==0 ) { /* Normal listing */
10443       ast_cli(fd,"\n\n");
10444       ast_cli(fd, "  * Name       : %s\n", peer->name);
10445       if (realtimepeers) { /* Realtime is enabled */
10446          ast_cli(fd, "  Realtime peer: %s\n", ast_test_flag(&peer->flags[0], SIP_REALTIME) ? "Yes, cached" : "No");
10447       }
10448       ast_cli(fd, "  Secret       : %s\n", ast_strlen_zero(peer->secret)?"<Not set>":"<Set>");
10449       ast_cli(fd, "  MD5Secret    : %s\n", ast_strlen_zero(peer->md5secret)?"<Not set>":"<Set>");
10450       for (auth = peer->auth; auth; auth = auth->next) {
10451          ast_cli(fd, "  Realm-auth   : Realm %-15.15s User %-10.20s ", auth->realm, auth->username);
10452          ast_cli(fd, "%s\n", !ast_strlen_zero(auth->secret)?"<Secret set>":(!ast_strlen_zero(auth->md5secret)?"<MD5secret set>" : "<Not set>"));
10453       }
10454       ast_cli(fd, "  Context      : %s\n", peer->context);
10455       ast_cli(fd, "  Subscr.Cont. : %s\n", S_OR(peer->subscribecontext, "<Not set>") );
10456       ast_cli(fd, "  Language     : %s\n", peer->language);
10457       if (!ast_strlen_zero(peer->accountcode))
10458          ast_cli(fd, "  Accountcode  : %s\n", peer->accountcode);
10459       ast_cli(fd, "  AMA flags    : %s\n", ast_cdr_flags2str(peer->amaflags));
10460       ast_cli(fd, "  Transfer mode: %s\n", transfermode2str(peer->allowtransfer));
10461       ast_cli(fd, "  CallingPres  : %s\n", ast_describe_caller_presentation(peer->callingpres));
10462       if (!ast_strlen_zero(peer->fromuser))
10463          ast_cli(fd, "  FromUser     : %s\n", peer->fromuser);
10464       if (!ast_strlen_zero(peer->fromdomain))
10465          ast_cli(fd, "  FromDomain   : %s\n", peer->fromdomain);
10466       ast_cli(fd, "  Callgroup    : ");
10467       print_group(fd, peer->callgroup, 0);
10468       ast_cli(fd, "  Pickupgroup  : ");
10469       print_group(fd, peer->pickupgroup, 0);
10470       ast_cli(fd, "  Mailbox      : %s\n", peer->mailbox);
10471       ast_cli(fd, "  VM Extension : %s\n", peer->vmexten);
10472       ast_cli(fd, "  LastMsgsSent : %d/%d\n", (peer->lastmsgssent & 0x7fff0000) >> 16, peer->lastmsgssent & 0xffff);
10473       ast_cli(fd, "  Call limit   : %d\n", peer->call_limit);
10474       ast_cli(fd, "  Dynamic      : %s\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)?"Yes":"No"));
10475       ast_cli(fd, "  Callerid     : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>"));
10476       ast_cli(fd, "  MaxCallBR    : %d kbps\n", peer->maxcallbitrate);
10477       ast_cli(fd, "  Expire       : %ld\n", ast_sched_when(sched, peer->expire));
10478       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)));
10479       ast_cli(fd, "  Nat          : %s\n", nat2str(ast_test_flag(&peer->flags[0], SIP_NAT)));
10480       ast_cli(fd, "  ACL          : %s\n", (peer->ha?"Yes":"No"));
10481       ast_cli(fd, "  T38 pt UDPTL : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT_UDPTL)?"Yes":"No");
10482 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS
10483       ast_cli(fd, "  T38 pt RTP   : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT_RTP)?"Yes":"No");
10484       ast_cli(fd, "  T38 pt TCP   : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT_TCP)?"Yes":"No");
10485 #endif
10486       ast_cli(fd, "  CanReinvite  : %s\n", ast_test_flag(&peer->flags[0], SIP_CAN_REINVITE)?"Yes":"No");
10487       ast_cli(fd, "  PromiscRedir : %s\n", ast_test_flag(&peer->flags[0], SIP_PROMISCREDIR)?"Yes":"No");
10488       ast_cli(fd, "  User=Phone   : %s\n", ast_test_flag(&peer->flags[0], SIP_USEREQPHONE)?"Yes":"No");
10489       ast_cli(fd, "  Video Support: %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_VIDEOSUPPORT)?"Yes":"No");
10490       ast_cli(fd, "  Trust RPID   : %s\n", ast_test_flag(&peer->flags[0], SIP_TRUSTRPID) ? "Yes" : "No");
10491       ast_cli(fd, "  Send RPID    : %s\n", ast_test_flag(&peer->flags[0], SIP_SENDRPID) ? "Yes" : "No");
10492       ast_cli(fd, "  Subscriptions: %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE) ? "Yes" : "No");
10493       ast_cli(fd, "  Overlap dial : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWOVERLAP) ? "Yes" : "No");
10494 
10495       /* - is enumerated */
10496       ast_cli(fd, "  DTMFmode     : %s\n", dtmfmode2str(ast_test_flag(&peer->flags[0], SIP_DTMF)));
10497       ast_cli(fd, "  LastMsg      : %d\n", peer->lastmsg);
10498       ast_cli(fd, "  ToHost       : %s\n", peer->tohost);
10499       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));
10500       ast_cli(fd, "  Defaddr->IP  : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port));
10501       if (!ast_strlen_zero(global_regcontext))
10502          ast_cli(fd, "  Reg. exten   : %s\n", peer->regexten);
10503       ast_cli(fd, "  Def. Username: %s\n", peer->username);
10504       ast_cli(fd, "  SIP Options  : ");
10505       if (peer->sipoptions) {
10506          int lastoption = -1;
10507          for (x=0 ; (x < (sizeof(sip_options) / sizeof(sip_options[0]))); x++) {
10508             if (sip_options[x].id != lastoption) {
10509                if (peer->sipoptions & sip_options[x].id)
10510                   ast_cli(fd, "%s ", sip_options[x].text);
10511                lastoption = x;
10512             }
10513          }
10514       } else
10515          ast_cli(fd, "(none)");
10516 
10517       ast_cli(fd, "\n");
10518       ast_cli(fd, "  Codecs       : ");
10519       ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability);
10520       ast_cli(fd, "%s\n", codec_buf);
10521       ast_cli(fd, "  Codec Order  : (");
10522       print_codec_to_cli(fd, &peer->prefs);
10523       ast_cli(fd, ")\n");
10524 
10525       ast_cli(fd, "  Auto-Framing:  %s \n", peer->autoframing ? "Yes" : "No");
10526       ast_cli(fd, "  Status       : ");
10527       peer_status(peer, status, sizeof(status));
10528       ast_cli(fd, "%s\n",status);
10529       ast_cli(fd, "  Useragent    : %s\n", peer->useragent);
10530       ast_cli(fd, "  Reg. Contact : %s\n", peer->fullcontact);
10531       if (peer->chanvars) {
10532          ast_cli(fd, "  Variables    :\n");
10533          for (v = peer->chanvars ; v ; v = v->next)
10534             ast_cli(fd, "                 %s = %s\n", v->name, v->value);
10535       }
10536       ast_cli(fd,"\n");
10537       ASTOBJ_UNREF(peer,sip_destroy_peer);
10538    } else  if (peer && type == 1) { /* manager listing */
10539       char buf[256];
10540       astman_append(s, "Channeltype: SIP\r\n");
10541       astman_append(s, "ObjectName: %s\r\n", peer->name);
10542       astman_append(s, "ChanObjectType: peer\r\n");
10543       astman_append(s, "SecretExist: %s\r\n", ast_strlen_zero(peer->secret)?"N":"Y");
10544       astman_append(s, "MD5SecretExist: %s\r\n", ast_strlen_zero(peer->md5secret)?"N":"Y");
10545       astman_append(s, "Context: %s\r\n", peer->context);
10546       astman_append(s, "Language: %s\r\n", peer->language);
10547       if (!ast_strlen_zero(peer->accountcode))
10548          astman_append(s, "Accountcode: %s\r\n", peer->accountcode);
10549       astman_append(s, "AMAflags: %s\r\n", ast_cdr_flags2str(peer->amaflags));
10550       astman_append(s, "CID-CallingPres: %s\r\n", ast_describe_caller_presentation(peer->callingpres));
10551       if (!ast_strlen_zero(peer->fromuser))
10552          astman_append(s, "SIP-FromUser: %s\r\n", peer->fromuser);
10553       if (!ast_strlen_zero(peer->fromdomain))
10554          astman_append(s, "SIP-FromDomain: %s\r\n", peer->fromdomain);
10555       astman_append(s, "Callgroup: ");
10556       astman_append(s, "%s\r\n", ast_print_group(buf, sizeof(buf), peer->callgroup));
10557       astman_append(s, "Pickupgroup: ");
10558       astman_append(s, "%s\r\n", ast_print_group(buf, sizeof(buf), peer->pickupgroup));
10559       astman_append(s, "VoiceMailbox: %s\r\n", peer->mailbox);
10560       astman_append(s, "TransferMode: %s\r\n", transfermode2str(peer->allowtransfer));
10561       astman_append(s, "LastMsgsSent: %d\r\n", peer->lastmsgssent);
10562       astman_append(s, "Call-limit: %d\r\n", peer->call_limit);
10563       astman_append(s, "MaxCallBR: %d kbps\r\n", peer->maxcallbitrate);
10564       astman_append(s, "Dynamic: %s\r\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)?"Y":"N"));
10565       astman_append(s, "Callerid: %s\r\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, ""));
10566       astman_append(s, "RegExpire: %ld seconds\r\n", ast_sched_when(sched,peer->expire));
10567       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)));
10568       astman_append(s, "SIP-NatSupport: %s\r\n", nat2str(ast_test_flag(&peer->flags[0], SIP_NAT)));
10569       astman_append(s, "ACL: %s\r\n", (peer->ha?"Y":"N"));
10570       astman_append(s, "SIP-CanReinvite: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_CAN_REINVITE)?"Y":"N"));
10571       astman_append(s, "SIP-PromiscRedir: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_PROMISCREDIR)?"Y":"N"));
10572       astman_append(s, "SIP-UserPhone: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_USEREQPHONE)?"Y":"N"));
10573       astman_append(s, "SIP-VideoSupport: %s\r\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_VIDEOSUPPORT)?"Y":"N"));
10574 
10575       /* - is enumerated */
10576       astman_append(s, "SIP-DTMFmode: %s\r\n", dtmfmode2str(ast_test_flag(&peer->flags[0], SIP_DTMF)));
10577       astman_append(s, "SIPLastMsg: %d\r\n", peer->lastmsg);
10578       astman_append(s, "ToHost: %s\r\n", peer->tohost);
10579       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));
10580       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));
10581       astman_append(s, "Default-Username: %s\r\n", peer->username);
10582       if (!ast_strlen_zero(global_regcontext))
10583          astman_append(s, "RegExtension: %s\r\n", peer->regexten);
10584       astman_append(s, "Codecs: ");
10585       ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability);
10586       astman_append(s, "%s\r\n", codec_buf);
10587       astman_append(s, "CodecOrder: ");
10588       pref = &peer->prefs;
10589       for(x = 0; x < 32 ; x++) {
10590          codec = ast_codec_pref_index(pref,x);
10591          if (!codec)
10592             break;
10593          astman_append(s, "%s", ast_getformatname(codec));
10594          if (x < 31 && ast_codec_pref_index(pref,x+1))
10595             astman_append(s, ",");
10596       }
10597 
10598       astman_append(s, "\r\n");
10599       astman_append(s, "Status: ");
10600       peer_status(peer, status, sizeof(status));
10601       astman_append(s, "%s\r\n", status);
10602       astman_append(s, "SIP-Useragent: %s\r\n", peer->useragent);
10603       astman_append(s, "Reg-Contact : %s\r\n", peer->fullcontact);
10604       if (peer->chanvars) {
10605          for (v = peer->chanvars ; v ; v = v->next) {
10606             astman_append(s, "ChanVariable:\n");
10607             astman_append(s, " %s,%s\r\n", v->name, v->value);
10608          }
10609       }
10610 
10611       ASTOBJ_UNREF(peer,sip_destroy_peer);
10612 
10613    } else {
10614       ast_cli(fd,"Peer %s not found.\n", argv[3]);
10615       ast_cli(fd,"\n");
10616    }
10617 
10618    return RESULT_SUCCESS;
10619 }

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

09961 {
09962    regex_t regexbuf;
09963    int havepattern = FALSE;
09964 
09965 #define FORMAT2 "%-25.25s  %-15.15s %-3.3s %-3.3s %-3.3s %-8s %-10s %-10s\n"
09966 #define FORMAT  "%-25.25s  %-15.15s %-3.3s %-3.3s %-3.3s %-8d %-10s %-10s\n"
09967 
09968    char name[256];
09969    int total_peers = 0;
09970    int peers_mon_online = 0;
09971    int peers_mon_offline = 0;
09972    int peers_unmon_offline = 0;
09973    int peers_unmon_online = 0;
09974    const char *id;
09975    char idtext[256] = "";
09976    int realtimepeers;
09977 
09978    realtimepeers = ast_check_realtime("sippeers");
09979 
09980    if (s) { /* Manager - get ActionID */
09981       id = astman_get_header(m,"ActionID");
09982       if (!ast_strlen_zero(id))
09983          snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
09984    }
09985 
09986    switch (argc) {
09987    case 5:
09988       if (!strcasecmp(argv[3], "like")) {
09989          if (regcomp(&regexbuf, argv[4], REG_EXTENDED | REG_NOSUB))
09990             return RESULT_SHOWUSAGE;
09991          havepattern = TRUE;
09992       } else
09993          return RESULT_SHOWUSAGE;
09994    case 3:
09995       break;
09996    default:
09997       return RESULT_SHOWUSAGE;
09998    }
09999 
10000    if (!s) /* Normal list */
10001       ast_cli(fd, FORMAT2, "Name/username", "Host", "Dyn", "Nat", "ACL", "Port", "Status", (realtimepeers ? "Realtime" : ""));
10002    
10003    ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do {
10004       char status[20] = "";
10005       char srch[2000];
10006       char pstatus;
10007       
10008       ASTOBJ_RDLOCK(iterator);
10009 
10010       if (havepattern && regexec(&regexbuf, iterator->name, 0, NULL, 0)) {
10011          ASTOBJ_UNLOCK(iterator);
10012          continue;
10013       }
10014 
10015       if (!ast_strlen_zero(iterator->username) && !s)
10016          snprintf(name, sizeof(name), "%s/%s", iterator->name, iterator->username);
10017       else
10018          ast_copy_string(name, iterator->name, sizeof(name));
10019       
10020       pstatus = peer_status(iterator, status, sizeof(status));
10021       if (pstatus == 1)
10022          peers_mon_online++;
10023       else if (pstatus == 0)
10024          peers_mon_offline++;
10025       else {
10026          if (iterator->addr.sin_port == 0)
10027             peers_unmon_offline++;
10028          else
10029             peers_unmon_online++;
10030       }
10031 
10032       snprintf(srch, sizeof(srch), FORMAT, name,
10033          iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iterator->addr.sin_addr) : "(Unspecified)",
10034          ast_test_flag(&iterator->flags[1], SIP_PAGE2_DYNAMIC) ? " D " : "   ",  /* Dynamic or not? */
10035          ast_test_flag(&iterator->flags[0], SIP_NAT_ROUTE) ? " N " : "   ",   /* NAT=yes? */
10036          iterator->ha ? " A " : "   ",    /* permit/deny */
10037          ntohs(iterator->addr.sin_port), status,
10038          realtimepeers ? (ast_test_flag(&iterator->flags[0], SIP_REALTIME) ? "Cached RT":"") : "");
10039 
10040       if (!s)  {/* Normal CLI list */
10041          ast_cli(fd, FORMAT, name, 
10042          iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iterator->addr.sin_addr) : "(Unspecified)",
10043          ast_test_flag(&iterator->flags[1], SIP_PAGE2_DYNAMIC) ? " D " : "   ",  /* Dynamic or not? */
10044          ast_test_flag(&iterator->flags[0], SIP_NAT_ROUTE) ? " N " : "   ",   /* NAT=yes? */
10045          iterator->ha ? " A " : "   ",       /* permit/deny */
10046          
10047          ntohs(iterator->addr.sin_port), status,
10048          realtimepeers ? (ast_test_flag(&iterator->flags[0], SIP_REALTIME) ? "Cached RT":"") : "");
10049       } else { /* Manager format */
10050          /* The names here need to be the same as other channels */
10051          astman_append(s, 
10052          "Event: PeerEntry\r\n%s"
10053          "Channeltype: SIP\r\n"
10054          "ObjectName: %s\r\n"
10055          "ChanObjectType: peer\r\n" /* "peer" or "user" */
10056          "IPaddress: %s\r\n"
10057          "IPport: %d\r\n"
10058          "Dynamic: %s\r\n"
10059          "Natsupport: %s\r\n"
10060          "VideoSupport: %s\r\n"
10061          "ACL: %s\r\n"
10062          "Status: %s\r\n"
10063          "RealtimeDevice: %s\r\n\r\n", 
10064          idtext,
10065          iterator->name, 
10066          iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iterator->addr.sin_addr) : "-none-",
10067          ntohs(iterator->addr.sin_port), 
10068          ast_test_flag(&iterator->flags[1], SIP_PAGE2_DYNAMIC) ? "yes" : "no",   /* Dynamic or not? */
10069          ast_test_flag(&iterator->flags[0], SIP_NAT_ROUTE) ? "yes" : "no", /* NAT=yes? */
10070          ast_test_flag(&iterator->flags[1], SIP_PAGE2_VIDEOSUPPORT) ? "yes" : "no", /* VIDEOSUPPORT=yes? */
10071          iterator->ha ? "yes" : "no",       /* permit/deny */
10072          status,
10073          realtimepeers ? (ast_test_flag(&iterator->flags[0], SIP_REALTIME) ? "yes":"no") : "no");
10074       }
10075 
10076       ASTOBJ_UNLOCK(iterator);
10077 
10078       total_peers++;
10079    } while(0) );
10080    
10081    if (!s)
10082       ast_cli(fd, "%d sip peers [Monitored: %d online, %d offline Unmonitored: %d online, %d offline]\n",
10083               total_peers, peers_mon_online, peers_mon_offline, peers_unmon_online, peers_unmon_offline);
10084 
10085    if (havepattern)
10086       regfree(&regexbuf);
10087 
10088    if (total)
10089       *total = total_peers;
10090    
10091 
10092    return RESULT_SUCCESS;
10093 #undef FORMAT
10094 #undef FORMAT2
10095 }

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

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

14756 {
14757    struct ast_rtp_quality qos;
14758    struct sip_pvt *p = chan->tech_pvt;
14759    char *all = "", *parse = ast_strdupa(preparse);
14760    AST_DECLARE_APP_ARGS(args,
14761       AST_APP_ARG(param);
14762       AST_APP_ARG(type);
14763       AST_APP_ARG(field);
14764    );
14765    AST_STANDARD_APP_ARGS(args, parse);
14766 
14767    /* Sanity check */
14768    if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) {
14769       ast_log(LOG_ERROR, "Cannot call %s on a non-SIP channel\n", funcname);
14770       return 0;
14771    }
14772 
14773    if (strcasecmp(args.param, "rtpqos"))
14774       return 0;
14775 
14776    /* Default arguments of audio,all */
14777    if (ast_strlen_zero(args.type))
14778       args.type = "audio";
14779    if (ast_strlen_zero(args.field))
14780       args.field = "all";
14781 
14782    memset(buf, 0, buflen);
14783    memset(&qos, 0, sizeof(qos));
14784 
14785    if (strcasecmp(args.type, "AUDIO") == 0) {
14786       all = ast_rtp_get_quality(p->rtp, &qos);
14787    } else if (strcasecmp(args.type, "VIDEO") == 0) {
14788       all = ast_rtp_get_quality(p->vrtp, &qos);
14789    }
14790 
14791    if (strcasecmp(args.field, "local_ssrc") == 0)
14792       snprintf(buf, buflen, "%u", qos.local_ssrc);
14793    else if (strcasecmp(args.field, "local_lostpackets") == 0)
14794       snprintf(buf, buflen, "%u", qos.local_lostpackets);
14795    else if (strcasecmp(args.field, "local_jitter") == 0)
14796       snprintf(buf, buflen, "%.0lf", qos.local_jitter * 1000.0);
14797    else if (strcasecmp(args.field, "local_count") == 0)
14798       snprintf(buf, buflen, "%u", qos.local_count);
14799    else if (strcasecmp(args.field, "remote_ssrc") == 0)
14800       snprintf(buf, buflen, "%u", qos.remote_ssrc);
14801    else if (strcasecmp(args.field, "remote_lostpackets") == 0)
14802       snprintf(buf, buflen, "%u", qos.remote_lostpackets);
14803    else if (strcasecmp(args.field, "remote_jitter") == 0)
14804       snprintf(buf, buflen, "%.0lf", qos.remote_jitter * 1000.0);
14805    else if (strcasecmp(args.field, "remote_count") == 0)
14806       snprintf(buf, buflen, "%u", qos.remote_count);
14807    else if (strcasecmp(args.field, "rtt") == 0)
14808       snprintf(buf, buflen, "%.0lf", qos.rtt * 1000.0);
14809    else if (strcasecmp(args.field, "all") == 0)
14810       ast_copy_string(buf, all, buflen);
14811    else {
14812       ast_log(LOG_WARNING, "Unrecognized argument '%s' to %s\n", preparse, funcname);
14813       return -1;
14814    }
14815    return 0;
14816 }

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

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

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

Add DTMF INFO tone to sip message.

Definition at line 6208 of file chan_sip.c.

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

Referenced by transmit_info_with_digit().

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

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

Add header to SIP message.

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

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

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

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

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

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

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

16374 {
16375    char authcopy[256];
16376    char *username=NULL, *realm=NULL, *secret=NULL, *md5secret=NULL;
16377    char *stringp;
16378    struct sip_auth *a, *b, *auth;
16379 
16380    if (ast_strlen_zero(configuration))
16381       return authlist;
16382 
16383    if (option_debug)
16384       ast_log(LOG_DEBUG, "Auth config ::  %s\n", configuration);
16385 
16386    ast_copy_string(authcopy, configuration, sizeof(authcopy));
16387    stringp = authcopy;
16388 
16389    username = stringp;
16390    realm = strrchr(stringp, '@');
16391    if (realm)
16392       *realm++ = '\0';
16393    if (ast_strlen_zero(username) || ast_strlen_zero(realm)) {
16394       ast_log(LOG_WARNING, "Format for authentication entry is user[:secret]@realm at line %d\n", lineno);
16395       return authlist;
16396    }
16397    stringp = username;
16398    username = strsep(&stringp, ":");
16399    if (username) {
16400       secret = strsep(&stringp, ":");
16401       if (!secret) {
16402          stringp = username;
16403          md5secret = strsep(&stringp,"#");
16404       }
16405    }
16406    if (!(auth = ast_calloc(1, sizeof(*auth))))
16407       return authlist;
16408 
16409    ast_copy_string(auth->realm, realm, sizeof(auth->realm));
16410    ast_copy_string(auth->username, username, sizeof(auth->username));
16411    if (secret)
16412       ast_copy_string(auth->secret, secret, sizeof(auth->secret));
16413    if (md5secret)
16414       ast_copy_string(auth->md5secret, md5secret, sizeof(auth->md5secret));
16415 
16416    /* find the end of the list */
16417    for (b = NULL, a = authlist; a ; b = a, a = a->next)
16418       ;
16419    if (b)
16420       b->next = auth;   /* Add structure add end of list */
16421    else
16422       authlist = auth;
16423 
16424    if (option_verbose > 2)
16425       ast_verbose("Added authentication for realm %s\n", realm);
16426 
16427    return authlist;
16428 
16429 }

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

Add route header into request per learned route.

Definition at line 5764 of file chan_sip.c.

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

Referenced by reqprep().

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

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

Add Session Description Protocol message.

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

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

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

16310 {
16311    struct domain *d;
16312 
16313    if (ast_strlen_zero(domain)) {
16314       ast_log(LOG_WARNING, "Zero length domain.\n");
16315       return 1;
16316    }
16317 
16318    if (!(d = ast_calloc(1, sizeof(*d))))
16319       return 0;
16320 
16321    ast_copy_string(d->domain, domain, sizeof(d->domain));
16322 
16323    if (!ast_strlen_zero(context))
16324       ast_copy_string(d->context, context, sizeof(d->context));
16325 
16326    d->mode = mode;
16327 
16328    AST_LIST_LOCK(&domain_list);
16329    AST_LIST_INSERT_TAIL(&domain_list, d, list);
16330    AST_LIST_UNLOCK(&domain_list);
16331 
16332    if (sipdebug)  
16333       ast_log(LOG_DEBUG, "Added local SIP domain '%s'\n", domain);
16334 
16335    return 1;
16336 }

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

Add T.38 Session Description Protocol message.

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

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

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

Add text body to SIP message.

Definition at line 6197 of file chan_sip.c.

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

Referenced by transmit_message_with_text().

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

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

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

Referenced by transmit_info_with_vidupdate().

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

static void append_date ( struct sip_request req  )  [static]

Append date to SIP message.

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

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

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

13303 {
13304    if (chan && chan->_state == AST_STATE_UP) {
13305       if (ast_test_flag(chan, AST_FLAG_MOH))
13306          ast_moh_stop(chan);
13307       else if (chan->generatordata)
13308          ast_deactivate_generator(chan);
13309    }
13310 }

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

13315 {
13316    int res = 0;
13317    struct ast_channel *peera = NULL,   
13318       *peerb = NULL,
13319       *peerc = NULL,
13320       *peerd = NULL;
13321 
13322 
13323    /* We will try to connect the transferee with the target and hangup
13324       all channels to the transferer */   
13325    if (option_debug > 3) {
13326       ast_log(LOG_DEBUG, "Sip transfer:--------------------\n");
13327       if (transferer->chan1)
13328          ast_log(LOG_DEBUG, "-- Transferer to PBX channel: %s State %s\n", transferer->chan1->name, ast_state2str(transferer->chan1->_state));
13329       else
13330          ast_log(LOG_DEBUG, "-- No transferer first channel - odd??? \n");
13331       if (target->chan1)
13332          ast_log(LOG_DEBUG, "-- Transferer to PBX second channel (target): %s State %s\n", target->chan1->name, ast_state2str(target->chan1->_state));
13333       else
13334          ast_log(LOG_DEBUG, "-- No target first channel ---\n");
13335       if (transferer->chan2)
13336          ast_log(LOG_DEBUG, "-- Bridged call to transferee: %s State %s\n", transferer->chan2->name, ast_state2str(transferer->chan2->_state));
13337       else
13338          ast_log(LOG_DEBUG, "-- No bridged call to transferee\n");
13339       if (target->chan2)
13340          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)");
13341       else
13342          ast_log(LOG_DEBUG, "-- No target second channel ---\n");
13343       ast_log(LOG_DEBUG, "-- END Sip transfer:--------------------\n");
13344    }
13345    if (transferer->chan2) { /* We have a bridge on the transferer's channel */
13346       peera = transferer->chan1; /* Transferer - PBX -> transferee channel * the one we hangup */
13347       peerb = target->chan1;     /* Transferer - PBX -> target channel - This will get lost in masq */
13348       peerc = transferer->chan2; /* Asterisk to Transferee */
13349       peerd = target->chan2;     /* Asterisk to Target */
13350       if (option_debug > 2)
13351          ast_log(LOG_DEBUG, "SIP transfer: Four channels to handle\n");
13352    } else if (target->chan2) {   /* Transferer has no bridge (IVR), but transferee */
13353       peera = target->chan1;     /* Transferer to PBX -> target channel */
13354       peerb = transferer->chan1; /* Transferer to IVR*/
13355       peerc = target->chan2;     /* Asterisk to Target */
13356       peerd = transferer->chan2; /* Nothing */
13357       if (option_debug > 2)
13358          ast_log(LOG_DEBUG, "SIP transfer: Three channels to handle\n");
13359    }
13360 
13361    if (peera && peerb && peerc && (peerb != peerc)) {
13362       ast_quiet_chan(peera);     /* Stop generators */
13363       ast_quiet_chan(peerb);  
13364       ast_quiet_chan(peerc);
13365       if (peerd)
13366          ast_quiet_chan(peerd);
13367 
13368       /* Fix CDRs so they're attached to the remaining channel */
13369       if (peera->cdr && peerb->cdr)
13370          peerb->cdr = ast_cdr_append(peerb->cdr, peera->cdr);
13371       else if (peera->cdr) 
13372          peerb->cdr = peera->cdr;
13373       peera->cdr = NULL;
13374 
13375       if (peerb->cdr && peerc->cdr) 
13376          peerb->cdr = ast_cdr_append(peerb->cdr, peerc->cdr);
13377       else if (peerc->cdr)
13378          peerb->cdr = peerc->cdr;
13379       peerc->cdr = NULL;
13380    
13381       if (option_debug > 3)
13382          ast_log(LOG_DEBUG, "SIP transfer: trying to masquerade %s into %s\n", peerc->name, peerb->name);
13383       if (ast_channel_masquerade(peerb, peerc)) {
13384          ast_log(LOG_WARNING, "Failed to masquerade %s into %s\n", peerb->name, peerc->name);
13385          res = -1;
13386       } else
13387          ast_log(LOG_DEBUG, "SIP transfer: Succeeded to masquerade channels.\n");
13388       return res;
13389    } else {
13390       ast_log(LOG_NOTICE, "SIP Transfer attempted with no appropriate bridged calls to transfer\n");
13391       if (transferer->chan1)
13392          ast_softhangup_nolock(transferer->chan1, AST_SOFTHANGUP_DEV);
13393       if (target->chan1)
13394          ast_softhangup_nolock(target->chan1, AST_SOFTHANGUP_DEV);
13395       return -2;
13396    }
13397    return 0;
13398 }

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

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

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

16641 {
16642    struct sip_peer *peer = NULL;
16643    struct ast_ha *oldha = NULL;
16644    int obproxyfound=0;
16645    int found=0;
16646    int firstpass=1;
16647    int format=0;     /* Ama flags */
16648    time_t regseconds = 0;
16649    char *varname = NULL, *varval = NULL;
16650    struct ast_variable *tmpvar = NULL;
16651    struct ast_flags peerflags[2] = {{(0)}};
16652    struct ast_flags mask[2] = {{(0)}};
16653    char fullcontact[sizeof(peer->fullcontact)] = "";
16654 
16655    if (!realtime || ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS))
16656       /* Note we do NOT use find_peer here, to avoid realtime recursion */
16657       /* We also use a case-sensitive comparison (unlike find_peer) so
16658          that case changes made to the peer name will be properly handled
16659          during reload
16660       */
16661       peer = ASTOBJ_CONTAINER_FIND_UNLINK_FULL(&peerl, name, name, 0, 0, strcmp);
16662 
16663    if (peer) {
16664       /* Already in the list, remove it and it will be added back (or FREE'd)  */
16665       found = 1;
16666       if (!(peer->objflags & ASTOBJ_FLAG_MARKED))
16667          firstpass = 0;
16668    } else {
16669       if (!(peer = ast_calloc(1, sizeof(*peer))))
16670          return NULL;
16671 
16672       if (realtime && !ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS))
16673          rpeerobjs++;
16674       else
16675          speerobjs++;
16676       ASTOBJ_INIT(peer);
16677    }
16678    /* Note that our peer HAS had its reference count incrased */
16679    if (firstpass) {
16680       peer->lastmsgssent = -1;
16681       oldha = peer->ha;
16682       peer->ha = NULL;
16683       set_peer_defaults(peer);   /* Set peer defaults */
16684    }
16685    if (!found && name)
16686          ast_copy_string(peer->name, name, sizeof(peer->name));
16687 
16688    /* If we have channel variables, remove them (reload) */
16689    if (peer->chanvars) {
16690       ast_variables_destroy(peer->chanvars);
16691       peer->chanvars = NULL;
16692       /* XXX should unregister ? */
16693    }
16694 
16695    /* If we have realm authentication information, remove them (reload) */
16696    clear_realm_authentication(peer->auth);
16697    peer->auth = NULL;
16698 
16699    for (; v || ((v = alt) && !(alt=NULL)); v = v->next) {
16700       if (handle_common_options(&peerflags[0], &mask[0], v))
16701          continue;
16702       if (realtime && !strcasecmp(v->name, "regseconds")) {
16703          ast_get_time_t(v->value, &regseconds, 0, NULL);
16704       } else if (realtime && !strcasecmp(v->name, "ipaddr") && !ast_strlen_zero(v->value) ) {
16705          inet_aton(v->value, &(peer->addr.sin_addr));
16706       } else if (realtime && !strcasecmp(v->name, "name"))
16707          ast_copy_string(peer->name, v->value, sizeof(peer->name));
16708       else if (realtime && !strcasecmp(v->name, "fullcontact")) {
16709          /* Reconstruct field, because realtime separates our value at the ';' */
16710          if (!ast_strlen_zero(fullcontact)) {
16711             strncat(fullcontact, ";", sizeof(fullcontact) - strlen(fullcontact) - 1);
16712             strncat(fullcontact, v->value, sizeof(fullcontact) - strlen(fullcontact) - 1);
16713          } else {
16714             ast_copy_string(fullcontact, v->value, sizeof(fullcontact));
16715             ast_set_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT);
16716          }
16717       } else if (!strcasecmp(v->name, "secret")) 
16718          ast_copy_string(peer->secret, v->value, sizeof(peer->secret));
16719       else if (!strcasecmp(v->name, "md5secret")) 
16720          ast_copy_string(peer->md5secret, v->value, sizeof(peer->md5secret));
16721       else if (!strcasecmp(v->name, "auth"))
16722          peer->auth = add_realm_authentication(peer->auth, v->value, v->lineno);
16723       else if (!strcasecmp(v->name, "callerid")) {
16724          ast_callerid_split(v->value, peer->cid_name, sizeof(peer->cid_name), peer->cid_num, sizeof(peer->cid_num));
16725       } else if (!strcasecmp(v->name, "fullname")) {
16726          ast_copy_string(peer->cid_name, v->value, sizeof(peer->cid_name));
16727       } else if (!strcasecmp(v->name, "cid_number")) {
16728          ast_copy_string(peer->cid_num, v->value, sizeof(peer->cid_num));
16729       } else if (!strcasecmp(v->name, "context")) {
16730          ast_copy_string(peer->context, v->value, sizeof(peer->context));
16731       } else if (!strcasecmp(v->name, "subscribecontext")) {
16732          ast_copy_string(peer->subscribecontext, v->value, sizeof(peer->subscribecontext));
16733       } else if (!strcasecmp(v->name, "fromdomain")) {
16734          ast_copy_string(peer->fromdomain, v->value, sizeof(peer->fromdomain));
16735       } else if (!strcasecmp(v->name, "usereqphone")) {
16736          ast_set2_flag(&peer->flags[0], ast_true(v->value), SIP_USEREQPHONE);
16737       } else if (!strcasecmp(v->name, "fromuser")) {
16738          ast_copy_string(peer->fromuser, v->value, sizeof(peer->fromuser));
16739       } else if (!strcasecmp(v->name, "host") || !strcasecmp(v->name, "outboundproxy")) {
16740          if (!strcasecmp(v->value, "dynamic")) {
16741             if (!strcasecmp(v->name, "outboundproxy") || obproxyfound) {
16742                ast_log(LOG_WARNING, "You can't have a dynamic outbound proxy, you big silly head at line %d.\n", v->lineno);
16743             } else {
16744                /* They'll register with us */
16745                if (!found || !ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)) {
16746                   /* Initialize stuff if this is a new peer, or if it used to be
16747                    * non-dynamic before the reload. */
16748                   memset(&peer->addr.sin_addr, 0, 4);
16749                   if (peer->addr.sin_port) {
16750                      /* If we've already got a port, make it the default rather than absolute */
16751                      peer->defaddr.sin_port = peer->addr.sin_port;
16752                      peer->addr.sin_port = 0;
16753                   }
16754                }
16755                ast_set_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC);
16756             }
16757          } else {
16758             /* Non-dynamic.  Make sure we become that way if we're not */
16759             if (!AST_SCHED_DEL(sched, peer->expire)) {
16760                struct sip_peer *peer_ptr = peer;
16761                ASTOBJ_UNREF(peer_ptr, sip_destroy_peer);
16762             }
16763             ast_clear_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC);
16764             if (!obproxyfound || !strcasecmp(v->name, "outboundproxy")) {
16765                if (ast_get_ip_or_srv(&peer->addr, v->value, srvlookup ? "_sip._udp" : NULL)) {
16766                   ASTOBJ_UNREF(peer, sip_destroy_peer);
16767                   return NULL;
16768                }
16769             }
16770             if (!strcasecmp(v->name, "outboundproxy"))
16771                obproxyfound=1;
16772             else {
16773                ast_copy_string(peer->tohost, v->value, sizeof(peer->tohost));
16774                if (!peer->addr.sin_port)
16775                   peer->addr.sin_port = htons(STANDARD_SIP_PORT);
16776             }
16777          }
16778       } else if (!strcasecmp(v->name, "defaultip")) {
16779          if (ast_get_ip(&peer->defaddr, v->value)) {
16780             ASTOBJ_UNREF(peer, sip_destroy_peer);
16781             return NULL;
16782          }
16783       } else if (!strcasecmp(v->name, "permit") || !strcasecmp(v->name, "deny")) {
16784          peer->ha = ast_append_ha(v->name, v->value, peer->ha);
16785       } else if (!strcasecmp(v->name, "port")) {
16786          if (!realtime && ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC))
16787             peer->defaddr.sin_port = htons(atoi(v->value));
16788          else
16789             peer->addr.sin_port = htons(atoi(v->value));
16790       } else if (!strcasecmp(v->name, "callingpres")) {
16791          peer->callingpres = ast_parse_caller_presentation(v->value);
16792          if (peer->callingpres == -1)
16793             peer->callingpres = atoi(v->value);
16794       } else if (!strcasecmp(v->name, "username")) {
16795          ast_copy_string(peer->username, v->value, sizeof(peer->username));
16796       } else if (!strcasecmp(v->name, "language")) {
16797          ast_copy_string(peer->language, v->value, sizeof(peer->language));
16798       } else if (!strcasecmp(v->name, "regexten")) {
16799          ast_copy_string(peer->regexten, v->value, sizeof(peer->regexten));
16800       } else if (!strcasecmp(v->name, "call-limit") || !strcasecmp(v->name, "incominglimit")) {
16801          peer->call_limit = atoi(v->value);
16802          if (peer->call_limit < 0)
16803             peer->call_limit = 0;
16804       } else if (!strcasecmp(v->name, "amaflags")) {
16805          format = ast_cdr_amaflags2int(v->value);
16806          if (format < 0) {
16807             ast_log(LOG_WARNING, "Invalid AMA Flags for peer: %s at line %d\n", v->value, v->lineno);
16808          } else {
16809             peer->amaflags = format;
16810          }
16811       } else if (!strcasecmp(v->name, "accountcode")) {
16812          ast_copy_string(peer->accountcode, v->value, sizeof(peer->accountcode));
16813       } else if (!strcasecmp(v->name, "mohinterpret")
16814          || !strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) {
16815          ast_copy_string(peer->mohinterpret, v->value, sizeof(peer->mohinterpret));
16816       } else if (!strcasecmp(v->name, "mohsuggest")) {
16817          ast_copy_string(peer->mohsuggest, v->value, sizeof(peer->mohsuggest));
16818       } else if (!strcasecmp(v->name, "mailbox")) {
16819          ast_copy_string(peer->mailbox, v->value, sizeof(peer->mailbox));
16820       } else if (!strcasecmp(v->name, "subscribemwi")) {
16821          ast_set2_flag(&peer->flags[1], ast_true(v->value), SIP_PAGE2_SUBSCRIBEMWIONLY);
16822       } else if (!strcasecmp(v->name, "vmexten")) {
16823          ast_copy_string(peer->vmexten, v->value, sizeof(peer->vmexten));
16824       } else if (!strcasecmp(v->name, "callgroup")) {
16825          peer->callgroup = ast_get_group(v->value);
16826       } else if (!strcasecmp(v->name, "allowtransfer")) {
16827          peer->allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED;
16828       } else if (!strcasecmp(v->name, "pickupgroup")) {
16829          peer->pickupgroup = ast_get_group(v->value);
16830       } else if (!strcasecmp(v->name, "allow")) {
16831          ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1);
16832       } else if (!strcasecmp(v->name, "disallow")) {
16833          ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0);
16834       } else if (!strcasecmp(v->name, "autoframing")) {
16835          peer->autoframing = ast_true(v->value);
16836       } else if (!strcasecmp(v->name, "rtptimeout")) {
16837          if ((sscanf(v->value, "%d", &peer->rtptimeout) != 1) || (peer->rtptimeout < 0)) {
16838             ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d.  Using default.\n", v->value, v->lineno);
16839             peer->rtptimeout = global_rtptimeout;
16840          }
16841       } else if (!strcasecmp(v->name, "rtpholdtimeout")) {
16842          if ((sscanf(v->value, "%d", &peer->rtpholdtimeout) != 1) || (peer->rtpholdtimeout < 0)) {
16843             ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d.  Using default.\n", v->value, v->lineno);
16844             peer->rtpholdtimeout = global_rtpholdtimeout;
16845          }
16846       } else if (!strcasecmp(v->name, "rtpkeepalive")) {
16847          if ((sscanf(v->value, "%d", &peer->rtpkeepalive) != 1) || (peer->rtpkeepalive < 0)) {
16848             ast_log(LOG_WARNING, "'%s' is not a valid RTP keepalive time at line %d.  Using default.\n", v->value, v->lineno);
16849             peer->rtpkeepalive = global_rtpkeepalive;
16850          }
16851       } else if (!strcasecmp(v->name, "setvar")) {
16852          /* Set peer channel variable */
16853          varname = ast_strdupa(v->value);
16854          if ((varval = strchr(varname, '='))) {
16855             *varval++ = '\0';
16856             if ((tmpvar = ast_variable_new(varname, varval))) {
16857                tmpvar->next = peer->chanvars;
16858                peer->chanvars = tmpvar;
16859             }
16860          }
16861       } else if (!strcasecmp(v->name, "qualify")) {
16862          if (!strcasecmp(v->value, "no")) {
16863             peer->maxms = 0;
16864          } else if (!strcasecmp(v->value, "yes")) {
16865             peer->maxms = default_qualify ? default_qualify : DEFAULT_MAXMS;
16866          } else if (sscanf(v->value, "%d", &peer->maxms) != 1) {
16867             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);
16868             peer->maxms = 0;
16869          }
16870       } else if (!strcasecmp(v->name, "maxcallbitrate")) {
16871          peer->maxcallbitrate = atoi(v->value);
16872          if (peer->maxcallbitrate < 0)
16873             peer->maxcallbitrate = default_maxcallbitrate;
16874       }
16875    }
16876    if (!ast_strlen_zero(fullcontact)) {
16877       ast_copy_string(peer->fullcontact, fullcontact, sizeof(peer->fullcontact));
16878    }
16879 
16880    if (!ast_test_flag(&global_flags[1], SIP_PAGE2_IGNOREREGEXPIRE) && ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC) && realtime) {
16881       time_t nowtime = time(NULL);
16882 
16883       if ((nowtime - regseconds) > 0) {
16884          destroy_association(peer);
16885          memset(&peer->addr, 0, sizeof(peer->addr));
16886          if (option_debug)
16887             ast_log(LOG_DEBUG, "Bah, we're expired (%d/%d/%d)!\n", (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
16888       }
16889    }
16890    ast_copy_flags(&peer->flags[0], &peerflags[0], mask[0].flags);
16891    ast_copy_flags(&peer->flags[1], &peerflags[1], mask[1].flags);
16892    if (ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE))
16893       global_allowsubscribe = TRUE; /* No global ban any more */
16894    if (!found && ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC) && !ast_test_flag(&peer->flags[0], SIP_REALTIME))
16895       reg_source_db(peer);
16896    ASTOBJ_UNMARK(peer);
16897    ast_free_ha(oldha);
16898    return peer;
16899 }

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

11603 {
11604    char a1[256];
11605    char a2[256];
11606    char a1_hash[256];
11607    char a2_hash[256];
11608    char resp[256];
11609    char resp_hash[256];
11610    char uri[256];
11611    char opaque[256] = "";
11612    char cnonce[80];
11613    const char *username;
11614    const char *secret;
11615    const char *md5secret;
11616    struct sip_auth *auth = NULL; /* Realm authentication */
11617 
11618    if (!ast_strlen_zero(p->domain))
11619       ast_copy_string(uri, p->domain, sizeof(uri));
11620    else if (!ast_strlen_zero(p->uri))
11621       ast_copy_string(uri, p->uri, sizeof(uri));
11622    else
11623       snprintf(uri, sizeof(uri), "sip:%s@%s",p->username, ast_inet_ntoa(p->sa.sin_addr));
11624 
11625    snprintf(cnonce, sizeof(cnonce), "%08lx", ast_random());
11626 
11627    /* Check if we have separate auth credentials */
11628    if ((auth = find_realm_authentication(authl, p->realm))) {
11629       ast_log(LOG_WARNING, "use realm [%s] from peer [%s][%s]\n",
11630          auth->username, p->peername, p->username);
11631       username = auth->username;
11632       secret = auth->secret;
11633       md5secret = auth->md5secret;
11634       if (sipdebug)
11635          ast_log(LOG_DEBUG,"Using realm %s authentication for call %s\n", p->realm, p->callid);
11636    } else {
11637       /* No authentication, use peer or register= config */
11638       username = p->authname;
11639       secret =  p->peersecret;
11640       md5secret = p->peermd5secret;
11641    }
11642    if (ast_strlen_zero(username))   /* We have no authentication */
11643       return -1;
11644 
11645    /* Calculate SIP digest response */
11646    snprintf(a1,sizeof(a1),"%s:%s:%s", username, p->realm, secret);
11647    snprintf(a2,sizeof(a2),"%s:%s", sip_methods[method].text, uri);
11648    if (!ast_strlen_zero(md5secret))
11649       ast_copy_string(a1_hash, md5secret, sizeof(a1_hash));
11650    else
11651       ast_md5_hash(a1_hash,a1);
11652    ast_md5_hash(a2_hash,a2);
11653 
11654    p->noncecount++;
11655    if (!ast_strlen_zero(p->qop))
11656       snprintf(resp,sizeof(resp),"%s:%s:%08x:%s:%s:%s", a1_hash, p->nonce, p->noncecount, cnonce, "auth", a2_hash);
11657    else
11658       snprintf(resp,sizeof(resp),"%s:%s:%s", a1_hash, p->nonce, a2_hash);
11659    ast_md5_hash(resp_hash, resp);
11660 
11661    /* only include the opaque string if it's set */
11662    if (!ast_strlen_zero(p->opaque)) {
11663      snprintf(opaque, sizeof(opaque), ", opaque=\"%s\"", p->opaque);
11664    }
11665 
11666    /* XXX We hard code our qop to "auth" for now.  XXX */
11667    if (!ast_strlen_zero(p->qop))
11668       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);
11669    else
11670       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);
11671 
11672    append_history(p, "AuthResp", "Auth response sent for %s in realm %s - nc %d", username, p->realm, p->noncecount);
11673 
11674    return 0;
11675 }

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

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

static void build_rpid ( struct sip_pvt p  )  [static]

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

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

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

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

16461 {
16462    struct sip_user *user;
16463    int format;
16464    struct ast_ha *oldha = NULL;
16465    char *varname = NULL, *varval = NULL;
16466    struct ast_variable *tmpvar = NULL;
16467    struct ast_flags userflags[2] = {{(0)}};
16468    struct ast_flags mask[2] = {{(0)}};
16469 
16470 
16471    if (!(user = ast_calloc(1, sizeof(*user))))
16472       return NULL;
16473       
16474    suserobjs++;
16475    ASTOBJ_INIT(user);
16476    ast_copy_string(user->name, name, sizeof(user->name));
16477    oldha = user->ha;
16478    user->ha = NULL;
16479    ast_copy_flags(&user->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY);
16480    ast_copy_flags(&user->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY);
16481    user->capability = global_capability;
16482    user->allowtransfer = global_allowtransfer;
16483    user->maxcallbitrate = default_maxcallbitrate;
16484    user->autoframing = global_autoframing;
16485    user->prefs = default_prefs;
16486    /* set default context */
16487    strcpy(user->context, default_context);
16488    strcpy(user->language, default_language);
16489    strcpy(user->mohinterpret, default_mohinterpret);
16490    strcpy(user->mohsuggest, default_mohsuggest);
16491    /* First we walk through the v parameters list and then the alt parameters list */
16492    for (; v || ((v = alt) && !(alt=NULL)); v = v->next) {
16493       if (handle_common_options(&userflags[0], &mask[0], v))
16494          continue;
16495 
16496       if (!strcasecmp(v->name, "context")) {
16497          ast_copy_string(user->context, v->value, sizeof(user->context));
16498       } else if (!strcasecmp(v->name, "subscribecontext")) {
16499          ast_copy_string(user->subscribecontext, v->value, sizeof(user->subscribecontext));
16500       } else if (!strcasecmp(v->name, "setvar")) {
16501          varname = ast_strdupa(v->value);
16502          if ((varval = strchr(varname,'='))) {
16503             *varval++ = '\0';
16504             if ((tmpvar = ast_variable_new(varname, varval))) {
16505                tmpvar->next = user->chanvars;
16506                user->chanvars = tmpvar;
16507             }
16508          }
16509       } else if (!strcasecmp(v->name, "permit") ||
16510                !strcasecmp(v->name, "deny")) {
16511          user->ha = ast_append_ha(v->name, v->value, user->ha);
16512       } else if (!strcasecmp(v->name, "allowtransfer")) {
16513          user->allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED;
16514       } else if (!strcasecmp(v->name, "secret")) {
16515          ast_copy_string(user->secret, v->value, sizeof(user->secret)); 
16516       } else if (!strcasecmp(v->name, "md5secret")) {
16517          ast_copy_string(user->md5secret, v->value, sizeof(user->md5secret));
16518       } else if (!strcasecmp(v->name, "callerid")) {
16519          ast_callerid_split(v->value, user->cid_name, sizeof(user->cid_name), user->cid_num, sizeof(user->cid_num));
16520       } else if (!strcasecmp(v->name, "fullname")) {
16521          ast_copy_string(user->cid_name, v->value, sizeof(user->cid_name));
16522       } else if (!strcasecmp(v->name, "cid_number")) {
16523          ast_copy_string(user->cid_num, v->value, sizeof(user->cid_num));
16524       } else if (!strcasecmp(v->name, "callgroup")) {
16525          user->callgroup = ast_get_group(v->value);
16526       } else if (!strcasecmp(v->name, "pickupgroup")) {
16527          user->pickupgroup = ast_get_group(v->value);
16528       } else if (!strcasecmp(v->name, "language")) {
16529          ast_copy_string(user->language, v->value, sizeof(user->language));
16530       } else if (!strcasecmp(v->name, "mohinterpret") 
16531          || !strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) {
16532          ast_copy_string(user->mohinterpret, v->value, sizeof(user->mohinterpret));
16533       } else if (!strcasecmp(v->name, "mohsuggest")) {
16534          ast_copy_string(user->mohsuggest, v->value, sizeof(user->mohsuggest));
16535       } else if (!strcasecmp(v->name, "accountcode")) {
16536          ast_copy_string(user->accountcode, v->value, sizeof(user->accountcode));
16537       } else if (!strcasecmp(v->name, "call-limit")) {
16538          user->call_limit = atoi(v->value);
16539          if (user->call_limit < 0)
16540             user->call_limit = 0;
16541       } else if (!strcasecmp(v->name, "amaflags")) {
16542          format = ast_cdr_amaflags2int(v->value);
16543          if (format < 0) {
16544             ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
16545          } else {
16546             user->amaflags = format;
16547          }
16548       } else if (!strcasecmp(v->name, "allow")) {
16549          ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1);
16550       } else if (!strcasecmp(v->name, "disallow")) {
16551          ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 0);
16552       } else if (!strcasecmp(v->name, "autoframing")) {
16553          user->autoframing = ast_true(v->value);
16554       } else if (!strcasecmp(v->name, "callingpres")) {
16555          user->callingpres = ast_parse_caller_presentation(v->value);
16556          if (user->callingpres == -1)
16557             user->callingpres = atoi(v->value);
16558       } else if (!strcasecmp(v->name, "maxcallbitrate")) {
16559          user->maxcallbitrate = atoi(v->value);
16560          if (user->maxcallbitrate < 0)
16561             user->maxcallbitrate = default_maxcallbitrate;
16562       }
16563       /* We can't just report unknown options here because this may be a
16564        * type=friend entry.  All user options are valid for a peer, but not
16565        * the other way around.  */
16566    }
16567    ast_copy_flags(&user->flags[0], &userflags[0], mask[0].flags);
16568    ast_copy_flags(&user->flags[1], &userflags[1], mask[1].flags);
16569    if (ast_test_flag(&user->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE))
16570       global_allowsubscribe = TRUE; /* No global ban any more */
16571    ast_free_ha(oldha);
16572    return user;
16573 }

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

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

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

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

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

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

static void check_pendings ( struct sip_pvt p  )  [static]

Check pending actions on SIP call.

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

12071 {
12072    if (ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) {
12073       /* if we can't BYE, then this is really a pending CANCEL */
12074       if (p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA)
12075          transmit_request(p, SIP_CANCEL, p->lastinvite, XMIT_RELIABLE, FALSE);
12076          /* Actually don't destroy us yet, wait for the 487 on our original 
12077             INVITE, but do set an autodestruct just in case we never get it. */
12078       else {
12079          /* We have a pending outbound invite, don't send someting
12080             new in-transaction */
12081          if (p->pendinginvite)
12082             return;
12083 
12084          /* Perhaps there is an SD change INVITE outstanding */
12085          transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, TRUE);
12086       }
12087       ast_clear_flag(&p->flags[0], SIP_PENDINGBYE);   
12088       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
12089    } else if (ast_test_flag(&p->flags[0], SIP_NEEDREINVITE)) {
12090       /* if we can't REINVITE, hold it for later */
12091       if (p->pendinginvite || p->invitestate == INV_CALLING || p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA || p->waitid > 0) {
12092          if (option_debug)
12093             ast_log(LOG_DEBUG, "NOT Sending pending reinvite (yet) on '%s'\n", p->callid);
12094       } else {
12095          if (option_debug)
12096             ast_log(LOG_DEBUG, "Sending pending reinvite on '%s'\n", p->callid);
12097          /* Didn't get to reinvite yet, so do it now */
12098          transmit_reinvite_with_sdp(p);
12099          ast_clear_flag(&p->flags[0], SIP_NEEDREINVITE); 
12100       }
12101    }
12102 }

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

16340 {
16341    struct domain *d;
16342    int result = 0;
16343 
16344    AST_LIST_LOCK(&domain_list);
16345    AST_LIST_TRAVERSE(&domain_list, d, list) {
16346       if (strcasecmp(d->domain, domain))
16347          continue;
16348 
16349       if (len && !ast_strlen_zero(d->context))
16350          ast_copy_string(context, d->context, len);
16351       
16352       result = 1;
16353       break;
16354    }
16355    AST_LIST_UNLOCK(&domain_list);
16356 
16357    return result;
16358 }

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

References check_user_full().

Referenced by handle_request_invite().

09707 {
09708    return check_user_full(p, req, sipmethod, uri, reliable, sin, NULL);
09709 }

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

09389 {
09390    struct sip_user *user = NULL;
09391    struct sip_peer *peer;
09392    char from[256], *c;
09393    char *of;
09394    char rpid_num[50];
09395    const char *rpid;
09396    enum check_auth_result res = AUTH_SUCCESSFUL;
09397    char *t;
09398    char calleridname[50];
09399    int debug=sip_debug_test_addr(sin);
09400    struct ast_variable *tmpvar = NULL, *v = NULL;
09401    char *uri2 = ast_strdupa(uri);
09402 
09403    /* Terminate URI */
09404    t = uri2;
09405    while (*t && *t > 32 && *t != ';')
09406       t++;
09407    *t = '\0';
09408    ast_copy_string(from, get_header(req, "From"), sizeof(from));  /* XXX bug in original code, overwrote string */
09409    if (pedanticsipchecking)
09410       ast_uri_decode(from);
09411    /* XXX here tries to map the username for invite things */
09412    memset(calleridname, 0, sizeof(calleridname));
09413    get_calleridname(from, calleridname, sizeof(calleridname));
09414    if (calleridname[0])
09415       ast_string_field_set(p, cid_name, calleridname);
09416 
09417    rpid = get_header(req, "Remote-Party-ID");
09418    memset(rpid_num, 0, sizeof(rpid_num));
09419    if (!ast_strlen_zero(rpid)) 
09420       p->callingpres = get_rpid_num(rpid, rpid_num, sizeof(rpid_num));
09421 
09422    of = get_in_brackets(from);
09423    if (ast_strlen_zero(p->exten)) {
09424       t = uri2;
09425       if (!strncasecmp(t, "sip:", 4))
09426          t+= 4;
09427       ast_string_field_set(p, exten, t);
09428       t = strchr(p->exten, '@');
09429       if (t)
09430          *t = '\0';
09431       if (ast_strlen_zero(p->our_contact))
09432          build_contact(p);
09433    }
09434    /* save the URI part of the From header */
09435    ast_string_field_set(p, from, of);
09436    if (strncasecmp(of, "sip:", 4)) {
09437       ast_log(LOG_NOTICE, "From address missing 'sip:', using it anyway\n");
09438    } else
09439       of += 4;
09440    /* Get just the username part */
09441    if ((c = strchr(of, '@'))) {
09442       char *tmp;
09443       *c = '\0';
09444       if ((c = strchr(of, ':')))
09445          *c = '\0';
09446       tmp = ast_strdupa(of);
09447       /* We need to be able to handle auth-headers looking like
09448          <sip:8164444422;phone-context=+1@1.2.3.4:5060;user=phone;tag=SDadkoa01-gK0c3bdb43>
09449       */
09450       tmp = strsep(&tmp, ";");
09451       if (ast_is_shrinkable_phonenumber(tmp))
09452          ast_shrink_phone_number(tmp);
09453       ast_string_field_set(p, cid_num, tmp);
09454    }
09455 
09456    if (!authpeer) /* If we are looking for a peer, don't check the user objects (or realtime) */
09457       user = find_user(of, 1);
09458 
09459    /* Find user based on user name in the from header */
09460    if (user && ast_apply_ha(user->ha, sin)) {
09461       ast_copy_flags(&p->flags[0], &user->flags[0], SIP_FLAGS_TO_COPY);
09462       ast_copy_flags(&p->flags[1], &user->flags[1], SIP_PAGE2_FLAGS_TO_COPY);
09463       /* copy channel vars */
09464       for (v = user->chanvars ; v ; v = v->next) {
09465          if ((tmpvar = ast_variable_new(v->name, v->value))) {
09466             tmpvar->next = p->chanvars; 
09467             p->chanvars = tmpvar;
09468          }
09469       }
09470       p->prefs = user->prefs;
09471       /* Set Frame packetization */
09472       if (p->rtp) {
09473          ast_rtp_codec_setpref(p->rtp, &p->prefs);
09474          p->autoframing = user->autoframing;
09475       }
09476       /* replace callerid if rpid found, and not restricted */
09477       if (!ast_strlen_zero(rpid_num) && ast_test_flag(&p->flags[0], SIP_TRUSTRPID)) {
09478          char *tmp;
09479          if (*calleridname)
09480             ast_string_field_set(p, cid_name, calleridname);
09481          tmp = ast_strdupa(rpid_num);
09482          if (ast_is_shrinkable_phonenumber(tmp))
09483             ast_shrink_phone_number(tmp);
09484          ast_string_field_set(p, cid_num, tmp);
09485       }
09486       
09487       do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT_ROUTE) );
09488 
09489       if (!(res = check_auth(p, req, user->name, user->secret, user->md5secret, sipmethod, uri2, reliable, ast_test_flag(req, SIP_PKT_IGNORE)))) {
09490          if (sip_cancel_destroy(p))
09491             ast_log(LOG_WARNING, "Unable to cancel SIP destruction.  Expect bad things.\n");
09492          ast_copy_flags(&p->flags[0], &user->flags[0], SIP_FLAGS_TO_COPY);
09493          ast_copy_flags(&p->flags[1], &user->flags[1], SIP_PAGE2_FLAGS_TO_COPY);
09494          /* Copy SIP extensions profile from INVITE */
09495          if (p->sipoptions)
09496             user->sipoptions = p->sipoptions;
09497 
09498          /* If we have a call limit, set flag */
09499          if (user->call_limit)
09500             ast_set_flag(&p->flags[0], SIP_CALL_LIMIT);
09501          if (!ast_strlen_zero(user->context))
09502             ast_string_field_set(p, context, user->context);
09503          if (!ast_strlen_zero(user->cid_num)) {
09504             char *tmp = ast_strdupa(user->cid_num);
09505             if (ast_is_shrinkable_phonenumber(tmp))
09506                ast_shrink_phone_number(tmp);
09507             ast_string_field_set(p, cid_num, tmp);
09508          }
09509          if (!ast_strlen_zero(user->cid_name))
09510             ast_string_field_set(p, cid_name, user->cid_name);
09511          ast_string_field_set(p, username, user->name);
09512          ast_string_field_set(p, peername, user->name);
09513          ast_string_field_set(p, peersecret, user->secret);
09514          ast_string_field_set(p, peermd5secret, user->md5secret);
09515          ast_string_field_set(p, subscribecontext, user->subscribecontext);
09516          ast_string_field_set(p, accountcode, user->accountcode);
09517          ast_string_field_set(p, language, user->language);
09518          ast_string_field_set(p, mohsuggest, user->mohsuggest);
09519          ast_string_field_set(p, mohinterpret, user->mohinterpret);
09520          p->allowtransfer = user->allowtransfer;
09521          p->amaflags = user->amaflags;
09522          p->callgroup = user->callgroup;
09523          p->pickupgroup = user->pickupgroup;
09524          if (user->callingpres)  /* User callingpres setting will override RPID header */
09525             p->callingpres = user->callingpres;
09526          
09527          /* Set default codec settings for this call */
09528          p->capability = user->capability;      /* User codec choice */
09529          p->jointcapability = user->capability;    /* Our codecs */
09530          if (p->peercapability)           /* AND with peer's codecs */
09531             p->jointcapability &= p->peercapability;
09532          if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) ||
09533              (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO))
09534             p->noncodeccapability |= AST_RTP_DTMF;
09535          else
09536             p->noncodeccapability &= ~AST_RTP_DTMF;
09537          p->jointnoncodeccapability = p->noncodeccapability;
09538          if (p->t38.peercapability)
09539             p->t38.jointcapability &= p->t38.peercapability;
09540          p->maxcallbitrate = user->maxcallbitrate;
09541          /* If we do not support video, remove video from call structure */
09542          if ((!ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) || !(p->capability & AST_FORMAT_VIDEO_MASK)) && p->vrtp) {
09543             ast_rtp_destroy(p->vrtp);
09544             p->vrtp = NULL;
09545          }
09546       }
09547       if (user && debug)
09548          ast_verbose("Found user '%s'\n", user->name);
09549    } else {
09550       if (user) {
09551          if (!authpeer && debug)
09552             ast_verbose("Found user '%s', but fails host access\n", user->name);
09553          ASTOBJ_UNREF(user,sip_destroy_user);
09554       }
09555       user = NULL;
09556    }
09557 
09558    if (!user) {
09559       /* If we didn't find a user match, check for peers */
09560       if (sipmethod == SIP_SUBSCRIBE)
09561          /* For subscribes, match on peer name only */
09562          peer = find_peer(of, NULL, 1);
09563       else
09564          /* Look for peer based on the IP address we received data from */
09565          /* If peer is registered from this IP address or have this as a default
09566             IP address, this call is from the peer 
09567          */
09568          peer = find_peer(NULL, &p->recv, 1);
09569 
09570       if (peer) {
09571          /* Set Frame packetization */
09572          if (p->rtp) {
09573             ast_rtp_codec_setpref(p->rtp, &peer->prefs);
09574             p->autoframing = peer->autoframing;
09575          }
09576          if (debug)
09577             ast_verbose("Found peer '%s'\n", peer->name);
09578 
09579          /* Take the peer */
09580          ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY);
09581          ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY);
09582 
09583          /* Copy SIP extensions profile to peer */
09584          if (p->sipoptions)
09585             peer->sipoptions = p->sipoptions;
09586 
09587          /* replace callerid if rpid found, and not restricted */
09588          if (!ast_strlen_zero(rpid_num) && ast_test_flag(&p->flags[0], SIP_TRUSTRPID)) {
09589             char *tmp = ast_strdupa(rpid_num);
09590             if (*calleridname)
09591                ast_string_field_set(p, cid_name, calleridname);
09592             if (ast_is_shrinkable_phonenumber(tmp))
09593                ast_shrink_phone_number(tmp);
09594             ast_string_field_set(p, cid_num, tmp);
09595          }
09596          do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT_ROUTE));
09597 
09598          ast_string_field_set(p, peersecret, peer->secret);
09599          ast_string_field_set(p, peermd5secret, peer->md5secret);
09600          ast_string_field_set(p, subscribecontext, peer->subscribecontext);
09601          ast_string_field_set(p, mohinterpret, peer->mohinterpret);
09602          ast_string_field_set(p, mohsuggest, peer->mohsuggest);
09603          if (peer->callingpres)  /* Peer calling pres setting will override RPID */
09604             p->callingpres = peer->callingpres;
09605          if (peer->maxms && peer->lastms)
09606             p->timer_t1 = peer->lastms < global_t1min ? global_t1min : peer->lastms;
09607          if (ast_test_flag(&peer->flags[0], SIP_INSECURE_INVITE)) {
09608             /* Pretend there is no required authentication */
09609             ast_string_field_free(p, peersecret);
09610             ast_string_field_free(p, peermd5secret);
09611          }
09612          if (!(res = check_auth(p, req, peer->name, p->peersecret, p->peermd5secret, sipmethod, uri2, reliable, ast_test_flag(req, SIP_PKT_IGNORE)))) {
09613             ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY);
09614             ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY);
09615             /* If we have a call limit, set flag */
09616             if (peer->call_limit)
09617                ast_set_flag(&p->flags[0], SIP_CALL_LIMIT);
09618             ast_string_field_set(p, peername, peer->name);
09619             ast_string_field_set(p, authname, peer->name);
09620 
09621             /* copy channel vars */
09622             for (v = peer->chanvars ; v ; v = v->next) {
09623                if ((tmpvar = ast_variable_new(v->name, v->value))) {
09624                   tmpvar->next = p->chanvars; 
09625                   p->chanvars = tmpvar;
09626                }
09627             }
09628             if (authpeer) {
09629                (*authpeer) = ASTOBJ_REF(peer);  /* Add a ref to the object here, to keep it in memory a bit longer if it is realtime */
09630             }
09631 
09632             if (!ast_strlen_zero(peer->username)) {
09633                ast_string_field_set(p, username, peer->username);
09634                /* Use the default username for authentication on outbound calls */
09635                /* XXX this takes the name from the caller... can we override ? */
09636                ast_string_field_set(p, authname, peer->username);
09637             }
09638             if (!ast_strlen_zero(peer->cid_num)) {
09639                char *tmp = ast_strdupa(peer->cid_num);
09640                if (ast_is_shrinkable_phonenumber(tmp))
09641                   ast_shrink_phone_number(tmp);
09642                ast_string_field_set(p, cid_num, tmp);
09643             }
09644             if (!ast_strlen_zero(peer->cid_name)) 
09645                ast_string_field_set(p, cid_name, peer->cid_name);
09646             ast_string_field_set(p, fullcontact, peer->fullcontact);
09647             if (!ast_strlen_zero(peer->context))
09648                ast_string_field_set(p, context, peer->context);
09649             ast_string_field_set(p, peersecret, peer->secret);
09650             ast_string_field_set(p, peermd5secret, peer->md5secret);
09651             ast_string_field_set(p, language, peer->language);
09652             ast_string_field_set(p, accountcode, peer->accountcode);
09653             p->amaflags = peer->amaflags;
09654             p->callgroup = peer->callgroup;
09655             p->pickupgroup = peer->pickupgroup;
09656             p->capability = peer->capability;
09657             p->prefs = peer->prefs;
09658             p->jointcapability = peer->capability;
09659             if (p->peercapability)
09660                p->jointcapability &= p->peercapability;
09661             p->maxcallbitrate = peer->maxcallbitrate;
09662             if ((!ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) || !(p->capability & AST_FORMAT_VIDEO_MASK)) && p->vrtp) {
09663                ast_rtp_destroy(p->vrtp);
09664                p->vrtp = NULL;
09665             }
09666             if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) ||
09667                 (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO))
09668                p->noncodeccapability |= AST_RTP_DTMF;
09669             else
09670                p->noncodeccapability &= ~AST_RTP_DTMF;
09671             p->jointnoncodeccapability = p->noncodeccapability;
09672             if (p->t38.peercapability)
09673                p->t38.jointcapability &= p->t38.peercapability;
09674          }
09675          ASTOBJ_UNREF(peer, sip_destroy_peer);
09676       } else { 
09677          if (debug)
09678             ast_verbose("Found no matching peer or user for '%s:%d'\n", ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port));
09679 
09680          /* do we allow guests? */
09681          if (!global_allowguest) {
09682             if (global_alwaysauthreject)
09683                res = AUTH_FAKE_AUTH; /* reject with fake authorization request */
09684             else
09685                res = AUTH_SECRET_FAILED; /* we don't want any guests, authentication will fail */
09686          } else if (!ast_strlen_zero(rpid_num) && ast_test_flag(&p->flags[0], SIP_TRUSTRPID)) {
09687             char *tmp = ast_strdupa(rpid_num);
09688             if (*calleridname)
09689                ast_string_field_set(p, cid_name, calleridname);
09690             if (ast_is_shrinkable_phonenumber(tmp))
09691                ast_shrink_phone_number(tmp);
09692             ast_string_field_set(p, cid_num, tmp);
09693                         }
09694       }
09695 
09696    }
09697 
09698    if (user)
09699       ASTOBJ_UNREF(user, sip_destroy_user);
09700    return res;
09701 }

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

09255 {
09256    char via[512];
09257    char *c, *pt;
09258    struct hostent *hp;
09259    struct ast_hostent ahp;
09260 
09261    ast_copy_string(via, get_header(req, "Via"), sizeof(via));
09262 
09263    /* Work on the leftmost value of the topmost Via header */
09264    c = strchr(via, ',');
09265    if (c)
09266       *c = '\0';
09267 
09268    /* Check for rport */
09269    c = strstr(via, ";rport");
09270    if (c && (c[6] != '=')) /* rport query, not answer */
09271       ast_set_flag(&p->flags[0], SIP_NAT_ROUTE);
09272 
09273    c = strchr(via, ';');
09274    if (c) 
09275       *c = '\0';
09276 
09277    c = strchr(via, ' ');
09278    if (c) {
09279       *c = '\0';
09280       c = ast_skip_blanks(c+1);
09281       if (strcasecmp(via, "SIP/2.0/UDP")) {
09282          ast_log(LOG_WARNING, "Don't know how to respond via '%s'\n", via);
09283          return;
09284       }
09285       pt = strchr(c, ':');
09286       if (pt)
09287          *pt++ = '\0';  /* remember port pointer */
09288       hp = ast_gethostbyname(c, &ahp);
09289       if (!hp) {
09290          ast_log(LOG_WARNING, "'%s' is not a valid host\n", c);
09291          return;
09292       }
09293       memset(&p->sa, 0, sizeof(p->sa));
09294       p->sa.sin_family = AF_INET;
09295       memcpy(&p->sa.sin_addr, hp->h_addr, sizeof(p->sa.sin_addr));
09296       p->sa.sin_port = htons(pt ? atoi(pt) : STANDARD_SIP_PORT);
09297 
09298       if (sip_debug_test_pvt(p)) {
09299          const struct sockaddr_in *dst = sip_real_dst(p);
09300          ast_verbose("Sending to %s : %d (%s)\n", ast_inet_ntoa(dst->sin_addr), ntohs(dst->sin_port), sip_nat_mode(p));
09301       }
09302    }
09303 }

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

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

Referenced by reload_config().

10151 {
10152    char *oldcontext, *newcontext, *stalecontext, *stringp, newlist[AST_MAX_CONTEXT];
10153 
10154    while ((oldcontext = strsep(&old, "&"))) {
10155       stalecontext = '\0';
10156       ast_copy_string(newlist, new, sizeof(newlist));
10157       stringp = newlist;
10158       while ((newcontext = strsep(&stringp, "&"))) {
10159          if (strcmp(newcontext, oldcontext) == 0) {
10160             /* This is not the context you're looking for */
10161             stalecontext = '\0';
10162             break;
10163          } else if (strcmp(newcontext, oldcontext)) {
10164             stalecontext = oldcontext;
10165          }
10166          
10167       }
10168       if (stalecontext)
10169          ast_context_destroy(ast_context_find(stalecontext), "SIP");
10170    }
10171 }

static int clear_realm_authentication ( struct sip_auth authlist  )  [static]

Clear realm authentication list (at reload).

Definition at line 16432 of file chan_sip.c.

References free, and sip_auth::next.

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

16433 {
16434    struct sip_auth *a = authlist;
16435    struct sip_auth *b;
16436 
16437    while (a) {
16438       b = a;
16439       a = a->next;
16440       free(b);
16441    }
16442 
16443    return 1;
16444 }

static void clear_sip_domains ( void   )  [static]

Clear our domain list (at reload).

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

16362 {
16363    struct domain *d;
16364 
16365    AST_LIST_LOCK(&domain_list);
16366    while ((d = AST_LIST_REMOVE_HEAD(&domain_list, list)))
16367       free(d);
16368    AST_LIST_UNLOCK(&domain_list);
16369 }

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

References complete_sip_peer().

10963 {
10964    if (pos == 3)
10965       return complete_sip_peer(word, state, 0);
10966 
10967    return NULL;
10968 }

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

Do completion on peer name.

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

10937 {
10938    char *result = NULL;
10939    int wordlen = strlen(word);
10940    int which = 0;
10941 
10942    ASTOBJ_CONTAINER_TRAVERSE(&peerl, !result, do {
10943       /* locking of the object is not required because only the name and flags are being compared */
10944       if (!strncasecmp(word, iterator->name, wordlen) &&
10945             (!flags2 || ast_test_flag(&iterator->flags[1], flags2)) &&
10946             ++which > state)
10947          result = ast_strdup(iterator->name);
10948    } while(0) );
10949    return result;
10950 }

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

References complete_sip_peer(), and SIP_PAGE2_RTCACHEFRIENDS.

11031 {
11032    if (pos == 4)
11033       return complete_sip_peer(word, state, SIP_PAGE2_RTCACHEFRIENDS);
11034    return NULL;
11035 }

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

References complete_sip_user(), and SIP_PAGE2_RTCACHEFRIENDS.

11039 {
11040    if (pos == 4)
11041       return complete_sip_user(word, state, SIP_PAGE2_RTCACHEFRIENDS);
11042 
11043    return NULL;
11044 }

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

References complete_sip_peer().

10954 {
10955    if (pos == 3)
10956       return complete_sip_peer(word, state, 0);
10957 
10958    return NULL;
10959 }

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

References complete_sip_user().

10992 {
10993    if (pos == 3)
10994       return complete_sip_user(word, state, 0);
10995 
10996    return NULL;
10997 }

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

Do completion on user name.

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

10972 {
10973    char *result = NULL;
10974    int wordlen = strlen(word);
10975    int which = 0;
10976 
10977    ASTOBJ_CONTAINER_TRAVERSE(&userl, !result, do {
10978       /* locking of the object is not required because only the name and flags are being compared */
10979       if (!strncasecmp(word, iterator->name, wordlen)) {
10980          if (flags2 && !ast_test_flag(&iterator->flags[1], flags2))
10981             continue;
10982          if (++which > state) {
10983             result = ast_strdup(iterator->name);
10984          }
10985       }
10986    } while(0) );
10987    return result;
10988 }

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

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

10914 {
10915    int which=0;
10916    struct sip_pvt *cur;
10917    char *c = NULL;
10918    int wordlen = strlen(word);
10919 
10920    if (pos != 3) {
10921       return NULL;
10922    }
10923 
10924    ast_mutex_lock(&iflock);
10925    for (cur = iflist; cur; cur = cur->next) {
10926       if (!strncasecmp(word, cur->callid, wordlen) && ++which > state) {
10927          c = ast_strdup(cur->callid);
10928          break;
10929       }
10930    }
10931    ast_mutex_unlock(&iflock);
10932    return c;
10933 }

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

Support routine for 'sip notify' CLI.

Definition at line 11000 of file chan_sip.c.

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

11001 {
11002    char *c = NULL;
11003 
11004    if (pos == 2) {
11005       int which = 0;
11006       char *cat = NULL;
11007       int wordlen = strlen(word);
11008 
11009       /* do completion for notify type */
11010 
11011       if (!notify_types)
11012          return NULL;
11013       
11014       while ( (cat = ast_category_browse(notify_types, cat)) ) {
11015          if (!strncasecmp(word, cat, wordlen) && ++which > state) {
11016             c = ast_strdup(cat);
11017             break;
11018          }
11019       }
11020       return c;
11021    }
11022 
11023    if (pos > 2)
11024       return complete_sip_peer(word, state, 0);
11025 
11026    return NULL;
11027 }

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

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

Referenced by respprep().

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

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

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

Referenced by reqprep(), and respprep().

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

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

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

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

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

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

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

static int determine_firstline_parts ( struct sip_request req  )  [static]

Parse first line of incoming SIP request.

Definition at line 6764 of file chan_sip.c.

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

Referenced by parse_request().

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

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

15651 {
15652    int res;
15653    struct sip_pvt *sip;
15654    struct sip_peer *peer = NULL;
15655    time_t t;
15656    int fastrestart = FALSE;
15657    int lastpeernum = -1;
15658    int curpeernum;
15659    int reloading;
15660 
15661    /* Add an I/O event to our SIP UDP socket */
15662    if (sipsock > -1) 
15663       sipsock_read_id = ast_io_add(io, sipsock, sipsock_read, AST_IO_IN, NULL);
15664    
15665    /* From here on out, we die whenever asked */
15666    for(;;) {
15667       /* Check for a reload request */
15668       ast_mutex_lock(&sip_reload_lock);
15669       reloading = sip_reloading;
15670       sip_reloading = FALSE;
15671       ast_mutex_unlock(&sip_reload_lock);
15672       if (reloading) {
15673          if (option_verbose > 0)
15674             ast_verbose(VERBOSE_PREFIX_1 "Reloading SIP\n");
15675          sip_do_reload(sip_reloadreason);
15676 
15677          /* Change the I/O fd of our UDP socket */
15678          if (sipsock > -1) {
15679             if (sipsock_read_id)
15680                sipsock_read_id = ast_io_change(io, sipsock_read_id, sipsock, NULL, 0, NULL);
15681             else
15682                sipsock_read_id = ast_io_add(io, sipsock, sipsock_read, AST_IO_IN, NULL);
15683          } else if (sipsock_read_id) {
15684             ast_io_remove(io, sipsock_read_id);
15685             sipsock_read_id = NULL;
15686          }
15687       }
15688 restartsearch:    
15689       /* Check for interfaces needing to be killed */
15690       ast_mutex_lock(&iflock);
15691       t = time(NULL);
15692       /* don't scan the interface list if it hasn't been a reasonable period
15693          of time since the last time we did it (when MWI is being sent, we can
15694          get back to this point every millisecond or less)
15695       */
15696       for (sip = iflist; !fastrestart && sip; sip = sip->next) {
15697          /*! \note If we can't get a lock on an interface, skip it and come
15698           * back later. Note that there is the possibility of a deadlock with
15699           * sip_hangup otherwise, because sip_hangup is called with the channel
15700           * locked first, and the iface lock is attempted second.
15701           */
15702          if (ast_mutex_trylock(&sip->lock))
15703             continue;
15704 
15705          /* Check RTP timeouts and kill calls if we have a timeout set and do not get RTP */
15706          if (sip->rtp && sip->owner &&
15707              (sip->owner->_state == AST_STATE_UP) &&
15708              !sip->redirip.sin_addr.s_addr &&
15709              sip->t38.state != T38_ENABLED) {
15710             if (sip->lastrtptx &&
15711                 ast_rtp_get_rtpkeepalive(sip->rtp) &&
15712                 (t > sip->lastrtptx + ast_rtp_get_rtpkeepalive(sip->rtp))) {
15713                /* Need to send an empty RTP packet */
15714                sip->lastrtptx = time(NULL);
15715                ast_rtp_sendcng(sip->rtp, 0);
15716             }
15717             if (sip->lastrtprx &&
15718                (ast_rtp_get_rtptimeout(sip->rtp) || ast_rtp_get_rtpholdtimeout(sip->rtp)) &&
15719                 (t > sip->lastrtprx + ast_rtp_get_rtptimeout(sip->rtp))) {
15720                /* Might be a timeout now -- see if we're on hold */
15721                struct sockaddr_in sin;
15722                ast_rtp_get_peer(sip->rtp, &sin);
15723                if (sin.sin_addr.s_addr || 
15724                    (ast_rtp_get_rtpholdtimeout(sip->rtp) &&
15725                     (t > sip->lastrtprx + ast_rtp_get_rtpholdtimeout(sip->rtp)))) {
15726                   /* Needs a hangup */
15727                   if (ast_rtp_get_rtptimeout(sip->rtp)) {
15728                      while (sip->owner && ast_channel_trylock(sip->owner)) {
15729                         DEADLOCK_AVOIDANCE(&sip->lock);
15730                      }
15731                      if (sip->owner) {
15732                         ast_log(LOG_NOTICE,
15733                            "Disconnecting call '%s' for lack of RTP activity in %ld seconds\n",
15734                            sip->owner->name,
15735                            (long) (t - sip->lastrtprx));
15736                         /* Issue a softhangup */
15737                         ast_softhangup_nolock(sip->owner, AST_SOFTHANGUP_DEV);
15738                         ast_channel_unlock(sip->owner);
15739                         /* forget the timeouts for this call, since a hangup
15740                            has already been requested and we don't want to
15741                            repeatedly request hangups
15742                         */
15743                         ast_rtp_set_rtptimeout(sip->rtp, 0);
15744                         ast_rtp_set_rtpholdtimeout(sip->rtp, 0);
15745                         if (sip->vrtp) {
15746                            ast_rtp_set_rtptimeout(sip->vrtp, 0);
15747                            ast_rtp_set_rtpholdtimeout(sip->vrtp, 0);
15748                         }
15749                      }
15750                   }
15751                }
15752             }
15753          }
15754          /* If we have sessions that needs to be destroyed, do it now */
15755          if (ast_test_flag(&sip->flags[0], SIP_NEEDDESTROY) && !sip->packets &&
15756              !sip->owner) {
15757             ast_mutex_unlock(&sip->lock);
15758             __sip_destroy(sip, 1);
15759             ast_mutex_unlock(&iflock);
15760             usleep(1);
15761             goto restartsearch;
15762          }
15763          ast_mutex_unlock(&sip->lock);
15764       }
15765       ast_mutex_unlock(&iflock);
15766 
15767       pthread_testcancel();
15768       /* Wait for sched or io */
15769       res = ast_sched_wait(sched);
15770       if ((res < 0) || (res > 1000))
15771          res = 1000;
15772       /* If we might need to send more mailboxes, don't wait long at all.*/
15773       if (fastrestart)
15774          res = 1;
15775       res = ast_io_wait(io, res);
15776       if (option_debug && res > 20)
15777          ast_log(LOG_DEBUG, "chan_sip: ast_io_wait ran %d all at once\n", res);
15778       ast_mutex_lock(&monlock);
15779       if (res >= 0)  {
15780          res = ast_sched_runq(sched);
15781          if (option_debug && res >= 20)
15782             ast_log(LOG_DEBUG, "chan_sip: ast_sched_runq ran %d all at once\n", res);
15783       }
15784 
15785       /* Send MWI notifications to peers - static and cached realtime peers */
15786       t = time(NULL);
15787       fastrestart = FALSE;
15788       curpeernum = 0;
15789       peer = NULL;
15790       /* Find next peer that needs mwi */
15791       ASTOBJ_CONTAINER_TRAVERSE(&peerl, !peer, do {
15792          if ((curpeernum > lastpeernum) && does_peer_need_mwi(iterator)) {
15793             fastrestart = TRUE;
15794             lastpeernum = curpeernum;
15795             peer = ASTOBJ_REF(iterator);
15796          };
15797          curpeernum++;
15798       } while (0)
15799       );
15800       /* Send MWI to the peer */
15801       if (peer) {
15802          ASTOBJ_WRLOCK(peer);
15803          sip_send_mwi_to_peer(peer);
15804          ASTOBJ_UNLOCK(peer);
15805          ASTOBJ_UNREF(peer,sip_destroy_peer);
15806       } else {
15807          /* Reset where we come from */
15808          lastpeernum = -1;
15809       }
15810       ast_mutex_unlock(&monlock);
15811    }
15812    /* Never reached */
15813    return NULL;
15814    
15815 }

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

11504 {
11505    char digest[1024];
11506 
11507    if (!p->options && !(p->options = ast_calloc(1, sizeof(*p->options))))
11508       return -2;
11509 
11510    p->authtries++;
11511    if (option_debug > 1)
11512       ast_log(LOG_DEBUG, "Auth attempt %d on %s\n", p->authtries, sip_methods[sipmethod].text);
11513    memset(digest, 0, sizeof(digest));
11514    if (reply_digest(p, req, header, sipmethod, digest, sizeof(digest) )) {
11515       /* No way to authenticate */
11516       return -1;
11517    }
11518    /* Now we have a reply digest */
11519    p->options->auth = digest;
11520    p->options->authheader = respheader;
11521    return transmit_invite(p, sipmethod, sipmethod == SIP_INVITE, init); 
11522 }

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

11483 {
11484    char digest[1024];
11485    p->authtries++;
11486    memset(digest,0,sizeof(digest));
11487    if (reply_digest(p, req, header, SIP_REGISTER, digest, sizeof(digest))) {
11488       /* There's nothing to use for authentication */
11489       /* No digest challenge in request */
11490       if (sip_debug_test_pvt(p) && p->registry)
11491          ast_verbose("No authentication challenge, sending blank registration to domain/host name %s\n", p->registry->hostname);
11492          /* No old challenge */
11493       return -1;
11494    }
11495    if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY))
11496       append_history(p, "RegistryAuth", "Try: %d", p->authtries);
11497    if (sip_debug_test_pvt(p) && p->registry)
11498       ast_verbose("Responding to challenge, registration to domain/host name %s\n", p->registry->hostname);
11499    return transmit_register(p->registry, SIP_REGISTER, digest, respheader); 
11500 }

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

15630 {
15631    time_t t = time(NULL);
15632 
15633    if (ast_test_flag(&peer->flags[1], SIP_PAGE2_SUBSCRIBEMWIONLY) &&
15634        !peer->mwipvt) { /* We don't have a subscription */
15635       peer->lastmsgcheck = t; /* Reset timer */
15636       return FALSE;
15637    }
15638 
15639    if (!ast_strlen_zero(peer->mailbox) && (t - peer->lastmsgcheck) > global_mwitime)
15640       return TRUE;
15641 
15642    return FALSE;
15643 }

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

Print domain mode to cli.

Definition at line 10339 of file chan_sip.c.

References SIP_DOMAIN_AUTO, and SIP_DOMAIN_CONFIG.

Referenced by sip_show_domains().

10340 {
10341    switch (mode) {
10342    case SIP_DOMAIN_AUTO:
10343       return "[Automatic]";
10344    case SIP_DOMAIN_CONFIG:
10345       return "[Configured]";
10346    }
10347 
10348    return "";
10349 }

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

Convert DTMF mode to printable string.

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

10120 {
10121    switch (mode) {
10122    case SIP_DTMF_RFC2833:
10123       return "rfc2833";
10124    case SIP_DTMF_INFO:
10125       return "info";
10126    case SIP_DTMF_INBAND:
10127       return "inband";
10128    case SIP_DTMF_AUTO:
10129       return "auto";
10130    }
10131    return "<error>";
10132 }

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

Expire registration of SIP peer.

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

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

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

Check Contact: URI of SIP message.

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

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

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 
04636 
04637       if (found) {
04638          /* Found the call */
04639          ast_mutex_lock(&p->lock);
04640          ast_mutex_unlock(&iflock);
04641          return p;
04642       }
04643    }
04644    ast_mutex_unlock(&iflock);
04645 
04646    /* See if the method is capable of creating a dialog */
04647    if (sip_methods[intended_method].can_create == CAN_CREATE_DIALOG) {
04648       if (intended_method == SIP_REFER) {
04649          /* We do support REFER, but not outside of a dialog yet */
04650          transmit_response_using_temp(callid, sin, 1, intended_method, req, "603 Declined (no dialog)");
04651       } else if (intended_method == SIP_NOTIFY) {
04652          /* We do not support out-of-dialog NOTIFY either,
04653             like voicemail notification, so cancel that early */
04654          transmit_response_using_temp(callid, sin, 1, intended_method, req, "489 Bad event");
04655       } else {
04656          /* Ok, time to create a new SIP dialog object, a pvt */
04657          if ((p = sip_alloc(callid, sin, 1, intended_method)))  {
04658             /* Ok, we've created a dialog, let's go and process it */
04659             ast_mutex_lock(&p->lock);
04660          } else {
04661             /* We have a memory or file/socket error (can't allocate RTP sockets or something) so we're not
04662                getting a dialog from sip_alloc. 
04663    
04664                Without a dialog we can't retransmit and handle ACKs and all that, but at least
04665                send an error message.
04666    
04667                Sorry, we apologize for the inconvienience
04668             */
04669             transmit_response_using_temp(callid, sin, 1, intended_method, req, "500 Server internal error");
04670             if (option_debug > 3)
04671                ast_log(LOG_DEBUG, "Failed allocating SIP dialog, sending 500 Server internal error and giving up\n");
04672          }
04673       }
04674       return p;
04675    } else if( sip_methods[intended_method].can_create == CAN_CREATE_DIALOG_UNSUPPORTED_METHOD) {
04676       /* A method we do not support, let's take it on the volley */
04677       transmit_response_using_temp(callid, sin, 1, intended_method, req, "501 Method Not Implemented");
04678    } else if (intended_method != SIP_RESPONSE && intended_method != SIP_ACK) {
04679       /* This is a request outside of a dialog that we don't know about 
04680          ...never reply to an ACK!
04681       */
04682       transmit_response_using_temp(callid, sin, 1, intended_method, req, "481 Call leg/transaction does not exist");
04683    }
04684    /* We do not respond to responses for dialogs that we don't know about, we just drop
04685       the session quickly */
04686 
04687    return p;
04688 }

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

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

Referenced by build_reply_digest().

16448 {
16449    struct sip_auth *a;
16450 
16451    for (a = authlist; a; a = a->next) {
16452       if (!strcasecmp(a->realm, realm))
16453          break;
16454    }
16455 
16456    return a;
16457 }

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

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

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

References subscription_types, and type.

Referenced by transmit_state_notify().

10828 {
10829    int i;
10830 
10831    for (i = 1; (i < (sizeof(subscription_types) / sizeof(subscription_types[0]))); i++) {
10832       if (subscription_types[i].type == subtype) {
10833          return &subscription_types[i];
10834       }
10835    }
10836    return &subscription_types[0];
10837 }

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

References free, and sip_route::next.

Referenced by __sip_destroy(), and build_route().

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

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

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

11837 {
11838    if (ast_strlen_zero(data)) {
11839       ast_log(LOG_WARNING, "CHECKSIPDOMAIN requires an argument - A domain name\n");
11840       return -1;
11841    }
11842    if (check_sip_domain(data, NULL, 0))
11843       ast_copy_string(buf, data, len);
11844    else
11845       buf[0] = '\0';
11846    return 0;
11847 }

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

11773 {
11774    struct sip_pvt *p;
11775    const char *content = NULL;
11776    AST_DECLARE_APP_ARGS(args,
11777       AST_APP_ARG(header);
11778       AST_APP_ARG(number);
11779    );
11780    int i, number, start = 0;
11781 
11782    if (ast_strlen_zero(data)) {
11783       ast_log(LOG_WARNING, "This function requires a header name.\n");
11784       return -1;
11785    }
11786 
11787    ast_channel_lock(chan);
11788    if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) {
11789       ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n");
11790       ast_channel_unlock(chan);
11791       return -1;
11792    }
11793 
11794    AST_STANDARD_APP_ARGS(args, data);
11795    if (!args.number) {
11796       number = 1;
11797    } else {
11798       sscanf(args.number, "%d", &number);
11799       if (number < 1)
11800          number = 1;
11801    }
11802 
11803    p = chan->tech_pvt;
11804 
11805    /* If there is no private structure, this channel is no longer alive */
11806    if (!p) {
11807       ast_channel_unlock(chan);
11808       return -1;
11809    }
11810 
11811    for (i = 0; i < number; i++)
11812       content = __get_header(&p->initreq, args.header, &start);
11813 
11814    if (ast_strlen_zero(content)) {
11815       ast_channel_unlock(chan);
11816       return -1;
11817    }
11818 
11819    ast_copy_string(buf, content, len);
11820    ast_channel_unlock(chan);
11821 
11822    return 0;
11823 }

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

11952 {
11953    struct sip_pvt *p;
11954 
11955    *buf = 0;
11956    
11957    if (!data) {
11958       ast_log(LOG_WARNING, "This function requires a parameter name.\n");
11959       return -1;
11960    }
11961 
11962    ast_channel_lock(chan);
11963    if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) {
11964       ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n");
11965       ast_channel_unlock(chan);
11966       return -1;
11967    }
11968 
11969    p = chan->tech_pvt;
11970 
11971    /* If there is no private structure, this channel is no longer alive */
11972    if (!p) {
11973       ast_channel_unlock(chan);
11974       return -1;
11975    }
11976 
11977    if (!strcasecmp(data, "peerip")) {
11978       ast_copy_string(buf, p->sa.sin_addr.s_addr ? ast_inet_ntoa(p->sa.sin_addr) : "", len);
11979    } else  if (!strcasecmp(data, "recvip")) {
11980       ast_copy_string(buf, p->recv.sin_addr.s_addr ? ast_inet_ntoa(p->recv.sin_addr) : "", len);
11981    } else  if (!strcasecmp(data, "from")) {
11982       ast_copy_string(buf, p->from, len);
11983    } else  if (!strcasecmp(data, "uri")) {
11984       ast_copy_string(buf, p->uri, len);
11985    } else  if (!strcasecmp(data, "useragent")) {
11986       ast_copy_string(buf, p->useragent, len);
11987    } else  if (!strcasecmp(data, "peername")) {
11988       ast_copy_string(buf, p->peername, len);
11989    } else if (!strcasecmp(data, "t38passthrough")) {
11990       if (p->t38.state == T38_DISABLED)
11991          ast_copy_string(buf, "0", sizeof("0"));
11992       else    /* T38 is offered or enabled in this call */
11993          ast_copy_string(buf, "1", sizeof("1"));
11994    } else {
11995       ast_channel_unlock(chan);
11996       return -1;
11997    }
11998    ast_channel_unlock(chan);
11999 
12000    return 0;
12001 }

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

11862 {
11863    struct sip_peer *peer;
11864    char *colname;
11865 
11866    if ((colname = strchr(data, ':')))  /*! \todo Will be deprecated after 1.4 */
11867       *colname++ = '\0';
11868    else if ((colname = strchr(data, '|')))
11869       *colname++ = '\0';
11870    else
11871       colname = "ip";
11872 
11873    if (!(peer = find_peer(data, NULL, 1)))
11874       return -1;
11875 
11876    if (!strcasecmp(colname, "ip")) {
11877       ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "", len);
11878    } else  if (!strcasecmp(colname, "status")) {
11879       peer_status(peer, buf, len);
11880    } else  if (!strcasecmp(colname, "language")) {
11881       ast_copy_string(buf, peer->language, len);
11882    } else  if (!strcasecmp(colname, "regexten")) {
11883       ast_copy_string(buf, peer->regexten, len);
11884    } else  if (!strcasecmp(colname, "limit")) {
11885       snprintf(buf, len, "%d", peer->call_limit);
11886    } else  if (!strcasecmp(colname, "curcalls")) {
11887       snprintf(buf, len, "%d", peer->inUse);
11888    } else  if (!strcasecmp(colname, "accountcode")) {
11889       ast_copy_string(buf, peer->accountcode, len);
11890    } else  if (!strcasecmp(colname, "useragent")) {
11891       ast_copy_string(buf, peer->useragent, len);
11892    } else  if (!strcasecmp(colname, "mailbox")) {
11893       ast_copy_string(buf, peer->mailbox, len);
11894    } else  if (!strcasecmp(colname, "context")) {
11895       ast_copy_string(buf, peer->context, len);
11896    } else  if (!strcasecmp(colname, "expire")) {
11897       snprintf(buf, len, "%d", peer->expire);
11898    } else  if (!strcasecmp(colname, "dynamic")) {
11899       ast_copy_string(buf, (ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC) ? "yes" : "no"), len);
11900    } else  if (!strcasecmp(colname, "callerid_name")) {
11901       ast_copy_string(buf, peer->cid_name, len);
11902    } else  if (!strcasecmp(colname, "callerid_num")) {
11903       ast_copy_string(buf, peer->cid_num, len);
11904    } else  if (!strcasecmp(colname, "codecs")) {
11905       ast_getformatname_multiple(buf, len -1, peer->capability);
11906    } else  if (!strncasecmp(colname, "codec[", 6)) {
11907       char *codecnum;
11908       int index = 0, codec = 0;
11909       
11910       codecnum = colname + 6; /* move past the '[' */
11911       codecnum = strsep(&codecnum, "]"); /* trim trailing ']' if any */
11912       index = atoi(codecnum);
11913       if((codec = ast_codec_pref_index(&peer->prefs, index))) {
11914          ast_copy_string(buf, ast_getformatname(codec), len);
11915       }
11916    }
11917 
11918    ASTOBJ_UNREF(peer, sip_destroy_peer);
11919 
11920    return 0;
11921 }

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

09195 {
09196    char tmp[256] = "", *c, *a;
09197    struct sip_request *req = oreq ? oreq : &p->initreq;
09198    struct sip_refer *referdata = NULL;
09199    const char *transfer_context = NULL;
09200    
09201    if (!p->refer && !sip_refer_allocate(p))
09202       return -1;
09203 
09204    referdata = p->refer;
09205 
09206    ast_copy_string(tmp, get_header(req, "Also"), sizeof(tmp));
09207    c = get_in_brackets(tmp);
09208 
09209    if (pedanticsipchecking)
09210       ast_uri_decode(c);
09211    
09212    if (strncasecmp(c, "sip:", 4)) {
09213       ast_log(LOG_WARNING, "Huh?  Not a SIP header in Also: transfer (%s)?\n", c);
09214       return -1;
09215    }
09216    c += 4;
09217    if ((a = strchr(c, ';')))  /* Remove arguments */
09218       *a = '\0';
09219    
09220    if ((a = strchr(c, '@'))) {   /* Separate Domain */
09221       *a++ = '\0';
09222       ast_copy_string(referdata->refer_to_domain, a, sizeof(referdata->refer_to_domain));
09223    }
09224    
09225    if (sip_debug_test_pvt(p))
09226       ast_verbose("Looking for %s in %s\n", c, p->context);
09227 
09228    if (p->owner)  /* Mimic behaviour in res_features.c */
09229       transfer_context = pbx_builtin_getvar_helper(p->owner, "TRANSFER_CONTEXT");
09230 
09231    /* By default, use the context in the channel sending the REFER */
09232    if (ast_strlen_zero(transfer_context)) {
09233       transfer_context = S_OR(p->owner->macrocontext,
09234                S_OR(p->context, default_context));
09235    }
09236    if (ast_exists_extension(NULL, transfer_context, c, 1, NULL)) {
09237       /* This is a blind transfer */
09238       if (option_debug)
09239          ast_log(LOG_DEBUG,"SIP Bye-also transfer to Extension %s@%s \n", c, transfer_context);
09240       ast_copy_string(referdata->refer_to, c, sizeof(referdata->refer_to));
09241       ast_copy_string(referdata->referred_by, "", sizeof(referdata->referred_by));
09242       ast_copy_string(referdata->refer_contact, "", sizeof(referdata->refer_contact));
09243       referdata->refer_call = NULL;
09244       /* Set new context */
09245       ast_string_field_set(p, context, transfer_context);
09246       return 0;
09247    } else if (ast_canmatch_extension(NULL, p->context, c, 1, NULL)) {
09248       return 1;
09249    }
09250 
09251    return -1;
09252 }

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

Referenced by check_user_full().

09307 {
09308    const char *end = strchr(input,'<');   /* first_bracket */
09309    const char *tmp = strchr(input,'"');   /* first quote */
09310    int bytes = 0;
09311    int maxbytes = outputsize - 1;
09312 
09313    if (!end || end == input)  /* we require a part in brackets */
09314       return NULL;
09315 
09316    end--; /* move just before "<" */
09317 
09318    if (tmp && tmp <= end) {
09319       /* The quote (tmp) precedes the bracket (end+1).
09320        * Find the matching quote and return the content.
09321        */
09322       end = strchr(tmp+1, '"');
09323       if (!end)
09324          return NULL;
09325       bytes = (int) (end - tmp);
09326       /* protect the output buffer */
09327       if (bytes > maxbytes)
09328          bytes = maxbytes;
09329       ast_copy_string(output, tmp + 1, bytes);
09330    } else {
09331       /* No quoted string, or it is inside brackets. */
09332       /* clear the empty characters in the begining*/
09333       input = ast_skip_blanks(input);
09334       /* clear the empty characters in the end */
09335       while(*end && *end < 33 && end > input)
09336          end--;
09337       if (end >= input) {
09338          bytes = (int) (end - input) + 2;
09339          /* protect the output buffer */
09340          if (bytes > maxbytes)
09341             bytes = maxbytes;
09342          ast_copy_string(output, input, bytes);
09343       } else
09344          return NULL;
09345    }
09346    return output;
09347 }

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

08852 {
08853    char tmp[256] = "", *uri, *a;
08854    char tmpf[256] = "", *from;
08855    struct sip_request *req;
08856    char *colon;
08857    
08858    req = oreq;
08859    if (!req)
08860       req = &p->initreq;
08861 
08862    /* Find the request URI */
08863    if (req->rlPart2)
08864       ast_copy_string(tmp, req->rlPart2, sizeof(tmp));
08865    
08866    if (pedanticsipchecking)
08867       ast_uri_decode(tmp);
08868 
08869    uri = get_in_brackets(tmp);
08870 
08871    if (strncasecmp(uri, "sip:", 4)) {
08872       ast_log(LOG_WARNING, "Huh?  Not a SIP header (%s)?\n", uri);
08873       return -1;
08874    }
08875    uri += 4;
08876 
08877    /* Now find the From: caller ID and name */
08878    ast_copy_string(tmpf, get_header(req, "From"), sizeof(tmpf));
08879    if (!ast_strlen_zero(tmpf)) {
08880       if (pedanticsipchecking)
08881          ast_uri_decode(tmpf);
08882       from = get_in_brackets(tmpf);
08883    } else {
08884       from = NULL;
08885    }
08886    
08887    if (!ast_strlen_zero(from)) {
08888       if (strncasecmp(from, "sip:", 4)) {
08889          ast_log(LOG_WARNING, "Huh?  Not a SIP header (%s)?\n", from);
08890          return -1;
08891       }
08892       from += 4;
08893       if ((a = strchr(from, '@')))
08894          *a++ = '\0';
08895       else
08896          a = from;   /* just a domain */
08897       from = strsep(&from, ";"); /* Remove userinfo options */
08898       a = strsep(&a, ";");    /* Remove URI options */
08899       ast_string_field_set(p, fromdomain, a);
08900    }
08901 
08902    /* Skip any options and find the domain */
08903 
08904    /* Get the target domain */
08905    if ((a = strchr(uri, '@'))) {
08906       *a++ = '\0';
08907    } else { /* No username part */
08908       a = uri;
08909       uri = "s";  /* Set extension to "s" */
08910    }
08911    colon = strchr(a, ':'); /* Remove :port */
08912    if (colon)
08913       *colon = '\0';
08914 
08915    uri = strsep(&uri, ";");   /* Remove userinfo options */
08916    a = strsep(&a, ";");    /* Remove URI options */
08917 
08918    ast_string_field_set(p, domain, a);
08919 
08920    if (!AST_LIST_EMPTY(&domain_list)) {
08921       char domain_context[AST_MAX_EXTENSION];
08922 
08923       domain_context[0] = '\0';
08924       if (!check_sip_domain(p->domain, domain_context, sizeof(domain_context))) {
08925          if (!allow_external_domains && (req->method == SIP_INVITE || req->method == SIP_REFER)) {
08926             if (option_debug)
08927                ast_log(LOG_DEBUG, "Got SIP %s to non-local domain '%s'; refusing request.\n", sip_methods[req->method].text, p->domain);
08928             return -2;
08929          }
08930       }
08931       /* If we have a context defined, overwrite the original context */
08932       if (!ast_strlen_zero(domain_context))
08933          ast_string_field_set(p, context, domain_context);
08934    }
08935 
08936    /* If the request coming in is a subscription and subscribecontext has been specified use it */
08937    if (req->method == SIP_SUBSCRIBE && !ast_strlen_zero(p->subscribecontext))
08938       ast_string_field_set(p, context, p->subscribecontext);
08939 
08940    if (sip_debug_test_pvt(p))
08941       ast_verbose("Looking for %s in %s (domain %s)\n", uri, p->context, p->domain);
08942 
08943    /* If this is a subscription we actually just need to see if a hint exists for the extension */
08944    if (req->method == SIP_SUBSCRIBE) {
08945       char hint[AST_MAX_EXTENSION];
08946       return (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, p->context, p->exten) ? 0 : -1);
08947    } else {
08948       /* Check the dialplan for the username part of the request URI,
08949          the domain will be stored in the SIPDOMAIN variable
08950          Since extensions.conf can have unescaped characters, try matching a decoded
08951          uri in addition to the non-decoded uri
08952          Return 0 if we have a matching extension */
08953       char *decoded_uri = ast_strdupa(uri);
08954       ast_uri_decode(decoded_uri);
08955       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)) ||
08956           !strcmp(uri, ast_pickup_ext())) {
08957          if (!oreq)
08958             ast_string_field_set(p, exten, uri);
08959          return 0;
08960       } 
08961    }
08962 
08963    /* Return 1 for pickup extension or overlap dialling support (if we support it) */
08964    if((ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP) && 
08965        ast_canmatch_extension(NULL, p->context, uri, 1, S_OR(p->cid_num, from))) ||
08966        !strncmp(uri, ast_pickup_ext(), strlen(uri))) {
08967       return 1;
08968    }
08969    
08970    return -1;
08971 }

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

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

Referenced by handle_request_notify(), and receive_message().

09713 {
09714    int x;
09715    int y;
09716 
09717    buf[0] = '\0';
09718    y = len - strlen(buf) - 5;
09719    if (y < 0)
09720       y = 0;
09721    for (x=0;x<req->lines;x++) {
09722       strncat(buf, req->line[x], y); /* safe */
09723       y -= strlen(req->line[x]) + 1;
09724       if (y < 0)
09725          y = 0;
09726       if (y != 0)
09727          strcat(buf, "\n"); /* safe */
09728    }
09729    return 0;
09730 }

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

Get referring dnis.

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

08823 {
08824    char tmp[256], *c, *a;
08825    struct sip_request *req;
08826    
08827    req = oreq;
08828    if (!req)
08829       req = &p->initreq;
08830    ast_copy_string(tmp, get_header(req, "Diversion"), sizeof(tmp));
08831    if (ast_strlen_zero(tmp))
08832       return 0;
08833    c = get_in_brackets(tmp);
08834    if (strncasecmp(c, "sip:", 4)) {
08835       ast_log(LOG_WARNING, "Huh?  Not an RDNIS SIP header (%s)?\n", c);
08836       return -1;
08837    }
08838    c += 4;
08839    a = c;
08840    strsep(&a, "@;"); /* trim anything after @ or ; */
08841    if (sip_debug_test_pvt(p))
08842       ast_verbose("RDNIS is %s\n", c);
08843    ast_string_field_set(p, rdnis, c);
08844 
08845    return 0;
08846 }

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

09029 {
09030 
09031    const char *p_referred_by = NULL;
09032    char *h_refer_to = NULL; 
09033    char *h_referred_by = NULL;
09034    char *refer_to;
09035    const char *p_refer_to;
09036    char *referred_by_uri = NULL;
09037    char *ptr;
09038    struct sip_request *req = NULL;
09039    const char *transfer_context = NULL;
09040    struct sip_refer *referdata;
09041 
09042 
09043    req = outgoing_req;
09044    referdata = transferer->refer;
09045 
09046    if (!req)
09047       req = &transferer->initreq;
09048 
09049    p_refer_to = get_header(req, "Refer-To");
09050    if (ast_strlen_zero(p_refer_to)) {
09051       ast_log(LOG_WARNING, "Refer-To Header missing. Skipping transfer.\n");
09052       return -2;  /* Syntax error */
09053    }
09054    h_refer_to = ast_strdupa(p_refer_to);
09055    refer_to = get_in_brackets(h_refer_to);
09056    if (pedanticsipchecking)
09057       ast_uri_decode(refer_to);
09058 
09059    if (strncasecmp(refer_to, "sip:", 4)) {
09060       ast_log(LOG_WARNING, "Can't transfer to non-sip: URI.  (Refer-to: %s)?\n", refer_to);
09061       return -3;
09062    }
09063    refer_to += 4;       /* Skip sip: */
09064 
09065    /* Get referred by header if it exists */
09066    p_referred_by = get_header(req, "Referred-By");
09067    if (!ast_strlen_zero(p_referred_by)) {
09068       char *lessthan;
09069       h_referred_by = ast_strdupa(p_referred_by);
09070       if (pedanticsipchecking)
09071          ast_uri_decode(h_referred_by);
09072 
09073       /* Store referrer's caller ID name */
09074       ast_copy_string(referdata->referred_by_name, h_referred_by, sizeof(referdata->referred_by_name));
09075       if ((lessthan = strchr(referdata->referred_by_name, '<'))) {
09076          *(lessthan - 1) = '\0'; /* Space */
09077       }
09078 
09079       referred_by_uri = get_in_brackets(h_referred_by);
09080       if(strncasecmp(referred_by_uri, "sip:", 4)) {
09081          ast_log(LOG_WARNING, "Huh?  Not a sip: header (Referred-by: %s). Skipping.\n", referred_by_uri);
09082          referred_by_uri = (char *) NULL;
09083       } else {
09084          referred_by_uri += 4;      /* Skip sip: */
09085       }
09086    }
09087 
09088    /* Check for arguments in the refer_to header */
09089    if ((ptr = strchr(refer_to, '?'))) { /* Search for arguments */
09090       *ptr++ = '\0';
09091       if (!strncasecmp(ptr, "REPLACES=", 9)) {
09092          char *to = NULL, *from = NULL;
09093 
09094          /* This is an attended transfer */
09095          referdata->attendedtransfer = 1;
09096          ast_copy_string(referdata->replaces_callid, ptr+9, sizeof(referdata->replaces_callid));
09097          ast_uri_decode(referdata->replaces_callid);
09098          if ((ptr = strchr(referdata->replaces_callid, ';')))  /* Find options */ {
09099             *ptr++ = '\0';
09100          }
09101 
09102          if (ptr) {
09103             /* Find the different tags before we destroy the string */
09104             to = strcasestr(ptr, "to-tag=");
09105             from = strcasestr(ptr, "from-tag=");
09106          }
09107 
09108          /* Grab the to header */
09109          if (to) {
09110             ptr = to + 7;
09111             if ((to = strchr(ptr, '&')))
09112                *to = '\0';
09113             if ((to = strchr(ptr, ';')))
09114                *to = '\0';
09115             ast_copy_string(referdata->replaces_callid_totag, ptr, sizeof(referdata->replaces_callid_totag));
09116          }
09117 
09118          if (from) {
09119             ptr = from + 9;
09120             if ((to = strchr(ptr, '&')))
09121                *to = '\0';
09122             if ((to = strchr(ptr, ';')))
09123                *to = '\0';
09124             ast_copy_string(referdata->replaces_callid_fromtag, ptr, sizeof(referdata->replaces_callid_fromtag));
09125          }
09126 
09127          if (option_debug > 1) {
09128             if (!pedanticsipchecking)
09129                ast_log(LOG_DEBUG,"Attended transfer: Will use Replace-Call-ID : %s (No check of from/to tags)\n", referdata->replaces_callid );
09130             else
09131                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>" );
09132          }
09133       }
09134    }
09135    
09136    if ((ptr = strchr(refer_to, '@'))) {   /* Separate domain */
09137       char *urioption = NULL, *domain;
09138       *ptr++ = '\0';
09139 
09140       if ((urioption = strchr(ptr, ';'))) /* Separate urioptions */
09141          *urioption++ = '\0';
09142       
09143       domain = ptr;
09144       if ((ptr = strchr(domain, ':'))) /* Remove :port */
09145          *ptr = '\0';
09146       
09147       /* Save the domain for the dial plan */
09148       ast_copy_string(referdata->refer_to_domain, domain, sizeof(referdata->refer_to_domain));
09149       if (urioption)
09150          ast_copy_string(referdata->refer_to_urioption, urioption, sizeof(referdata->refer_to_urioption));
09151    }
09152 
09153    if ((ptr = strchr(refer_to, ';')))  /* Remove options */
09154       *ptr = '\0';
09155    ast_copy_string(referdata->refer_to, refer_to, sizeof(referdata->refer_to));
09156    
09157    if (referred_by_uri) {
09158       if ((ptr = strchr(referred_by_uri, ';')))    /* Remove options */
09159          *ptr = '\0';
09160       ast_copy_string(referdata->referred_by, referred_by_uri, sizeof(referdata->referred_by));
09161    } else {
09162       referdata->referred_by[0] = '\0';
09163    }
09164 
09165    /* Determine transfer context */
09166    if (transferer->owner)  /* Mimic behaviour in res_features.c */
09167       transfer_context = pbx_builtin_getvar_helper(transferer->owner, "TRANSFER_CONTEXT");
09168 
09169    /* By default, use the context in the channel sending the REFER */
09170    if (ast_strlen_zero(transfer_context)) {
09171       transfer_context = S_OR(transferer->owner->macrocontext,
09172                S_OR(transferer->context, default_context));
09173    }
09174 
09175    ast_copy_string(referdata->refer_to_context, transfer_context, sizeof(referdata->refer_to_context));
09176    
09177    /* Either an existing extension or the parking extension */
09178    if (ast_exists_extension(NULL, transfer_context, refer_to, 1, NULL) ) {
09179       if (sip_debug_test_pvt(transferer)) {
09180          ast_verbose("SIP transfer to extension %s@%s by %s\n", refer_to, transfer_context, referred_by_uri);
09181       }
09182       /* We are ready to transfer to the extension */
09183       return 0;
09184    } 
09185    if (sip_debug_test_pvt(transferer))
09186       ast_verbose("Failed SIP Transfer to non-existing extension %s in context %s\n n", refer_to, transfer_context);
09187 
09188    /* Failure, we can't find this extension */
09189    return -1;
09190 }

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

References AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED.

Referenced by check_user_full().

09354 {
09355    char *start;
09356    char *end;
09357 
09358    start = strchr(input,':');
09359    if (!start) {
09360       output[0] = '\0';
09361       return 0;
09362    }
09363    start++;
09364 
09365    /* we found "number" */
09366    ast_copy_string(output,start,maxlen);
09367    output[maxlen-1] = '\0';
09368 
09369    end = strchr(output,'@');
09370    if (end)
09371       *end = '\0';
09372    else
09373       output[0] = '\0';
09374    if (strstr(input,"privacy=full") || strstr(input,"privacy=uri"))
09375       return AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED;
09376 
09377    return 0;
09378 }

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

08979 {
08980    struct sip_pvt *sip_pvt_ptr;
08981 
08982    ast_mutex_lock(&iflock);
08983 
08984    if (option_debug > 3 && totag)
08985       ast_log(LOG_DEBUG, "Looking for callid %s (fromtag %s totag %s)\n", callid, fromtag ? fromtag : "<no fromtag>", totag ? totag : "<no totag>");
08986 
08987    /* Search interfaces and find the match */
08988    for (sip_pvt_ptr = iflist; sip_pvt_ptr; sip_pvt_ptr = sip_pvt_ptr->next) {
08989       if (!strcmp(sip_pvt_ptr->callid, callid)) {
08990          int match = 1;
08991          char *ourtag = sip_pvt_ptr->tag;
08992 
08993          /* Go ahead and lock it (and its owner) before returning */
08994          ast_mutex_lock(&sip_pvt_ptr->lock);
08995 
08996          /* Check if tags match. If not, this is not the call we want
08997             (With a forking SIP proxy, several call legs share the
08998             call id, but have different tags)
08999          */
09000          if (pedanticsipchecking && (strcmp(fromtag, sip_pvt_ptr->theirtag) || (!ast_strlen_zero(totag) && strcmp(totag, ourtag))))
09001             match = 0;
09002 
09003          if (!match) {
09004             ast_mutex_unlock(&sip_pvt_ptr->lock);
09005             continue;
09006          }
09007 
09008          if (option_debug > 3 && totag)             
09009             ast_log(LOG_DEBUG, "Matched %s call - their tag is %s Our tag is %s\n",
09010                ast_test_flag(&sip_pvt_ptr->flags[0], SIP_OUTGOING) ? "OUTGOING": "INCOMING",
09011                sip_pvt_ptr->theirtag, sip_pvt_ptr->tag);
09012 
09013          /* deadlock avoidance... */
09014          while (sip_pvt_ptr->owner && ast_channel_trylock(sip_pvt_ptr->owner)) {
09015             DEADLOCK_AVOIDANCE(&sip_pvt_ptr->lock);
09016          }
09017          break;
09018       }
09019    }
09020    ast_mutex_unlock(&iflock);
09021    if (option_debug > 3 && !sip_pvt_ptr)
09022       ast_log(LOG_DEBUG, "Found no match for callid %s to-tag %s from-tag %s\n", callid, totag, fromtag);
09023    return sip_pvt_ptr;
09024 }

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

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

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

13406 {
13407    const char *thetag;
13408 
13409    if (!tagbuf)
13410       return NULL;
13411    tagbuf[0] = '\0';    /* reset the buffer */
13412    thetag = get_header(req, header);
13413    thetag = strcasestr(thetag, ";tag=");
13414    if (thetag) {
13415       thetag += 5;
13416       ast_copy_string(tagbuf, thetag, tagbufsize);
13417       return strsep(&tagbuf, ";");
13418    }
13419    return NULL;
13420 }

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

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

16197 {
16198    int res = 1;
16199 
16200    if (!strcasecmp(v->name, "trustrpid")) {
16201       ast_set_flag(&mask[0], SIP_TRUSTRPID);
16202       ast_set2_flag(&flags[0], ast_true(v->value), SIP_TRUSTRPID);
16203    } else if (!strcasecmp(v->name, "sendrpid")) {
16204       ast_set_flag(&mask[0], SIP_SENDRPID);
16205       ast_set2_flag(&flags[0], ast_true(v->value), SIP_SENDRPID);
16206    } else if (!strcasecmp(v->name, "g726nonstandard")) {
16207       ast_set_flag(&mask[0], SIP_G726_NONSTANDARD);
16208       ast_set2_flag(&flags[0], ast_true(v->value), SIP_G726_NONSTANDARD);
16209    } else if (!strcasecmp(v->name, "useclientcode")) {
16210       ast_set_flag(&mask[0], SIP_USECLIENTCODE);
16211       ast_set2_flag(&flags[0], ast_true(v->value), SIP_USECLIENTCODE);
16212    } else if (!strcasecmp(v->name, "dtmfmode")) {
16213       ast_set_flag(&mask[0], SIP_DTMF);
16214       ast_clear_flag(&flags[0], SIP_DTMF);
16215       if (!strcasecmp(v->value, "inband"))
16216          ast_set_flag(&flags[0], SIP_DTMF_INBAND);
16217       else if (!strcasecmp(v->value, "rfc2833"))
16218          ast_set_flag(&flags[0], SIP_DTMF_RFC2833);
16219       else if (!strcasecmp(v->value, "info"))
16220          ast_set_flag(&flags[0], SIP_DTMF_INFO);
16221       else if (!strcasecmp(v->value, "auto"))
16222          ast_set_flag(&flags[0], SIP_DTMF_AUTO);
16223       else {
16224          ast_log(LOG_WARNING, "Unknown dtmf mode '%s' on line %d, using rfc2833\n", v->value, v->lineno);
16225          ast_set_flag(&flags[0], SIP_DTMF_RFC2833);
16226       }
16227    } else if (!strcasecmp(v->name, "nat")) {
16228       ast_set_flag(&mask[0], SIP_NAT);
16229       ast_clear_flag(&flags[0], SIP_NAT);
16230       if (!strcasecmp(v->value, "never"))
16231          ast_set_flag(&flags[0], SIP_NAT_NEVER);
16232       else if (!strcasecmp(v->value, "route"))
16233          ast_set_flag(&flags[0], SIP_NAT_ROUTE);
16234       else if (ast_true(v->value))
16235          ast_set_flag(&flags[0], SIP_NAT_ALWAYS);
16236       else
16237          ast_set_flag(&flags[0], SIP_NAT_RFC3581);
16238    } else if (!strcasecmp(v->name, "canreinvite")) {
16239       ast_set_flag(&mask[0], SIP_REINVITE);
16240       ast_clear_flag(&flags[0], SIP_REINVITE);
16241       if(ast_true(v->value)) {
16242          ast_set_flag(&flags[0], SIP_CAN_REINVITE | SIP_CAN_REINVITE_NAT);
16243       } else if (!ast_false(v->value)) {
16244          char buf[64];
16245          char *word, *next = buf;
16246 
16247          ast_copy_string(buf, v->value, sizeof(buf));
16248          while ((word = strsep(&next, ","))) {
16249             if(!strcasecmp(word, "update")) {
16250                ast_set_flag(&flags[0], SIP_REINVITE_UPDATE | SIP_CAN_REINVITE);
16251             } else if(!strcasecmp(word, "nonat")) {
16252                ast_set_flag(&flags[0], SIP_CAN_REINVITE);
16253                ast_clear_flag(&flags[0], SIP_CAN_REINVITE_NAT);
16254             } else {
16255                ast_log(LOG_WARNING, "Unknown canreinvite mode '%s' on line %d\n", v->value, v->lineno);
16256             }
16257          }
16258       }
16259    } else if (!strcasecmp(v->name, "insecure")) {
16260       ast_set_flag(&mask[0], SIP_INSECURE_PORT | SIP_INSECURE_INVITE);
16261       ast_clear_flag(&flags[0], SIP_INSECURE_PORT | SIP_INSECURE_INVITE);
16262       set_insecure_flags(flags, v->value, v->lineno);
16263    } else if (!strcasecmp(v->name, "progressinband")) {
16264       ast_set_flag(&mask[0], SIP_PROG_INBAND);
16265       ast_clear_flag(&flags[0], SIP_PROG_INBAND);
16266       if (ast_true(v->value))
16267          ast_set_flag(&flags[0], SIP_PROG_INBAND_YES);
16268       else if (strcasecmp(v->value, "never"))
16269          ast_set_flag(&flags[0], SIP_PROG_INBAND_NO);
16270    } else if (!strcasecmp(v->name, "promiscredir")) {
16271       ast_set_flag(&mask[0], SIP_PROMISCREDIR);
16272       ast_set2_flag(&flags[0], ast_true(v->value), SIP_PROMISCREDIR);
16273    } else if (!strcasecmp(v->name, "videosupport")) {
16274       ast_set_flag(&mask[1], SIP_PAGE2_VIDEOSUPPORT);
16275       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_VIDEOSUPPORT);
16276    } else if (!strcasecmp(v->name, "allowoverlap")) {
16277       ast_set_flag(&mask[1], SIP_PAGE2_ALLOWOVERLAP);
16278       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_ALLOWOVERLAP);
16279    } else if (!strcasecmp(v->name, "allowsubscribe")) {
16280       ast_set_flag(&mask[1], SIP_PAGE2_ALLOWSUBSCRIBE);
16281       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_ALLOWSUBSCRIBE);
16282    } else if (!strcasecmp(v->name, "t38pt_udptl")) {
16283       ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT_UDPTL);
16284       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_T38SUPPORT_UDPTL);
16285 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS
16286    } else if (!strcasecmp(v->name, "t38pt_rtp")) {
16287       ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT_RTP);
16288       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_T38SUPPORT_RTP);
16289    } else if (!strcasecmp(v->name, "t38pt_tcp")) {
16290       ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT_TCP);
16291       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_T38SUPPORT_TCP);
16292 #endif
16293    } else if (!strcasecmp(v->name, "rfc2833compensate")) {
16294       ast_set_flag(&mask[1], SIP_PAGE2_RFC2833_COMPENSATE);
16295       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_RFC2833_COMPENSATE);
16296    } else if (!strcasecmp(v->name, "buggymwi")) {
16297       ast_set_flag(&mask[1], SIP_PAGE2_BUGGY_MWI);
16298       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_BUGGY_MWI);
16299    } else if (!strcasecmp(v->name, "t38pt_usertpsource")) {
16300       ast_set_flag(&mask[1], SIP_PAGE2_UDPTL_DESTINATION);
16301       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_UDPTL_DESTINATION);
16302    } else
16303       res = 0;
16304 
16305    return res;
16306 }

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

13585 {
13586    struct ast_frame *f;
13587    int earlyreplace = 0;
13588    int oneleggedreplace = 0;     /* Call with no bridge, propably IVR or voice message */
13589    struct ast_channel *c = p->owner;   /* Our incoming call */
13590    struct ast_channel *replacecall = p->refer->refer_call->owner; /* The channel we're about to take over */
13591    struct ast_channel *targetcall;     /* The bridge to the take-over target */
13592 
13593    /* Check if we're in ring state */
13594    if (replacecall->_state == AST_STATE_RING)
13595       earlyreplace = 1;
13596 
13597    /* Check if we have a bridge */
13598    if (!(targetcall = ast_bridged_channel(replacecall))) {
13599       /* We have no bridge */
13600       if (!earlyreplace) {
13601          if (option_debug > 1)
13602             ast_log(LOG_DEBUG, " Attended transfer attempted to replace call with no bridge (maybe ringing). Channel %s!\n", replacecall->name);
13603          oneleggedreplace = 1;
13604       }
13605    } 
13606    if (option_debug > 3 && targetcall && targetcall->_state == AST_STATE_RINGING)
13607          ast_log(LOG_DEBUG, "SIP transfer: Target channel is in ringing state\n");
13608 
13609    if (option_debug > 3) {
13610       if (targetcall) 
13611          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); 
13612       else
13613          ast_log(LOG_DEBUG, "SIP transfer: Invite Replace incoming channel should replace and hang up channel %s (one call leg)\n", replacecall->name); 
13614    }
13615 
13616    if (ignore) {
13617       ast_log(LOG_NOTICE, "Ignoring this INVITE with replaces in a stupid way.\n");
13618       /* We should answer something here. If we are here, the
13619          call we are replacing exists, so an accepted 
13620          can't harm */
13621       transmit_response_with_sdp(p, "200 OK", req, XMIT_RELIABLE);
13622       /* Do something more clever here */
13623       ast_channel_unlock(c);
13624       ast_mutex_unlock(&p->refer->refer_call->lock);
13625       return 1;
13626    } 
13627    if (!c) {
13628       /* What to do if no channel ??? */
13629       ast_log(LOG_ERROR, "Unable to create new channel.  Invite/replace failed.\n");
13630       transmit_response_reliable(p, "503 Service Unavailable", req);
13631       append_history(p, "Xfer", "INVITE/Replace Failed. No new channel.");
13632       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
13633       ast_mutex_unlock(&p->refer->refer_call->lock);
13634       return 1;
13635    }
13636    append_history(p, "Xfer", "INVITE/Replace received");
13637    /* We have three channels to play with
13638       channel c: New incoming call
13639       targetcall: Call from PBX to target
13640       p->refer->refer_call: SIP pvt dialog from transferer to pbx.
13641       replacecall: The owner of the previous
13642       We need to masq C into refer_call to connect to 
13643       targetcall;
13644       If we are talking to internal audio stream, target call is null.
13645    */
13646 
13647    /* Fake call progress */
13648    transmit_response(p, "100 Trying", req);
13649    ast_setstate(c, AST_STATE_RING);
13650 
13651    /* Masquerade the new call into the referred call to connect to target call 
13652       Targetcall is not touched by the masq */
13653 
13654    /* Answer the incoming call and set channel to UP state */
13655    transmit_response_with_sdp(p, "200 OK", req, XMIT_RELIABLE);
13656       
13657    ast_setstate(c, AST_STATE_UP);
13658    
13659    /* Stop music on hold and other generators */
13660    ast_quiet_chan(replacecall);
13661    ast_quiet_chan(targetcall);
13662    if (option_debug > 3)
13663       ast_log(LOG_DEBUG, "Invite/Replaces: preparing to masquerade %s into %s\n", c->name, replacecall->name);
13664    /* Unlock clone, but not original (replacecall) */
13665    if (!oneleggedreplace)
13666       ast_channel_unlock(c);
13667 
13668    /* Unlock PVT */
13669    ast_mutex_unlock(&p->refer->refer_call->lock);
13670 
13671    /* Make sure that the masq does not free our PVT for the old call */
13672    if (! earlyreplace && ! oneleggedreplace )
13673       ast_set_flag(&p->refer->refer_call->flags[0], SIP_DEFER_BYE_ON_TRANSFER);  /* Delay hangup */
13674       
13675    /* Prepare the masquerade - if this does not happen, we will be gone */
13676    if(ast_channel_masquerade(replacecall, c))
13677       ast_log(LOG_ERROR, "Failed to masquerade C into Replacecall\n");
13678    else if (option_debug > 3)
13679       ast_log(LOG_DEBUG, "Invite/Replaces: Going to masquerade %s into %s\n", c->name, replacecall->name);
13680 
13681    /* The masquerade will happen as soon as someone reads a frame from the channel */
13682 
13683    /* C should now be in place of replacecall */
13684    /* ast_read needs to lock channel */
13685    ast_channel_unlock(c);
13686    
13687    if (earlyreplace || oneleggedreplace ) {
13688       /* Force the masq to happen */
13689       if ((f = ast_read(replacecall))) {  /* Force the masq to happen */
13690          ast_frfree(f);
13691          f = NULL;
13692          if (option_debug > 3)
13693             ast_log(LOG_DEBUG, "Invite/Replace:  Could successfully read frame from RING channel!\n");
13694       } else {
13695          ast_log(LOG_WARNING, "Invite/Replace:  Could not read frame from RING channel \n");
13696       }
13697       c->hangupcause = AST_CAUSE_SWITCH_CONGESTION;
13698       if (!oneleggedreplace)
13699          ast_channel_unlock(replacecall);
13700    } else { /* Bridged call, UP channel */
13701       if ((f = ast_read(replacecall))) {  /* Force the masq to happen */
13702          /* Masq ok */
13703          ast_frfree(f);
13704          f = NULL;
13705          if (option_debug > 2)
13706             ast_log(LOG_DEBUG, "Invite/Replace:  Could successfully read frame from channel! Masq done.\n");
13707       } else {
13708          ast_log(LOG_WARNING, "Invite/Replace:  Could not read frame from channel. Transfer failed\n");
13709       }
13710       ast_channel_unlock(replacecall);
13711    }
13712    ast_mutex_unlock(&p->refer->refer_call->lock);
13713 
13714    ast_setstate(c, AST_STATE_DOWN);
13715    if (option_debug > 3) {
13716       struct ast_channel *test;
13717       ast_log(LOG_DEBUG, "After transfer:----------------------------\n");
13718       ast_log(LOG_DEBUG, " -- C:        %s State %s\n", c->name, ast_state2str(c->_state));
13719       if (replacecall)
13720          ast_log(LOG_DEBUG, " -- replacecall:        %s State %s\n", replacecall->name, ast_state2str(replacecall->_state));
13721       if (p->owner) {
13722          ast_log(LOG_DEBUG, " -- P->owner: %s State %s\n", p->owner->name, ast_state2str(p->owner->_state));
13723          test = ast_bridged_channel(p->owner);
13724          if (test)
13725             ast_log(LOG_DEBUG, " -- Call bridged to P->owner: %s State %s\n", test->name, ast_state2str(test->_state));
13726          else
13727             ast_log(LOG_DEBUG, " -- No call bridged to C->owner \n");
13728       } else 
13729          ast_log(LOG_DEBUG, " -- No channel yet \n");
13730       ast_log(LOG_DEBUG, "End After transfer:----------------------------\n");
13731    }
13732 
13733    ast_channel_unlock(p->owner); /* Unlock new owner */
13734    if (!oneleggedreplace)
13735       ast_mutex_unlock(&p->lock);   /* Unlock SIP structure */
13736 
13737    /* The call should be down with no ast_channel, so hang it up */
13738    c->tech_pvt = NULL;
13739    ast_hangup(c);
13740    return 0;
13741 }

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

15255 {
15256    /* Called with p->lock held, as well as p->owner->lock if appropriate, keeping things
15257       relatively static */
15258    const char *cmd;
15259    const char *cseq;
15260    const char *useragent;
15261    int seqno;
15262    int len;
15263    int ignore = FALSE;
15264    int respid;
15265    int res = 0;
15266    int debug = sip_debug_test_pvt(p);
15267    char *e;
15268    int error = 0;
15269 
15270    /* Get Method and Cseq */
15271    cseq = get_header(req, "Cseq");
15272    cmd = req->header[0];
15273 
15274    /* Must have Cseq */
15275    if (ast_strlen_zero(cmd) || ast_strlen_zero(cseq)) {
15276       ast_log(LOG_ERROR, "Missing Cseq. Dropping this SIP message, it's incomplete.\n");
15277       error = 1;
15278    }
15279    if (!error && sscanf(cseq, "%d%n", &seqno, &len) != 1) {
15280       ast_log(LOG_ERROR, "No seqno in '%s'. Dropping incomplete message.\n", cmd);
15281       error = 1;
15282    }
15283    if (error) {
15284       if (!p->initreq.headers)   /* New call */
15285          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); /* Make sure we destroy this dialog */
15286       return -1;
15287    }
15288    /* Get the command XXX */
15289 
15290    cmd = req->rlPart1;
15291    e = req->rlPart2;
15292 
15293    /* Save useragent of the client */
15294    useragent = get_header(req, "User-Agent");
15295    if (!ast_strlen_zero(useragent))
15296       ast_string_field_set(p, useragent, useragent);
15297 
15298    /* Find out SIP method for incoming request */
15299    if (req->method == SIP_RESPONSE) {  /* Response to our request */
15300       /* Response to our request -- Do some sanity checks */   
15301       if (!p->initreq.headers) {
15302          if (option_debug)
15303             ast_log(LOG_DEBUG, "That's odd...  Got a response on a call we dont know about. Cseq %d Cmd %s\n", seqno, cmd);
15304          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
15305          return 0;
15306       } else if (p->ocseq && (p->ocseq < seqno) && (seqno != p->lastnoninvite)) {
15307          if (option_debug)
15308             ast_log(LOG_DEBUG, "Ignoring out of order response %d (expecting %d)\n", seqno, p->ocseq);
15309          return -1;
15310       } else if (p->ocseq && (p->ocseq != seqno) && (seqno != p->lastnoninvite)) {
15311          /* ignore means "don't do anything with it" but still have to 
15312             respond appropriately  */
15313          ignore = TRUE;
15314          ast_set_flag(req, SIP_PKT_IGNORE);
15315          ast_set_flag(req, SIP_PKT_IGNORE_RESP);
15316          append_history(p, "Ignore", "Ignoring this retransmit\n");
15317       } else if (e) {
15318          e = ast_skip_blanks(e);
15319          if (sscanf(e, "%d %n", &respid, &len) != 1) {
15320             ast_log(LOG_WARNING, "Invalid response: '%s'\n", e);
15321          } else {
15322             if (respid <= 0) {
15323                ast_log(LOG_WARNING, "Invalid SIP response code: '%d'\n", respid);
15324                return 0;
15325             }
15326             /* More SIP ridiculousness, we have to ignore bogus contacts in 100 etc responses */
15327             if ((respid == 200) || ((respid >= 300) && (respid <= 399)))
15328                extract_uri(p, req);
15329             handle_response(p, respid, e + len, req, ignore, seqno);
15330          }
15331       }
15332       return 0;
15333    }
15334 
15335    /* New SIP request coming in 
15336       (could be new request in existing SIP dialog as well...) 
15337     */         
15338    
15339    p->method = req->method;   /* Find out which SIP method they are using */
15340    if (option_debug > 3)
15341       ast_log(LOG_DEBUG, "**** Received %s (%d) - Command in SIP %s\n", sip_methods[p->method].text, sip_methods[p->method].id, cmd); 
15342 
15343    if (p->icseq && (p->icseq > seqno) ) {
15344       if (p->pendinginvite && seqno == p->pendinginvite && (req->method == SIP_ACK || req->method == SIP_CANCEL)) {
15345          if (option_debug > 2)
15346             ast_log(LOG_DEBUG, "Got CANCEL or ACK on INVITE with transactions in between.\n");
15347       }  else {
15348          if (option_debug)
15349             ast_log(LOG_DEBUG, "Ignoring too old SIP packet packet %d (expecting >= %d)\n", seqno, p->icseq);
15350          if (req->method != SIP_ACK)
15351             transmit_response(p, "503 Server error", req);  /* We must respond according to RFC 3261 sec 12.2 */
15352          return -1;
15353       }
15354    } else if (p->icseq &&
15355          p->icseq == seqno &&
15356          req->method != SIP_ACK &&
15357          (p->method != SIP_CANCEL || ast_test_flag(&p->flags[0], SIP_ALREADYGONE))) {
15358       /* ignore means "don't do anything with it" but still have to 
15359          respond appropriately.  We do this if we receive a repeat of
15360          the last sequence number  */
15361       ignore = 2;
15362       ast_set_flag(req, SIP_PKT_IGNORE);
15363       ast_set_flag(req, SIP_PKT_IGNORE_REQ);
15364       if (option_debug > 2)
15365          ast_log(LOG_DEBUG, "Ignoring SIP message because of retransmit (%s Seqno %d, ours %d)\n", sip_methods[p->method].text, p->icseq, seqno);
15366    }
15367       
15368    if (seqno >= p->icseq)
15369       /* Next should follow monotonically (but not necessarily 
15370          incrementally -- thanks again to the genius authors of SIP --
15371          increasing */
15372       p->icseq = seqno;
15373 
15374    /* Find their tag if we haven't got it */
15375    if (ast_strlen_zero(p->theirtag)) {
15376       char tag[128];
15377 
15378       gettag(req, "From", tag, sizeof(tag));
15379       ast_string_field_set(p, theirtag, tag);
15380    }
15381    snprintf(p->lastmsg, sizeof(p->lastmsg), "Rx: %s", cmd);
15382 
15383    if (pedanticsipchecking) {
15384       /* If this is a request packet without a from tag, it's not
15385          correct according to RFC 3261  */
15386       /* Check if this a new request in a new dialog with a totag already attached to it,
15387          RFC 3261 - section 12.2 - and we don't want to mess with recovery  */
15388       if (!p->initreq.headers && ast_test_flag(req, SIP_PKT_WITH_TOTAG)) {
15389          /* If this is a first request and it got a to-tag, it is not for us */
15390          if (!ast_test_flag(req, SIP_PKT_IGNORE) && req->method == SIP_INVITE) {
15391             transmit_response_reliable(p, "481 Call/Transaction Does Not Exist", req);
15392             /* Will cease to exist after ACK */
15393          } else if (req->method != SIP_ACK) {
15394             transmit_response(p, "481 Call/Transaction Does Not Exist", req);
15395             sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
15396          }
15397          return res;
15398       }
15399    }
15400 
15401    if (!e && (p->method == SIP_INVITE || p->method == SIP_SUBSCRIBE || p->method == SIP_REGISTER || p->method == SIP_NOTIFY)) {
15402       transmit_response(p, "400 Bad request", req);
15403       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
15404       return -1;
15405    }
15406 
15407    /* Handle various incoming SIP methods in requests */
15408    switch (p->method) {
15409    case SIP_OPTIONS:
15410       res = handle_request_options(p, req);
15411       break;
15412    case SIP_INVITE:
15413       res = handle_request_invite(p, req, debug, seqno, sin, recount, e, nounlock);
15414       break;
15415    case SIP_REFER:
15416       res = handle_request_refer(p, req, debug, ignore, seqno, nounlock);
15417       break;
15418    case SIP_CANCEL:
15419       res = handle_request_cancel(p, req);
15420       break;
15421    case SIP_BYE:
15422       res = handle_request_bye(p, req);
15423       break;
15424    case SIP_MESSAGE:
15425       res = handle_request_message(p, req);
15426       break;
15427    case SIP_SUBSCRIBE:
15428       res = handle_request_subscribe(p, req, sin, seqno, e);
15429       break;
15430    case SIP_REGISTER:
15431       res = handle_request_register(p, req, sin, e);
15432       break;
15433    case SIP_INFO:
15434       if (ast_test_flag(req, SIP_PKT_DEBUG))
15435          ast_verbose("Receiving INFO!\n");
15436       if (!ignore) 
15437          handle_request_info(p, req);
15438       else  /* if ignoring, transmit response */
15439          transmit_response(p, "200 OK", req);
15440       break;
15441    case SIP_NOTIFY:
15442       res = handle_request_notify(p, req, sin, seqno, e);
15443       break;
15444    case SIP_ACK:
15445       /* Make sure we don't ignore this */
15446       if (seqno == p->pendinginvite) {
15447          p->invitestate = INV_TERMINATED;
15448          p->pendinginvite = 0;
15449          __sip_ack(p, seqno, FLAG_RESPONSE, 0);
15450          if (find_sdp(req)) {
15451             if (process_sdp(p, req))
15452                return -1;
15453          } 
15454          check_pendings(p);
15455       }
15456       /* Got an ACK that we did not match. Ignore silently */
15457       if (!p->lastinvite && ast_strlen_zero(p->randdata))
15458          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
15459       break;
15460    default:
15461       transmit_response_with_allow(p, "501 Method Not Implemented", req, 0);
15462       ast_log(LOG_NOTICE, "Unknown SIP command '%s' from '%s'\n", 
15463          cmd, ast_inet_ntoa(p->sa.sin_addr));
15464       /* If this is some new method, and we don't have a call, destroy it now */
15465       if (!p->initreq.headers)
15466          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
15467       break;
15468    }
15469    return res;
15470 }

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

Handle incoming BYE request.

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

14820 {
14821    struct ast_channel *c=NULL;
14822    int res;
14823    struct ast_channel *bridged_to;
14824    
14825    /* If we have an INCOMING invite that we haven't answered, terminate that transaction */
14826    if (p->pendinginvite && !ast_test_flag(&p->flags[0], SIP_OUTGOING) && !ast_test_flag(req, SIP_PKT_IGNORE) && !p->owner) 
14827       transmit_response_reliable(p, "487 Request Terminated", &p->initreq);
14828 
14829    p->invitestate = INV_TERMINATED;
14830 
14831    copy_request(&p->initreq, req);
14832    check_via(p, req);
14833    sip_alreadygone(p);
14834 
14835    /* Get RTCP quality before end of call */
14836    if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY) || p->owner) {
14837       char *audioqos, *videoqos;
14838       if (p->rtp) {
14839          audioqos = ast_rtp_get_quality(p->rtp, NULL);
14840          if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY))
14841             append_history(p, "RTCPaudio", "Quality:%s", audioqos);
14842          if (p->owner)
14843             pbx_builtin_setvar_helper(p->owner, "RTPAUDIOQOS", audioqos);
14844       }
14845       if (p->vrtp) {
14846          videoqos = ast_rtp_get_quality(p->vrtp, NULL);
14847          if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY))
14848             append_history(p, "RTCPvideo", "Quality:%s", videoqos);
14849          if (p->owner)
14850             pbx_builtin_setvar_helper(p->owner, "RTPVIDEOQOS", videoqos);
14851       }
14852    }
14853 
14854    stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */
14855 
14856    if (!ast_strlen_zero(get_header(req, "Also"))) {
14857       ast_log(LOG_NOTICE, "Client '%s' using deprecated BYE/Also transfer method.  Ask vendor to support REFER instead\n",
14858          ast_inet_ntoa(p->recv.sin_addr));
14859       if (ast_strlen_zero(p->context))
14860          ast_string_field_set(p, context, default_context);
14861       res = get_also_info(p, req);
14862       if (!res) {
14863          c = p->owner;
14864          if (c) {
14865             bridged_to = ast_bridged_channel(c);
14866             if (bridged_to) {
14867                /* Don't actually hangup here... */
14868                ast_queue_control(c, AST_CONTROL_UNHOLD);
14869                ast_async_goto(bridged_to, p->context, p->refer->refer_to,1);
14870             } else
14871                ast_queue_hangup(p->owner);
14872          }
14873       } else {
14874          ast_log(LOG_WARNING, "Invalid transfer information from '%s'\n", ast_inet_ntoa(p->recv.sin_addr));
14875          if (p->owner)
14876             ast_queue_hangup(p->owner);
14877       }
14878    } else if (p->owner) {
14879       ast_queue_hangup(p->owner);
14880       if (option_debug > 2)
14881          ast_log(LOG_DEBUG, "Received bye, issuing owner hangup\n");
14882    } else {
14883       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
14884       if (option_debug > 2)
14885          ast_log(LOG_DEBUG, "Received bye, no owner, selfdestruct soon.\n");
14886    }
14887    transmit_response(p, "200 OK", req);
14888 
14889    return 1;
14890 }

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

Handle incoming CANCEL request.

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

14714 {
14715       
14716    check_via(p, req);
14717    sip_alreadygone(p);
14718 
14719    /* At this point, we could have cancelled the invite at the same time
14720       as the other side sends a CANCEL. Our final reply with error code
14721       might not have been received by the other side before the CANCEL
14722       was sent, so let's just give up retransmissions and waiting for
14723       ACK on our error code. The call is hanging up any way. */
14724    if (p->invitestate == INV_TERMINATED)
14725       __sip_pretend_ack(p);
14726    else
14727       p->invitestate = INV_CANCELLED;
14728    
14729    if (p->owner && p->owner->_state == AST_STATE_UP) {
14730       /* This call is up, cancel is ignored, we need a bye */
14731       transmit_response(p, "200 OK", req);
14732       if (option_debug)
14733          ast_log(LOG_DEBUG, "Got CANCEL on an answered call. Ignoring... \n");
14734       return 0;
14735    }
14736 
14737    if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) 
14738       update_call_counter(p, DEC_CALL_LIMIT);
14739 
14740    stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */
14741    if (p->owner)
14742       ast_queue_hangup(p->owner);
14743    else
14744       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
14745    if (p->initreq.len > 0) {
14746       transmit_response_reliable(p, "487 Request Terminated", &p->initreq);
14747       transmit_response(p, "200 OK", req);
14748       return 1;
14749    } else {
14750       transmit_response(p, "481 Call Leg Does Not Exist", req);
14751       return 0;
14752    }
14753 }

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

11186 {
11187    char buf[1024];
11188    unsigned int event;
11189    const char *c = get_header(req, "Content-Type");
11190 
11191    /* Need to check the media/type */
11192    if (!strcasecmp(c, "application/dtmf-relay") ||
11193        !strcasecmp(c, "application/vnd.nortelnetworks.digits")) {
11194       unsigned int duration = 0;
11195 
11196       /* Try getting the "signal=" part */
11197       if (ast_strlen_zero(c = get_body(req, "Signal")) && ast_strlen_zero(c = get_body(req, "d"))) {
11198          ast_log(LOG_WARNING, "Unable to retrieve DTMF signal from INFO message from %s\n", p->callid);
11199          transmit_response(p, "200 OK", req); /* Should return error */
11200          return;
11201       } else {
11202          ast_copy_string(buf, c, sizeof(buf));
11203       }
11204 
11205       if (!ast_strlen_zero((c = get_body(req, "Duration"))))
11206          duration = atoi(c);
11207       if (!duration)
11208          duration = 100; /* 100 ms */
11209 
11210       if (!p->owner) {  /* not a PBX call */
11211          transmit_response(p, "481 Call leg/transaction does not exist", req);
11212          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
11213          return;
11214       }
11215 
11216       if (ast_strlen_zero(buf)) {
11217          transmit_response(p, "200 OK", req);
11218          return;
11219       }
11220 
11221       if (buf[0] == '*')
11222          event = 10;
11223       else if (buf[0] == '#')
11224          event = 11;
11225       else if ((buf[0] >= 'A') && (buf[0] <= 'D'))
11226          event = 12 + buf[0] - 'A';
11227       else
11228          event = atoi(buf);
11229       if (event == 16) {
11230          /* send a FLASH event */
11231          struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_FLASH, };
11232          ast_queue_frame(p->owner, &f);
11233          if (sipdebug)
11234             ast_verbose("* DTMF-relay event received: FLASH\n");
11235       } else {
11236          /* send a DTMF event */
11237          struct ast_frame f = { AST_FRAME_DTMF, };
11238          if (event < 10) {
11239             f.subclass = '0' + event;
11240          } else if (event < 11) {
11241             f.subclass = '*';
11242          } else if (event < 12) {
11243             f.subclass = '#';
11244          } else if (event < 16) {
11245             f.subclass = 'A' + (event - 12);
11246          }
11247          f.len = duration;
11248          ast_queue_frame(p->owner, &f);
11249          if (sipdebug)
11250             ast_verbose("* DTMF-relay event received: %c\n", f.subclass);
11251       }
11252       transmit_response(p, "200 OK", req);
11253       return;
11254    } else if (!strcasecmp(c, "application/media_control+xml")) {
11255       /* Eh, we'll just assume it's a fast picture update for now */
11256       if (p->owner)
11257          ast_queue_control(p->owner, AST_CONTROL_VIDUPDATE);
11258       transmit_response(p, "200 OK", req);
11259       return;
11260    } else if (!ast_strlen_zero(c = get_header(req, "X-ClientCode"))) {
11261       /* Client code (from SNOM phone) */
11262       if (ast_test_flag(&p->flags[0], SIP_USECLIENTCODE)) {
11263          if (p->owner && p->owner->cdr)
11264             ast_cdr_setuserfield(p->owner, c);
11265          if (p->owner && ast_bridged_channel(p->owner) && ast_bridged_channel(p->owner)->cdr)
11266             ast_cdr_setuserfield(ast_bridged_channel(p->owner), c);
11267          transmit_response(p, "200 OK", req);
11268       } else {
11269          transmit_response(p, "403 Unauthorized", req);
11270       }
11271       return;
11272    } else if (ast_strlen_zero(c = get_header(req, "Content-Length")) || !strcasecmp(c, "0")) {
11273       /* This is probably just a packet making sure the signalling is still up, just send back a 200 OK */
11274       transmit_response(p, "200 OK", req);
11275       return;
11276    }
11277 
11278    /* Other type of INFO message, not really understood by Asterisk */
11279    /* if (get_msg_text(buf, sizeof(buf), req)) { */
11280 
11281    ast_log(LOG_WARNING, "Unable to parse INFO message from %s. Content %s\n", p->callid, buf);
11282    transmit_response(p, "415 Unsupported media type", req);
11283    return;
11284 }

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 13750 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_setstate(), AST_STATE_DOWN, AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, ast_strdupa, ast_string_field_free, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_uri_decode(), ast_verbose(), AUTH_CHALLENGE_SENT, AUTH_FAKE_AUTH, sip_pvt::autokillid, build_contact(), build_route(), sip_pvt::capability, change_hold_state(), check_user(), check_via(), context, copy_request(), DEC_CALL_LIMIT, DEFAULT_TRANS_TIMEOUT, error(), exten, extract_uri(), FALSE, find_sdp(), sip_pvt::flags, get_destination(), get_header(), get_rdnis(), get_sip_pvt_byid_locked(), handle_invite_replaces(), ast_channel::hangupcause, sip_request::headers, INC_CALL_LIMIT, sip_pvt::initreq, INV_COMPLETED, INV_PROCEEDING, INV_TERMINATED, sip_pvt::invitestate, sip_pvt::jointcapability, sip_pvt::lastinvite, ast_channel::lock, sip_pvt::lock, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, make_our_tag(), option_debug, sip_pvt::owner, parse_ok_contact(), parse_sip_options(), sip_pvt::pendinginvite, process_sdp(), sip_pvt::refer, sip_refer::refer_call, sip_pvt::rtp, S_OR, sip_alreadygone(), sip_cancel_destroy(), SIP_DTMF, SIP_DTMF_RFC2833, sip_handle_t38_reinvite(), SIP_INVITE, sip_new(), SIP_NO_HISTORY, SIP_OPT_REPLACES, SIP_OUTGOING, SIP_PAGE2_ALLOWOVERLAP, SIP_PAGE2_CALL_ONHOLD, SIP_PAGE2_RFC2833_COMPENSATE, SIP_PKT_IGNORE, sip_refer_allocate(), sip_scheddestroy(), sip_tech, sip_tech_info, sipdebug, sip_pvt::sipoptions, t38properties::state, strcasestr(), strsep(), sip_pvt::t38, T38_DISABLED, T38_ENABLED, T38_PEER_REINVITE, sip_pvt::tag, ast_channel::tech, ast_channel::tech_pvt, transmit_fake_auth_response(), transmit_response(), transmit_response_reliable(), transmit_response_with_sdp(), transmit_response_with_t38_sdp(), transmit_response_with_unsupported(), TRUE, sip_pvt::udptl, update_call_counter(), XMIT_CRITICAL, XMIT_RELIABLE, and XMIT_UNRELIABLE.

Referenced by handle_request().

13751 {
13752    int res = 1;
13753    int gotdest;
13754    const char *p_replaces;
13755    char *replace_id = NULL;
13756    const char *required;
13757    unsigned int required_profile = 0;
13758    struct ast_channel *c = NULL;    /* New channel */
13759    int reinvite = 0;
13760 
13761    /* Find out what they support */
13762    if (!p->sipoptions) {
13763       const char *supported = get_header(req, "Supported");
13764       if (!ast_strlen_zero(supported))
13765          parse_sip_options(p, supported);
13766    }
13767 
13768    /* Find out what they require */
13769    required = get_header(req, "Require");
13770    if (!ast_strlen_zero(required)) {
13771       required_profile = parse_sip_options(NULL, required);
13772       if (required_profile && required_profile != SIP_OPT_REPLACES) {
13773          /* At this point we only support REPLACES */
13774          transmit_response_with_unsupported(p, "420 Bad extension (unsupported)", req, required);
13775          ast_log(LOG_WARNING,"Received SIP INVITE with unsupported required extension: %s\n", required);
13776          p->invitestate = INV_COMPLETED;
13777          if (!p->lastinvite)
13778             sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
13779          return -1;
13780       }
13781    }
13782 
13783    /* Check if this is a loop */
13784    if (ast_test_flag(&p->flags[0], SIP_OUTGOING) && p->owner && (p->owner->_state != AST_STATE_UP)) {
13785       /* This is a call to ourself.  Send ourselves an error code and stop
13786          processing immediately, as SIP really has no good mechanism for
13787          being able to call yourself */
13788       /* If pedantic is on, we need to check the tags. If they're different, this is
13789          in fact a forked call through a SIP proxy somewhere. */
13790       transmit_response(p, "482 Loop Detected", req);
13791       p->invitestate = INV_COMPLETED;
13792       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
13793       return 0;
13794    }
13795    
13796    if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->pendinginvite) {
13797       /* We already have a pending invite. Sorry. You are on hold. */
13798       transmit_response(p, "491 Request Pending", req);
13799       if (option_debug)
13800          ast_log(LOG_DEBUG, "Got INVITE on call where we already have pending INVITE, deferring that - %s\n", p->callid);
13801       /* Don't destroy dialog here */
13802       return 0;
13803    }
13804 
13805    p_replaces = get_header(req, "Replaces");
13806    if (!ast_strlen_zero(p_replaces)) {
13807       /* We have a replaces header */
13808       char *ptr;
13809       char *fromtag = NULL;
13810       char *totag = NULL;
13811       char *start, *to;
13812       int error = 0;
13813 
13814       if (p->owner) {
13815          if (option_debug > 2)
13816             ast_log(LOG_DEBUG, "INVITE w Replaces on existing call? Refusing action. [%s]\n", p->callid);
13817          transmit_response(p, "400 Bad request", req);   /* The best way to not not accept the transfer */
13818          /* Do not destroy existing call */
13819          return -1;
13820       }
13821 
13822       if (sipdebug && option_debug > 2)
13823          ast_log(LOG_DEBUG, "INVITE part of call transfer. Replaces [%s]\n", p_replaces);
13824       /* Create a buffer we can manipulate */
13825       replace_id = ast_strdupa(p_replaces);
13826       ast_uri_decode(replace_id);
13827 
13828       if (!p->refer && !sip_refer_allocate(p)) {
13829          transmit_response(p, "500 Server Internal Error", req);
13830          append_history(p, "Xfer", "INVITE/Replace Failed. Out of memory.");
13831          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
13832          p->invitestate = INV_COMPLETED;
13833          return -1;
13834       }
13835 
13836       /*  Todo: (When we find phones that support this)
13837          if the replaces header contains ";early-only"
13838          we can only replace the call in early
13839          stage, not after it's up.
13840 
13841          If it's not in early mode, 486 Busy.
13842       */
13843       
13844       /* Skip leading whitespace */
13845       replace_id = ast_skip_blanks(replace_id);
13846 
13847       start = replace_id;
13848       while ( (ptr = strsep(&start, ";")) ) {
13849          ptr = ast_skip_blanks(ptr); /* XXX maybe unnecessary ? */
13850          if ( (to = strcasestr(ptr, "to-tag=") ) )
13851             totag = to + 7;   /* skip the keyword */
13852          else if ( (to = strcasestr(ptr, "from-tag=") ) ) {
13853             fromtag = to + 9; /* skip the keyword */
13854             fromtag = strsep(&fromtag, "&"); /* trim what ? */
13855          }
13856       }
13857 
13858       if (sipdebug && option_debug > 3) 
13859          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>");
13860 
13861 
13862       /* Try to find call that we are replacing 
13863          If we have a Replaces  header, we need to cancel that call if we succeed with this call 
13864       */
13865       if ((p->refer->refer_call = get_sip_pvt_byid_locked(replace_id, totag, fromtag)) == NULL) {
13866          ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-existent call id (%s)!\n", replace_id);
13867          transmit_response(p, "481 Call Leg Does Not Exist (Replaces)", req);
13868          error = 1;
13869       }
13870 
13871       /* At this point, bot the pvt and the owner of the call to be replaced is locked */
13872 
13873       /* The matched call is the call from the transferer to Asterisk .
13874          We want to bridge the bridged part of the call to the 
13875          incoming invite, thus taking over the refered call */
13876 
13877       if (p->refer->refer_call == p) {
13878          ast_log(LOG_NOTICE, "INVITE with replaces into it's own call id (%s == %s)!\n", replace_id, p->callid);
13879          p->refer->refer_call = NULL;
13880          transmit_response(p, "400 Bad request", req);   /* The best way to not not accept the transfer */
13881          error = 1;
13882       }
13883 
13884       if (!error && !p->refer->refer_call->owner) {
13885          /* Oops, someting wrong anyway, no owner, no call */
13886          ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-existing call id (%s)!\n", replace_id);
13887          /* Check for better return code */
13888          transmit_response(p, "481 Call Leg Does Not Exist (Replace)", req);
13889          error = 1;
13890       }
13891 
13892       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 ) {
13893          ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-ringing or active call id (%s)!\n", replace_id);
13894          transmit_response(p, "603 Declined (Replaces)", req);
13895          error = 1;
13896       }
13897 
13898       if (error) {   /* Give up this dialog */
13899          append_history(p, "Xfer", "INVITE/Replace Failed.");
13900          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
13901          ast_mutex_unlock(&p->lock);
13902          if (p->refer->refer_call) {
13903             ast_mutex_unlock(&p->refer->refer_call->lock);
13904             ast_channel_unlock(p->refer->refer_call->owner);
13905          }
13906          p->invitestate = INV_COMPLETED;
13907          return -1;
13908       }
13909    }
13910 
13911 
13912    /* Check if this is an INVITE that sets up a new dialog or
13913       a re-invite in an existing dialog */
13914 
13915    if (!ast_test_flag(req, SIP_PKT_IGNORE)) {
13916       int newcall = (p->initreq.headers ? TRUE : FALSE);
13917 
13918       if (sip_cancel_destroy(p))
13919          ast_log(LOG_WARNING, "Unable to cancel SIP destruction.  Expect bad things.\n");
13920       /* This also counts as a pending invite */
13921       p->pendinginvite = seqno;
13922       check_via(p, req);
13923 
13924       copy_request(&p->initreq, req);     /* Save this INVITE as the transaction basis */
13925       if (!p->owner) {  /* Not a re-invite */
13926          if (debug)
13927             ast_verbose("Using INVITE request as basis request - %s\n", p->callid);
13928          if (newcall)
13929             append_history(p, "Invite", "New call: %s", p->callid);
13930          parse_ok_contact(p, req);
13931       } else { /* Re-invite on existing call */
13932          ast_clear_flag(&p->flags[0], SIP_OUTGOING);  /* This is now an inbound dialog */
13933          /* Handle SDP here if we already have an owner */
13934          if (find_sdp(req)) {
13935             if (process_sdp(p, req)) {
13936                transmit_response(p, "488 Not acceptable here", req);
13937                if (!p->lastinvite)
13938                   sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
13939                return -1;
13940             }
13941          } else {
13942             p->jointcapability = p->capability;
13943             if (option_debug > 2)
13944                ast_log(LOG_DEBUG, "Hm....  No sdp for the moment\n");
13945             /* Some devices signal they want to be put off hold by sending a re-invite
13946                *without* an SDP, which is supposed to mean "Go back to your state"
13947                and since they put os on remote hold, we go back to off hold */
13948             if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD))
13949                change_hold_state(p, req, FALSE, 0);
13950          }
13951          if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) /* This is a response, note what it was for */
13952             append_history(p, "ReInv", "Re-invite received");
13953       }
13954    } else if (debug)
13955       ast_verbose("Ignoring this INVITE request\n");
13956 
13957    
13958    if (!p->lastinvite && !ast_test_flag(req, SIP_PKT_IGNORE) && !p->owner) {
13959       /* This is a new invite */
13960       /* Handle authentication if this is our first invite */
13961       res = check_user(p, req, SIP_INVITE, e, XMIT_RELIABLE, sin);
13962       if (res == AUTH_CHALLENGE_SENT) {
13963          p->invitestate = INV_COMPLETED;     /* Needs to restart in another INVITE transaction */
13964          return 0;
13965       }
13966       if (res < 0) { /* Something failed in authentication */
13967          if (res == AUTH_FAKE_AUTH) {
13968             ast_log(LOG_NOTICE, "Sending fake auth rejection for user %s\n", get_header(req, "From"));
13969             transmit_fake_auth_response(p, req, 1);
13970          } else {
13971             ast_log(LOG_NOTICE, "Failed to authenticate user %s\n", get_header(req, "From"));
13972             transmit_response_reliable(p, "403 Forbidden", req);
13973          }
13974          p->invitestate = INV_COMPLETED;  
13975          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
13976          ast_string_field_free(p, theirtag);
13977          return 0;
13978       }
13979 
13980       /* We have a succesful authentication, process the SDP portion if there is one */
13981       if (find_sdp(req)) {
13982          if (process_sdp(p, req)) {
13983             /* Unacceptable codecs */
13984             transmit_response_reliable(p, "488 Not acceptable here", req);
13985             p->invitestate = INV_COMPLETED;  
13986             sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
13987             if (option_debug)
13988                ast_log(LOG_DEBUG, "No compatible codecs for this SIP call.\n");
13989             return -1;
13990          }
13991       } else { /* No SDP in invite, call control session */
13992          p->jointcapability = p->capability;
13993          if (option_debug > 1)
13994             ast_log(LOG_DEBUG, "No SDP in Invite, third party call control\n");
13995       }
13996 
13997       /* Queue NULL frame to prod ast_rtp_bridge if appropriate */
13998       /* This seems redundant ... see !p-owner above */
13999       if (p->owner)
14000          ast_queue_frame(p->owner, &ast_null_frame);
14001 
14002 
14003       /* Initialize the context if it hasn't been already */
14004       if (ast_strlen_zero(p->context))
14005          ast_string_field_set(p, context, default_context);
14006 
14007 
14008       /* Check number of concurrent calls -vs- incoming limit HERE */
14009       if (option_debug)
14010          ast_log(LOG_DEBUG, "Checking SIP call limits for device %s\n", p->username);
14011       if ((res = update_call_counter(p, INC_CALL_LIMIT))) {
14012          if (res < 0) {
14013             ast_log(LOG_NOTICE, "Failed to place call for user %s, too many calls\n", p->username);
14014             transmit_response_reliable(p, "480 Temporarily Unavailable (Call limit) ", req);
14015             sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
14016             p->invitestate = INV_COMPLETED;  
14017          }
14018          return 0;
14019       }
14020       gotdest = get_destination(p, NULL); /* Get destination right away */
14021       get_rdnis(p, NULL);        /* Get redirect information */
14022       extract_uri(p, req);       /* Get the Contact URI */
14023       build_contact(p);       /* Build our contact header */
14024 
14025       if (p->rtp) {
14026          ast_rtp_setdtmf(p->rtp, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833);
14027          ast_rtp_setdtmfcompensate(p->rtp, ast_test_flag(&p->flags[1], SIP_PAGE2_RFC2833_COMPENSATE));
14028       }
14029 
14030       if (!replace_id && gotdest) { /* No matching extension found */
14031          if (gotdest == 1 && ast_test_flag(&p->flags[1], SIP_PAGE2_ALLOWOVERLAP))
14032             transmit_response_reliable(p, "484 Address Incomplete", req);
14033          else {
14034             transmit_response_reliable(p, "404 Not Found", req);
14035             ast_log(LOG_NOTICE, "Call from '%s' to extension"
14036                " '%s' rejected because extension not found.\n",
14037                S_OR(p->username, p->peername), p->exten);
14038          }
14039          p->invitestate = INV_COMPLETED;  
14040          update_call_counter(p, DEC_CALL_LIMIT);
14041          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
14042          return 0;
14043       } else {
14044          /* If no extension was specified, use the s one */
14045          /* Basically for calling to IP/Host name only */
14046          if (ast_strlen_zero(p->exten))
14047             ast_string_field_set(p, exten, "s");
14048          /* Initialize our tag */   
14049 
14050          make_our_tag(p->tag, sizeof(p->tag));
14051          /* First invitation - create the channel */
14052          c = sip_new(p, AST_STATE_DOWN, S_OR(p->username, NULL));
14053          *recount = 1;
14054 
14055          /* Save Record-Route for any later requests we make on this dialogue */
14056          build_route(p, req, 0);
14057 
14058          if (c) {
14059             /* Pre-lock the call */
14060             ast_channel_lock(c);
14061          }
14062       }
14063    } else {
14064       if (option_debug > 1 && sipdebug) {
14065          if (!ast_test_flag(req, SIP_PKT_IGNORE))
14066             ast_log(LOG_DEBUG, "Got a SIP re-invite for call %s\n", p->callid);
14067          else
14068             ast_log(LOG_DEBUG, "Got a SIP re-transmit of INVITE for call %s\n", p->callid);
14069       }
14070       reinvite = 1;
14071       c = p->owner;
14072    }
14073 
14074    if (!ast_test_flag(req, SIP_PKT_IGNORE) && p)
14075       p->lastinvite = seqno;
14076 
14077    if (replace_id) {    /* Attended transfer or call pickup - we're the target */
14078       /* Go and take over the target call */
14079       if (sipdebug && option_debug > 3)
14080          ast_log(LOG_DEBUG, "Sending this call to the invite/replcaes handler %s\n", p->callid);
14081       return handle_invite_replaces(p, req, debug, ast_test_flag(req, SIP_PKT_IGNORE), seqno, sin);
14082    }
14083 
14084 
14085    if (c) { /* We have a call  -either a new call or an old one (RE-INVITE) */
14086       switch(c->_state) {
14087       case AST_STATE_DOWN:
14088          if (option_debug > 1)
14089             ast_log(LOG_DEBUG, "%s: New call is still down.... Trying... \n", c->name);
14090          transmit_response(p, "100 Trying", req);
14091          p->invitestate = INV_PROCEEDING;
14092          ast_setstate(c, AST_STATE_RING);
14093          if (strcmp(p->exten, ast_pickup_ext())) { /* Call to extension -start pbx on this call */
14094             enum ast_pbx_result res;
14095 
14096             res = ast_pbx_start(c);
14097 
14098             switch(res) {
14099             case AST_PBX_FAILED:
14100                ast_log(LOG_WARNING, "Failed to start PBX :(\n");
14101                p->invitestate = INV_COMPLETED;
14102                if (ast_test_flag(req, SIP_PKT_IGNORE))
14103                   transmit_response(p, "503 Unavailable", req);
14104                else
14105                   transmit_response_reliable(p, "503 Unavailable", req);
14106                break;
14107             case AST_PBX_CALL_LIMIT:
14108                ast_log(LOG_WARNING, "Failed to start PBX (call limit reached) \n");
14109                p->invitestate = INV_COMPLETED;
14110                if (ast_test_flag(req, SIP_PKT_IGNORE))
14111                   transmit_response(p, "480 Temporarily Unavailable", req);
14112                else
14113                   transmit_response_reliable(p, "480 Temporarily Unavailable", req);
14114                break;
14115             case AST_PBX_SUCCESS:
14116                /* nothing to do */
14117                break;
14118             }
14119 
14120             if (res) {
14121 
14122                /* Unlock locks so ast_hangup can do its magic */
14123                ast_mutex_unlock(&c->lock);
14124                ast_mutex_unlock(&p->lock);
14125                ast_hangup(c);
14126                ast_mutex_lock(&p->lock);
14127                c = NULL;
14128             }
14129          } else { /* Pickup call in call group */
14130             ast_channel_unlock(c);
14131             *nounlock = 1;
14132             if (ast_pickup_call(c)) {
14133                ast_log(LOG_NOTICE, "Nothing to pick up for %s\n", p->callid);
14134                if (ast_test_flag(req, SIP_PKT_IGNORE))
14135                   transmit_response(p, "503 Unavailable", req);   /* OEJ - Right answer? */
14136                else
14137                   transmit_response_reliable(p, "503 Unavailable", req);
14138                sip_alreadygone(p);
14139                /* Unlock locks so ast_hangup can do its magic */
14140                ast_mutex_unlock(&p->lock);
14141                c->hangupcause = AST_CAUSE_CALL_REJECTED;
14142             } else {
14143                ast_mutex_unlock(&p->lock);
14144                ast_setstate(c, AST_STATE_DOWN);
14145                c->hangupcause = AST_CAUSE_NORMAL_CLEARING;
14146             }
14147             p->invitestate = INV_COMPLETED;
14148             ast_hangup(c);
14149             ast_mutex_lock(&p->lock);
14150             c = NULL;
14151          }
14152          break;
14153       case AST_STATE_RING:
14154          transmit_response(p, "100 Trying", req);
14155          p->invitestate = INV_PROCEEDING;
14156          break;
14157       case AST_STATE_RINGING:
14158          transmit_response(p, "180 Ringing", req);
14159          p->invitestate = INV_PROCEEDING;
14160          break;
14161       case AST_STATE_UP:
14162          if (option_debug > 1)
14163             ast_log(LOG_DEBUG, "%s: This call is UP.... \n", c->name);
14164 
14165          transmit_response(p, "100 Trying", req);
14166 
14167          if (p->t38.state == T38_PEER_REINVITE) {
14168             struct ast_channel *bridgepeer = NULL;
14169             struct sip_pvt *bridgepvt = NULL;
14170             
14171             if ((bridgepeer = ast_bridged_channel(p->owner))) {
14172                /* 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*/
14173                /*! XXX: we should also check here does the other side supports t38 at all !!! XXX */
14174                if (bridgepeer->tech == &sip_tech || bridgepeer->tech == &sip_tech_info) {
14175                   bridgepvt = (struct sip_pvt*)bridgepeer->tech_pvt;
14176                   if (bridgepvt->t38.state == T38_DISABLED) {
14177                      if (bridgepvt->udptl) { /* If everything is OK with other side's udptl struct */
14178                         /* Send re-invite to the bridged channel */
14179                         sip_handle_t38_reinvite(bridgepeer, p, 1);
14180                      } else { /* Something is wrong with peers udptl struct */
14181                         ast_log(LOG_WARNING, "Strange... The other side of the bridge don't have udptl struct\n");
14182                         ast_mutex_lock(&bridgepvt->lock);
14183                         bridgepvt->t38.state = T38_DISABLED;
14184                         ast_mutex_unlock(&bridgepvt->lock);
14185                         if (option_debug > 1)
14186                            ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", bridgepvt->t38.state, bridgepeer->name);
14187                         if (ast_test_flag(req, SIP_PKT_IGNORE))
14188                            transmit_response(p, "488 Not acceptable here", req);
14189                         else
14190                            transmit_response_reliable(p, "488 Not acceptable here", req);
14191                      
14192                      }
14193                   } else {
14194                      /* The other side is already setup for T.38 most likely so we need to acknowledge this too */
14195                      transmit_response_with_t38_sdp(p, "200 OK", req, XMIT_CRITICAL);
14196                      p->t38.state = T38_ENABLED;
14197                      if (option_debug)
14198                         ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>");
14199                   }
14200                } else {
14201                   /* Other side is not a SIP channel */
14202                   if (ast_test_flag(req, SIP_PKT_IGNORE))
14203                      transmit_response(p, "488 Not acceptable here", req);
14204                   else
14205                      transmit_response_reliable(p, "488 Not acceptable here", req);
14206                   p->t38.state = T38_DISABLED;
14207                   if (option_debug > 1)
14208                      ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>");
14209 
14210                   if (!p->lastinvite) /* Only destroy if this is *not* a re-invite */
14211                      sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
14212                }
14213             } else {
14214                /* we are not bridged in a call */
14215                transmit_response_with_t38_sdp(p, "200 OK", req, XMIT_CRITICAL);
14216                p->t38.state = T38_ENABLED;
14217                if (option_debug)
14218                   ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>");
14219             }
14220          } else if (p->t38.state == T38_DISABLED) { /* Channel doesn't have T38 offered or enabled */
14221             int sendok = TRUE;
14222 
14223             /* If we are bridged to a channel that has T38 enabled than this is a case of RTP re-invite after T38 session */
14224             /* so handle it here (re-invite other party to RTP) */
14225             struct ast_channel *bridgepeer = NULL;
14226             struct sip_pvt *bridgepvt = NULL;
14227             if ((bridgepeer = ast_bridged_channel(p->owner))) {
14228                if ((bridgepeer->tech == &sip_tech || bridgepeer->tech == &sip_tech_info) && !ast_check_hangup(bridgepeer)) {
14229                   bridgepvt = (struct sip_pvt*)bridgepeer->tech_pvt;
14230                   /* Does the bridged peer have T38 ? */
14231                   if (bridgepvt->t38.state == T38_ENABLED) {
14232                      ast_log(LOG_WARNING, "RTP re-invite after T38 session not handled yet !\n");
14233                      /* Insted of this we should somehow re-invite the other side of the bridge to RTP */
14234                      if (ast_test_flag(req, SIP_PKT_IGNORE))
14235                         transmit_response(p, "488 Not Acceptable Here (unsupported)", req);
14236                      else
14237                         transmit_response_reliable(p, "488 Not Acceptable Here (unsupported)", req);
14238                      sendok = FALSE;
14239                   } 
14240                   /* No bridged peer with T38 enabled*/
14241                }
14242             } 
14243             /* Respond to normal re-invite */
14244             if (sendok)
14245                /* If this is not a re-invite or something to ignore - it's critical */
14246                transmit_response_with_sdp(p, "200 OK", req, (reinvite ? XMIT_RELIABLE : (ast_test_flag(req, SIP_PKT_IGNORE) ? XMIT_UNRELIABLE : XMIT_CRITICAL)));
14247          }
14248          p->invitestate = INV_TERMINATED;
14249          break;
14250       default:
14251          ast_log(LOG_WARNING, "Don't know how to handle INVITE in state %d\n", c->_state);
14252          transmit_response(p, "100 Trying", req);
14253          break;
14254       }
14255    } else {
14256       if (p && (p->autokillid == -1)) {
14257          const char *msg;
14258 
14259          if (!p->jointcapability)
14260             msg = "488 Not Acceptable Here (codec error)";
14261          else {
14262             ast_log(LOG_NOTICE, "Unable to create/find SIP channel for this INVITE\n");
14263             msg = "503 Unavailable";
14264          }
14265          if (ast_test_flag(req, SIP_PKT_IGNORE))
14266             transmit_response(p, msg, req);
14267          else
14268             transmit_response_reliable(p, msg, req);
14269          p->invitestate = INV_COMPLETED;
14270          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
14271       }
14272    }
14273    return res;
14274 }

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

Handle incoming MESSAGE request.

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

14894 {
14895    if (!ast_test_flag(req, SIP_PKT_IGNORE)) {
14896       if (ast_test_flag(req, SIP_PKT_DEBUG))
14897          ast_verbose("Receiving message!\n");
14898       receive_message(p, req);
14899    } else
14900       transmit_response(p, "202 Accepted", req);
14901    return 1;
14902 }

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

13424 {
13425    /* This is mostly a skeleton for future improvements */
13426    /* Mostly created to return proper answers on notifications on outbound REFER's */
13427    int res = 0;
13428    const char *event = get_header(req, "Event");
13429    char *eventid = NULL;
13430    char *sep;
13431 
13432    if( (sep = strchr(event, ';')) ) {  /* XXX bug here - overwriting string ? */
13433       *sep++ = '\0';
13434       eventid = sep;
13435    }
13436    
13437    if (option_debug > 1 && sipdebug)
13438       ast_log(LOG_DEBUG, "Got NOTIFY Event: %s\n", event);
13439 
13440    if (strcmp(event, "refer")) {
13441       /* We don't understand this event. */
13442       /* Here's room to implement incoming voicemail notifications :-) */
13443       transmit_response(p, "489 Bad event", req);
13444       res = -1;
13445    } else {
13446       /* Save nesting depth for now, since there might be other events we will
13447          support in the future */
13448 
13449       /* Handle REFER notifications */
13450 
13451       char buf[1024];
13452       char *cmd, *code;
13453       int respcode;
13454       int success = TRUE;
13455 
13456       /* EventID for each transfer... EventID is basically the REFER cseq 
13457 
13458        We are getting notifications on a call that we transfered
13459        We should hangup when we are getting a 200 OK in a sipfrag
13460        Check if we have an owner of this event */
13461       
13462       /* Check the content type */
13463       if (strncasecmp(get_header(req, "Content-Type"), "message/sipfrag", strlen("message/sipfrag"))) {
13464          /* We need a sipfrag */
13465          transmit_response(p, "400 Bad request", req);
13466          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
13467          return -1;
13468       }
13469 
13470       /* Get the text of the attachment */
13471       if (get_msg_text(buf, sizeof(buf), req)) {
13472          ast_log(LOG_WARNING, "Unable to retrieve attachment from NOTIFY %s\n", p->callid);
13473          transmit_response(p, "400 Bad request", req);
13474          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
13475          return -1;
13476       }
13477 
13478       /*
13479       From the RFC...
13480       A minimal, but complete, implementation can respond with a single
13481          NOTIFY containing either the body:
13482                SIP/2.0 100 Trying
13483       
13484          if the subscription is pending, the body:
13485                SIP/2.0 200 OK
13486          if the reference was successful, the body:
13487                SIP/2.0 503 Service Unavailable
13488          if the reference failed, or the body:
13489                SIP/2.0 603 Declined
13490 
13491          if the REFER request was accepted before approval to follow the
13492          reference could be obtained and that approval was subsequently denied
13493          (see Section 2.4.7).
13494       
13495       If there are several REFERs in the same dialog, we need to
13496       match the ID of the event header...
13497       */
13498       if (option_debug > 2)
13499          ast_log(LOG_DEBUG, "* SIP Transfer NOTIFY Attachment: \n---%s\n---\n", buf);
13500       cmd = ast_skip_blanks(buf);
13501       code = cmd;
13502       /* We are at SIP/2.0 */
13503       while(*code && (*code > 32)) {   /* Search white space */
13504          code++;
13505       }
13506       *code++ = '\0';
13507       code = ast_skip_blanks(code);
13508       sep = code;
13509       sep++;
13510       while(*sep && (*sep > 32)) {  /* Search white space */
13511          sep++;
13512       }
13513       *sep++ = '\0';       /* Response string */
13514       respcode = atoi(code);
13515       switch (respcode) {
13516       case 100:   /* Trying: */
13517       case 101:   /* dialog establishment */
13518          /* Don't do anything yet */
13519          break;
13520       case 183:   /* Ringing: */
13521          /* Don't do anything yet */
13522          break;
13523       case 200:   /* OK: The new call is up, hangup this call */
13524          /* Hangup the call that we are replacing */
13525          break;
13526       case 301: /* Moved permenantly */
13527       case 302: /* Moved temporarily */
13528          /* Do we get the header in the packet in this case? */
13529          success = FALSE;
13530          break;
13531       case 503:   /* Service Unavailable: The new call failed */
13532             /* Cancel transfer, continue the call */
13533          success = FALSE;
13534          break;
13535       case 603:   /* Declined: Not accepted */
13536             /* Cancel transfer, continue the current call */
13537          success = FALSE;
13538          break;
13539       }
13540       if (!success) {
13541          ast_log(LOG_NOTICE, "Transfer failed. Sorry. Nothing further to do with this call\n");
13542       }
13543       
13544       /* Confirm that we received this packet */
13545       transmit_response(p, "200 OK", req);
13546    };
13547 
13548    if (!p->lastinvite)
13549       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
13550 
13551    return res;
13552 }

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

Handle incoming OPTIONS request.

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

13556 {
13557    int res;
13558 
13559    res = get_destination(p, req);
13560    build_contact(p);
13561 
13562    /* XXX Should we authenticate OPTIONS? XXX */
13563 
13564    if (ast_strlen_zero(p->context))
13565       ast_string_field_set(p, context, default_context);
13566 
13567    if (ast_shutting_down())
13568       transmit_response_with_allow(p, "503 Unavailable", req, 0);
13569    else if (res < 0)
13570       transmit_response_with_allow(p, "404 Not Found", req, 0);
13571    else 
13572       transmit_response_with_allow(p, "200 OK", req, 0);
13573 
13574    /* Destroy if this OPTIONS was the opening request, but not if
13575       it's in the middle of a normal call flow. */
13576    if (!p->lastinvite)
13577       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
13578 
13579    return res;
13580 }

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

14443 {
14444    struct sip_dual current;   /* Chan1: Call between asterisk and transferer */
14445                /* Chan2: Call between asterisk and transferee */
14446 
14447    int res = 0;
14448 
14449    if (ast_test_flag(req, SIP_PKT_DEBUG))
14450       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");
14451 
14452    if (!p->owner) {
14453       /* This is a REFER outside of an existing SIP dialog */
14454       /* We can't handle that, so decline it */
14455       if (option_debug > 2)
14456          ast_log(LOG_DEBUG, "Call %s: Declined REFER, outside of dialog...\n", p->callid);
14457       transmit_response(p, "603 Declined (No dialog)", req);
14458       if (!ast_test_flag(req, SIP_PKT_IGNORE)) {
14459          append_history(p, "Xfer", "Refer failed. Outside of dialog.");
14460          sip_alreadygone(p);
14461          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
14462       }
14463       return 0;
14464    }  
14465 
14466 
14467    /* Check if transfer is allowed from this device */
14468    if (p->allowtransfer == TRANSFER_CLOSED ) {
14469       /* Transfer not allowed, decline */
14470       transmit_response(p, "603 Declined (policy)", req);
14471       append_history(p, "Xfer", "Refer failed. Allowtransfer == closed.");
14472       /* Do not destroy SIP session */
14473       return 0;
14474    }
14475 
14476    if(!ignore && ast_test_flag(&p->flags[0], SIP_GOTREFER)) {
14477       /* Already have a pending REFER */  
14478       transmit_response(p, "491 Request pending", req);
14479       append_history(p, "Xfer", "Refer failed. Request pending.");
14480       return 0;
14481    }
14482 
14483    /* Allocate memory for call transfer data */
14484    if (!p->refer && !sip_refer_allocate(p)) {
14485       transmit_response(p, "500 Internal Server Error", req);
14486       append_history(p, "Xfer", "Refer failed. Memory allocation error.");
14487       return -3;
14488    }
14489 
14490    res = get_refer_info(p, req); /* Extract headers */
14491 
14492    p->refer->status = REFER_SENT;
14493 
14494    if (res != 0) {
14495       switch (res) {
14496       case -2: /* Syntax error */
14497          transmit_response(p, "400 Bad Request (Refer-to missing)", req);
14498          append_history(p, "Xfer", "Refer failed. Refer-to missing.");
14499          if (ast_test_flag(req, SIP_PKT_DEBUG) && option_debug)
14500             ast_log(LOG_DEBUG, "SIP transfer to black hole can't be handled (no refer-to: )\n");
14501          break;
14502       case -3:
14503          transmit_response(p, "603 Declined (Non sip: uri)", req);
14504          append_history(p, "Xfer", "Refer failed. Non SIP uri");
14505          if (ast_test_flag(req, SIP_PKT_DEBUG) && option_debug)
14506             ast_log(LOG_DEBUG, "SIP transfer to non-SIP uri denied\n");
14507          break;
14508       default:
14509          /* Refer-to extension not found, fake a failed transfer */
14510          transmit_response(p, "202 Accepted", req);
14511          append_history(p, "Xfer", "Refer failed. Bad extension.");
14512          transmit_notify_with_sipfrag(p, seqno, "404 Not found", TRUE);
14513          ast_clear_flag(&p->flags[0], SIP_GOTREFER);  
14514          if (ast_test_flag(req, SIP_PKT_DEBUG) && option_debug)
14515             ast_log(LOG_DEBUG, "SIP transfer to bad extension: %s\n", p->refer->refer_to);
14516          break;
14517       } 
14518       return 0;
14519    }
14520    if (ast_strlen_zero(p->context))
14521       ast_string_field_set(p, context, default_context);
14522 
14523    /* If we do not support SIP domains, all transfers are local */
14524    if (allow_external_domains && check_sip_domain(p->refer->refer_to_domain, NULL, 0)) {
14525       p->refer->localtransfer = 1;
14526       if (sipdebug && option_debug > 2)
14527          ast_log(LOG_DEBUG, "This SIP transfer is local : %s\n", p->refer->refer_to_domain);
14528    } else if (AST_LIST_EMPTY(&domain_list) || check_sip_domain(p->refer->refer_to_domain, NULL, 0)) {
14529       /* This PBX doesn't bother with SIP domains or domain is local, so this transfer is local */
14530       p->refer->localtransfer = 1;
14531    } else if (sipdebug && option_debug > 2)
14532          ast_log(LOG_DEBUG, "This SIP transfer is to a remote SIP extension (remote domain %s)\n", p->refer->refer_to_domain);
14533    
14534    /* Is this a repeat of a current request? Ignore it */
14535    /* Don't know what else to do right now. */
14536    if (ignore) 
14537       return res;
14538 
14539    /* If this is a blind transfer, we have the following
14540       channels to work with:
14541       - chan1, chan2: The current call between transferer and transferee (2 channels)
14542       - target_channel: A new call from the transferee to the target (1 channel)
14543       We need to stay tuned to what happens in order to be able
14544       to bring back the call to the transferer */
14545 
14546    /* If this is a attended transfer, we should have all call legs within reach:
14547       - chan1, chan2: The call between the transferer and transferee (2 channels)
14548       - target_channel, targetcall_pvt: The call between the transferer and the target (2 channels)
14549    We want to bridge chan2 with targetcall_pvt!
14550    
14551       The replaces call id in the refer message points
14552       to the call leg between Asterisk and the transferer.
14553       So we need to connect the target and the transferee channel
14554       and hangup the two other channels silently 
14555    
14556       If the target is non-local, the call ID could be on a remote
14557       machine and we need to send an INVITE with replaces to the
14558       target. We basically handle this as a blind transfer
14559       and let the sip_call function catch that we need replaces
14560       header in the INVITE.
14561    */
14562 
14563 
14564    /* Get the transferer's channel */
14565    current.chan1 = p->owner;
14566 
14567    /* Find the other part of the bridge (2) - transferee */
14568    current.chan2 = ast_bridged_channel(current.chan1);
14569    
14570    if (sipdebug && option_debug > 2)
14571       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>");
14572 
14573    if (!current.chan2 && !p->refer->attendedtransfer) {
14574       /* No bridged channel, propably IVR or echo or similar... */
14575       /* Guess we should masquerade or something here */
14576       /* Until we figure it out, refuse transfer of such calls */
14577       if (sipdebug && option_debug > 2)
14578          ast_log(LOG_DEBUG,"Refused SIP transfer on non-bridged channel.\n");
14579       p->refer->status = REFER_FAILED;
14580       append_history(p, "Xfer", "Refer failed. Non-bridged channel.");
14581       transmit_response(p, "603 Declined", req);
14582       return -1;
14583    }
14584 
14585    if (current.chan2) {
14586       if (sipdebug && option_debug > 3)
14587          ast_log(LOG_DEBUG, "Got SIP transfer, applying to bridged peer '%s'\n", current.chan2->name);
14588 
14589       ast_queue_control(current.chan1, AST_CONTROL_UNHOLD);
14590    }
14591 
14592    ast_set_flag(&p->flags[0], SIP_GOTREFER); 
14593 
14594    /* Attended transfer: Find all call legs and bridge transferee with target*/
14595    if (p->refer->attendedtransfer) {
14596       if ((res = local_attended_transfer(p, &current, req, seqno)))
14597          return res; /* We're done with the transfer */
14598       /* Fall through for remote transfers that we did not find locally */
14599       if (sipdebug && option_debug > 3)
14600          ast_log(LOG_DEBUG, "SIP attended transfer: Still not our call - generating INVITE with replaces\n");
14601       /* Fallthrough if we can't find the call leg internally */
14602    }
14603 
14604 
14605    /* Parking a call */
14606    if (p->refer->localtransfer && !strcmp(p->refer->refer_to, ast_parking_ext())) {
14607       /* Must release c's lock now, because it will not longer be accessible after the transfer! */
14608       *nounlock = 1;
14609       ast_channel_unlock(current.chan1);
14610       copy_request(&current.req, req);
14611       ast_clear_flag(&p->flags[0], SIP_GOTREFER);  
14612       p->refer->status = REFER_200OK;
14613       append_history(p, "Xfer", "REFER to call parking.");
14614       if (sipdebug && option_debug > 3)
14615          ast_log(LOG_DEBUG, "SIP transfer to parking: trying to park %s. Parked by %s\n", current.chan2->name, current.chan1->name);
14616       sip_park(current.chan2, current.chan1, req, seqno);
14617       return res;
14618    } 
14619 
14620    /* Blind transfers and remote attended xfers */
14621    transmit_response(p, "202 Accepted", req);
14622 
14623    if (current.chan1 && current.chan2) {
14624       if (option_debug > 2)
14625          ast_log(LOG_DEBUG, "chan1->name: %s\n", current.chan1->name);
14626       pbx_builtin_setvar_helper(current.chan1, "BLINDTRANSFER", current.chan2->name);
14627    }
14628    if (current.chan2) {
14629       pbx_builtin_setvar_helper(current.chan2, "BLINDTRANSFER", current.chan1->name);
14630       pbx_builtin_setvar_helper(current.chan2, "SIPDOMAIN", p->refer->refer_to_domain);
14631       pbx_builtin_setvar_helper(current.chan2, "SIPTRANSFER", "yes");
14632       /* One for the new channel */
14633       pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER", "yes");
14634       /* Attended transfer to remote host, prepare headers for the INVITE */
14635       if (p->refer->referred_by) 
14636          pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER_REFERER", p->refer->referred_by);
14637    }
14638    /* Generate a Replaces string to be used in the INVITE during attended transfer */
14639    if (p->refer->replaces_callid && !ast_strlen_zero(p->refer->replaces_callid)) {
14640       char tempheader[SIPBUFSIZE];
14641       snprintf(tempheader, sizeof(tempheader), "%s%s%s%s%s", p->refer->replaces_callid, 
14642             p->refer->replaces_callid_totag ? ";to-tag=" : "", 
14643             p->refer->replaces_callid_totag, 
14644             p->refer->replaces_callid_fromtag ? ";from-tag=" : "",
14645             p->refer->replaces_callid_fromtag);
14646       if (current.chan2)
14647          pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER_REPLACES", tempheader);
14648    }
14649    /* Must release lock now, because it will not longer
14650          be accessible after the transfer! */
14651    *nounlock = 1;
14652    ast_channel_unlock(current.chan1);
14653 
14654    /* Connect the call */
14655 
14656    /* FAKE ringing if not attended transfer */
14657    if (!p->refer->attendedtransfer)
14658       transmit_notify_with_sipfrag(p, seqno, "183 Ringing", FALSE); 
14659       
14660    /* For blind transfer, this will lead to a new call */
14661    /* For attended transfer to remote host, this will lead to
14662          a new SIP call with a replaces header, if the dial plan allows it 
14663    */
14664    if (!current.chan2) {
14665       /* We have no bridge, so we're talking with Asterisk somehow */
14666       /* We need to masquerade this call */
14667       /* What to do to fix this situation:
14668          * Set up the new call in a new channel 
14669          * Let the new channel masq into this channel
14670          Please add that code here :-)
14671       */
14672       p->refer->status = REFER_FAILED;
14673       transmit_notify_with_sipfrag(p, seqno, "503 Service Unavailable (can't handle one-legged xfers)", TRUE);
14674       ast_clear_flag(&p->flags[0], SIP_GOTREFER);  
14675       append_history(p, "Xfer", "Refer failed (only bridged calls).");
14676       return -1;
14677    }
14678    ast_set_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER);   /* Delay hangup */
14679 
14680    /* For blind transfers, move the call to the new extensions. For attended transfers on multiple
14681       servers - generate an INVITE with Replaces. Either way, let the dial plan decided  */
14682    res = ast_async_goto(current.chan2, p->refer->refer_to_context, p->refer->refer_to, 1);
14683 
14684    if (!res) {
14685       /* Success  - we have a new channel */
14686       if (option_debug > 2)
14687          ast_log(LOG_DEBUG, "%s transfer succeeded. Telling transferer.\n", p->refer->attendedtransfer? "Attended" : "Blind");
14688       transmit_notify_with_sipfrag(p, seqno, "200 Ok", TRUE);
14689       if (p->refer->localtransfer)
14690          p->refer->status = REFER_200OK;
14691       if (p->owner)
14692          p->owner->hangupcause = AST_CAUSE_NORMAL_CLEARING;
14693       append_history(p, "Xfer", "Refer succeeded.");
14694       ast_clear_flag(&p->flags[0], SIP_GOTREFER);  
14695       /* Do not hangup call, the other side do that when we say 200 OK */
14696       /* We could possibly implement a timer here, auto congestion */
14697       res = 0;
14698    } else {
14699       ast_clear_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Don't delay hangup */
14700       if (option_debug > 2)
14701          ast_log(LOG_DEBUG, "%s transfer failed. Resuming original call.\n", p->refer->attendedtransfer? "Attended" : "Blind");
14702       append_history(p, "Xfer", "Refer failed.");
14703       /* Failure of some kind */
14704       p->refer->status = REFER_FAILED;
14705       transmit_notify_with_sipfrag(p, seqno, "503 Service Unavailable", TRUE);
14706       ast_clear_flag(&p->flags[0], SIP_GOTREFER);  
14707       res = -1;
14708    }
14709    return res;
14710 }

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

15202 {
15203    enum check_auth_result res;
15204 
15205    /* Use this as the basis */
15206    if (ast_test_flag(req, SIP_PKT_DEBUG))
15207       ast_verbose("Using latest REGISTER request as basis request\n");
15208    copy_request(&p->initreq, req);
15209    check_via(p, req);
15210    if ((res = register_verify(p, sin, req, e)) < 0) {
15211       const char *reason;
15212 
15213       switch (res) {
15214       case AUTH_SECRET_FAILED:
15215          reason = "Wrong password";
15216          break;
15217       case AUTH_USERNAME_MISMATCH:
15218          reason = "Username/auth name mismatch";
15219          break;
15220       case AUTH_NOT_FOUND:
15221          reason = "No matching peer found";
15222          break;
15223       case AUTH_UNKNOWN_DOMAIN:
15224          reason = "Not a local domain";
15225          break;
15226       case AUTH_PEER_NOT_DYNAMIC:
15227          reason = "Peer is not supposed to register";
15228          break;
15229       case AUTH_ACL_FAILED:
15230          reason = "Device does not match ACL";
15231          break;
15232       default:
15233          reason = "Unknown failure";
15234          break;
15235       }
15236       ast_log(LOG_NOTICE, "Registration from '%s' failed for '%s' - %s\n",
15237          get_header(req, "To"), ast_inet_ntoa(sin->sin_addr),
15238          reason);
15239       append_history(p, "RegRequest", "Failed : Account %s : %s", get_header(req, "To"), reason);
15240    } else
15241       append_history(p, "RegRequest", "Succeeded : Account %s", get_header(req, "To"));
15242 
15243    if (res < 1) {
15244       /* Destroy the session, but keep us around for just a bit in case they don't
15245          get our 200 OK */
15246       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
15247    }
15248    return res;
15249 }

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 14905 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(), and XPIDF_XML.

Referenced by handle_request().

14906 {
14907    int gotdest;
14908    int res = 0;
14909    int firststate = AST_EXTENSION_REMOVED;
14910    struct sip_peer *authpeer = NULL;
14911    const char *eventheader = get_header(req, "Event");   /* Get Event package name */
14912    const char *accept = get_header(req, "Accept");
14913    int resubscribe = (p->subscribed != NONE);
14914    char *temp, *event;
14915 
14916    if (p->initreq.headers) {  
14917       /* We already have a dialog */
14918       if (p->initreq.method != SIP_SUBSCRIBE) {
14919          /* This is a SUBSCRIBE within another SIP dialog, which we do not support */
14920          /* For transfers, this could happen, but since we haven't seen it happening, let us just refuse this */
14921          transmit_response(p, "403 Forbidden (within dialog)", req);
14922          /* Do not destroy session, since we will break the call if we do */
14923          if (option_debug)
14924             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);
14925          return 0;
14926       } else if (ast_test_flag(req, SIP_PKT_DEBUG)) {
14927          if (option_debug) {
14928             if (resubscribe)
14929                ast_log(LOG_DEBUG, "Got a re-subscribe on existing subscription %s\n", p->callid);
14930             else
14931                ast_log(LOG_DEBUG, "Got a new subscription %s (possibly with auth)\n", p->callid);
14932          }
14933       }
14934    }
14935 
14936    /* Check if we have a global disallow setting on subscriptions. 
14937       if so, we don't have to check peer/user settings after auth, which saves a lot of processing
14938    */
14939    if (!global_allowsubscribe) {
14940       transmit_response(p, "403 Forbidden (policy)", req);
14941       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
14942       return 0;
14943    }
14944 
14945    if (!ast_test_flag(req, SIP_PKT_IGNORE) && !resubscribe) {  /* Set up dialog, new subscription */
14946       const char *to = get_header(req, "To");
14947       char totag[128];
14948 
14949       /* Check to see if a tag was provided, if so this is actually a resubscription of a dialog we no longer know about */
14950       if (!ast_strlen_zero(to) && gettag(req, "To", totag, sizeof(totag))) {
14951          if (ast_test_flag(req, SIP_PKT_DEBUG))
14952             ast_verbose("Received resubscription for a dialog we no longer know about. Telling remote side to subscribe again.\n");
14953          transmit_response(p, "481 Subscription does not exist", req);
14954          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
14955          return 0;
14956       }
14957 
14958       /* Use this as the basis */
14959       if (ast_test_flag(req, SIP_PKT_DEBUG))
14960          ast_verbose("Creating new subscription\n");
14961 
14962       copy_request(&p->initreq, req);
14963       check_via(p, req);
14964    } else if (ast_test_flag(req, SIP_PKT_DEBUG) && ast_test_flag(req, SIP_PKT_IGNORE))
14965       ast_verbose("Ignoring this SUBSCRIBE request\n");
14966 
14967    /* Find parameters to Event: header value and remove them for now */
14968    if (ast_strlen_zero(eventheader)) {
14969       transmit_response(p, "489 Bad Event", req);
14970       if (option_debug > 1)
14971          ast_log(LOG_DEBUG, "Received SIP subscribe for unknown event package: <none>\n");
14972       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
14973       return 0;
14974    }
14975 
14976    if ( (strchr(eventheader, ';'))) {
14977       event = ast_strdupa(eventheader);   /* Since eventheader is a const, we can't change it */
14978       temp = strchr(event, ';');       
14979       *temp = '\0';           /* Remove any options for now */
14980                      /* We might need to use them later :-) */
14981    } else
14982       event = (char *) eventheader;    /* XXX is this legal ? */
14983 
14984    /* Handle authentication */
14985    res = check_user_full(p, req, SIP_SUBSCRIBE, e, 0, sin, &authpeer);
14986    /* if an authentication response was sent, we are done here */
14987    if (res == AUTH_CHALLENGE_SENT) {
14988       if (authpeer)
14989          ASTOBJ_UNREF(authpeer, sip_destroy_peer);
14990       return 0;
14991    }
14992    if (res < 0) {
14993       if (res == AUTH_FAKE_AUTH) {
14994          ast_log(LOG_NOTICE, "Sending fake auth rejection for user %s\n", get_header(req, "From"));
14995          transmit_fake_auth_response(p, req, 1);
14996       } else {
14997          ast_log(LOG_NOTICE, "Failed to authenticate user %s for SUBSCRIBE\n", get_header(req, "From"));
14998          transmit_response_reliable(p, "403 Forbidden", req);
14999       }
15000       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
15001       if (authpeer)
15002          ASTOBJ_UNREF(authpeer, sip_destroy_peer);
15003       return 0;
15004    }
15005 
15006    /* Check if this user/peer is allowed to subscribe at all */
15007    if (!ast_test_flag(&p->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)) {
15008       transmit_response(p, "403 Forbidden (policy)", req);
15009       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
15010       if (authpeer)
15011          ASTOBJ_UNREF(authpeer, sip_destroy_peer);
15012       return 0;
15013    }
15014 
15015    /* Get destination right away */
15016    gotdest = get_destination(p, NULL);
15017 
15018    /* Get full contact header - this needs to be used as a request URI in NOTIFY's */
15019    parse_ok_contact(p, req);
15020 
15021    build_contact(p);
15022    if (strcmp(event, "message-summary") && gotdest) {
15023       transmit_response(p, "404 Not Found", req);
15024       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
15025       if (authpeer)
15026          ASTOBJ_UNREF(authpeer, sip_destroy_peer);
15027       return 0;
15028    }
15029 
15030    /* Initialize tag for new subscriptions */   
15031    if (ast_strlen_zero(p->tag))
15032       make_our_tag(p->tag, sizeof(p->tag));
15033 
15034    if (!strcmp(event, "presence") || !strcmp(event, "dialog")) { /* Presence, RFC 3842 */
15035       if (authpeer)  /* No need for authpeer here */
15036          ASTOBJ_UNREF(authpeer, sip_destroy_peer);
15037 
15038       /* Header from Xten Eye-beam Accept: multipart/related, application/rlmi+xml, application/pidf+xml, application/xpidf+xml */
15039       /* Polycom phones only handle xpidf+xml, even if they say they can
15040          handle pidf+xml as well
15041       */
15042       if (strstr(p->useragent, "Polycom")) {
15043          p->subscribed = XPIDF_XML;
15044       } else if (strstr(accept, "application/pidf+xml")) {
15045          p->subscribed = PIDF_XML;         /* RFC 3863 format */
15046       } else if (strstr(accept, "application/dialog-info+xml")) {
15047          p->subscribed = DIALOG_INFO_XML;
15048          /* IETF draft: draft-ietf-sipping-dialog-package-05.txt */
15049       } else if (strstr(accept, "application/cpim-pidf+xml")) {
15050          p->subscribed = CPIM_PIDF_XML;    /* RFC 3863 format */
15051       } else if (strstr(accept, "application/xpidf+xml")) {
15052          p->subscribed = XPIDF_XML;        /* Early pre-RFC 3863 format with MSN additions (Microsoft Messenger) */
15053       } else if (ast_strlen_zero(accept)) {
15054          if (p->subscribed == NONE) { /* if the subscribed field is not already set, and there is no accept header... */
15055             transmit_response(p, "489 Bad Event", req);
15056   
15057             ast_log(LOG_WARNING,"SUBSCRIBE failure: no Accept header: pvt: stateid: %d, laststate: %d, dialogver: %d, subscribecont: '%s', subscribeuri: '%s'\n",
15058                p->stateid, p->laststate, p->dialogver, p->subscribecontext, p->subscribeuri);
15059             ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
15060             return 0;
15061          }
15062          /* if p->subscribed is non-zero, then accept is not obligatory; according to rfc 3265 section 3.1.3, at least.
15063             so, we'll just let it ride, keeping the value from a previous subscription, and not abort the subscription */
15064       } else {
15065          /* Can't find a format for events that we know about */
15066          char mybuf[200];
15067          snprintf(mybuf,sizeof(mybuf),"489 Bad Event (format %s)", accept);
15068          transmit_response(p, mybuf, req);
15069  
15070          ast_log(LOG_WARNING,"SUBSCRIBE failure: unrecognized format: '%s' pvt: subscribed: %d, stateid: %d, laststate: %d, dialogver: %d, subscribecont: '%s', subscribeuri: '%s'\n",
15071             accept, (int)p->subscribed, p->stateid, p->laststate, p->dialogver, p->subscribecontext, p->subscribeuri);
15072          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
15073          return 0;
15074       }
15075    } else if (!strcmp(event, "message-summary")) { 
15076       if (!ast_strlen_zero(accept) && strcmp(accept, "application/simple-message-summary")) {
15077          /* Format requested that we do not support */
15078          transmit_response(p, "406 Not Acceptable", req);
15079          if (option_debug > 1)
15080             ast_log(LOG_DEBUG, "Received SIP mailbox subscription for unknown format: %s\n", accept);
15081          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
15082          if (authpeer)  /* No need for authpeer here */
15083             ASTOBJ_UNREF(authpeer, sip_destroy_peer);
15084          return 0;
15085       }
15086       /* Looks like they actually want a mailbox status 
15087         This version of Asterisk supports mailbox subscriptions
15088         The subscribed URI needs to exist in the dial plan
15089         In most devices, this is configurable to the voicemailmain extension you use
15090       */
15091       if (!authpeer || ast_strlen_zero(authpeer->mailbox)) {
15092          transmit_response(p, "404 Not found (no mailbox)", req);
15093          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
15094          ast_log(LOG_NOTICE, "Received SIP subscribe for peer without mailbox: %s\n", authpeer->name);
15095          if (authpeer)  /* No need for authpeer here */
15096             ASTOBJ_UNREF(authpeer, sip_destroy_peer);
15097          return 0;
15098       }
15099 
15100       p->subscribed = MWI_NOTIFICATION;
15101       if (authpeer->mwipvt && authpeer->mwipvt != p)  /* Destroy old PVT if this is a new one */
15102          /* We only allow one subscription per peer */
15103          sip_destroy(authpeer->mwipvt);
15104       authpeer->mwipvt = p;      /* Link from peer to pvt */
15105       p->relatedpeer = ASTOBJ_REF(authpeer); /* Link from pvt to peer */
15106    } else { /* At this point, Asterisk does not understand the specified event */
15107       transmit_response(p, "489 Bad Event", req);
15108       if (option_debug > 1)
15109          ast_log(LOG_DEBUG, "Received SIP subscribe for unknown event package: %s\n", event);
15110       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
15111       if (authpeer)  /* No need for authpeer here */
15112          ASTOBJ_UNREF(authpeer, sip_destroy_peer);
15113       return 0;
15114    }
15115 
15116    if (p->subscribed != MWI_NOTIFICATION && !resubscribe) {
15117       if (p->stateid > -1)
15118          ast_extension_state_del(p->stateid, cb_extensionstate);
15119       p->stateid = ast_extension_state_add(p->context, p->exten, cb_extensionstate, p);
15120    }
15121 
15122    if (!ast_test_flag(req, SIP_PKT_IGNORE) && p)
15123       p->lastinvite = seqno;
15124    if (p && !ast_test_flag(&p->flags[0], SIP_NEEDDESTROY)) {
15125       p->expiry = atoi(get_header(req, "Expires"));
15126 
15127       /* check if the requested expiry-time is within the approved limits from sip.conf */
15128       if (p->expiry > max_expiry)
15129          p->expiry = max_expiry;
15130       if (p->expiry < min_expiry && p->expiry > 0)
15131          p->expiry = min_expiry;
15132 
15133       if (sipdebug || option_debug > 1) {
15134          if (p->subscribed == MWI_NOTIFICATION && p->relatedpeer)
15135             ast_log(LOG_DEBUG, "Adding subscription for mailbox notification - peer %s Mailbox %s\n", p->relatedpeer->name, p->relatedpeer->mailbox);
15136          else
15137             ast_log(LOG_DEBUG, "Adding subscription for extension %s context %s for peer %s\n", p->exten, p->context, p->username);
15138       }
15139       if (p->autokillid > -1 && sip_cancel_destroy(p))   /* Remove subscription expiry for renewals */
15140          ast_log(LOG_WARNING, "Unable to cancel SIP destruction.  Expect bad things.\n");
15141       if (p->expiry > 0)
15142          sip_scheddestroy(p, (p->expiry + 10) * 1000);   /* Set timer for destruction of call at expiration */
15143 
15144       if (p->subscribed == MWI_NOTIFICATION) {
15145          transmit_response(p, "200 OK", req);
15146          if (p->relatedpeer) {   /* Send first notification */
15147             ASTOBJ_WRLOCK(p->relatedpeer);
15148             sip_send_mwi_to_peer(p->relatedpeer);
15149             ASTOBJ_UNLOCK(p->relatedpeer);
15150          }
15151       } else {
15152          struct sip_pvt *p_old;
15153 
15154          if ((firststate = ast_extension_state(NULL, p->context, p->exten)) < 0) {
15155 
15156             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));
15157             transmit_response(p, "404 Not found", req);
15158             ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
15159             return 0;
15160          }
15161 
15162          transmit_response(p, "200 OK", req);
15163          transmit_state_notify(p, firststate, 1, FALSE); /* Send first notification */
15164          append_history(p, "Subscribestatus", "%s", ast_extension_state2str(firststate));
15165          /* hide the 'complete' exten/context in the refer_to field for later display */
15166          ast_string_field_build(p, subscribeuri, "%s@%s", p->exten, p->context);
15167 
15168          /* remove any old subscription from this peer for the same exten/context,
15169          as the peer has obviously forgotten about it and it's wasteful to wait
15170          for it to expire and send NOTIFY messages to the peer only to have them
15171          ignored (or generate errors)
15172          */
15173          ast_mutex_lock(&iflock);
15174          for (p_old = iflist; p_old; p_old = p_old->next) {
15175             if (p_old == p)
15176                continue;
15177             if (p_old->initreq.method != SIP_SUBSCRIBE)
15178                continue;
15179             if (p_old->subscribed == NONE)
15180                continue;
15181             ast_mutex_lock(&p_old->lock);
15182             if (!strcmp(p_old->username, p->username)) {
15183                if (!strcmp(p_old->exten, p->exten) &&
15184                    !strcmp(p_old->context, p->context)) {
15185                   ast_set_flag(&p_old->flags[0], SIP_NEEDDESTROY);
15186                   ast_mutex_unlock(&p_old->lock);
15187                   break;
15188                }
15189             }
15190             ast_mutex_unlock(&p_old->lock);
15191          }
15192          ast_mutex_unlock(&iflock);
15193       }
15194       if (!p->expiry)
15195          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
15196    }
15197    return 1;
15198 }

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

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

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

12120 {
12121    int outgoing = ast_test_flag(&p->flags[0], SIP_OUTGOING);
12122    int res = 0;
12123    int xmitres = 0;
12124    int reinvite = (p->owner && p->owner->_state == AST_STATE_UP);
12125    struct ast_channel *bridgepeer = NULL;
12126    
12127    if (option_debug > 3) {
12128       if (reinvite)
12129          ast_log(LOG_DEBUG, "SIP response %d to RE-invite on %s call %s\n", resp, outgoing ? "outgoing" : "incoming", p->callid);
12130       else
12131          ast_log(LOG_DEBUG, "SIP response %d to standard invite\n", resp);
12132    }
12133 
12134    if (ast_test_flag(&p->flags[0], SIP_ALREADYGONE)) { /* This call is already gone */
12135       if (option_debug)
12136          ast_log(LOG_DEBUG, "Got response on call that is already terminated: %s (ignoring)\n", p->callid);
12137       return;
12138    }
12139 
12140    /* Acknowledge sequence number - This only happens on INVITE from SIP-call */
12141    /* Don't auto congest anymore since we've gotten something useful back */
12142    AST_SCHED_DEL(sched, p->initid);
12143 
12144    /* RFC3261 says we must treat every 1xx response (but not 100)
12145       that we don't recognize as if it was 183.
12146    */
12147    if (resp > 100 && resp < 200 && resp!=101 && resp != 180 && resp != 182 && resp != 183)
12148       resp = 183;
12149 
12150    /* Any response between 100 and 199 is PROCEEDING */
12151    if (resp >= 100 && resp < 200 && p->invitestate == INV_CALLING)
12152       p->invitestate = INV_PROCEEDING;
12153  
12154    /* Final response, not 200 ? */
12155    if (resp >= 300 && (p->invitestate == INV_CALLING || p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA ))
12156       p->invitestate = INV_COMPLETED;
12157       
12158 
12159    switch (resp) {
12160    case 100:   /* Trying */
12161    case 101:   /* Dialog establishment */
12162       if (!ast_test_flag(req, SIP_PKT_IGNORE) && (p->invitestate != INV_CANCELLED) && sip_cancel_destroy(p))
12163          ast_log(LOG_WARNING, "Unable to cancel SIP destruction.  Expect bad things.\n");
12164       check_pendings(p);
12165       break;
12166 
12167    case 180:   /* 180 Ringing */
12168    case 182:       /* 182 Queued */
12169       if (!ast_test_flag(req, SIP_PKT_IGNORE) && (p->invitestate != INV_CANCELLED) && sip_cancel_destroy(p))
12170          ast_log(LOG_WARNING, "Unable to cancel SIP destruction.  Expect bad things.\n");
12171       if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) {
12172          ast_queue_control(p->owner, AST_CONTROL_RINGING);
12173          if (p->owner->_state != AST_STATE_UP) {
12174             ast_setstate(p->owner, AST_STATE_RINGING);
12175          }
12176       }
12177       if (find_sdp(req)) {
12178          if (p->invitestate != INV_CANCELLED)
12179             p->invitestate = INV_EARLY_MEDIA;
12180          res = process_sdp(p, req);
12181          if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) {
12182             /* Queue a progress frame only if we have SDP in 180 or 182 */
12183             ast_queue_control(p->owner, AST_CONTROL_PROGRESS);
12184          }
12185       }
12186       check_pendings(p);
12187       break;
12188 
12189    case 183:   /* Session progress */
12190       if (!ast_test_flag(req, SIP_PKT_IGNORE) && (p->invitestate != INV_CANCELLED) && sip_cancel_destroy(p))
12191          ast_log(LOG_WARNING, "Unable to cancel SIP destruction.  Expect bad things.\n");
12192       /* Ignore 183 Session progress without SDP */
12193       if (find_sdp(req)) {
12194          if (p->invitestate != INV_CANCELLED)
12195             p->invitestate = INV_EARLY_MEDIA;
12196          res = process_sdp(p, req);
12197          if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) {
12198             /* Queue a progress frame */
12199             ast_queue_control(p->owner, AST_CONTROL_PROGRESS);
12200          }
12201       }
12202       check_pendings(p);
12203       break;
12204 
12205    case 200:   /* 200 OK on invite - someone's answering our call */
12206       if (!ast_test_flag(req, SIP_PKT_IGNORE) && (p->invitestate != INV_CANCELLED) && sip_cancel_destroy(p))
12207          ast_log(LOG_WARNING, "Unable to cancel SIP destruction.  Expect bad things.\n");
12208       p->authtries = 0;
12209       if (find_sdp(req)) {
12210          if ((res = process_sdp(p, req)) && !ast_test_flag(req, SIP_PKT_IGNORE))
12211             if (!reinvite)
12212                /* This 200 OK's SDP is not acceptable, so we need to ack, then hangup */
12213                /* For re-invites, we try to recover */
12214                ast_set_flag(&p->flags[0], SIP_PENDINGBYE);  
12215       }
12216 
12217       /* Parse contact header for continued conversation */
12218       /* When we get 200 OK, we know which device (and IP) to contact for this call */
12219       /* This is important when we have a SIP proxy between us and the phone */
12220       if (outgoing) {
12221          update_call_counter(p, DEC_CALL_RINGING);
12222          parse_ok_contact(p, req);
12223          if(set_address_from_contact(p)) {
12224             /* Bad contact - we don't know how to reach this device */
12225             /* We need to ACK, but then send a bye */
12226             /* OEJ: Possible issue that may need a check:
12227                If we have a proxy route between us and the device,
12228                should we care about resolving the contact
12229                or should we just send it?
12230             */
12231             if (!ast_test_flag(req, SIP_PKT_IGNORE))
12232                ast_set_flag(&p->flags[0], SIP_PENDINGBYE);  
12233          } 
12234 
12235          /* Save Record-Route for any later requests we make on this dialogue */
12236          if (!reinvite)
12237             build_route(p, req, 1);
12238       }
12239       
12240       if (p->owner && (p->owner->_state == AST_STATE_UP) && (bridgepeer = ast_bridged_channel(p->owner))) { /* if this is a re-invite */
12241          struct sip_pvt *bridgepvt = NULL;
12242 
12243          if (!bridgepeer->tech) {
12244             ast_log(LOG_WARNING, "Ooooh.. no tech!  That's REALLY bad\n");
12245             break;
12246          }
12247          if (bridgepeer->tech == &sip_tech || bridgepeer->tech == &sip_tech_info) {
12248             bridgepvt = (struct sip_pvt*)(bridgepeer->tech_pvt);
12249             if (bridgepvt->udptl) {
12250                if (p->t38.state == T38_PEER_REINVITE) {
12251                   sip_handle_t38_reinvite(bridgepeer, p, 0);
12252                   ast_rtp_set_rtptimers_onhold(p->rtp);
12253                   if (p->vrtp)
12254                      ast_rtp_set_rtptimers_onhold(p->vrtp); /* Turn off RTP timers while we send fax */
12255                } else if (p->t38.state == T38_DISABLED && bridgepeer && (bridgepvt->t38.state == T38_ENABLED)) {
12256                   ast_log(LOG_WARNING, "RTP re-invite after T38 session not handled yet !\n");
12257                   /* Insted of this we should somehow re-invite the other side of the bridge to RTP */
12258                   /* XXXX Should we really destroy this session here, without any response at all??? */
12259                   sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
12260                }
12261             } else {
12262                if (option_debug > 1)
12263                   ast_log(LOG_DEBUG, "Strange... The other side of the bridge does not have a udptl struct\n");
12264                ast_mutex_lock(&bridgepvt->lock);
12265                bridgepvt->t38.state = T38_DISABLED;
12266                ast_mutex_unlock(&bridgepvt->lock);
12267                if (option_debug)
12268                   ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", bridgepvt->t38.state, bridgepeer->tech->type);
12269                p->t38.state = T38_DISABLED;
12270                if (option_debug > 1)
12271                   ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>");
12272             }
12273          } else {
12274             /* Other side is not a SIP channel */
12275             if (option_debug > 1)
12276                ast_log(LOG_DEBUG, "Strange... The other side of the bridge is not a SIP channel\n");
12277             p->t38.state = T38_DISABLED;
12278             if (option_debug > 1)
12279                ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>");
12280          }
12281       }
12282       if ((p->t38.state == T38_LOCAL_REINVITE) || (p->t38.state == T38_LOCAL_DIRECT)) {
12283          /* If there was T38 reinvite and we are supposed to answer with 200 OK than this should set us to T38 negotiated mode */
12284          p->t38.state = T38_ENABLED;
12285          if (option_debug)
12286             ast_log(LOG_DEBUG, "T38 changed state to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>");
12287       }
12288 
12289       if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) {
12290          if (!reinvite) {
12291             ast_queue_control(p->owner, AST_CONTROL_ANSWER);
12292          } else { /* RE-invite */
12293             ast_queue_frame(p->owner, &ast_null_frame);
12294          }
12295       } else {
12296           /* It's possible we're getting an 200 OK after we've tried to disconnect
12297               by sending CANCEL */
12298          /* First send ACK, then send bye */
12299          if (!ast_test_flag(req, SIP_PKT_IGNORE))
12300             ast_set_flag(&p->flags[0], SIP_PENDINGBYE);  
12301       }
12302       /* If I understand this right, the branch is different for a non-200 ACK only */
12303       p->invitestate = INV_TERMINATED;
12304       xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, TRUE);
12305       check_pendings(p);
12306       break;
12307    case 407: /* Proxy authentication */
12308    case 401: /* Www auth */
12309       /* First we ACK */
12310       xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
12311       if (p->options)
12312          p->options->auth_type = (resp == 401 ? WWW_AUTH : PROXY_AUTH);
12313 
12314       /* Then we AUTH */
12315       ast_string_field_free(p, theirtag); /* forget their old tag, so we don't match tags when getting response */
12316       if (!ast_test_flag(req, SIP_PKT_IGNORE)) {
12317          char *authenticate = (resp == 401 ? "WWW-Authenticate" : "Proxy-Authenticate");
12318          char *authorization = (resp == 401 ? "Authorization" : "Proxy-Authorization");
12319          if (p->authtries < MAX_AUTHTRIES)
12320             p->invitestate = INV_CALLING;
12321          if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, authenticate, authorization, SIP_INVITE, 1)) {
12322             ast_log(LOG_NOTICE, "Failed to authenticate on INVITE to '%s'\n", get_header(&p->initreq, "From"));
12323             ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12324             sip_alreadygone(p);
12325             if (p->owner)
12326                ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
12327          }
12328       }
12329       break;
12330 
12331    case 403: /* Forbidden */
12332       /* First we ACK */
12333       xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
12334       ast_log(LOG_WARNING, "Received response: \"Forbidden\" from '%s'\n", get_header(&p->initreq, "From"));
12335       if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner)
12336          ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
12337       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12338       sip_alreadygone(p);
12339       break;
12340 
12341    case 404: /* Not found */
12342       xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
12343       if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE))
12344          ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
12345       sip_alreadygone(p);
12346       break;
12347 
12348    case 408: /* Request timeout */
12349    case 481: /* Call leg does not exist */
12350       /* Could be REFER caused INVITE with replaces */
12351       ast_log(LOG_WARNING, "Re-invite to non-existing call leg on other UA. SIP dialog '%s'. Giving up.\n", p->callid);
12352       xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
12353       if (p->owner)
12354          ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
12355       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
12356       break;
12357    case 487: /* Cancelled transaction */
12358       /* We have sent CANCEL on an outbound INVITE 
12359          This transaction is already scheduled to be killed by sip_hangup().
12360       */
12361       xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
12362       if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) {
12363          ast_queue_hangup(p->owner);
12364          append_history(p, "Hangup", "Got 487 on CANCEL request from us. Queued AST hangup request");
12365       } else if (!ast_test_flag(req, SIP_PKT_IGNORE)) {
12366          update_call_counter(p, DEC_CALL_LIMIT);
12367          append_history(p, "Hangup", "Got 487 on CANCEL request from us on call without owner. Killing this dialog.");
12368          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12369          sip_alreadygone(p);
12370       }
12371       break;
12372    case 488: /* Not acceptable here */
12373       xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
12374       if (reinvite && p->udptl) {
12375          /* If this is a T.38 call, we should go back to 
12376             audio. If this is an audio call - something went
12377             terribly wrong since we don't renegotiate codecs,
12378             only IP/port .
12379          */
12380          p->t38.state = T38_DISABLED;
12381          /* Try to reset RTP timers */
12382          ast_rtp_set_rtptimers_onhold(p->rtp);
12383          ast_log(LOG_ERROR, "Got error on T.38 re-invite. Bad configuration. Peer needs to have T.38 disabled.\n");
12384 
12385          /*! \bug Is there any way we can go back to the audio call on both
12386             sides here? 
12387          */
12388          /* While figuring that out, hangup the call */
12389          if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE))
12390             ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
12391          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12392       } else if (p->udptl && p->t38.state == T38_LOCAL_DIRECT) {
12393          /* We tried to send T.38 out in an initial INVITE and the remote side rejected it,
12394             right now we can't fall back to audio so totally abort.
12395          */
12396          p->t38.state = T38_DISABLED;
12397          /* Try to reset RTP timers */
12398          ast_rtp_set_rtptimers_onhold(p->rtp);
12399          ast_log(LOG_ERROR, "Got error on T.38 initial invite. Bailing out.\n");
12400 
12401          /* The dialog is now terminated */
12402          if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE))
12403             ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
12404          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
12405          sip_alreadygone(p);
12406       } else {
12407          /* We can't set up this call, so give up */
12408          if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE))
12409             ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
12410          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
12411          /* If there's no dialog to end, then mark p as already gone */
12412          if (!reinvite)
12413             sip_alreadygone(p);
12414       }
12415       break;
12416    case 491: /* Pending */
12417       /* we really should have to wait a while, then retransmit
12418        * We should support the retry-after at some point 
12419        * At this point, we treat this as a congestion if the call is not in UP state 
12420        */
12421       xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
12422       if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) {
12423          if (p->owner->_state != AST_STATE_UP) {
12424             ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
12425             ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12426          } else {
12427             /* This is a re-invite that failed.
12428              * Reset the flag after a while 
12429              */
12430             int wait = 3 + ast_random() % 5;
12431             p->waitid = ast_sched_add(sched, wait, sip_reinvite_retry, p); 
12432             if (option_debug > 2)
12433                ast_log(LOG_DEBUG, "Reinvite race. Waiting %d secs before retry\n", wait);
12434          }
12435       }
12436       break;
12437 
12438    case 501: /* Not implemented */
12439       xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
12440       if (p->owner)
12441          ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
12442       break;
12443    }
12444    if (xmitres == XMIT_ERROR)
12445       ast_log(LOG_WARNING, "Could not transmit message in dialog %s\n", p->callid);
12446 }

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

Handle qualification responses (OPTIONS).

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

12642 {
12643    struct sip_peer *peer = p->relatedpeer;
12644    int statechanged, is_reachable, was_reachable;
12645    int pingtime = ast_tvdiff_ms(ast_tvnow(), peer->ps);
12646 
12647    /*
12648     * Compute the response time to a ping (goes in peer->lastms.)
12649     * -1 means did not respond, 0 means unknown,
12650     * 1..maxms is a valid response, >maxms means late response.
12651     */
12652    if (pingtime < 1) /* zero = unknown, so round up to 1 */
12653       pingtime = 1;
12654 
12655    /* Now determine new state and whether it has changed.
12656     * Use some helper variables to simplify the writing
12657     * of the expressions.
12658     */
12659    was_reachable = peer->lastms > 0 && peer->lastms <= peer->maxms;
12660    is_reachable = pingtime <= peer->maxms;
12661    statechanged = peer->lastms == 0 /* yes, unknown before */
12662       || was_reachable != is_reachable;
12663 
12664    peer->lastms = pingtime;
12665    peer->call = NULL;
12666    if (statechanged) {
12667       const char *s = is_reachable ? "Reachable" : "Lagged";
12668 
12669       ast_log(LOG_NOTICE, "Peer '%s' is now %s. (%dms / %dms)\n",
12670          peer->name, s, pingtime, peer->maxms);
12671       ast_device_state_changed("SIP/%s", peer->name);
12672       manager_event(EVENT_FLAG_SYSTEM, "PeerStatus",
12673          "Peer: SIP/%s\r\nPeerStatus: %s\r\nTime: %d\r\n",
12674          peer->name, s, pingtime);
12675    }
12676 
12677    if (!AST_SCHED_DEL(sched, peer->pokeexpire)) {
12678       struct sip_peer *peer_ptr = peer;
12679       ASTOBJ_UNREF(peer_ptr, sip_destroy_peer);
12680    }
12681 
12682    ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12683 
12684    /* Try again eventually */
12685    peer->pokeexpire = ast_sched_add(sched,
12686       is_reachable ? DEFAULT_FREQ_OK : DEFAULT_FREQ_NOTOK,
12687       sip_poke_peer_s, ASTOBJ_REF(peer));
12688 
12689    if (peer->pokeexpire == -1) {
12690       ASTOBJ_UNREF(peer, sip_destroy_peer);
12691    }
12692 }

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

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

12452 {
12453    char *auth = "Proxy-Authenticate";
12454    char *auth2 = "Proxy-Authorization";
12455 
12456    /* If no refer structure exists, then do nothing */
12457    if (!p->refer)
12458       return;
12459 
12460    switch (resp) {
12461    case 202:   /* Transfer accepted */
12462       /* We need  to do something here */
12463       /* The transferee is now sending INVITE to target */
12464       p->refer->status = REFER_ACCEPTED;
12465       /* Now wait for next message */
12466       if (option_debug > 2)
12467          ast_log(LOG_DEBUG, "Got 202 accepted on transfer\n");
12468       /* We should hang along, waiting for NOTIFY's here */
12469       break;
12470 
12471    case 401:   /* Not www-authorized on SIP method */
12472    case 407:   /* Proxy auth */
12473       if (ast_strlen_zero(p->authname)) {
12474          ast_log(LOG_WARNING, "Asked to authenticate REFER to %s:%d but we have no matching peer or realm auth!\n",
12475             ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port));
12476          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
12477       }
12478       if (resp == 401) {
12479          auth = "WWW-Authenticate";
12480          auth2 = "Authorization";
12481       }
12482       if ((p->authtries > 1) || do_proxy_auth(p, req, auth, auth2, SIP_REFER, 0)) {
12483          ast_log(LOG_NOTICE, "Failed to authenticate on REFER to '%s'\n", get_header(&p->initreq, "From"));
12484          p->refer->status = REFER_NOAUTH;
12485          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
12486       }
12487       break;
12488    case 481: /* Call leg does not exist */
12489 
12490       /* A transfer with Replaces did not work */
12491       /* OEJ: We should Set flag, cancel the REFER, go back
12492       to original call - but right now we can't */
12493       ast_log(LOG_WARNING, "Remote host can't match REFER request to call '%s'. Giving up.\n", p->callid);
12494       if (p->owner)
12495          ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
12496       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
12497       break;
12498 
12499    case 500:   /* Server error */
12500    case 501:   /* Method not implemented */
12501       /* Return to the current call onhold */
12502       /* Status flag needed to be reset */
12503       ast_log(LOG_NOTICE, "SIP transfer to %s failed, call miserably fails. \n", p->refer->refer_to);
12504       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
12505       p->refer->status = REFER_FAILED;
12506       break;
12507    case 603:   /* Transfer declined */
12508       ast_log(LOG_NOTICE, "SIP transfer to %s declined, call miserably fails. \n", p->refer->refer_to);
12509       p->refer->status = REFER_FAILED;
12510       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
12511       break;
12512    }
12513 }

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

12517 {
12518    int expires, expires_ms;
12519    struct sip_registry *r;
12520    r=p->registry;
12521 
12522    switch (resp) {
12523    case 401:   /* Unauthorized */
12524       if ((p->authtries == MAX_AUTHTRIES) || do_register_auth(p, req, "WWW-Authenticate", "Authorization")) {
12525          ast_log(LOG_NOTICE, "Failed to authenticate on REGISTER to '%s@%s' (Tries %d)\n", p->registry->username, p->registry->hostname, p->authtries);
12526          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12527          }
12528       break;
12529    case 403:   /* Forbidden */
12530       ast_log(LOG_WARNING, "Forbidden - wrong password on authentication for REGISTER for '%s' to '%s'\n", p->registry->username, p->registry->hostname);
12531       if (global_regattempts_max)
12532          p->registry->regattempts = global_regattempts_max+1;
12533       AST_SCHED_DEL(sched, r->timeout);
12534       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12535       break;
12536    case 404:   /* Not found */
12537       ast_log(LOG_WARNING, "Got 404 Not found on SIP register to service %s@%s, giving up\n", p->registry->username,p->registry->hostname);
12538       if (global_regattempts_max)
12539          p->registry->regattempts = global_regattempts_max+1;
12540       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12541       r->call = NULL;
12542       AST_SCHED_DEL(sched, r->timeout);
12543       break;
12544    case 407:   /* Proxy auth */
12545       if ((p->authtries == MAX_AUTHTRIES) || do_register_auth(p, req, "Proxy-Authenticate", "Proxy-Authorization")) {
12546          ast_log(LOG_NOTICE, "Failed to authenticate on REGISTER to '%s' (tries '%d')\n", get_header(&p->initreq, "From"), p->authtries);
12547          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12548       }
12549       break;
12550    case 408:   /* Request timeout */
12551       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12552       r->call = NULL;
12553       AST_SCHED_DEL(sched, r->timeout);
12554       break;
12555    case 479:   /* SER: Not able to process the URI - address is wrong in register*/
12556       ast_log(LOG_WARNING, "Got error 479 on register to %s@%s, giving up (check config)\n", p->registry->username,p->registry->hostname);
12557       if (global_regattempts_max)
12558          p->registry->regattempts = global_regattempts_max+1;
12559       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12560       r->call = NULL;
12561       AST_SCHED_DEL(sched, r->timeout);
12562       break;
12563    case 200:   /* 200 OK */
12564       if (!r) {
12565          ast_log(LOG_WARNING, "Got 200 OK on REGISTER that isn't a register\n");
12566          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12567          return 0;
12568       }
12569 
12570       r->regstate = REG_STATE_REGISTERED;
12571       r->regtime = time(NULL);      /* Reset time of last succesful registration */
12572       manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelDriver: SIP\r\nDomain: %s\r\nStatus: %s\r\n", r->hostname, regstate2str(r->regstate));
12573       r->regattempts = 0;
12574       if (option_debug)
12575          ast_log(LOG_DEBUG, "Registration successful\n");
12576       if (r->timeout > -1) {
12577          if (option_debug)
12578             ast_log(LOG_DEBUG, "Cancelling timeout %d\n", r->timeout);
12579       }
12580       AST_SCHED_DEL(sched, r->timeout);
12581       r->call = NULL;
12582       p->registry = NULL;
12583       /* Let this one hang around until we have all the responses */
12584       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
12585       /* ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); */
12586 
12587       /* set us up for re-registering */
12588       /* figure out how long we got registered for */
12589       AST_SCHED_DEL(sched, r->expire);
12590       /* according to section 6.13 of RFC, contact headers override
12591          expires headers, so check those first */
12592       expires = 0;
12593 
12594       /* XXX todo: try to save the extra call */
12595       if (!ast_strlen_zero(get_header(req, "Contact"))) {
12596          const char *contact = NULL;
12597          const char *tmptmp = NULL;
12598          int start = 0;
12599          for(;;) {
12600             contact = __get_header(req, "Contact", &start);
12601             /* this loop ensures we get a contact header about our register request */
12602             if(!ast_strlen_zero(contact)) {
12603                if( (tmptmp=strstr(contact, p->our_contact))) {
12604                   contact=tmptmp;
12605                   break;
12606                }
12607             } else
12608                break;
12609          }
12610          tmptmp = strcasestr(contact, "expires=");
12611          if (tmptmp) {
12612             if (sscanf(tmptmp + 8, "%d;", &expires) != 1)
12613                expires = 0;
12614          }
12615 
12616       }
12617       if (!expires) 
12618          expires=atoi(get_header(req, "expires"));
12619       if (!expires)
12620          expires=default_expiry;
12621 
12622       expires_ms = expires * 1000;
12623       if (expires <= EXPIRY_GUARD_LIMIT)
12624          expires_ms -= MAX((expires_ms * EXPIRY_GUARD_PCT),EXPIRY_GUARD_MIN);
12625       else
12626          expires_ms -= EXPIRY_GUARD_SECS * 1000;
12627       if (sipdebug)
12628          ast_log(LOG_NOTICE, "Outbound Registration: Expiry for %s is %d sec (Scheduling reregistration in %d s)\n", r->hostname, expires, expires_ms/1000); 
12629 
12630       r->refresh= (int) expires_ms / 1000;
12631 
12632       /* Schedule re-registration before we expire */
12633       AST_SCHED_DEL(sched, r->expire);
12634       r->expire = ast_sched_add(sched, expires_ms, sip_reregister, r); 
12635       ASTOBJ_UNREF(r, sip_registry_destroy);
12636    }
12637    return 1;
12638 }

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

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

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

Initialize SIP response, based on SIP request.

Definition at line 5856 of file chan_sip.c.

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

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

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

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

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

Convert Insecure setting to printable string.

Definition at line 10135 of file chan_sip.c.

Referenced by _sip_show_peer().

10136 {
10137    if (port && invite)
10138       return "port,invite";
10139    else if (port)
10140       return "port";
10141    else if (invite)
10142       return "invite";
10143    else
10144       return "no";
10145 }

static void list_route ( struct sip_route route  )  [static]

List all routes - mostly for debugging.

Definition at line 8283 of file chan_sip.c.

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

Referenced by build_route().

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

static int load_module ( void   )  [static]

PBX load module - initialization.

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

18136 {
18137    ASTOBJ_CONTAINER_INIT(&userl);   /* User object list */
18138    ASTOBJ_CONTAINER_INIT(&peerl);   /* Peer object list */
18139    ASTOBJ_CONTAINER_INIT(&regl); /* Registry object list */
18140 
18141    if (!(sched = sched_context_create())) {
18142       ast_log(LOG_ERROR, "Unable to create scheduler context\n");
18143       return AST_MODULE_LOAD_FAILURE;
18144    }
18145 
18146    if (!(io = io_context_create())) {
18147       ast_log(LOG_ERROR, "Unable to create I/O context\n");
18148       sched_context_destroy(sched);
18149       return AST_MODULE_LOAD_FAILURE;
18150    }
18151 
18152    sip_reloadreason = CHANNEL_MODULE_LOAD;
18153 
18154    if(reload_config(sip_reloadreason)) /* Load the configuration from sip.conf */
18155       return AST_MODULE_LOAD_DECLINE;
18156 
18157    /* Make sure we can register our sip channel type */
18158    if (ast_channel_register(&sip_tech)) {
18159       ast_log(LOG_ERROR, "Unable to register channel type 'SIP'\n");
18160       io_context_destroy(io);
18161       sched_context_destroy(sched);
18162       return AST_MODULE_LOAD_FAILURE;
18163    }
18164 
18165    /* Register all CLI functions for SIP */
18166    ast_cli_register_multiple(cli_sip, sizeof(cli_sip)/ sizeof(struct ast_cli_entry));
18167 
18168    /* Tell the RTP subdriver that we're here */
18169    ast_rtp_proto_register(&sip_rtp);
18170 
18171    /* Tell the UDPTL subdriver that we're here */
18172    ast_udptl_proto_register(&sip_udptl);
18173 
18174    /* Register dialplan applications */
18175    ast_register_application(app_dtmfmode, sip_dtmfmode, synopsis_dtmfmode, descrip_dtmfmode);
18176    ast_register_application(app_sipaddheader, sip_addheader, synopsis_sipaddheader, descrip_sipaddheader);
18177 
18178    /* Register dialplan functions */
18179    ast_custom_function_register(&sip_header_function);
18180    ast_custom_function_register(&sippeer_function);
18181    ast_custom_function_register(&sipchaninfo_function);
18182    ast_custom_function_register(&checksipdomain_function);
18183 
18184    /* Register manager commands */
18185    ast_manager_register2("SIPpeers", EVENT_FLAG_SYSTEM, manager_sip_show_peers,
18186          "List SIP peers (text format)", mandescr_show_peers);
18187    ast_manager_register2("SIPshowpeer", EVENT_FLAG_SYSTEM, manager_sip_show_peer,
18188          "Show SIP peer (text format)", mandescr_show_peer);
18189 
18190    sip_poke_all_peers();   
18191    sip_send_all_registers();
18192    
18193    /* And start the monitor for the first time */
18194    restart_monitor();
18195 
18196    return AST_MODULE_LOAD_SUCCESS;
18197 }

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

14279 {
14280    struct sip_dual target;    /* Chan 1: Call from tranferer to Asterisk */
14281                /* Chan 2: Call from Asterisk to target */
14282    int res = 0;
14283    struct sip_pvt *targetcall_pvt;
14284 
14285    /* Check if the call ID of the replaces header does exist locally */
14286    if (!(targetcall_pvt = get_sip_pvt_byid_locked(transferer->refer->replaces_callid, transferer->refer->replaces_callid_totag, 
14287       transferer->refer->replaces_callid_fromtag))) {
14288       if (transferer->refer->localtransfer) {
14289          /* We did not find the refered call. Sorry, can't accept then */
14290          transmit_response(transferer, "202 Accepted", req);
14291          /* Let's fake a response from someone else in order
14292             to follow the standard */
14293          transmit_notify_with_sipfrag(transferer, seqno, "481 Call leg/transaction does not exist", TRUE);
14294          append_history(transferer, "Xfer", "Refer failed");
14295          ast_clear_flag(&transferer->flags[0], SIP_GOTREFER);  
14296          transferer->refer->status = REFER_FAILED;
14297          return -1;
14298       }
14299       /* Fall through for remote transfers that we did not find locally */
14300       if (option_debug > 2)
14301          ast_log(LOG_DEBUG, "SIP attended transfer: Not our call - generating INVITE with replaces\n");
14302       return 0;
14303    }
14304 
14305    /* Ok, we can accept this transfer */
14306    transmit_response(transferer, "202 Accepted", req);
14307    append_history(transferer, "Xfer", "Refer accepted");
14308    if (!targetcall_pvt->owner) { /* No active channel */
14309       if (option_debug > 3)
14310          ast_log(LOG_DEBUG, "SIP attended transfer: Error: No owner of target call\n");
14311       /* Cancel transfer */
14312       transmit_notify_with_sipfrag(transferer, seqno, "503 Service Unavailable", TRUE);
14313       append_history(transferer, "Xfer", "Refer failed");
14314       ast_clear_flag(&transferer->flags[0], SIP_GOTREFER);
14315       transferer->refer->status = REFER_FAILED;
14316       ast_mutex_unlock(&targetcall_pvt->lock);
14317       ast_channel_unlock(current->chan1);
14318       return -1;
14319    }
14320 
14321    /* We have a channel, find the bridge */
14322    target.chan1 = targetcall_pvt->owner;           /* Transferer to Asterisk */
14323    target.chan2 = ast_bridged_channel(targetcall_pvt->owner);  /* Asterisk to target */
14324 
14325    if (!target.chan2 || !(target.chan2->_state == AST_STATE_UP || target.chan2->_state == AST_STATE_RINGING) ) {
14326       /* Wrong state of new channel */
14327       if (option_debug > 3) {
14328          if (target.chan2) 
14329             ast_log(LOG_DEBUG, "SIP attended transfer: Error: Wrong state of target call: %s\n", ast_state2str(target.chan2->_state));
14330          else if (target.chan1->_state != AST_STATE_RING)
14331             ast_log(LOG_DEBUG, "SIP attended transfer: Error: No target channel\n");
14332          else
14333             ast_log(LOG_DEBUG, "SIP attended transfer: Attempting transfer in ringing state\n");
14334       }
14335    }
14336 
14337    /* Transfer */
14338    if (option_debug > 3 && sipdebug) {
14339       if (current->chan2)  /* We have two bridges */
14340          ast_log(LOG_DEBUG, "SIP attended transfer: trying to bridge %s and %s\n", target.chan1->name, current->chan2->name);
14341       else        /* One bridge, propably transfer of IVR/voicemail etc */
14342          ast_log(LOG_DEBUG, "SIP attended transfer: trying to make %s take over (masq) %s\n", target.chan1->name, current->chan1->name);
14343    }
14344 
14345    ast_set_flag(&transferer->flags[0], SIP_DEFER_BYE_ON_TRANSFER);   /* Delay hangup */
14346 
14347    /* Perform the transfer */
14348    res = attempt_transfer(current, &target);
14349    ast_mutex_unlock(&targetcall_pvt->lock);
14350    if (res) {
14351       /* Failed transfer */
14352       transmit_notify_with_sipfrag(transferer, seqno, "486 Busy Here", TRUE);
14353       append_history(transferer, "Xfer", "Refer failed");
14354       transferer->refer->status = REFER_FAILED;
14355       if (targetcall_pvt->owner)
14356          ast_channel_unlock(targetcall_pvt->owner);
14357       /* Right now, we have to hangup, sorry. Bridge is destroyed */
14358       if (res != -2)
14359          ast_hangup(transferer->owner);
14360       else
14361          ast_clear_flag(&transferer->flags[0], SIP_DEFER_BYE_ON_TRANSFER);
14362    } else {
14363       /* Transfer succeeded! */
14364 
14365       /* Tell transferer that we're done. */
14366       transmit_notify_with_sipfrag(transferer, seqno, "200 OK", TRUE);
14367       append_history(transferer, "Xfer", "Refer succeeded");
14368       transferer->refer->status = REFER_200OK;
14369       if (targetcall_pvt->owner) {
14370          if (option_debug)
14371             ast_log(LOG_DEBUG, "SIP attended transfer: Unlocking channel %s\n", targetcall_pvt->owner->name);
14372          ast_channel_unlock(targetcall_pvt->owner);
14373       }
14374    }
14375    return 1;
14376 }

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

References t.

Referenced by sipsock_read().

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

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

10381 {
10382    const char *a[4];
10383    const char *peer;
10384    int ret;
10385 
10386    peer = astman_get_header(m,"Peer");
10387    if (ast_strlen_zero(peer)) {
10388       astman_send_error(s, m, "Peer: <name> missing.\n");
10389       return 0;
10390    }
10391    a[0] = "sip";
10392    a[1] = "show";
10393    a[2] = "peer";
10394    a[3] = peer;
10395 
10396    ret = _sip_show_peer(1, -1, s, m, 4, a);
10397    astman_append(s, "\r\n\r\n" );
10398    return ret;
10399 }

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

Show SIP peers in the manager API.

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

09932 {
09933    const char *id = astman_get_header(m,"ActionID");
09934    const char *a[] = {"sip", "show", "peers"};
09935    char idtext[256] = "";
09936    int total = 0;
09937 
09938    if (!ast_strlen_zero(id))
09939       snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
09940 
09941    astman_send_ack(s, m, "Peer status list will follow");
09942    /* List the peers in separate manager events */
09943    _sip_show_peers(-1, &total, s, m, 3, a);
09944    /* Send final confirmation */
09945    astman_append(s,
09946    "Event: PeerlistComplete\r\n"
09947    "ListItems: %d\r\n"
09948    "%s"
09949    "\r\n", total, idtext);
09950    return 0;
09951 }

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

References SIP_NAT_ALWAYS, SIP_NAT_NEVER, SIP_NAT_RFC3581, and SIP_NAT_ROUTE.

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

09835 {
09836    switch(nat) {
09837    case SIP_NAT_NEVER:
09838       return "No";
09839    case SIP_NAT_ROUTE:
09840       return "Route";
09841    case SIP_NAT_ALWAYS:
09842       return "Always";
09843    case SIP_NAT_RFC3581:
09844       return "RFC3581";
09845    default:
09846       return "Unknown";
09847    }
09848 }

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

12021 {
12022    char tmp[SIPBUFSIZE];
12023    char *s, *e, *uri, *t;
12024    char *domain;
12025 
12026    ast_copy_string(tmp, get_header(req, "Contact"), sizeof(tmp));
12027    if ((t = strchr(tmp, ',')))
12028       *t = '\0';
12029    s = get_in_brackets(tmp);
12030    uri = ast_strdupa(s);
12031    if (ast_test_flag(&p->flags[0], SIP_PROMISCREDIR)) {
12032       if (!strncasecmp(s, "sip:", 4))
12033          s += 4;
12034       e = strchr(s, ';');
12035       if (e)
12036          *e = '\0';
12037       if (option_debug)
12038          ast_log(LOG_DEBUG, "Found promiscuous redirection to 'SIP/%s'\n", s);
12039       if (p->owner)
12040          ast_string_field_build(p->owner, call_forward, "SIP/%s", s);
12041    } else {
12042       e = strchr(tmp, '@');
12043       if (e) {
12044          *e++ = '\0';
12045          domain = e;
12046       } else {
12047          /* No username part */
12048          domain = tmp;
12049       }
12050       e = strchr(s, ';');  /* Strip of parameters in the username part */
12051       if (e)
12052          *e = '\0';
12053       e = strchr(domain, ';');   /* Strip of parameters in the domain part */
12054       if (e)
12055          *e = '\0';
12056    
12057       if (!strncasecmp(s, "sip:", 4))
12058          s += 4;
12059       if (option_debug > 1)
12060          ast_log(LOG_DEBUG, "Received 302 Redirect to extension '%s' (domain %s)\n", s, domain);
12061       if (p->owner) {
12062          pbx_builtin_setvar_helper(p->owner, "SIPREDIRECTURI", uri);
12063          pbx_builtin_setvar_helper(p->owner, "SIPDOMAIN", domain);
12064          ast_string_field_set(p->owner, call_forward, s);
12065       }
12066    }
12067 }

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

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

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

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

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

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

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

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

09854 {
09855    int res = 0;
09856    if (peer->maxms) {
09857       if (peer->lastms < 0) {
09858          ast_copy_string(status, "UNREACHABLE", statuslen);
09859       } else if (peer->lastms > peer->maxms) {
09860          snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms);
09861          res = 1;
09862       } else if (peer->lastms) {
09863          snprintf(status, statuslen, "OK (%d ms)", peer->lastms);
09864          res = 1;
09865       } else {
09866          ast_copy_string(status, "UNKNOWN", statuslen);
09867       }
09868    } else { 
09869       ast_copy_string(status, "Unmonitored", statuslen);
09870       /* Checking if port is 0 */
09871       res = -1;
09872    }
09873    return res;
09874 }

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

10322 {
10323    int x, codec;
10324 
10325    for(x = 0; x < 32 ; x++) {
10326       codec = ast_codec_pref_index(pref, x);
10327       if (!codec)
10328          break;
10329       ast_cli(fd, "%s", ast_getformatname(codec));
10330       ast_cli(fd, ":%d", pref->framing[x]);
10331       if (x < 31 && ast_codec_pref_index(pref, x + 1))
10332          ast_cli(fd, ",");
10333    }
10334    if (!x)
10335       ast_cli(fd, "none");
10336 }

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

Print call group and pickup group.

Definition at line 10112 of file chan_sip.c.

References ast_cli(), and ast_print_group().

Referenced by _sip_show_peer(), and sip_show_user().

10113 {
10114    char buf[256];
10115    ast_cli(fd, crlf ? "%s\r\n" : "%s\n", ast_print_group(buf, sizeof(buf), group) );
10116 }

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

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

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

09737 {
09738    char buf[1024];
09739    struct ast_frame f;
09740    const char *content_type = get_header(req, "Content-Type");
09741 
09742    if (strncmp(content_type, "text/plain", strlen("text/plain"))) { /* No text/plain attachment */
09743       transmit_response(p, "415 Unsupported Media Type", req); /* Good enough, or? */
09744       if (!p->owner)
09745          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
09746       return;
09747    }
09748 
09749    if (get_msg_text(buf, sizeof(buf), req)) {
09750       ast_log(LOG_WARNING, "Unable to retrieve text from %s\n", p->callid);
09751       transmit_response(p, "202 Accepted", req);
09752       if (!p->owner)
09753          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
09754       return;
09755    }
09756 
09757    if (p->owner) {
09758       if (sip_debug_test_pvt(p))
09759          ast_verbose("Message received: '%s'\n", buf);
09760       memset(&f, 0, sizeof(f));
09761       f.frametype = AST_FRAME_TEXT;
09762       f.subclass = 0;
09763       f.offset = 0;
09764       f.data = buf;
09765       f.datalen = strlen(buf);
09766       ast_queue_frame(p->owner, &f);
09767       transmit_response(p, "202 Accepted", req); /* We respond 202 accepted, since we relay the message */
09768    } else { /* Message outside of a call, we do not support that */
09769       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);
09770       transmit_response(p, "405 Method Not Allowed", req); /* Good enough, or? */
09771       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
09772    }
09773    return;
09774 }

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

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

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

08658 {
08659    enum check_auth_result res = AUTH_NOT_FOUND;
08660    struct sip_peer *peer;
08661    char tmp[256];
08662    char *name, *c;
08663    char *t;
08664    char *domain;
08665 
08666    /* Terminate URI */
08667    t = uri;
08668    while(*t && (*t > 32) && (*t != ';'))
08669       t++;
08670    *t = '\0';
08671    
08672    ast_copy_string(tmp, get_header(req, "To"), sizeof(tmp));
08673    if (pedanticsipchecking)
08674       ast_uri_decode(tmp);
08675 
08676    c = get_in_brackets(tmp);
08677    c = strsep(&c, ";"); /* Ditch ;user=phone */
08678 
08679    if (!strncasecmp(c, "sip:", 4)) {
08680       name = c + 4;
08681    } else {
08682       name = c;
08683       ast_log(LOG_NOTICE, "Invalid to address: '%s' from %s (missing sip:) trying to use anyway...\n", c, ast_inet_ntoa(sin->sin_addr));
08684    }
08685 
08686    /* Strip off the domain name */
08687    if ((c = strchr(name, '@'))) {
08688       *c++ = '\0';
08689       domain = c;
08690       if ((c = strchr(domain, ':')))   /* Remove :port */
08691          *c = '\0';
08692       if (!AST_LIST_EMPTY(&domain_list)) {
08693          if (!check_sip_domain(domain, NULL, 0)) {
08694             transmit_response(p, "404 Not found (unknown domain)", &p->initreq);
08695             return AUTH_UNKNOWN_DOMAIN;
08696          }
08697       }
08698    }
08699 
08700    ast_string_field_set(p, exten, name);
08701    build_contact(p);
08702    peer = find_peer(name, NULL, 1);
08703    if (!(peer && ast_apply_ha(peer->ha, sin))) {
08704       /* Peer fails ACL check */
08705       if (peer) {
08706          ASTOBJ_UNREF(peer, sip_destroy_peer);
08707          res = AUTH_ACL_FAILED;
08708       } else
08709          res = AUTH_NOT_FOUND;
08710    }
08711    if (peer) {
08712       /* Set Frame packetization */
08713       if (p->rtp) {
08714          ast_rtp_codec_setpref(p->rtp, &peer->prefs);
08715          p->autoframing = peer->autoframing;
08716       }
08717       if (!ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)) {
08718          ast_log(LOG_ERROR, "Peer '%s' is trying to register, but not configured as host=dynamic\n", peer->name);
08719          res = AUTH_PEER_NOT_DYNAMIC;
08720       } else {
08721          ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_NAT);
08722          transmit_response(p, "100 Trying", req);
08723          if (!(res = check_auth(p, req, peer->name, peer->secret, peer->md5secret, SIP_REGISTER, uri, XMIT_UNRELIABLE, ast_test_flag(req, SIP_PKT_IGNORE)))) {
08724             if (sip_cancel_destroy(p))
08725                ast_log(LOG_WARNING, "Unable to cancel SIP destruction.  Expect bad things.\n");
08726 
08727             /* We have a succesful registration attemp with proper authentication,
08728                now, update the peer */
08729             switch (parse_register_contact(p, peer, req)) {
08730             case PARSE_REGISTER_FAILED:
08731                ast_log(LOG_WARNING, "Failed to parse contact info\n");
08732                transmit_response_with_date(p, "400 Bad Request", req);
08733                peer->lastmsgssent = -1;
08734                res = 0;
08735                break;
08736             case PARSE_REGISTER_QUERY:
08737                transmit_response_with_date(p, "200 OK", req);
08738                peer->lastmsgssent = -1;
08739                res = 0;
08740                break;
08741             case PARSE_REGISTER_UPDATE:
08742                update_peer(peer, p->expiry);
08743                /* Say OK and ask subsystem to retransmit msg counter */
08744                transmit_response_with_date(p, "200 OK", req);
08745                if (!ast_test_flag((&peer->flags[1]), SIP_PAGE2_SUBSCRIBEMWIONLY))
08746                   peer->lastmsgssent = -1;
08747                res = 0;
08748                break;
08749             }
08750          } 
08751       }
08752    }
08753    if (!peer && autocreatepeer) {
08754       /* Create peer if we have autocreate mode enabled */
08755       peer = temp_peer(name);
08756       if (peer) {
08757          ASTOBJ_CONTAINER_LINK(&peerl, peer);
08758          if (sip_cancel_destroy(p))
08759             ast_log(LOG_WARNING, "Unable to cancel SIP destruction.  Expect bad things.\n");
08760          switch (parse_register_contact(p, peer, req)) {
08761          case PARSE_REGISTER_FAILED:
08762             ast_log(LOG_WARNING, "Failed to parse contact info\n");
08763             transmit_response_with_date(p, "400 Bad Request", req);
08764             peer->lastmsgssent = -1;
08765             res = 0;
08766             break;
08767          case PARSE_REGISTER_QUERY:
08768             transmit_response_with_date(p, "200 OK", req);
08769             peer->lastmsgssent = -1;
08770             res = 0;
08771             break;
08772          case PARSE_REGISTER_UPDATE:
08773             /* Say OK and ask subsystem to retransmit msg counter */
08774             transmit_response_with_date(p, "200 OK", req);
08775             manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Registered\r\n", peer->name);
08776             peer->lastmsgssent = -1;
08777             res = 0;
08778             break;
08779          }
08780       }
08781    }
08782    if (!res) {
08783       ast_device_state_changed("SIP/%s", peer->name);
08784    }
08785    if (res < 0) {
08786       switch (res) {
08787       case AUTH_SECRET_FAILED:
08788          /* Wrong password in authentication. Go away, don't try again until you fixed it */
08789          transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq);
08790          break;
08791       case AUTH_USERNAME_MISMATCH:
08792          /* Username and digest username does not match. 
08793             Asterisk uses the From: username for authentication. We need the
08794             users to use the same authentication user name until we support
08795             proper authentication by digest auth name */
08796          transmit_response(p, "403 Authentication user name does not match account name", &p->initreq);
08797          break;
08798       case AUTH_NOT_FOUND:
08799       case AUTH_PEER_NOT_DYNAMIC:
08800       case AUTH_ACL_FAILED:
08801          if (global_alwaysauthreject) {
08802             transmit_fake_auth_response(p, &p->initreq, 1);
08803          } else {
08804             /* URI not found */
08805             if (res == AUTH_PEER_NOT_DYNAMIC)
08806                transmit_response(p, "403 Forbidden", &p->initreq);
08807             else
08808                transmit_response(p, "404 Not found", &p->initreq);
08809          }
08810          break;
08811       default:
08812          break;
08813       }
08814    }
08815    if (peer)
08816       ASTOBJ_UNREF(peer, sip_destroy_peer);
08817 
08818    return res;
08819 }

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

Convert registration state status to string.

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

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

static int reload ( void   )  [static]

Part of Asterisk module interface.

Definition at line 18021 of file chan_sip.c.

References sip_reload().

18022 {
18023    return sip_reload(0, 0, NULL);
18024 }

static int reload_config ( enum channelreloadreason  reason  )  [static]

Re-read SIP.conf config file.

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

< Default DTMF setting: RFC2833

< NAT support if requested by device with rport

< Allow re-invites

Definition at line 16907 of file chan_sip.c.

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

16908 {
16909    struct ast_config *cfg, *ucfg;
16910    struct ast_variable *v;
16911    struct sip_peer *peer;
16912    struct sip_user *user;
16913    struct ast_hostent ahp;
16914    char *cat, *stringp, *context, *oldregcontext;
16915    char newcontexts[AST_MAX_CONTEXT], oldcontexts[AST_MAX_CONTEXT];
16916    struct hostent *hp;
16917    int format;
16918    struct ast_flags dummy[2];
16919    int auto_sip_domains = FALSE;
16920    struct sockaddr_in old_bindaddr = bindaddr;
16921    int registry_count = 0, peer_count = 0, user_count = 0;
16922    unsigned int temp_tos = 0;
16923    struct ast_flags debugflag = {0};
16924 
16925    cfg = ast_config_load(config);
16926 
16927    /* We *must* have a config file otherwise stop immediately */
16928    if (!cfg) {
16929       ast_log(LOG_NOTICE, "Unable to load config %s\n", config);
16930       return -1;
16931    }
16932    
16933    if (option_debug > 3)
16934       ast_log(LOG_DEBUG, "--------------- SIP reload started\n");
16935 
16936    clear_realm_authentication(authl);
16937    clear_sip_domains();
16938    authl = NULL;
16939 
16940    /* First, destroy all outstanding registry calls */
16941    /* This is needed, since otherwise active registry entries will not be destroyed */
16942    ASTOBJ_CONTAINER_TRAVERSE(&regl, 1, do {
16943       ASTOBJ_RDLOCK(iterator);
16944       if (iterator->call) {
16945          if (option_debug > 2)
16946             ast_log(LOG_DEBUG, "Destroying active SIP dialog for registry %s@%s\n", iterator->username, iterator->hostname);
16947          /* This will also remove references to the registry */
16948          sip_destroy(iterator->call);
16949       }
16950       ASTOBJ_UNLOCK(iterator);
16951    
16952    } while(0));
16953 
16954    /* Then, actually destroy users and registry */
16955    ASTOBJ_CONTAINER_DESTROYALL(&userl, sip_destroy_user);
16956    if (option_debug > 3)
16957       ast_log(LOG_DEBUG, "--------------- Done destroying user list\n");
16958    ASTOBJ_CONTAINER_DESTROYALL(&regl, sip_registry_destroy);
16959    if (option_debug > 3)
16960       ast_log(LOG_DEBUG, "--------------- Done destroying registry list\n");
16961    ASTOBJ_CONTAINER_MARKALL(&peerl);
16962 
16963    /* Initialize copy of current global_regcontext for later use in removing stale contexts */
16964    ast_copy_string(oldcontexts, global_regcontext, sizeof(oldcontexts));
16965    oldregcontext = oldcontexts;
16966 
16967    /* Clear all flags before setting default values */
16968    /* Preserve debugging settings for console */
16969    ast_copy_flags(&debugflag, &global_flags[1], SIP_PAGE2_DEBUG_CONSOLE);
16970    ast_clear_flag(&global_flags[0], AST_FLAGS_ALL);
16971    ast_clear_flag(&global_flags[1], AST_FLAGS_ALL);
16972    ast_copy_flags(&global_flags[1], &debugflag, SIP_PAGE2_DEBUG_CONSOLE);
16973 
16974    /* Reset IP addresses  */
16975    memset(&bindaddr, 0, sizeof(bindaddr));
16976    ast_free_ha(localaddr);
16977    memset(&localaddr, 0, sizeof(localaddr));
16978    memset(&externip, 0, sizeof(externip));
16979    memset(&default_prefs, 0 , sizeof(default_prefs));
16980    outboundproxyip.sin_port = htons(STANDARD_SIP_PORT);
16981    outboundproxyip.sin_family = AF_INET;  /* Type of address: IPv4 */
16982    ourport = STANDARD_SIP_PORT;
16983    srvlookup = DEFAULT_SRVLOOKUP;
16984    global_tos_sip = DEFAULT_TOS_SIP;
16985    global_tos_audio = DEFAULT_TOS_AUDIO;
16986    global_tos_video = DEFAULT_TOS_VIDEO;
16987    externhost[0] = '\0';         /* External host name (for behind NAT DynDNS support) */
16988    externexpire = 0;       /* Expiration for DNS re-issuing */
16989    externrefresh = 10;
16990    memset(&outboundproxyip, 0, sizeof(outboundproxyip));
16991 
16992    /* Reset channel settings to default before re-configuring */
16993    allow_external_domains = DEFAULT_ALLOW_EXT_DOM;          /* Allow external invites */
16994    global_regcontext[0] = '\0';
16995    expiry = DEFAULT_EXPIRY;
16996    global_notifyringing = DEFAULT_NOTIFYRINGING;
16997    global_limitonpeers = FALSE;
16998    global_directrtpsetup = FALSE;      /* Experimental feature, disabled by default */
16999    global_notifyhold = FALSE;
17000    global_alwaysauthreject = 0;
17001    global_allowsubscribe = FALSE;
17002    ast_copy_string(global_useragent, DEFAULT_USERAGENT, sizeof(global_useragent));
17003    ast_copy_string(default_notifymime, DEFAULT_NOTIFYMIME, sizeof(default_notifymime));
17004    if (ast_strlen_zero(ast_config_AST_SYSTEM_NAME))
17005       ast_copy_string(global_realm, DEFAULT_REALM, sizeof(global_realm));
17006    else
17007       ast_copy_string(global_realm, ast_config_AST_SYSTEM_NAME, sizeof(global_realm));
17008    ast_copy_string(default_callerid, DEFAULT_CALLERID, sizeof(default_callerid));
17009    compactheaders = DEFAULT_COMPACTHEADERS;
17010    global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT;
17011    global_regattempts_max = 0;
17012    pedanticsipchecking = DEFAULT_PEDANTIC;
17013    global_mwitime = DEFAULT_MWITIME;
17014    autocreatepeer = DEFAULT_AUTOCREATEPEER;
17015    global_autoframing = 0;
17016    global_allowguest = DEFAULT_ALLOWGUEST;
17017    global_rtptimeout = 0;
17018    global_rtpholdtimeout = 0;
17019    global_rtpkeepalive = 0;
17020    global_allowtransfer = TRANSFER_OPENFORALL;  /* Merrily accept all transfers by default */
17021    global_rtautoclear = 120;
17022    ast_set_flag(&global_flags[1], SIP_PAGE2_ALLOWSUBSCRIBE);   /* Default for peers, users: TRUE */
17023    ast_set_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP);     /* Default for peers, users: TRUE */
17024    ast_set_flag(&global_flags[1], SIP_PAGE2_RTUPDATE);
17025 
17026    /* Initialize some reasonable defaults at SIP reload (used both for channel and as default for peers and users */
17027    ast_copy_string(default_context, DEFAULT_CONTEXT, sizeof(default_context));
17028    default_subscribecontext[0] = '\0';
17029    default_language[0] = '\0';
17030    default_fromdomain[0] = '\0';
17031    default_qualify = DEFAULT_QUALIFY;
17032    default_maxcallbitrate = DEFAULT_MAX_CALL_BITRATE;
17033    ast_copy_string(default_mohinterpret, DEFAULT_MOHINTERPRET, sizeof(default_mohinterpret));
17034    ast_copy_string(default_mohsuggest, DEFAULT_MOHSUGGEST, sizeof(default_mohsuggest));
17035    ast_copy_string(default_vmexten, DEFAULT_VMEXTEN, sizeof(default_vmexten));
17036    ast_set_flag(&global_flags[0], SIP_DTMF_RFC2833);        /*!< Default DTMF setting: RFC2833 */
17037    ast_set_flag(&global_flags[0], SIP_NAT_RFC3581);         /*!< NAT support if requested by device with rport */
17038    ast_set_flag(&global_flags[0], SIP_CAN_REINVITE);        /*!< Allow re-invites */
17039 
17040    /* Debugging settings, always default to off */
17041    dumphistory = FALSE;
17042    recordhistory = FALSE;
17043    ast_clear_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONFIG);
17044 
17045    /* Misc settings for the channel */
17046    global_relaxdtmf = FALSE;
17047    global_callevents = FALSE;
17048    global_t1min = DEFAULT_T1MIN;    
17049 
17050    global_matchexterniplocally = FALSE;
17051 
17052    /* Copy the default jb config over global_jbconf */
17053    memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf));
17054 
17055    ast_clear_flag(&global_flags[1], SIP_PAGE2_VIDEOSUPPORT);
17056 
17057    /* Read the [general] config section of sip.conf (or from realtime config) */
17058    for (v = ast_variable_browse(cfg, "general"); v; v = v->next) {
17059       if (handle_common_options(&global_flags[0], &dummy[0], v))
17060          continue;
17061       /* handle jb conf */
17062       if (!ast_jb_read_conf(&global_jbconf, v->name, v->value))
17063          continue;
17064 
17065       /* Create the interface list */
17066       if (!strcasecmp(v->name, "context")) {
17067          ast_copy_string(default_context, v->value, sizeof(default_context));
17068       } else if (!strcasecmp(v->name, "subscribecontext")) {
17069          ast_copy_string(default_subscribecontext, v->value, sizeof(default_subscribecontext));
17070       } else if (!strcasecmp(v->name, "allowguest")) {
17071          global_allowguest = ast_true(v->value) ? 1 : 0;
17072       } else if (!strcasecmp(v->name, "realm")) {
17073          ast_copy_string(global_realm, v->value, sizeof(global_realm));
17074       } else if (!strcasecmp(v->name, "useragent")) {
17075          ast_copy_string(global_useragent, v->value, sizeof(global_useragent));
17076          if (option_debug)
17077             ast_log(LOG_DEBUG, "Setting SIP channel User-Agent Name to %s\n", global_useragent);
17078       } else if (!strcasecmp(v->name, "allowtransfer")) {
17079          global_allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED;
17080       } else if (!strcasecmp(v->name, "rtcachefriends")) {
17081          ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_RTCACHEFRIENDS);   
17082       } else if (!strcasecmp(v->name, "rtsavesysname")) {
17083          ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_RTSAVE_SYSNAME);   
17084       } else if (!strcasecmp(v->name, "rtupdate")) {
17085          ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_RTUPDATE);   
17086       } else if (!strcasecmp(v->name, "ignoreregexpire")) {
17087          ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_IGNOREREGEXPIRE);  
17088       } else if (!strcasecmp(v->name, "t1min")) {
17089          global_t1min = atoi(v->value);
17090       } else if (!strcasecmp(v->name, "rtautoclear")) {
17091          int i = atoi(v->value);
17092          if (i > 0)
17093             global_rtautoclear = i;
17094          else
17095             i = 0;
17096          ast_set2_flag(&global_flags[1], i || ast_true(v->value), SIP_PAGE2_RTAUTOCLEAR);
17097       } else if (!strcasecmp(v->name, "usereqphone")) {
17098          ast_set2_flag(&global_flags[0], ast_true(v->value), SIP_USEREQPHONE);   
17099       } else if (!strcasecmp(v->name, "relaxdtmf")) {
17100          global_relaxdtmf = ast_true(v->value);
17101       } else if (!strcasecmp(v->name, "checkmwi")) {
17102          if ((sscanf(v->value, "%d", &global_mwitime) != 1) || (global_mwitime < 0)) {
17103             ast_log(LOG_WARNING, "'%s' is not a valid MWI time setting at line %d.  Using default (10).\n", v->value, v->lineno);
17104             global_mwitime = DEFAULT_MWITIME;
17105          }
17106       } else if (!strcasecmp(v->name, "vmexten")) {
17107          ast_copy_string(default_vmexten, v->value, sizeof(default_vmexten));
17108       } else if (!strcasecmp(v->name, "rtptimeout")) {
17109          if ((sscanf(v->value, "%d", &global_rtptimeout) != 1) || (global_rtptimeout < 0)) {
17110             ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d.  Using default.\n", v->value, v->lineno);
17111             global_rtptimeout = 0;
17112          }
17113       } else if (!strcasecmp(v->name, "rtpholdtimeout")) {
17114          if ((sscanf(v->value, "%d", &global_rtpholdtimeout) != 1) || (global_rtpholdtimeout < 0)) {
17115             ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d.  Using default.\n", v->value, v->lineno);
17116             global_rtpholdtimeout = 0;
17117          }
17118       } else if (!strcasecmp(v->name, "rtpkeepalive")) {
17119          if ((sscanf(v->value, "%d", &global_rtpkeepalive) != 1) || (global_rtpkeepalive < 0)) {
17120             ast_log(LOG_WARNING, "'%s' is not a valid RTP keepalive time at line %d.  Using default.\n", v->value, v->lineno);
17121             global_rtpkeepalive = 0;
17122          }
17123       } else if (!strcasecmp(v->name, "compactheaders")) {
17124          compactheaders = ast_true(v->value);
17125       } else if (!strcasecmp(v->name, "notifymimetype")) {
17126          ast_copy_string(default_notifymime, v->value, sizeof(default_notifymime));
17127       } else if (!strncasecmp(v->name, "limitonpeer", 11)) {
17128          global_limitonpeers = ast_true(v->value);
17129       } else if (!strcasecmp(v->name, "directrtpsetup")) {
17130          global_directrtpsetup = ast_true(v->value);
17131       } else if (!strcasecmp(v->name, "notifyringing")) {
17132          global_notifyringing = ast_true(v->value);
17133       } else if (!strcasecmp(v->name, "notifyhold")) {
17134          global_notifyhold = ast_true(v->value);
17135       } else if (!strcasecmp(v->name, "alwaysauthreject")) {
17136          global_alwaysauthreject = ast_true(v->value);
17137       } else if (!strcasecmp(v->name, "mohinterpret") 
17138          || !strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) {
17139          ast_copy_string(default_mohinterpret, v->value, sizeof(default_mohinterpret));
17140       } else if (!strcasecmp(v->name, "mohsuggest")) {
17141          ast_copy_string(default_mohsuggest, v->value, sizeof(default_mohsuggest));
17142       } else if (!strcasecmp(v->name, "language")) {
17143          ast_copy_string(default_language, v->value, sizeof(default_language));
17144       } else if (!strcasecmp(v->name, "regcontext")) {
17145          ast_copy_string(newcontexts, v->value, sizeof(newcontexts));
17146          stringp = newcontexts;
17147          /* Let's remove any contexts that are no longer defined in regcontext */
17148          cleanup_stale_contexts(stringp, oldregcontext);
17149          /* Create contexts if they don't exist already */
17150          while ((context = strsep(&stringp, "&"))) {
17151             if (!ast_context_find(context))
17152                ast_context_create(NULL, context,"SIP");
17153          }
17154          ast_copy_string(global_regcontext, v->value, sizeof(global_regcontext));
17155       } else if (!strcasecmp(v->name, "callerid")) {
17156          ast_copy_string(default_callerid, v->value, sizeof(default_callerid));
17157       } else if (!strcasecmp(v->name, "fromdomain")) {
17158          ast_copy_string(default_fromdomain, v->value, sizeof(default_fromdomain));
17159       } else if (!strcasecmp(v->name, "outboundproxy")) {
17160          if (ast_get_ip_or_srv(&outboundproxyip, v->value, srvlookup ? "_sip._udp" : NULL) < 0)
17161             ast_log(LOG_WARNING, "Unable to locate host '%s'\n", v->value);
17162       } else if (!strcasecmp(v->name, "outboundproxyport")) {
17163          /* Port needs to be after IP */
17164          sscanf(v->value, "%d", &format);
17165          outboundproxyip.sin_port = htons(format);
17166       } else if (!strcasecmp(v->name, "autocreatepeer")) {
17167          autocreatepeer = ast_true(v->value);
17168       } else if (!strcasecmp(v->name, "srvlookup")) {
17169          srvlookup = ast_true(v->value);
17170       } else if (!strcasecmp(v->name, "pedantic")) {
17171          pedanticsipchecking = ast_true(v->value);
17172       } else if (!strcasecmp(v->name, "maxexpirey") || !strcasecmp(v->name, "maxexpiry")) {
17173          max_expiry = atoi(v->value);
17174          if (max_expiry < 1)
17175             max_expiry = DEFAULT_MAX_EXPIRY;
17176       } else if (!strcasecmp(v->name, "minexpirey") || !strcasecmp(v->name, "minexpiry")) {
17177          min_expiry = atoi(v->value);
17178          if (min_expiry < 1)
17179             min_expiry = DEFAULT_MIN_EXPIRY;
17180       } else if (!strcasecmp(v->name, "defaultexpiry") || !strcasecmp(v->name, "defaultexpirey")) {
17181          default_expiry = atoi(v->value);
17182          if (default_expiry < 1)
17183             default_expiry = DEFAULT_DEFAULT_EXPIRY;
17184       } else if (!strcasecmp(v->name, "sipdebug")) {  /* XXX maybe ast_set2_flags ? */
17185          if (ast_true(v->value))
17186             ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONFIG);
17187       } else if (!strcasecmp(v->name, "dumphistory")) {
17188          dumphistory = ast_true(v->value);
17189       } else if (!strcasecmp(v->name, "recordhistory")) {
17190          recordhistory = ast_true(v->value);
17191       } else if (!strcasecmp(v->name, "registertimeout")) {
17192          global_reg_timeout = atoi(v->value);
17193          if (global_reg_timeout < 1)
17194             global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT;
17195       } else if (!strcasecmp(v->name, "registerattempts")) {
17196          global_regattempts_max = atoi(v->value);
17197       } else if (!strcasecmp(v->name, "bindaddr")) {
17198          if (!(hp = ast_gethostbyname(v->value, &ahp))) {
17199             ast_log(LOG_WARNING, "Invalid address: %s\n", v->value);
17200          } else {
17201             memcpy(&bindaddr.sin_addr, hp->h_addr, sizeof(bindaddr.sin_addr));
17202          }
17203       } else if (!strcasecmp(v->name, "localnet")) {
17204          struct ast_ha *na;
17205          if (!(na = ast_append_ha("d", v->value, localaddr)))
17206             ast_log(LOG_WARNING, "Invalid localnet value: %s\n", v->value);
17207          else
17208             localaddr = na;
17209       } else if (!strcasecmp(v->name, "localmask")) {
17210          ast_log(LOG_WARNING, "Use of localmask is no long supported -- use localnet with mask syntax\n");
17211       } else if (!strcasecmp(v->name, "externip")) {
17212          if (!(hp = ast_gethostbyname(v->value, &ahp))) 
17213             ast_log(LOG_WARNING, "Invalid address for externip keyword: %s\n", v->value);
17214          else
17215             memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr));
17216          externexpire = 0;
17217       } else if (!strcasecmp(v->name, "externhost")) {
17218          ast_copy_string(externhost, v->value, sizeof(externhost));
17219          if (!(hp = ast_gethostbyname(externhost, &ahp))) 
17220             ast_log(LOG_WARNING, "Invalid address for externhost keyword: %s\n", externhost);
17221          else
17222             memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr));
17223          externexpire = time(NULL);
17224       } else if (!strcasecmp(v->name, "externrefresh")) {
17225          if (sscanf(v->value, "%d", &externrefresh) != 1) {
17226             ast_log(LOG_WARNING, "Invalid externrefresh value '%s', must be an integer >0 at line %d\n", v->value, v->lineno);
17227             externrefresh = 10;
17228          }
17229       } else if (!strcasecmp(v->name, "allow")) {
17230          ast_parse_allow_disallow(&default_prefs, &global_capability, v->value, 1);
17231       } else if (!strcasecmp(v->name, "disallow")) {
17232          ast_parse_allow_disallow(&default_prefs, &global_capability, v->value, 0);
17233       } else if (!strcasecmp(v->name, "autoframing")) {
17234          global_autoframing = ast_true(v->value);
17235       } else if (!strcasecmp(v->name, "allowexternaldomains")) {
17236          allow_external_domains = ast_true(v->value);
17237       } else if (!strcasecmp(v->name, "autodomain")) {
17238          auto_sip_domains = ast_true(v->value);
17239       } else if (!strcasecmp(v->name, "domain")) {
17240          char *domain = ast_strdupa(v->value);
17241          char *context = strchr(domain, ',');
17242 
17243          if (context)
17244             *context++ = '\0';
17245 
17246          if (option_debug && ast_strlen_zero(context))
17247             ast_log(LOG_DEBUG, "No context specified at line %d for domain '%s'\n", v->lineno, domain);
17248          if (ast_strlen_zero(domain))
17249             ast_log(LOG_WARNING, "Empty domain specified at line %d\n", v->lineno);
17250          else
17251             add_sip_domain(ast_strip(domain), SIP_DOMAIN_CONFIG, context ? ast_strip(context) : "");
17252       } else if (!strcasecmp(v->name, "register")) {
17253          if (sip_register(v->value, v->lineno) == 0)
17254             registry_count++;
17255       } else if (!strcasecmp(v->name, "tos")) {
17256          if (!ast_str2tos(v->value, &temp_tos)) {
17257             global_tos_sip = temp_tos;
17258             global_tos_audio = temp_tos;
17259             global_tos_video = temp_tos;
17260             ast_log(LOG_WARNING, "tos value at line %d is deprecated.  See doc/ip-tos.txt for more information.\n", v->lineno);
17261          } else
17262             ast_log(LOG_WARNING, "Invalid tos value at line %d, See doc/ip-tos.txt for more information.\n", v->lineno);
17263       } else if (!strcasecmp(v->name, "tos_sip")) {
17264          if (ast_str2tos(v->value, &global_tos_sip))
17265             ast_log(LOG_WARNING, "Invalid tos_sip value at line %d, recommended value is 'cs3'. See doc/ip-tos.txt.\n", v->lineno);
17266       } else if (!strcasecmp(v->name, "tos_audio")) {
17267          if (ast_str2tos(v->value, &global_tos_audio))
17268             ast_log(LOG_WARNING, "Invalid tos_audio value at line %d, recommended value is 'ef'. See doc/ip-tos.txt.\n", v->lineno);
17269       } else if (!strcasecmp(v->name, "tos_video")) {
17270          if (ast_str2tos(v->value, &global_tos_video))
17271             ast_log(LOG_WARNING, "Invalid tos_video value at line %d, recommended value is 'af41'. See doc/ip-tos.txt.\n", v->lineno);
17272       } else if (!strcasecmp(v->name, "bindport")) {
17273          if (sscanf(v->value, "%d", &ourport) == 1) {
17274             bindaddr.sin_port = htons(ourport);
17275          } else {
17276             ast_log(LOG_WARNING, "Invalid port number '%s' at line %d of %s\n", v->value, v->lineno, config);
17277          }
17278       } else if (!strcasecmp(v->name, "qualify")) {
17279          if (!strcasecmp(v->value, "no")) {
17280             default_qualify = 0;
17281          } else if (!strcasecmp(v->value, "yes")) {
17282             default_qualify = DEFAULT_MAXMS;
17283          } else if (sscanf(v->value, "%d", &default_qualify) != 1) {
17284             ast_log(LOG_WARNING, "Qualification default should be 'yes', 'no', or a number of milliseconds at line %d of sip.conf\n", v->lineno);
17285             default_qualify = 0;
17286          }
17287       } else if (!strcasecmp(v->name, "callevents")) {
17288          global_callevents = ast_true(v->value);
17289       } else if (!strcasecmp(v->name, "maxcallbitrate")) {
17290          default_maxcallbitrate = atoi(v->value);
17291          if (default_maxcallbitrate < 0)
17292             default_maxcallbitrate = DEFAULT_MAX_CALL_BITRATE;
17293       } else if (!strcasecmp(v->name, "matchexterniplocally")) {
17294          global_matchexterniplocally = ast_true(v->value);
17295       }
17296    }
17297 
17298    if (!allow_external_domains && AST_LIST_EMPTY(&domain_list)) {
17299       ast_log(LOG_WARNING, "To disallow external domains, you need to configure local SIP domains.\n");
17300       allow_external_domains = 1;
17301    }
17302    
17303    /* Build list of authentication to various SIP realms, i.e. service providers */
17304    for (v = ast_variable_browse(cfg, "authentication"); v ; v = v->next) {
17305       /* Format for authentication is auth = username:password@realm */
17306       if (!strcasecmp(v->name, "auth"))
17307          authl = add_realm_authentication(authl, v->value, v->lineno);
17308    }
17309    
17310    ucfg = ast_config_load("users.conf");
17311    if (ucfg) {
17312       struct ast_variable *gen;
17313       int genhassip, genregistersip;
17314       const char *hassip, *registersip;
17315       
17316       genhassip = ast_true(ast_variable_retrieve(ucfg, "general", "hassip"));
17317       genregistersip = ast_true(ast_variable_retrieve(ucfg, "general", "registersip"));
17318       gen = ast_variable_browse(ucfg, "general");
17319       cat = ast_category_browse(ucfg, NULL);
17320       while (cat) {
17321          if (strcasecmp(cat, "general")) {
17322             hassip = ast_variable_retrieve(ucfg, cat, "hassip");
17323             registersip = ast_variable_retrieve(ucfg, cat, "registersip");
17324             if (ast_true(hassip) || (!hassip && genhassip)) {
17325                user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0);
17326                if (user) {
17327                   ASTOBJ_CONTAINER_LINK(&userl,user);
17328                   ASTOBJ_UNREF(user, sip_destroy_user);
17329                   user_count++;
17330                }
17331                peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0);
17332                if (peer) {
17333                   ast_device_state_changed("SIP/%s", peer->name);
17334                   ASTOBJ_CONTAINER_LINK(&peerl,peer);
17335                   ASTOBJ_UNREF(peer, sip_destroy_peer);
17336                   peer_count++;
17337                }
17338             }
17339             if (ast_true(registersip) || (!registersip && genregistersip)) {
17340                char tmp[256];
17341                const char *host = ast_variable_retrieve(ucfg, cat, "host");
17342                const char *username = ast_variable_retrieve(ucfg, cat, "username");
17343                const char *secret = ast_variable_retrieve(ucfg, cat, "secret");
17344                const char *contact = ast_variable_retrieve(ucfg, cat, "contact");
17345                if (!host)
17346                   host = ast_variable_retrieve(ucfg, "general", "host");
17347                if (!username)
17348                   username = ast_variable_retrieve(ucfg, "general", "username");
17349                if (!secret)
17350                   secret = ast_variable_retrieve(ucfg, "general", "secret");
17351                if (!contact)
17352                   contact = "s";
17353                if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) {
17354                   if (!ast_strlen_zero(secret))
17355                      snprintf(tmp, sizeof(tmp), "%s:%s@%s/%s", username, secret, host, contact);
17356                   else
17357                      snprintf(tmp, sizeof(tmp), "%s@%s/%s", username, host, contact);
17358                   if (sip_register(tmp, 0) == 0)
17359                      registry_count++;
17360                }
17361             }
17362          }
17363          cat = ast_category_browse(ucfg, cat);
17364       }
17365       ast_config_destroy(ucfg);
17366    }
17367    
17368 
17369    /* Load peers, users and friends */
17370    cat = NULL;
17371    while ( (cat = ast_category_browse(cfg, cat)) ) {
17372       const char *utype;
17373       if (!strcasecmp(cat, "general") || !strcasecmp(cat, "authentication"))
17374          continue;
17375       utype = ast_variable_retrieve(cfg, cat, "type");
17376       if (!utype) {
17377          ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat);
17378          continue;
17379       } else {
17380          int is_user = 0, is_peer = 0;
17381          if (!strcasecmp(utype, "user"))
17382             is_user = 1;
17383          else if (!strcasecmp(utype, "friend"))
17384             is_user = is_peer = 1;
17385          else if (!strcasecmp(utype, "peer"))
17386             is_peer = 1;
17387          else {
17388             ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, "sip.conf");
17389             continue;
17390          }
17391          if (is_user) {
17392             user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0);
17393             if (user) {
17394                ASTOBJ_CONTAINER_LINK(&userl,user);
17395                ASTOBJ_UNREF(user, sip_destroy_user);
17396                user_count++;
17397             }
17398          }
17399          if (is_peer) {
17400             peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0);
17401             if (peer) {
17402                ASTOBJ_CONTAINER_LINK(&peerl,peer);
17403                ASTOBJ_UNREF(peer, sip_destroy_peer);
17404                peer_count++;
17405             }
17406          }
17407       }
17408    }
17409    if (ast_find_ourip(&__ourip, bindaddr)) {
17410       ast_log(LOG_WARNING, "Unable to get own IP address, SIP disabled\n");
17411       ast_config_destroy(cfg);
17412       return 0;
17413    }
17414    if (!ntohs(bindaddr.sin_port))
17415       bindaddr.sin_port = ntohs(STANDARD_SIP_PORT);
17416    bindaddr.sin_family = AF_INET;
17417    ast_mutex_lock(&netlock);
17418    if ((sipsock > -1) && (memcmp(&old_bindaddr, &bindaddr, sizeof(struct sockaddr_in)))) {
17419       close(sipsock);
17420       sipsock = -1;
17421    }
17422    if (sipsock < 0) {
17423       sipsock = socket(AF_INET, SOCK_DGRAM, 0);
17424       if (sipsock < 0) {
17425          ast_log(LOG_WARNING, "Unable to create SIP socket: %s\n", strerror(errno));
17426          ast_config_destroy(cfg);
17427          return -1;
17428       } else {
17429          /* Allow SIP clients on the same host to access us: */
17430          const int reuseFlag = 1;
17431 
17432          setsockopt(sipsock, SOL_SOCKET, SO_REUSEADDR,
17433                (const char*)&reuseFlag,
17434                sizeof reuseFlag);
17435 
17436          ast_enable_packet_fragmentation(sipsock);
17437 
17438          if (bind(sipsock, (struct sockaddr *)&bindaddr, sizeof(bindaddr)) < 0) {
17439             ast_log(LOG_WARNING, "Failed to bind to %s:%d: %s\n",
17440             ast_inet_ntoa(bindaddr.sin_addr), ntohs(bindaddr.sin_port),
17441             strerror(errno));
17442             close(sipsock);
17443             sipsock = -1;
17444          } else {
17445             if (option_verbose > 1) { 
17446                ast_verbose(VERBOSE_PREFIX_2 "SIP Listening on %s:%d\n", 
17447                ast_inet_ntoa(bindaddr.sin_addr), ntohs(bindaddr.sin_port));
17448                ast_verbose(VERBOSE_PREFIX_2 "Using SIP TOS: %s\n", ast_tos2str(global_tos_sip));
17449             }
17450             if (setsockopt(sipsock, IPPROTO_IP, IP_TOS, &global_tos_sip, sizeof(global_tos_sip))) 
17451                ast_log(LOG_WARNING, "Unable to set SIP TOS to %s\n", ast_tos2str(global_tos_sip));
17452          }
17453       }
17454    }
17455    ast_mutex_unlock(&netlock);
17456 
17457    /* Add default domains - host name, IP address and IP:port */
17458    /* Only do this if user added any sip domain with "localdomains" */
17459    /* In order to *not* break backwards compatibility */
17460    /*    Some phones address us at IP only, some with additional port number */
17461    if (auto_sip_domains) {
17462       char temp[MAXHOSTNAMELEN];
17463 
17464       /* First our default IP address */
17465       if (bindaddr.sin_addr.s_addr)
17466          add_sip_domain(ast_inet_ntoa(bindaddr.sin_addr), SIP_DOMAIN_AUTO, NULL);
17467       else
17468          ast_log(LOG_NOTICE, "Can't add wildcard IP address to domain list, please add IP address to domain manually.\n");
17469 
17470       /* Our extern IP address, if configured */
17471       if (externip.sin_addr.s_addr)
17472          add_sip_domain(ast_inet_ntoa(externip.sin_addr), SIP_DOMAIN_AUTO, NULL);
17473 
17474       /* Extern host name (NAT traversal support) */
17475       if (!ast_strlen_zero(externhost))
17476          add_sip_domain(externhost, SIP_DOMAIN_AUTO, NULL);
17477       
17478       /* Our host name */
17479       if (!gethostname(temp, sizeof(temp)))
17480          add_sip_domain(temp, SIP_DOMAIN_AUTO, NULL);
17481    }
17482 
17483    /* Release configuration from memory */
17484    ast_config_destroy(cfg);
17485 
17486    /* Load the list of manual NOTIFY types to support */
17487    if (notify_types)
17488       ast_config_destroy(notify_types);
17489    notify_types = ast_config_load(notify_config);
17490 
17491    /* Done, tell the manager */
17492    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);
17493 
17494    return 0;
17495 }

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

11529 {
11530    char tmp[512];
11531    char *c;
11532    char oldnonce[256];
11533 
11534    /* table of recognised keywords, and places where they should be copied */
11535    const struct x {
11536       const char *key;
11537       int field_index;
11538    } *i, keys[] = {
11539       { "realm=", ast_string_field_index(p, realm) },
11540       { "nonce=", ast_string_field_index(p, nonce) },
11541       { "opaque=", ast_string_field_index(p, opaque) },
11542       { "qop=", ast_string_field_index(p, qop) },
11543       { "domain=", ast_string_field_index(p, domain) },
11544       { NULL, 0 },
11545    };
11546 
11547    ast_copy_string(tmp, get_header(req, header), sizeof(tmp));
11548    if (ast_strlen_zero(tmp)) 
11549       return -1;
11550    if (strncasecmp(tmp, "Digest ", strlen("Digest "))) {
11551       ast_log(LOG_WARNING, "missing Digest.\n");
11552       return -1;
11553    }
11554    c = tmp + strlen("Digest ");
11555    ast_copy_string(oldnonce, p->nonce, sizeof(oldnonce));
11556    while (c && *(c = ast_skip_blanks(c))) {  /* lookup for keys */
11557       for (i = keys; i->key != NULL; i++) {
11558          char *src, *separator;
11559          if (strncasecmp(c, i->key, strlen(i->key)) != 0)
11560             continue;
11561          /* Found. Skip keyword, take text in quotes or up to the separator. */
11562          c += strlen(i->key);
11563          if (*c == '"') {
11564             src = ++c;
11565             separator = "\"";
11566          } else {
11567             src = c;
11568             separator = ",";
11569          }
11570          strsep(&c, separator); /* clear separator and move ptr */
11571          ast_string_field_index_set(p, i->field_index, src);
11572          break;
11573       }
11574       if (i->key == NULL) /* not found, try ',' */
11575          strsep(&c, ",");
11576    }
11577    /* Reset nonce count */
11578    if (strcmp(p->nonce, oldnonce)) 
11579       p->noncecount = 0;
11580 
11581    /* Save auth data for following registrations */
11582    if (p->registry) {
11583       struct sip_registry *r = p->registry;
11584 
11585       if (strcmp(r->nonce, p->nonce)) {
11586          ast_string_field_set(r, realm, p->realm);
11587          ast_string_field_set(r, nonce, p->nonce);
11588          ast_string_field_set(r, domain, p->domain);
11589          ast_string_field_set(r, opaque, p->opaque);
11590          ast_string_field_set(r, qop, p->qop);
11591          r->noncecount = 0;
11592       }
11593    }
11594    return build_reply_digest(p, sipmethod, digest, digest_len); 
11595 }

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

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

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

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

static int restart_monitor ( void   )  [static]

Start the channel monitor thread.

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

15819 {
15820    /* If we're supposed to be stopped -- stay stopped */
15821    if (monitor_thread == AST_PTHREADT_STOP)
15822       return 0;
15823    ast_mutex_lock(&monlock);
15824    if (monitor_thread == pthread_self()) {
15825       ast_mutex_unlock(&monlock);
15826       ast_log(LOG_WARNING, "Cannot kill myself\n");
15827       return -1;
15828    }
15829    if (monitor_thread != AST_PTHREADT_NULL) {
15830       /* Wake up the thread */
15831       pthread_kill(monitor_thread, SIGURG);
15832    } else {
15833       /* Start a new monitor */
15834       if (ast_pthread_create_background(&monitor_thread, NULL, do_monitor, NULL) < 0) {
15835          ast_mutex_unlock(&monlock);
15836          ast_log(LOG_ERROR, "Unable to start monitor thread.\n");
15837          return -1;
15838       }
15839    }
15840    ast_mutex_unlock(&monlock);
15841    return 0;
15842 }

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

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

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

Set destination from SIP URI.

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

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

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

16146 {
16147    static int dep_insecure_very = 0;
16148    static int dep_insecure_yes = 0;
16149 
16150    if (ast_strlen_zero(value))
16151       return;
16152 
16153    if (!strcasecmp(value, "very")) {
16154       ast_set_flag(flags, SIP_INSECURE_PORT | SIP_INSECURE_INVITE);
16155       if(!dep_insecure_very) {
16156          if(lineno != -1)
16157             ast_log(LOG_WARNING, "insecure=very at line %d is deprecated; use insecure=port,invite instead\n", lineno);
16158          else
16159             ast_log(LOG_WARNING, "insecure=very is deprecated; use insecure=port,invite instead\n");
16160          dep_insecure_very = 1;
16161       }
16162    }
16163    else if (ast_true(value)) {
16164       ast_set_flag(flags, SIP_INSECURE_PORT);
16165       if(!dep_insecure_yes) {
16166          if(lineno != -1)
16167             ast_log(LOG_WARNING, "insecure=%s at line %d is deprecated; use insecure=port instead\n", value, lineno);
16168          else
16169             ast_log(LOG_WARNING, "insecure=%s is deprecated; use insecure=port instead\n", value);
16170          dep_insecure_yes = 1;
16171       }
16172    }
16173    else if (!ast_false(value)) {
16174       char buf[64];
16175       char *word, *next;
16176       ast_copy_string(buf, value, sizeof(buf));
16177       next = buf;
16178       while ((word = strsep(&next, ","))) {
16179          if (!strcasecmp(word, "port"))
16180             ast_set_flag(flags, SIP_INSECURE_PORT);
16181          else if (!strcasecmp(word, "invite"))
16182             ast_set_flag(flags, SIP_INSECURE_INVITE);
16183          else
16184             ast_log(LOG_WARNING, "Unknown insecure mode '%s' on line %d\n", value, lineno);
16185       }
16186    }
16187 }

static void set_peer_defaults ( struct sip_peer peer  )  [static]

Set peer defaults before configuring specific configurations.

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

16577 {
16578    if (peer->expire == 0) {
16579       /* Don't reset expire or port time during reload 
16580          if we have an active registration 
16581       */
16582       peer->expire = -1;
16583       peer->pokeexpire = -1;
16584       peer->addr.sin_port = htons(STANDARD_SIP_PORT);
16585    }
16586    ast_copy_flags(&peer->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY);
16587    ast_copy_flags(&peer->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY);
16588    strcpy(peer->context, default_context);
16589    strcpy(peer->subscribecontext, default_subscribecontext);
16590    strcpy(peer->language, default_language);
16591    strcpy(peer->mohinterpret, default_mohinterpret);
16592    strcpy(peer->mohsuggest, default_mohsuggest);
16593    peer->addr.sin_family = AF_INET;
16594    peer->defaddr.sin_family = AF_INET;
16595    peer->capability = global_capability;
16596    peer->maxcallbitrate = default_maxcallbitrate;
16597    peer->rtptimeout = global_rtptimeout;
16598    peer->rtpholdtimeout = global_rtpholdtimeout;
16599    peer->rtpkeepalive = global_rtpkeepalive;
16600    peer->allowtransfer = global_allowtransfer;
16601    peer->autoframing = global_autoframing;
16602    strcpy(peer->vmexten, default_vmexten);
16603    peer->secret[0] = '\0';
16604    peer->md5secret[0] = '\0';
16605    peer->cid_num[0] = '\0';
16606    peer->cid_name[0] = '\0';
16607    peer->fromdomain[0] = '\0';
16608    peer->fromuser[0] = '\0';
16609    peer->regexten[0] = '\0';
16610    peer->mailbox[0] = '\0';
16611    peer->callgroup = 0;
16612    peer->pickupgroup = 0;
16613    peer->maxms = default_qualify;
16614    peer->prefs = default_prefs;
16615 }

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

Add a SIP header to an outbound INVITE.

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

17835 {
17836    int no = 0;
17837    int ok = FALSE;
17838    char varbuf[30];
17839    char *inbuf = (char *) data;
17840    
17841    if (ast_strlen_zero(inbuf)) {
17842       ast_log(LOG_WARNING, "This application requires the argument: Header\n");
17843       return 0;
17844    }
17845    ast_channel_lock(chan);
17846 
17847    /* Check for headers */
17848    while (!ok && no <= 50) {
17849       no++;
17850       snprintf(varbuf, sizeof(varbuf), "_SIPADDHEADER%.2d", no);
17851 
17852       /* Compare without the leading underscore */
17853       if( (pbx_builtin_getvar_helper(chan, (const char *) varbuf + 1) == (const char *) NULL) )
17854          ok = TRUE;
17855    }
17856    if (ok) {
17857       pbx_builtin_setvar_helper (chan, varbuf, inbuf);
17858       if (sipdebug)
17859          ast_log(LOG_DEBUG,"SIP Header added \"%s\" as %s\n", inbuf, varbuf);
17860    } else {
17861       ast_log(LOG_WARNING, "Too many SIP headers added, max 50\n");
17862    }
17863    ast_channel_unlock(chan);
17864    return 0;
17865 }

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

15988 {
15989    char *host;
15990    char *tmp;
15991 
15992    struct hostent *hp;
15993    struct ast_hostent ahp;
15994    struct sip_peer *p;
15995 
15996    int res = AST_DEVICE_INVALID;
15997 
15998    /* make sure data is not null. Maybe unnecessary, but better be safe */
15999    host = ast_strdupa(data ? data : "");
16000    if ((tmp = strchr(host, '@')))
16001       host = tmp + 1;
16002 
16003    if (option_debug > 2) 
16004       ast_log(LOG_DEBUG, "Checking device state for peer %s\n", host);
16005 
16006    if ((p = find_peer(host, NULL, 1))) {
16007       if (p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) {
16008          /* we have an address for the peer */
16009       
16010          /* Check status in this order
16011             - Hold
16012             - Ringing
16013             - Busy (enforced only by call limit)
16014             - Inuse (we have a call)
16015             - Unreachable (qualify)
16016             If we don't find any of these state, report AST_DEVICE_NOT_INUSE
16017             for registered devices */
16018 
16019          if (p->onHold)
16020             /* First check for hold or ring states */
16021             res = AST_DEVICE_ONHOLD;
16022          else if (p->inRinging) {
16023             if (p->inRinging == p->inUse)
16024                res = AST_DEVICE_RINGING;
16025             else
16026                res = AST_DEVICE_RINGINUSE;
16027          } else if (p->call_limit && (p->inUse == p->call_limit))
16028             /* check call limit */
16029             res = AST_DEVICE_BUSY;
16030          else if (p->call_limit && p->inUse)
16031             /* Not busy, but we do have a call */
16032             res = AST_DEVICE_INUSE;
16033          else if (p->maxms && ((p->lastms > p->maxms) || (p->lastms < 0))) 
16034             /* We don't have a call. Are we reachable at all? Requires qualify= */
16035             res = AST_DEVICE_UNAVAILABLE;
16036          else  /* Default reply if we're registered and have no other data */
16037             res = AST_DEVICE_NOT_INUSE;
16038       } else {
16039          /* there is no address, it's unavailable */
16040          res = AST_DEVICE_UNAVAILABLE;
16041       }
16042       ASTOBJ_UNREF(p,sip_destroy_peer);
16043    } else {
16044       char *port = strchr(host, ':');
16045       if (port)
16046          *port = '\0';
16047       hp = ast_gethostbyname(host, &ahp);
16048       if (hp)
16049          res = AST_DEVICE_UNKNOWN;
16050    }
16051 
16052    return res;
16053 }

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

Turn on SIP debugging (CLI command).

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

11342 {
11343    int oldsipdebug = sipdebug_console;
11344    if (argc != 3) {
11345       if (argc != 5) 
11346          return RESULT_SHOWUSAGE;
11347       else if (strcmp(argv[3], "ip") == 0)
11348          return sip_do_debug_ip(fd, argc, argv);
11349       else if (strcmp(argv[3], "peer") == 0)
11350          return sip_do_debug_peer(fd, argc, argv);
11351       else
11352          return RESULT_SHOWUSAGE;
11353    }
11354    ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE);
11355    memset(&debugaddr, 0, sizeof(debugaddr));
11356    ast_cli(fd, "SIP Debugging %senabled\n", oldsipdebug ? "re-" : "");
11357    return RESULT_SUCCESS;
11358 }

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

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

11361 {
11362    int oldsipdebug = sipdebug_console;
11363    char *newargv[6] = { "sip", "set", "debug", NULL };
11364    if (argc != 2) {
11365       if (argc != 4) 
11366          return RESULT_SHOWUSAGE;
11367       else if (strcmp(argv[2], "ip") == 0) {
11368          newargv[3] = argv[2];
11369          newargv[4] = argv[3];
11370          return sip_do_debug_ip(fd, argc + 1, newargv);
11371       } else if (strcmp(argv[2], "peer") == 0) {
11372          newargv[3] = argv[2];
11373          newargv[4] = argv[3];
11374          return sip_do_debug_peer(fd, argc + 1, newargv);
11375       } else
11376          return RESULT_SHOWUSAGE;
11377    }
11378    ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE);
11379    memset(&debugaddr, 0, sizeof(debugaddr));
11380    ast_cli(fd, "SIP Debugging %senabled\n", oldsipdebug ? "re-" : "");
11381    return RESULT_SUCCESS;
11382 }

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

Enable SIP Debugging in CLI.

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

11288 {
11289    struct hostent *hp;
11290    struct ast_hostent ahp;
11291    int port = 0;
11292    char *p, *arg;
11293 
11294    /* sip set debug ip <ip> */
11295    if (argc != 5)
11296       return RESULT_SHOWUSAGE;
11297    p = arg = argv[4];
11298    strsep(&p, ":");
11299    if (p)
11300       port = atoi(p);
11301    hp = ast_gethostbyname(arg, &ahp);
11302    if (hp == NULL)
11303       return RESULT_SHOWUSAGE;
11304 
11305    debugaddr.sin_family = AF_INET;
11306    memcpy(&debugaddr.sin_addr, hp->h_addr, sizeof(debugaddr.sin_addr));
11307    debugaddr.sin_port = htons(port);
11308    if (port == 0)
11309       ast_cli(fd, "SIP Debugging Enabled for IP: %s\n", ast_inet_ntoa(debugaddr.sin_addr));
11310    else
11311       ast_cli(fd, "SIP Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(debugaddr.sin_addr), port);
11312 
11313    ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE);
11314 
11315    return RESULT_SUCCESS;
11316 }

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

11320 {
11321    struct sip_peer *peer;
11322    if (argc != 5)
11323       return RESULT_SHOWUSAGE;
11324    peer = find_peer(argv[4], NULL, 1);
11325    if (peer) {
11326       if (peer->addr.sin_addr.s_addr) {
11327          debugaddr.sin_family = AF_INET;
11328          debugaddr.sin_addr = peer->addr.sin_addr;
11329          debugaddr.sin_port = peer->addr.sin_port;
11330          ast_cli(fd, "SIP Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(debugaddr.sin_addr), ntohs(debugaddr.sin_port));
11331          ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE);
11332       } else
11333          ast_cli(fd, "Unable to get IP address of peer '%s'\n", argv[4]);
11334       ASTOBJ_UNREF(peer,sip_destroy_peer);
11335    } else
11336       ast_cli(fd, "No such peer '%s'\n", argv[4]);
11337    return RESULT_SUCCESS;
11338 }

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

Enable SIP History logging (CLI).

Definition at line 11460 of file chan_sip.c.

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

11461 {
11462    if (argc != 2) {
11463       return RESULT_SHOWUSAGE;
11464    }
11465    recordhistory = TRUE;
11466    ast_cli(fd, "SIP History Recording Enabled (use 'sip show history')\n");
11467    return RESULT_SUCCESS;
11468 }

static int sip_do_reload ( enum channelreloadreason  reason  )  [static]

Reload module.

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

17981 {
17982    reload_config(reason);
17983 
17984    /* Prune peers who still are supposed to be deleted */
17985    ASTOBJ_CONTAINER_PRUNE_MARKED(&peerl, sip_destroy_peer);
17986    if (option_debug > 3)
17987       ast_log(LOG_DEBUG, "--------------- Done destroying pruned peers\n");
17988 
17989    /* Send qualify (OPTIONS) to all peers */
17990    sip_poke_all_peers();
17991 
17992    /* Register with all services */
17993    sip_send_all_registers();
17994 
17995    if (option_debug > 3)
17996       ast_log(LOG_DEBUG, "--------------- SIP reload done\n");
17997 
17998    return 0;
17999 }

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

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

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

17780 {
17781    struct sip_pvt *p;
17782    char *mode;
17783    if (data)
17784       mode = (char *)data;
17785    else {
17786       ast_log(LOG_WARNING, "This application requires the argument: info, inband, rfc2833\n");
17787       return 0;
17788    }
17789    ast_channel_lock(chan);
17790    if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) {
17791       ast_log(LOG_WARNING, "Call this application only on SIP incoming calls\n");
17792       ast_channel_unlock(chan);
17793       return 0;
17794    }
17795    p = chan->tech_pvt;
17796    if (!p) {
17797       ast_channel_unlock(chan);
17798       return 0;
17799    }
17800    ast_mutex_lock(&p->lock);
17801    if (!strcasecmp(mode,"info")) {
17802       ast_clear_flag(&p->flags[0], SIP_DTMF);
17803       ast_set_flag(&p->flags[0], SIP_DTMF_INFO);
17804       p->jointnoncodeccapability &= ~AST_RTP_DTMF;
17805    } else if (!strcasecmp(mode,"rfc2833")) {
17806       ast_clear_flag(&p->flags[0], SIP_DTMF);
17807       ast_set_flag(&p->flags[0], SIP_DTMF_RFC2833);
17808       p->jointnoncodeccapability |= AST_RTP_DTMF;
17809    } else if (!strcasecmp(mode,"inband")) { 
17810       ast_clear_flag(&p->flags[0], SIP_DTMF);
17811       ast_set_flag(&p->flags[0], SIP_DTMF_INBAND);
17812       p->jointnoncodeccapability &= ~AST_RTP_DTMF;
17813    } else
17814       ast_log(LOG_WARNING, "I don't know about this dtmf mode: %s\n",mode);
17815    if (p->rtp)
17816       ast_rtp_setdtmf(p->rtp, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833);
17817    if (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) {
17818       if (!p->vad) {
17819          p->vad = ast_dsp_new();
17820          ast_dsp_set_features(p->vad, DSP_FEATURE_DTMF_DETECT);
17821       }
17822    } else {
17823       if (p->vad) {
17824          ast_dsp_free(p->vad);
17825          p->vad = NULL;
17826       }
17827    }
17828    ast_mutex_unlock(&p->lock);
17829    ast_channel_unlock(chan);
17830    return 0;
17831 }

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

11153 {
11154    int x = 0;
11155    struct sip_history *hist;
11156    static int errmsg = 0;
11157 
11158    if (!dialog)
11159       return;
11160 
11161    if (!option_debug && !sipdebug) {
11162       if (!errmsg) {
11163          ast_log(LOG_NOTICE, "You must have debugging enabled (SIP or Asterisk) in order to dump SIP history.\n");
11164          errmsg = 1;
11165       }
11166       return;
11167    }
11168 
11169    ast_log(LOG_DEBUG, "\n---------- SIP HISTORY for '%s' \n", dialog->callid);
11170    if (dialog->subscribed)
11171       ast_log(LOG_DEBUG, "  * Subscription\n");
11172    else
11173       ast_log(LOG_DEBUG, "  * SIP Call\n");
11174    if (dialog->history)
11175       AST_LIST_TRAVERSE(dialog->history, hist, list)
11176          ast_log(LOG_DEBUG, "  %-3.3d. %s\n", ++x, hist->event);
11177    if (!x)
11178       ast_log(LOG_DEBUG, "Call '%s' has no history\n", dialog->callid);
11179    ast_log(LOG_DEBUG, "\n---------- END SIP HISTORY for '%s' \n", dialog->callid);
11180 }

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

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

17925 {
17926    struct sip_pvt *p = chan->tech_pvt;
17927    return p->peercapability ? p->peercapability : p->capability;  
17928 }

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

17633 {
17634    struct sip_pvt *p = NULL;
17635    enum ast_rtp_get_result res = AST_RTP_TRY_PARTIAL;
17636 
17637    if (!(p = chan->tech_pvt))
17638       return AST_RTP_GET_FAILED;
17639 
17640    ast_mutex_lock(&p->lock);
17641    if (!(p->rtp)) {
17642       ast_mutex_unlock(&p->lock);
17643       return AST_RTP_GET_FAILED;
17644    }
17645 
17646    *rtp = p->rtp;
17647 
17648    if (ast_rtp_getnat(*rtp) && !ast_test_flag(&p->flags[0], SIP_CAN_REINVITE_NAT))
17649       res = AST_RTP_TRY_PARTIAL;
17650    else if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE))
17651       res = AST_RTP_TRY_NATIVE;
17652    else if (ast_test_flag(&global_jbconf, AST_JB_FORCED))
17653       res = AST_RTP_GET_FAILED;
17654 
17655    ast_mutex_unlock(&p->lock);
17656 
17657    return res;
17658 }

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

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

17498 {
17499    struct sip_pvt *p;
17500    struct ast_udptl *udptl = NULL;
17501    
17502    p = chan->tech_pvt;
17503    if (!p)
17504       return NULL;
17505    
17506    ast_mutex_lock(&p->lock);
17507    if (p->udptl && ast_test_flag(&p->flags[0], SIP_CAN_REINVITE))
17508       udptl = p->udptl;
17509    ast_mutex_unlock(&p->lock);
17510    return udptl;
17511 }

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

17662 {
17663    struct sip_pvt *p = NULL;
17664    enum ast_rtp_get_result res = AST_RTP_TRY_PARTIAL;
17665    
17666    if (!(p = chan->tech_pvt))
17667       return AST_RTP_GET_FAILED;
17668 
17669    ast_mutex_lock(&p->lock);
17670    if (!(p->vrtp)) {
17671       ast_mutex_unlock(&p->lock);
17672       return AST_RTP_GET_FAILED;
17673    }
17674 
17675    *rtp = p->vrtp;
17676 
17677    if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE))
17678       res = AST_RTP_TRY_NATIVE;
17679 
17680    ast_mutex_unlock(&p->lock);
17681 
17682    return res;
17683 }

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

17550 {
17551    struct sip_pvt *p;
17552    int flag = 0;
17553    
17554    p = chan->tech_pvt;
17555    if (!p || !pvt->udptl)
17556       return -1;
17557    
17558    /* Setup everything on the other side like offered/responded from first side */
17559    ast_mutex_lock(&p->lock);
17560 
17561    /*! \todo check if this is not set earlier when setting up the PVT. If not
17562       maybe it should move there. */
17563    p->t38.jointcapability = p->t38.peercapability = pvt->t38.jointcapability;
17564 
17565    ast_udptl_set_far_max_datagram(p->udptl, ast_udptl_get_local_max_datagram(pvt->udptl));
17566    ast_udptl_set_local_max_datagram(p->udptl, ast_udptl_get_local_max_datagram(pvt->udptl));
17567    ast_udptl_set_error_correction_scheme(p->udptl, ast_udptl_get_error_correction_scheme(pvt->udptl));
17568    
17569    if (reinvite) {      /* If we are handling sending re-invite to the other side of the bridge */
17570       /*! \note The SIP_CAN_REINVITE flag is for RTP media redirects,
17571          not really T38 re-invites which are different. In this
17572          case it's used properly, to see if we can reinvite over
17573          NAT 
17574       */
17575       if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE) && ast_test_flag(&pvt->flags[0], SIP_CAN_REINVITE)) {
17576          ast_udptl_get_peer(pvt->udptl, &p->udptlredirip);
17577          flag =1;
17578       } else {
17579          memset(&p->udptlredirip, 0, sizeof(p->udptlredirip));
17580       }
17581       if (!ast_test_flag(&p->flags[0], SIP_GOTREFER)) {
17582          if (!p->pendinginvite) {
17583             if (option_debug > 2) {
17584                if (flag)
17585                   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));
17586                else
17587                   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));
17588             }
17589             transmit_reinvite_with_t38_sdp(p);
17590          } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) {
17591             if (option_debug > 2) {
17592                if (flag)
17593                   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));
17594                else
17595                   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));
17596             }
17597             ast_set_flag(&p->flags[0], SIP_NEEDREINVITE);
17598          }
17599       }
17600       /* Reset lastrtprx timer */
17601       p->lastrtprx = p->lastrtptx = time(NULL);
17602       ast_mutex_unlock(&p->lock);
17603       return 0;
17604    } else { /* If we are handling sending 200 OK to the other side of the bridge */
17605       if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE) && ast_test_flag(&pvt->flags[0], SIP_CAN_REINVITE)) {
17606          ast_udptl_get_peer(pvt->udptl, &p->udptlredirip);
17607          flag = 1;
17608       } else {
17609          memset(&p->udptlredirip, 0, sizeof(p->udptlredirip));
17610       }
17611       if (option_debug > 2) {
17612          if (flag)
17613             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));
17614          else
17615             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));
17616       }
17617       pvt->t38.state = T38_ENABLED;
17618       p->t38.state = T38_ENABLED;
17619       if (option_debug > 1) {
17620          ast_log(LOG_DEBUG, "T38 changed state to %d on channel %s\n", pvt->t38.state, pvt->owner ? pvt->owner->name : "<none>");
17621          ast_log(LOG_DEBUG, "T38 changed state to %d on channel %s\n", p->t38.state, chan ? chan->name : "<none>");
17622       }
17623       transmit_response_with_t38_sdp(p, "200 OK", &p->initreq, XMIT_CRITICAL);
17624       p->lastrtprx = p->lastrtptx = time(NULL);
17625       ast_mutex_unlock(&p->lock);
17626       return 0;
17627    }
17628 }

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

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

11442 {
11443    if (argc != 4)
11444       return RESULT_SHOWUSAGE;
11445    ast_clear_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE);
11446    ast_cli(fd, "SIP Debugging Disabled\n");
11447    return RESULT_SUCCESS;
11448 }

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

Definition at line 11450 of file chan_sip.c.

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

11451 {
11452    if (argc != 3)
11453       return RESULT_SHOWUSAGE;
11454    ast_clear_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE);
11455    ast_cli(fd, "SIP Debugging Disabled\n");
11456    return RESULT_SUCCESS;
11457 }

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

Disable SIP History logging (CLI).

Definition at line 11471 of file chan_sip.c.

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

11472 {
11473    if (argc != 3) {
11474       return RESULT_SHOWUSAGE;
11475    }
11476    recordhistory = FALSE;
11477    ast_cli(fd, "SIP History Recording Disabled\n");
11478    return RESULT_SUCCESS;
11479 }

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

Cli command to send SIP notify to peer.

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

11386 {
11387    struct ast_variable *varlist;
11388    int i;
11389 
11390    if (argc < 4)
11391       return RESULT_SHOWUSAGE;
11392 
11393    if (!notify_types) {
11394       ast_cli(fd, "No %s file found, or no types listed there\n", notify_config);
11395       return RESULT_FAILURE;
11396    }
11397 
11398    varlist = ast_variable_browse(notify_types, argv[2]);
11399 
11400    if (!varlist) {
11401       ast_cli(fd, "Unable to find notify type '%s'\n", argv[2]);
11402       return RESULT_FAILURE;
11403    }
11404 
11405    for (i = 3; i < argc; i++) {
11406       struct sip_pvt *p;
11407       struct sip_request req;
11408       struct ast_variable *var;
11409 
11410       if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY))) {
11411          ast_log(LOG_WARNING, "Unable to build sip pvt data for notify (memory/socket error)\n");
11412          return RESULT_FAILURE;
11413       }
11414 
11415       if (create_addr(p, argv[i])) {
11416          /* Maybe they're not registered, etc. */
11417          sip_destroy(p);
11418          ast_cli(fd, "Could not create address for '%s'\n", argv[i]);
11419          continue;
11420       }
11421 
11422       initreqprep(&req, p, SIP_NOTIFY);
11423 
11424       for (var = varlist; var; var = var->next)
11425          add_header(&req, var->name, ast_unescape_semicolon(var->value));
11426 
11427       /* Recalculate our side, and recalculate Call ID */
11428       if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
11429          p->ourip = __ourip;
11430       build_via(p);
11431       build_callid_pvt(p);
11432       ast_cli(fd, "Sending NOTIFY of type '%s' to '%s'\n", argv[2], argv[i]);
11433       transmit_sip_request(p, &req);
11434       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
11435    }
11436 
11437    return RESULT_SUCCESS;
11438 }

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

13202 {
13203    struct sip_dual *d;
13204    struct ast_channel *transferee, *transferer;
13205       /* Chan2m: The transferer, chan1m: The transferee */
13206    pthread_t th;
13207 
13208    transferee = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan1->accountcode, chan1->exten, chan1->context, chan1->amaflags, "Parking/%s", chan1->name);
13209    transferer = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->amaflags, "SIPPeer/%s", chan2->name);
13210    if ((!transferer) || (!transferee)) {
13211       if (transferee) {
13212          transferee->hangupcause = AST_CAUSE_SWITCH_CONGESTION;
13213          ast_hangup(transferee);
13214       }
13215       if (transferer) {
13216          transferer->hangupcause = AST_CAUSE_SWITCH_CONGESTION;
13217          ast_hangup(transferer);
13218       }
13219       return -1;
13220    }
13221 
13222    /* Make formats okay */
13223    transferee->readformat = chan1->readformat;
13224    transferee->writeformat = chan1->writeformat;
13225 
13226    /* Prepare for taking over the channel */
13227    ast_channel_masquerade(transferee, chan1);
13228 
13229    /* Setup the extensions and such */
13230    ast_copy_string(transferee->context, chan1->context, sizeof(transferee->context));
13231    ast_copy_string(transferee->exten, chan1->exten, sizeof(transferee->exten));
13232    transferee->priority = chan1->priority;
13233       
13234    /* We make a clone of the peer channel too, so we can play
13235       back the announcement */
13236 
13237    /* Make formats okay */
13238    transferer->readformat = chan2->readformat;
13239    transferer->writeformat = chan2->writeformat;
13240 
13241    /* Prepare for taking over the channel.  Go ahead and grab this channel
13242     * lock here to avoid a deadlock with callbacks into the channel driver
13243     * that hold the channel lock and want the pvt lock.  */
13244    while (ast_channel_trylock(chan2)) {
13245       struct sip_pvt *pvt = chan2->tech_pvt;
13246       DEADLOCK_AVOIDANCE(&pvt->lock);
13247    }
13248    ast_channel_masquerade(transferer, chan2);
13249    ast_channel_unlock(chan2);
13250 
13251    /* Setup the extensions and such */
13252    ast_copy_string(transferer->context, chan2->context, sizeof(transferer->context));
13253    ast_copy_string(transferer->exten, chan2->exten, sizeof(transferer->exten));
13254    transferer->priority = chan2->priority;
13255 
13256    ast_channel_lock(transferer);
13257    if (ast_do_masquerade(transferer)) {
13258       ast_log(LOG_WARNING, "Masquerade failed :(\n");
13259       ast_channel_unlock(transferer);
13260       transferer->hangupcause = AST_CAUSE_SWITCH_CONGESTION;
13261       ast_hangup(transferer);
13262       return -1;
13263    }
13264    ast_channel_unlock(transferer);
13265    if (!transferer || !transferee) {
13266       if (!transferer) { 
13267          if (option_debug)
13268             ast_log(LOG_DEBUG, "No transferer channel, giving up parking\n");
13269       }
13270       if (!transferee) {
13271          if (option_debug)
13272             ast_log(LOG_DEBUG, "No transferee channel, giving up parking\n");
13273       }
13274       return -1;
13275    }
13276    if ((d = ast_calloc(1, sizeof(*d)))) {
13277       pthread_attr_t attr;
13278 
13279       pthread_attr_init(&attr);
13280       pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);   
13281 
13282       /* Save original request for followup */
13283       copy_request(&d->req, req);
13284       d->chan1 = transferee;  /* Transferee */
13285       d->chan2 = transferer;  /* Transferer */
13286       d->seqno = seqno;
13287       if (ast_pthread_create_background(&th, &attr, sip_park_thread, d) < 0) {
13288          /* Could not start thread */
13289          free(d); /* We don't need it anymore. If thread is created, d will be free'd
13290                   by sip_park_thread() */
13291          pthread_attr_destroy(&attr);
13292          return 0;
13293       }
13294       pthread_attr_destroy(&attr);
13295    } 
13296    return -1;
13297 }

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

13135 {
13136    struct ast_channel *transferee, *transferer; /* Chan1: The transferee, Chan2: The transferer */
13137    struct sip_dual *d;
13138    struct sip_request req;
13139    int ext;
13140    int res;
13141 
13142    d = stuff;
13143    transferee = d->chan1;
13144    transferer = d->chan2;
13145    copy_request(&req, &d->req);
13146    free(d);
13147 
13148    if (!transferee || !transferer) {
13149       ast_log(LOG_ERROR, "Missing channels for parking! Transferer %s Transferee %s\n", transferer ? "<available>" : "<missing>", transferee ? "<available>" : "<missing>" );
13150       return NULL;
13151    }
13152    if (option_debug > 3) 
13153       ast_log(LOG_DEBUG, "SIP Park: Transferer channel %s, Transferee %s\n", transferer->name, transferee->name);
13154 
13155    ast_channel_lock(transferee);
13156    if (ast_do_masquerade(transferee)) {
13157       ast_log(LOG_WARNING, "Masquerade failed.\n");
13158       transmit_response(transferer->tech_pvt, "503 Internal error", &req);
13159       ast_channel_unlock(transferee);
13160       return NULL;
13161    } 
13162    ast_channel_unlock(transferee);
13163 
13164    res = ast_park_call(transferee, transferer, 0, &ext);
13165    
13166 
13167 #ifdef WHEN_WE_KNOW_THAT_THE_CLIENT_SUPPORTS_MESSAGE
13168    if (!res) {
13169       transmit_message_with_text(transferer->tech_pvt, "Unable to park call.\n");
13170    } else {
13171       /* Then tell the transferer what happened */
13172       sprintf(buf, "Call parked on extension '%d'", ext);
13173       transmit_message_with_text(transferer->tech_pvt, buf);
13174    }
13175 #endif
13176 
13177    /* Any way back to the current call??? */
13178    /* Transmit response to the REFER request */
13179    transmit_response(transferer->tech_pvt, "202 Accepted", &req);
13180    if (!res)   {
13181       /* Transfer succeeded */
13182       append_history(transferer->tech_pvt, "SIPpark","Parked call on %d", ext);
13183       transmit_notify_with_sipfrag(transferer->tech_pvt, d->seqno, "200 OK", TRUE);
13184       transferer->hangupcause = AST_CAUSE_NORMAL_CLEARING;
13185       ast_hangup(transferer); /* This will cause a BYE */
13186       if (option_debug)
13187          ast_log(LOG_DEBUG, "SIP Call parked on extension '%d'\n", ext);
13188    } else {
13189       transmit_notify_with_sipfrag(transferer->tech_pvt, d->seqno, "503 Service Unavailable", TRUE);
13190       append_history(transferer->tech_pvt, "SIPpark","Parking failed\n");
13191       if (option_debug)
13192          ast_log(LOG_DEBUG, "SIP Call parked failed \n");
13193       /* Do not hangup call */
13194    }
13195    return NULL;
13196 }

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

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

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

17935 {
17936    int ms = 0;
17937    
17938    if (!speerobjs)   /* No peers, just give up */
17939       return;
17940 
17941    ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do {
17942       ASTOBJ_WRLOCK(iterator);
17943       if (!AST_SCHED_DEL(sched, iterator->pokeexpire)) {
17944          struct sip_peer *peer_ptr = iterator;
17945          ASTOBJ_UNREF(peer_ptr, sip_destroy_peer);
17946       }
17947       ms += 100;
17948       iterator->pokeexpire = ast_sched_add(sched, ms, sip_poke_peer_s, ASTOBJ_REF(iterator));
17949       if (iterator->pokeexpire == -1) {
17950          struct sip_peer *peer_ptr = iterator;
17951          ASTOBJ_UNREF(peer_ptr, sip_destroy_peer);
17952       }
17953       ASTOBJ_UNLOCK(iterator);
17954    } while (0)
17955    );
17956 }

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

React to lack of answer to Qualify poke.

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

15846 {
15847    struct sip_peer *peer = (struct sip_peer *)data;
15848    
15849    peer->pokeexpire = -1;
15850    if (peer->lastms > -1) {
15851       ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE!  Last qualify: %d\n", peer->name, peer->lastms);
15852       manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, -1);
15853    }
15854    if (peer->call)
15855       sip_destroy(peer->call);
15856    peer->call = NULL;
15857    peer->lastms = -1;
15858    ast_device_state_changed("SIP/%s", peer->name);
15859 
15860    /* This function gets called one place outside of the scheduler ... */
15861    if (!AST_SCHED_DEL(sched, peer->pokeexpire)) {
15862       struct sip_peer *peer_ptr = peer;
15863       ASTOBJ_UNREF(peer_ptr, sip_destroy_peer);
15864    }
15865 
15866    /* There is no need to ASTOBJ_REF() here.  Just let the scheduled callback
15867     * inherit the reference that the current callback already has. */
15868    peer->pokeexpire = ast_sched_add(sched, DEFAULT_FREQ_NOTOK, sip_poke_peer_s, peer);
15869    if (peer->pokeexpire == -1) {
15870       ASTOBJ_UNREF(peer, sip_destroy_peer);
15871    }
15872 
15873    return 0;
15874 }

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

15880 {
15881    struct sip_pvt *p;
15882    int xmitres = 0;
15883 
15884    if (!peer->maxms || !peer->addr.sin_addr.s_addr) {
15885       /* IF we have no IP, or this isn't to be monitored, return
15886         imeediately after clearing things out */
15887       if (!AST_SCHED_DEL(sched, peer->pokeexpire)) {
15888          struct sip_peer *peer_ptr = peer;
15889          ASTOBJ_UNREF(peer_ptr, sip_destroy_peer);
15890       }
15891       peer->lastms = 0;
15892       peer->call = NULL;
15893       return 0;
15894    }
15895    if (peer->call) {
15896       if (sipdebug)
15897          ast_log(LOG_NOTICE, "Still have a QUALIFY dialog active, deleting\n");
15898       sip_destroy(peer->call);
15899    }
15900    if (!(p = peer->call = sip_alloc(NULL, NULL, 0, SIP_OPTIONS)))
15901       return -1;
15902    
15903    p->sa = peer->addr;
15904    p->recv = peer->addr;
15905    ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY);
15906    ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY);
15907 
15908    /* Send OPTIONs to peer's fullcontact */
15909    if (!ast_strlen_zero(peer->fullcontact))
15910       ast_string_field_set(p, fullcontact, peer->fullcontact);
15911 
15912    if (!ast_strlen_zero(peer->tohost))
15913       ast_string_field_set(p, tohost, peer->tohost);
15914    else
15915       ast_string_field_set(p, tohost, ast_inet_ntoa(peer->addr.sin_addr));
15916 
15917    /* Recalculate our side, and recalculate Call ID */
15918    if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
15919       p->ourip = __ourip;
15920    build_via(p);
15921    build_callid_pvt(p);
15922 
15923    if (!AST_SCHED_DEL(sched, peer->pokeexpire)) {
15924       struct sip_peer *peer_ptr = peer;
15925       ASTOBJ_UNREF(peer_ptr, sip_destroy_peer);
15926    }
15927 
15928    p->relatedpeer = ASTOBJ_REF(peer);
15929    ast_set_flag(&p->flags[0], SIP_OUTGOING);
15930 #ifdef VOCAL_DATA_HACK
15931    ast_copy_string(p->username, "__VOCAL_DATA_SHOULD_READ_THE_SIP_SPEC__", sizeof(p->username));
15932    xmitres = transmit_invite(p, SIP_INVITE, 0, 2);
15933 #else
15934    xmitres = transmit_invite(p, SIP_OPTIONS, 0, 2);
15935 #endif
15936    gettimeofday(&peer->ps, NULL);
15937    if (xmitres == XMIT_ERROR) {
15938       sip_poke_noanswer(ASTOBJ_REF(peer));   /* Immediately unreachable, network problems */
15939    } else {
15940       if (!AST_SCHED_DEL(sched, peer->pokeexpire)) {
15941          struct sip_peer *peer_ptr = peer;
15942          ASTOBJ_UNREF(peer_ptr, sip_destroy_peer);
15943       }
15944       peer->pokeexpire = ast_sched_add(sched, peer->maxms * 2, sip_poke_noanswer, ASTOBJ_REF(peer));
15945       if (peer->pokeexpire == -1) {
15946          struct sip_peer *peer_ptr = peer;
15947          ASTOBJ_UNREF(peer_ptr, sip_destroy_peer);
15948       }
15949    }
15950 
15951    return 0;
15952 }

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

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

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

Remove temporary realtime objects from memory (CLI).

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

10175 {
10176    struct sip_peer *peer;
10177    struct sip_user *user;
10178    int pruneuser = FALSE;
10179    int prunepeer = FALSE;
10180    int multi = FALSE;
10181    char *name = NULL;
10182    regex_t regexbuf;
10183 
10184    switch (argc) {
10185    case 4:
10186       if (!strcasecmp(argv[3], "user"))
10187          return RESULT_SHOWUSAGE;
10188       if (!strcasecmp(argv[3], "peer"))
10189          return RESULT_SHOWUSAGE;
10190       if (!strcasecmp(argv[3], "like"))
10191          return RESULT_SHOWUSAGE;
10192       if (!strcasecmp(argv[3], "all")) {
10193          multi = TRUE;
10194          pruneuser = prunepeer = TRUE;
10195       } else {
10196          pruneuser = prunepeer = TRUE;
10197          name = argv[3];
10198       }
10199       break;
10200    case 5:
10201       if (!strcasecmp(argv[4], "like"))
10202          return RESULT_SHOWUSAGE;
10203       if (!strcasecmp(argv[3], "all"))
10204          return RESULT_SHOWUSAGE;
10205       if (!strcasecmp(argv[3], "like")) {
10206          multi = TRUE;
10207          name = argv[4];
10208          pruneuser = prunepeer = TRUE;
10209       } else if (!strcasecmp(argv[3], "user")) {
10210          pruneuser = TRUE;
10211          if (!strcasecmp(argv[4], "all"))
10212             multi = TRUE;
10213          else
10214             name = argv[4];
10215       } else if (!strcasecmp(argv[3], "peer")) {
10216          prunepeer = TRUE;
10217          if (!strcasecmp(argv[4], "all"))
10218             multi = TRUE;
10219          else
10220             name = argv[4];
10221       } else
10222          return RESULT_SHOWUSAGE;
10223       break;
10224    case 6:
10225       if (strcasecmp(argv[4], "like"))
10226          return RESULT_SHOWUSAGE;
10227       if (!strcasecmp(argv[3], "user")) {
10228          pruneuser = TRUE;
10229          name = argv[5];
10230       } else if (!strcasecmp(argv[3], "peer")) {
10231          prunepeer = TRUE;
10232          name = argv[5];
10233       } else
10234          return RESULT_SHOWUSAGE;
10235       break;
10236    default:
10237       return RESULT_SHOWUSAGE;
10238    }
10239 
10240    if (multi && name) {
10241       if (regcomp(&regexbuf, name, REG_EXTENDED | REG_NOSUB))
10242          return RESULT_SHOWUSAGE;
10243    }
10244 
10245    if (multi) {
10246       if (prunepeer) {
10247          int pruned = 0;
10248 
10249          ASTOBJ_CONTAINER_WRLOCK(&peerl);
10250          ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do {
10251             ASTOBJ_RDLOCK(iterator);
10252             if (name && regexec(&regexbuf, iterator->name, 0, NULL, 0)) {
10253                ASTOBJ_UNLOCK(iterator);
10254                continue;
10255             };
10256             if (ast_test_flag(&iterator->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) {
10257                ASTOBJ_MARK(iterator);
10258                pruned++;
10259             }
10260             ASTOBJ_UNLOCK(iterator);
10261          } while (0) );
10262          if (pruned) {
10263             ASTOBJ_CONTAINER_PRUNE_MARKED(&peerl, sip_destroy_peer);
10264             ast_cli(fd, "%d peers pruned.\n", pruned);
10265          } else
10266             ast_cli(fd, "No peers found to prune.\n");
10267          ASTOBJ_CONTAINER_UNLOCK(&peerl);
10268       }
10269       if (pruneuser) {
10270          int pruned = 0;
10271 
10272          ASTOBJ_CONTAINER_WRLOCK(&userl);
10273          ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do {
10274             ASTOBJ_RDLOCK(iterator);
10275             if (name && regexec(&regexbuf, iterator->name, 0, NULL, 0)) {
10276                ASTOBJ_UNLOCK(iterator);
10277                continue;
10278             };
10279             if (ast_test_flag(&iterator->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) {
10280                ASTOBJ_MARK(iterator);
10281                pruned++;
10282             }
10283             ASTOBJ_UNLOCK(iterator);
10284          } while (0) );
10285          if (pruned) {
10286             ASTOBJ_CONTAINER_PRUNE_MARKED(&userl, sip_destroy_user);
10287             ast_cli(fd, "%d users pruned.\n", pruned);
10288          } else
10289             ast_cli(fd, "No users found to prune.\n");
10290          ASTOBJ_CONTAINER_UNLOCK(&userl);
10291       }
10292    } else {
10293       if (prunepeer) {
10294          if ((peer = ASTOBJ_CONTAINER_FIND_UNLINK(&peerl, name))) {
10295             if (!ast_test_flag(&peer->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) {
10296                ast_cli(fd, "Peer '%s' is not a Realtime peer, cannot be pruned.\n", name);
10297                ASTOBJ_CONTAINER_LINK(&peerl, peer);
10298             } else
10299                ast_cli(fd, "Peer '%s' pruned.\n", name);
10300             ASTOBJ_UNREF(peer, sip_destroy_peer);
10301          } else
10302             ast_cli(fd, "Peer '%s' not found.\n", name);
10303       }
10304       if (pruneuser) {
10305          if ((user = ASTOBJ_CONTAINER_FIND_UNLINK(&userl, name))) {
10306             if (!ast_test_flag(&user->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) {
10307                ast_cli(fd, "User '%s' is not a Realtime user, cannot be pruned.\n", name);
10308                ASTOBJ_CONTAINER_LINK(&userl, user);
10309             } else
10310                ast_cli(fd, "User '%s' pruned.\n", name);
10311             ASTOBJ_UNREF(user, sip_destroy_user);
10312          } else
10313             ast_cli(fd, "User '%s' not found.\n", name);
10314       }
10315    }
10316 
10317    return RESULT_SUCCESS;
10318 }

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

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

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

Registration timeout, register again.

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

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

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

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

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

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

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

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

Referenced by handle_response_invite().

12109 {
12110    struct sip_pvt *p = (struct sip_pvt *) data;
12111 
12112    ast_set_flag(&p->flags[0], SIP_NEEDREINVITE);   
12113    p->waitid = -1;
12114    return 0;
12115 }

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

Force reload of module from cli.

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

18003 {
18004    ast_mutex_lock(&sip_reload_lock);
18005    if (sip_reloading) 
18006       ast_verbose("Previous SIP reload not yet done\n");
18007    else {
18008       sip_reloading = TRUE;
18009       if (fd)
18010          sip_reloadreason = CHANNEL_CLI_RELOAD;
18011       else
18012          sip_reloadreason = CHANNEL_MODULE_RELOAD;
18013    }
18014    ast_mutex_unlock(&sip_reload_lock);
18015    restart_monitor();
18016 
18017    return 0;
18018 }

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

16058 {
16059    int oldformat;
16060    struct sip_pvt *p;
16061    struct ast_channel *tmpc = NULL;
16062    char *ext, *host;
16063    char tmp[256];
16064    char *dest = data;
16065 
16066    oldformat = format;
16067    if (!(format &= ((AST_FORMAT_MAX_AUDIO << 1) - 1))) {
16068       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));
16069       *cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;   /* Can't find codec to connect to host */
16070       return NULL;
16071    }
16072    if (option_debug)
16073       ast_log(LOG_DEBUG, "Asked to create a SIP channel with formats: %s\n", ast_getformatname_multiple(tmp, sizeof(tmp), oldformat));
16074 
16075    if (!(p = sip_alloc(NULL, NULL, 0, SIP_INVITE))) {
16076       ast_log(LOG_ERROR, "Unable to build sip pvt data for '%s' (Out of memory or socket error)\n", (char *)data);
16077       *cause = AST_CAUSE_SWITCH_CONGESTION;
16078       return NULL;
16079    }
16080 
16081    ast_set_flag(&p->flags[1], SIP_PAGE2_OUTGOING_CALL);
16082 
16083    if (!(p->options = ast_calloc(1, sizeof(*p->options)))) {
16084       sip_destroy(p);
16085       ast_log(LOG_ERROR, "Unable to build option SIP data structure - Out of memory\n");
16086       *cause = AST_CAUSE_SWITCH_CONGESTION;
16087       return NULL;
16088    }
16089 
16090    ast_copy_string(tmp, dest, sizeof(tmp));
16091    host = strchr(tmp, '@');
16092    if (host) {
16093       *host++ = '\0';
16094       ext = tmp;
16095    } else {
16096       ext = strchr(tmp, '/');
16097       if (ext) 
16098          *ext++ = '\0';
16099       host = tmp;
16100    }
16101 
16102    if (create_addr(p, host)) {
16103       *cause = AST_CAUSE_UNREGISTERED;
16104       if (option_debug > 2)
16105          ast_log(LOG_DEBUG, "Cant create SIP call - target device not registred\n");
16106       sip_destroy(p);
16107       return NULL;
16108    }
16109    if (ast_strlen_zero(p->peername) && ext)
16110       ast_string_field_set(p, peername, ext);
16111    /* Recalculate our side, and recalculate Call ID */
16112    if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
16113       p->ourip = __ourip;
16114    build_via(p);
16115    build_callid_pvt(p);
16116    
16117    /* We have an extension to call, don't use the full contact here */
16118    /* This to enable dialing registered peers with extension dialling,
16119       like SIP/peername/extension   
16120       SIP/peername will still use the full contact */
16121    if (ext) {
16122       ast_string_field_set(p, username, ext);
16123       ast_string_field_free(p, fullcontact);
16124    }
16125 #if 0
16126    printf("Setting up to call extension '%s' at '%s'\n", ext ? ext : "<none>", host);
16127 #endif
16128    p->prefcodec = oldformat;           /* Format for this call */
16129    ast_mutex_lock(&p->lock);
16130    tmpc = sip_new(p, AST_STATE_DOWN, host);  /* Place the call */
16131    ast_mutex_unlock(&p->lock);
16132    if (!tmpc)
16133       sip_destroy(p);
16134    ast_update_use_count();
16135    restart_monitor();
16136    return tmpc;
16137 }

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

Update registration with SIP Proxy.

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

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

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

17960 {
17961    int ms;
17962    int regspacing;
17963    if (!regobjs)
17964       return;
17965    regspacing = default_expiry * 1000/regobjs;
17966    if (regspacing > 100)
17967       regspacing = 100;
17968    ms = regspacing;
17969    ASTOBJ_CONTAINER_TRAVERSE(&regl, 1, do {
17970       ASTOBJ_WRLOCK(iterator);
17971       AST_SCHED_DEL(sched, iterator->expire);
17972       ms += regspacing;
17973       iterator->expire = ast_sched_add(sched, ms, sip_reregister, iterator);
17974       ASTOBJ_UNLOCK(iterator);
17975    } while (0)
17976    );
17977 }

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

15580 {
15581    /* Called with peerl lock, but releases it */
15582    struct sip_pvt *p;
15583    int newmsgs, oldmsgs;
15584 
15585    /* Do we have an IP address? If not, skip this peer */
15586    if (!peer->addr.sin_addr.s_addr && !peer->defaddr.sin_addr.s_addr) 
15587       return 0;
15588 
15589    /* Check for messages */
15590    ast_app_inboxcount(peer->mailbox, &newmsgs, &oldmsgs);
15591    
15592    peer->lastmsgcheck = time(NULL);
15593    
15594    /* Return now if it's the same thing we told them last time */
15595    if (((newmsgs > 0x7fff ? 0x7fff0000 : (newmsgs << 16)) | (oldmsgs > 0xffff ? 0xffff : oldmsgs)) == peer->lastmsgssent) {
15596       return 0;
15597    }
15598    
15599    
15600    peer->lastmsgssent = ((newmsgs > 0x7fff ? 0x7fff0000 : (newmsgs << 16)) | (oldmsgs > 0xffff ? 0xffff : oldmsgs));
15601 
15602    if (peer->mwipvt) {
15603       /* Base message on subscription */
15604       p = peer->mwipvt;
15605    } else {
15606       /* Build temporary dialog for this message */
15607       if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY))) 
15608          return -1;
15609       if (create_addr_from_peer(p, peer)) {
15610          /* Maybe they're not registered, etc. */
15611          sip_destroy(p);
15612          return 0;
15613       }
15614       /* Recalculate our side, and recalculate Call ID */
15615       if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
15616          p->ourip = __ourip;
15617       build_via(p);
15618       build_callid_pvt(p);
15619       /* Destroy this session after 32 secs */
15620       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
15621    }
15622    /* Send MWI */
15623    ast_set_flag(&p->flags[0], SIP_OUTGOING);
15624    transmit_notify_with_mwi(p, newmsgs, oldmsgs, peer->vmexten);
15625    return 0;
15626 }

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

17687 {
17688    struct sip_pvt *p;
17689    int changed = 0;
17690 
17691    p = chan->tech_pvt;
17692    if (!p) 
17693       return -1;
17694 
17695    /* Disable early RTP bridge  */
17696    if (chan->_state != AST_STATE_UP && !global_directrtpsetup)    /* We are in early state */
17697       return 0;
17698 
17699    ast_mutex_lock(&p->lock);
17700    if (ast_test_flag(&p->flags[0], SIP_ALREADYGONE)) {
17701       /* If we're destroyed, don't bother */
17702       ast_mutex_unlock(&p->lock);
17703       return 0;
17704    }
17705 
17706    /* if this peer cannot handle reinvites of the media stream to devices
17707       that are known to be behind a NAT, then stop the process now
17708    */
17709    if (nat_active && !ast_test_flag(&p->flags[0], SIP_CAN_REINVITE_NAT)) {
17710       ast_mutex_unlock(&p->lock);
17711       return 0;
17712    }
17713 
17714    if (rtp) {
17715       changed |= ast_rtp_get_peer(rtp, &p->redirip);
17716    } else if (p->redirip.sin_addr.s_addr || ntohs(p->redirip.sin_port) != 0) {
17717       memset(&p->redirip, 0, sizeof(p->redirip));
17718       changed = 1;
17719    }
17720    if (vrtp) {
17721       changed |= ast_rtp_get_peer(vrtp, &p->vredirip);
17722    } else if (p->vredirip.sin_addr.s_addr || ntohs(p->vredirip.sin_port) != 0) {
17723       memset(&p->vredirip, 0, sizeof(p->vredirip));
17724       changed = 1;
17725    }
17726    if (codecs) {
17727       if ((p->redircodecs != codecs)) {
17728          p->redircodecs = codecs;
17729          changed = 1;
17730       }
17731       if ((p->capability & codecs) != p->capability) {
17732          p->jointcapability &= codecs;
17733          p->capability &= codecs;
17734          changed = 1;
17735       }
17736    }
17737    if (changed && !ast_test_flag(&p->flags[0], SIP_GOTREFER) && !ast_test_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER)) {
17738       if (chan->_state != AST_STATE_UP) { /* We are in early state */
17739          if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY))
17740             append_history(p, "ExtInv", "Initial invite sent with remote bridge proposal.");
17741          if (option_debug)
17742             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));
17743       } else if (!p->pendinginvite) {     /* We are up, and have no outstanding invite */
17744          if (option_debug > 2) {
17745             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));
17746          }
17747          transmit_reinvite_with_sdp(p);
17748       } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) {
17749          if (option_debug > 2) {
17750             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));
17751          }
17752          /* We have a pending Invite. Send re-invite when we're done with the invite */
17753          ast_set_flag(&p->flags[0], SIP_NEEDREINVITE);   
17754       }
17755    }
17756    /* Reset lastrtprx timer */
17757    p->lastrtprx = p->lastrtptx = time(NULL);
17758    ast_mutex_unlock(&p->lock);
17759    return 0;
17760 }

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

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

17514 {
17515    struct sip_pvt *p;
17516    
17517    p = chan->tech_pvt;
17518    if (!p)
17519       return -1;
17520    ast_mutex_lock(&p->lock);
17521    if (udptl)
17522       ast_udptl_get_peer(udptl, &p->udptlredirip);
17523    else
17524       memset(&p->udptlredirip, 0, sizeof(p->udptlredirip));
17525    if (!ast_test_flag(&p->flags[0], SIP_GOTREFER)) {
17526       if (!p->pendinginvite) {
17527          if (option_debug > 2) {
17528             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);
17529          }
17530          transmit_reinvite_with_t38_sdp(p);
17531       } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) {
17532          if (option_debug > 2) {
17533             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);
17534          }
17535          ast_set_flag(&p->flags[0], SIP_NEEDREINVITE);
17536       }
17537    }
17538    /* Reset lastrtprx timer */
17539    p->lastrtprx = p->lastrtptx = time(NULL);
17540    ast_mutex_unlock(&p->lock);
17541    return 0;
17542 }

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

Show details of one active dialog.

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

11048 {
11049    struct sip_pvt *cur;
11050    size_t len;
11051    int found = 0;
11052 
11053    if (argc != 4)
11054       return RESULT_SHOWUSAGE;
11055    len = strlen(argv[3]);
11056    ast_mutex_lock(&iflock);
11057    for (cur = iflist; cur; cur = cur->next) {
11058       if (!strncasecmp(cur->callid, argv[3], len)) {
11059          char formatbuf[SIPBUFSIZE/2];
11060          ast_cli(fd,"\n");
11061          if (cur->subscribed != NONE)
11062             ast_cli(fd, "  * Subscription (type: %s)\n", subscription_type2str(cur->subscribed));
11063          else
11064             ast_cli(fd, "  * SIP Call\n");
11065          ast_cli(fd, "  Curr. trans. direction:  %s\n", ast_test_flag(&cur->flags[0], SIP_OUTGOING) ? "Outgoing" : "Incoming");
11066          ast_cli(fd, "  Call-ID:                %s\n", cur->callid);
11067          ast_cli(fd, "  Owner channel ID:       %s\n", cur->owner ? cur->owner->name : "<none>");
11068          ast_cli(fd, "  Our Codec Capability:   %d\n", cur->capability);
11069          ast_cli(fd, "  Non-Codec Capability (DTMF):   %d\n", cur->noncodeccapability);
11070          ast_cli(fd, "  Their Codec Capability:   %d\n", cur->peercapability);
11071          ast_cli(fd, "  Joint Codec Capability:   %d\n", cur->jointcapability);
11072          ast_cli(fd, "  Format:                 %s\n", ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->owner ? cur->owner->nativeformats : 0) );
11073          ast_cli(fd, "  MaxCallBR:              %d kbps\n", cur->maxcallbitrate);
11074          ast_cli(fd, "  Theoretical Address:    %s:%d\n", ast_inet_ntoa(cur->sa.sin_addr), ntohs(cur->sa.sin_port));
11075          ast_cli(fd, "  Received Address:       %s:%d\n", ast_inet_ntoa(cur->recv.sin_addr), ntohs(cur->recv.sin_port));
11076          ast_cli(fd, "  SIP Transfer mode:      %s\n", transfermode2str(cur->allowtransfer));
11077          ast_cli(fd, "  NAT Support:            %s\n", nat2str(ast_test_flag(&cur->flags[0], SIP_NAT)));
11078          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)" );
11079          ast_cli(fd, "  Our Tag:                %s\n", cur->tag);
11080          ast_cli(fd, "  Their Tag:              %s\n", cur->theirtag);
11081          ast_cli(fd, "  SIP User agent:         %s\n", cur->useragent);
11082          if (!ast_strlen_zero(cur->username))
11083             ast_cli(fd, "  Username:               %s\n", cur->username);
11084          if (!ast_strlen_zero(cur->peername))
11085             ast_cli(fd, "  Peername:               %s\n", cur->peername);
11086          if (!ast_strlen_zero(cur->uri))
11087             ast_cli(fd, "  Original uri:           %s\n", cur->uri);
11088          if (!ast_strlen_zero(cur->cid_num))
11089             ast_cli(fd, "  Caller-ID:              %s\n", cur->cid_num);
11090          ast_cli(fd, "  Need Destroy:           %d\n", ast_test_flag(&cur->flags[0], SIP_NEEDDESTROY));
11091          ast_cli(fd, "  Last Message:           %s\n", cur->lastmsg);
11092          ast_cli(fd, "  Promiscuous Redir:      %s\n", ast_test_flag(&cur->flags[0], SIP_PROMISCREDIR) ? "Yes" : "No");
11093          ast_cli(fd, "  Route:                  %s\n", cur->route ? cur->route->hop : "N/A");
11094          ast_cli(fd, "  DTMF Mode:              %s\n", dtmfmode2str(ast_test_flag(&cur->flags[0], SIP_DTMF)));
11095          ast_cli(fd, "  SIP Options:            ");
11096          if (cur->sipoptions) {
11097             int x;
11098             for (x=0 ; (x < (sizeof(sip_options) / sizeof(sip_options[0]))); x++) {
11099                if (cur->sipoptions & sip_options[x].id)
11100                   ast_cli(fd, "%s ", sip_options[x].text);
11101             }
11102          } else
11103             ast_cli(fd, "(none)\n");
11104          ast_cli(fd, "\n\n");
11105          found++;
11106       }
11107    }
11108    ast_mutex_unlock(&iflock);
11109    if (!found) 
11110       ast_cli(fd, "No such SIP Call ID starting with '%s'\n", argv[3]);
11111    return RESULT_SUCCESS;
11112 }

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

Show active SIP channels.

Definition at line 10840 of file chan_sip.c.

References __sip_show_channels().

10841 {
10842         return __sip_show_channels(fd, argc, argv, 0);
10843 }

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

CLI command to list local domains.

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

10353 {
10354    struct domain *d;
10355 #define FORMAT "%-40.40s %-20.20s %-16.16s\n"
10356 
10357    if (AST_LIST_EMPTY(&domain_list)) {
10358       ast_cli(fd, "SIP Domain support not enabled.\n\n");
10359       return RESULT_SUCCESS;
10360    } else {
10361       ast_cli(fd, FORMAT, "Our local SIP domains:", "Context", "Set by");
10362       AST_LIST_LOCK(&domain_list);
10363       AST_LIST_TRAVERSE(&domain_list, d, list)
10364          ast_cli(fd, FORMAT, d->domain, S_OR(d->context, "(default)"),
10365             domain_mode_to_text(d->mode));
10366       AST_LIST_UNLOCK(&domain_list);
10367       ast_cli(fd, "\n");
10368       return RESULT_SUCCESS;
10369    }
10370 }

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

Show history details of one dialog.

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

11116 {
11117    struct sip_pvt *cur;
11118    size_t len;
11119    int found = 0;
11120 
11121    if (argc != 4)
11122       return RESULT_SHOWUSAGE;
11123    if (!recordhistory)
11124       ast_cli(fd, "\n***Note: History recording is currently DISABLED.  Use 'sip history' to ENABLE.\n");
11125    len = strlen(argv[3]);
11126    ast_mutex_lock(&iflock);
11127    for (cur = iflist; cur; cur = cur->next) {
11128       if (!strncasecmp(cur->callid, argv[3], len)) {
11129          struct sip_history *hist;
11130          int x = 0;
11131 
11132          ast_cli(fd,"\n");
11133          if (cur->subscribed != NONE)
11134             ast_cli(fd, "  * Subscription\n");
11135          else
11136             ast_cli(fd, "  * SIP Call\n");
11137          if (cur->history)
11138             AST_LIST_TRAVERSE(cur->history, hist, list)
11139                ast_cli(fd, "%d. %s\n", ++x, hist->event);
11140          if (x == 0)
11141             ast_cli(fd, "Call '%s' has no history\n", cur->callid);
11142          found++;
11143       }
11144    }
11145    ast_mutex_unlock(&iflock);
11146    if (!found) 
11147       ast_cli(fd, "No such SIP Call ID starting with '%s'\n", argv[3]);
11148    return RESULT_SUCCESS;
11149 }

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

09778 {
09779 #define FORMAT  "%-25.25s %-15.15s %-15.15s \n"
09780 #define FORMAT2 "%-25.25s %-15.15s %-15.15s \n"
09781    char ilimits[40];
09782    char iused[40];
09783    int showall = FALSE;
09784 
09785    if (argc < 3) 
09786       return RESULT_SHOWUSAGE;
09787 
09788    if (argc == 4 && !strcmp(argv[3],"all")) 
09789          showall = TRUE;
09790    
09791    ast_cli(fd, FORMAT, "* User name", "In use", "Limit");
09792    ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do {
09793       ASTOBJ_RDLOCK(iterator);
09794       if (iterator->call_limit)
09795          snprintf(ilimits, sizeof(ilimits), "%d", iterator->call_limit);
09796       else 
09797          ast_copy_string(ilimits, "N/A", sizeof(ilimits));
09798       snprintf(iused, sizeof(iused), "%d", iterator->inUse);
09799       if (showall || iterator->call_limit)
09800          ast_cli(fd, FORMAT2, iterator->name, iused, ilimits);
09801       ASTOBJ_UNLOCK(iterator);
09802    } while (0) );
09803 
09804    ast_cli(fd, FORMAT, "* Peer name", "In use", "Limit");
09805 
09806    ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do {
09807       ASTOBJ_RDLOCK(iterator);
09808       if (iterator->call_limit)
09809          snprintf(ilimits, sizeof(ilimits), "%d", iterator->call_limit);
09810       else 
09811          ast_copy_string(ilimits, "N/A", sizeof(ilimits));
09812       snprintf(iused, sizeof(iused), "%d/%d", iterator->inUse, iterator->inRinging);
09813       if (showall || iterator->call_limit)
09814          ast_cli(fd, FORMAT2, iterator->name, iused, ilimits);
09815       ASTOBJ_UNLOCK(iterator);
09816    } while (0) );
09817 
09818    return RESULT_SUCCESS;
09819 #undef FORMAT
09820 #undef FORMAT2
09821 }

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

List all allocated SIP Objects (realtime or static).

Definition at line 10098 of file chan_sip.c.

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

10099 {
10100    char tmp[256];
10101    if (argc != 3)
10102       return RESULT_SHOWUSAGE;
10103    ast_cli(fd, "-= User objects: %d static, %d realtime =-\n\n", suserobjs, ruserobjs);
10104    ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), &userl);
10105    ast_cli(fd, "-= Peer objects: %d static, %d realtime, %d autocreate =-\n\n", speerobjs, rpeerobjs, apeerobjs);
10106    ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), &peerl);
10107    ast_cli(fd, "-= Registry objects: %d =-\n\n", regobjs);
10108    ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), &regl);
10109    return RESULT_SUCCESS;
10110 }

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

Show one peer in detail.

Definition at line 10404 of file chan_sip.c.

References _sip_show_peer().

10405 {
10406    return _sip_show_peer(0, fd, NULL, NULL, argc, (const char **) argv);
10407 }

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

CLI Show Peers command.

Definition at line 9954 of file chan_sip.c.

References _sip_show_peers().

09955 {
09956    return _sip_show_peers(fd, NULL, NULL, NULL, argc, (const char **) argv);
09957 }

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

Show SIP Registry (registrations with other SIP proxies.

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

10678 {
10679 #define FORMAT2 "%-30.30s  %-12.12s  %8.8s %-20.20s %-25.25s\n"
10680 #define FORMAT  "%-30.30s  %-12.12s  %8d %-20.20s %-25.25s\n"
10681    char host[80];
10682    char tmpdat[256];
10683    struct tm tm;
10684 
10685 
10686    if (argc != 3)
10687       return RESULT_SHOWUSAGE;
10688    ast_cli(fd, FORMAT2, "Host", "Username", "Refresh", "State", "Reg.Time");
10689    ASTOBJ_CONTAINER_TRAVERSE(&regl, 1, do {
10690       ASTOBJ_RDLOCK(iterator);
10691       snprintf(host, sizeof(host), "%s:%d", iterator->hostname, iterator->portno ? iterator->portno : STANDARD_SIP_PORT);
10692       if (iterator->regtime) {
10693          ast_localtime(&iterator->regtime, &tm, NULL);
10694          strftime(tmpdat, sizeof(tmpdat), "%a, %d %b %Y %T", &tm);
10695       } else {
10696          tmpdat[0] = 0;
10697       }
10698       ast_cli(fd, FORMAT, host, iterator->username, iterator->refresh, regstate2str(iterator->regstate), tmpdat);
10699       ASTOBJ_UNLOCK(iterator);
10700    } while(0));
10701    return RESULT_SUCCESS;
10702 #undef FORMAT
10703 #undef FORMAT2
10704 }

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

List global settings for the SIP channel.

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

10708 {
10709    int realtimepeers;
10710    int realtimeusers;
10711    char codec_buf[SIPBUFSIZE];
10712 
10713    realtimepeers = ast_check_realtime("sippeers");
10714    realtimeusers = ast_check_realtime("sipusers");
10715 
10716    if (argc != 3)
10717       return RESULT_SHOWUSAGE;
10718    ast_cli(fd, "\n\nGlobal Settings:\n");
10719    ast_cli(fd, "----------------\n");
10720    ast_cli(fd, "  SIP Port:               %d\n", ntohs(bindaddr.sin_port));
10721    ast_cli(fd, "  Bindaddress:            %s\n", ast_inet_ntoa(bindaddr.sin_addr));
10722    ast_cli(fd, "  Videosupport:           %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_VIDEOSUPPORT) ? "Yes" : "No");
10723    ast_cli(fd, "  AutoCreatePeer:         %s\n", autocreatepeer ? "Yes" : "No");
10724    ast_cli(fd, "  Allow unknown access:   %s\n", global_allowguest ? "Yes" : "No");
10725    ast_cli(fd, "  Allow subscriptions:    %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWSUBSCRIBE) ? "Yes" : "No");
10726    ast_cli(fd, "  Allow overlap dialing:  %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP) ? "Yes" : "No");
10727    ast_cli(fd, "  Promsic. redir:         %s\n", ast_test_flag(&global_flags[0], SIP_PROMISCREDIR) ? "Yes" : "No");
10728    ast_cli(fd, "  SIP domain support:     %s\n", AST_LIST_EMPTY(&domain_list) ? "No" : "Yes");
10729    ast_cli(fd, "  Call to non-local dom.: %s\n", allow_external_domains ? "Yes" : "No");
10730    ast_cli(fd, "  URI user is phone no:   %s\n", ast_test_flag(&global_flags[0], SIP_USEREQPHONE) ? "Yes" : "No");
10731    ast_cli(fd, "  Our auth realm          %s\n", global_realm);
10732    ast_cli(fd, "  Realm. auth:            %s\n", authl ? "Yes": "No");
10733    ast_cli(fd, "  Always auth rejects:    %s\n", global_alwaysauthreject ? "Yes" : "No");
10734    ast_cli(fd, "  Call limit peers only:  %s\n", global_limitonpeers ? "Yes" : "No");
10735    ast_cli(fd, "  Direct RTP setup:       %s\n", global_directrtpsetup ? "Yes" : "No");
10736    ast_cli(fd, "  User Agent:             %s\n", global_useragent);
10737    ast_cli(fd, "  MWI checking interval:  %d secs\n", global_mwitime);
10738    ast_cli(fd, "  Reg. context:           %s\n", S_OR(global_regcontext, "(not set)"));
10739    ast_cli(fd, "  Caller ID:              %s\n", default_callerid);
10740    ast_cli(fd, "  From: Domain:           %s\n", default_fromdomain);
10741    ast_cli(fd, "  Record SIP history:     %s\n", recordhistory ? "On" : "Off");
10742    ast_cli(fd, "  Call Events:            %s\n", global_callevents ? "On" : "Off");
10743    ast_cli(fd, "  IP ToS SIP:             %s\n", ast_tos2str(global_tos_sip));
10744    ast_cli(fd, "  IP ToS RTP audio:       %s\n", ast_tos2str(global_tos_audio));
10745    ast_cli(fd, "  IP ToS RTP video:       %s\n", ast_tos2str(global_tos_video));
10746    ast_cli(fd, "  T38 fax pt UDPTL:       %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT_UDPTL) ? "Yes" : "No");
10747 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS
10748    ast_cli(fd, "  T38 fax pt RTP:         %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT_RTP) ? "Yes" : "No");
10749    ast_cli(fd, "  T38 fax pt TCP:         %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT_TCP) ? "Yes" : "No");
10750 #endif
10751    ast_cli(fd, "  RFC2833 Compensation:   %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RFC2833_COMPENSATE) ? "Yes" : "No");
10752    if (!realtimepeers && !realtimeusers)
10753       ast_cli(fd, "  SIP realtime:           Disabled\n" );
10754    else
10755       ast_cli(fd, "  SIP realtime:           Enabled\n" );
10756 
10757    ast_cli(fd, "\nGlobal Signalling Settings:\n");
10758    ast_cli(fd, "---------------------------\n");
10759    ast_cli(fd, "  Codecs:                 ");
10760    ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, global_capability);
10761    ast_cli(fd, "%s\n", codec_buf);
10762    ast_cli(fd, "  Codec Order:            ");
10763    print_codec_to_cli(fd, &default_prefs);
10764    ast_cli(fd, "\n");
10765    ast_cli(fd, "  T1 minimum:             %d\n", global_t1min);
10766    ast_cli(fd, "  Relax DTMF:             %s\n", global_relaxdtmf ? "Yes" : "No");
10767    ast_cli(fd, "  Compact SIP headers:    %s\n", compactheaders ? "Yes" : "No");
10768    ast_cli(fd, "  RTP Keepalive:          %d %s\n", global_rtpkeepalive, global_rtpkeepalive ? "" : "(Disabled)" );
10769    ast_cli(fd, "  RTP Timeout:            %d %s\n", global_rtptimeout, global_rtptimeout ? "" : "(Disabled)" );
10770    ast_cli(fd, "  RTP Hold Timeout:       %d %s\n", global_rtpholdtimeout, global_rtpholdtimeout ? "" : "(Disabled)");
10771    ast_cli(fd, "  MWI NOTIFY mime type:   %s\n", default_notifymime);
10772    ast_cli(fd, "  DNS SRV lookup:         %s\n", srvlookup ? "Yes" : "No");
10773    ast_cli(fd, "  Pedantic SIP support:   %s\n", pedanticsipchecking ? "Yes" : "No");
10774    ast_cli(fd, "  Reg. min duration       %d secs\n", min_expiry);
10775    ast_cli(fd, "  Reg. max duration:      %d secs\n", max_expiry);
10776    ast_cli(fd, "  Reg. default duration:  %d secs\n", default_expiry);
10777    ast_cli(fd, "  Outbound reg. timeout:  %d secs\n", global_reg_timeout);
10778    ast_cli(fd, "  Outbound reg. attempts: %d\n", global_regattempts_max);
10779    ast_cli(fd, "  Notify ringing state:   %s\n", global_notifyringing ? "Yes" : "No");
10780    ast_cli(fd, "  Notify hold state:      %s\n", global_notifyhold ? "Yes" : "No");
10781    ast_cli(fd, "  SIP Transfer mode:      %s\n", transfermode2str(global_allowtransfer));
10782    ast_cli(fd, "  Max Call Bitrate:       %d kbps\r\n", default_maxcallbitrate);
10783    ast_cli(fd, "  Auto-Framing:           %s \r\n", global_autoframing ? "Yes" : "No");
10784    ast_cli(fd, "\nDefault Settings:\n");
10785    ast_cli(fd, "-----------------\n");
10786    ast_cli(fd, "  Context:                %s\n", default_context);
10787    ast_cli(fd, "  Nat:                    %s\n", nat2str(ast_test_flag(&global_flags[0], SIP_NAT)));
10788    ast_cli(fd, "  DTMF:                   %s\n", dtmfmode2str(ast_test_flag(&global_flags[0], SIP_DTMF)));
10789    ast_cli(fd, "  Qualify:                %d\n", default_qualify);
10790    ast_cli(fd, "  Use ClientCode:         %s\n", ast_test_flag(&global_flags[0], SIP_USECLIENTCODE) ? "Yes" : "No");
10791    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" );
10792    ast_cli(fd, "  Language:               %s\n", S_OR(default_language, "(Defaults to English)"));
10793    ast_cli(fd, "  MOH Interpret:          %s\n", default_mohinterpret);
10794    ast_cli(fd, "  MOH Suggest:            %s\n", default_mohsuggest);
10795    ast_cli(fd, "  Voice Mail Extension:   %s\n", default_vmexten);
10796 
10797    
10798    if (realtimepeers || realtimeusers) {
10799       ast_cli(fd, "\nRealtime SIP Settings:\n");
10800       ast_cli(fd, "----------------------\n");
10801       ast_cli(fd, "  Realtime Peers:         %s\n", realtimepeers ? "Yes" : "No");
10802       ast_cli(fd, "  Realtime Users:         %s\n", realtimeusers ? "Yes" : "No");
10803       ast_cli(fd, "  Cache Friends:          %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS) ? "Yes" : "No");
10804       ast_cli(fd, "  Update:                 %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RTUPDATE) ? "Yes" : "No");
10805       ast_cli(fd, "  Ignore Reg. Expire:     %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_IGNOREREGEXPIRE) ? "Yes" : "No");
10806       ast_cli(fd, "  Save sys. name:         %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RTSAVE_SYSNAME) ? "Yes" : "No");
10807       ast_cli(fd, "  Auto Clear:             %d\n", global_rtautoclear);
10808    }
10809    ast_cli(fd, "\n----\n");
10810    return RESULT_SUCCESS;
10811 }

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

Show active SIP subscriptions.

Definition at line 10846 of file chan_sip.c.

References __sip_show_channels().

10847 {
10848         return __sip_show_channels(fd, argc, argv, 1);
10849 }

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

Show one user in detail.

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

10623 {
10624    char cbuf[256];
10625    struct sip_user *user;
10626    struct ast_variable *v;
10627    int load_realtime;
10628 
10629    if (argc < 4)
10630       return RESULT_SHOWUSAGE;
10631 
10632    /* Load from realtime storage? */
10633    load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? TRUE : FALSE;
10634 
10635    user = find_user(argv[3], load_realtime);
10636    if (user) {
10637       ast_cli(fd,"\n\n");
10638       ast_cli(fd, "  * Name       : %s\n", user->name);
10639       ast_cli(fd, "  Secret       : %s\n", ast_strlen_zero(user->secret)?"<Not set>":"<Set>");
10640       ast_cli(fd, "  MD5Secret    : %s\n", ast_strlen_zero(user->md5secret)?"<Not set>":"<Set>");
10641       ast_cli(fd, "  Context      : %s\n", user->context);
10642       ast_cli(fd, "  Language     : %s\n", user->language);
10643       if (!ast_strlen_zero(user->accountcode))
10644          ast_cli(fd, "  Accountcode  : %s\n", user->accountcode);
10645       ast_cli(fd, "  AMA flags    : %s\n", ast_cdr_flags2str(user->amaflags));
10646       ast_cli(fd, "  Transfer mode: %s\n", transfermode2str(user->allowtransfer));
10647       ast_cli(fd, "  MaxCallBR    : %d kbps\n", user->maxcallbitrate);
10648       ast_cli(fd, "  CallingPres  : %s\n", ast_describe_caller_presentation(user->callingpres));
10649       ast_cli(fd, "  Call limit   : %d\n", user->call_limit);
10650       ast_cli(fd, "  Callgroup    : ");
10651       print_group(fd, user->callgroup, 0);
10652       ast_cli(fd, "  Pickupgroup  : ");
10653       print_group(fd, user->pickupgroup, 0);
10654       ast_cli(fd, "  Callerid     : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), user->cid_name, user->cid_num, "<unspecified>"));
10655       ast_cli(fd, "  ACL          : %s\n", (user->ha?"Yes":"No"));
10656       ast_cli(fd, "  Codec Order  : (");
10657       print_codec_to_cli(fd, &user->prefs);
10658       ast_cli(fd, ")\n");
10659 
10660       ast_cli(fd, "  Auto-Framing:  %s \n", user->autoframing ? "Yes" : "No");
10661       if (user->chanvars) {
10662          ast_cli(fd, "  Variables    :\n");
10663          for (v = user->chanvars ; v ; v = v->next)
10664             ast_cli(fd, "                 %s = %s\n", v->name, v->value);
10665       }
10666       ast_cli(fd,"\n");
10667       ASTOBJ_UNREF(user,sip_destroy_user);
10668    } else {
10669       ast_cli(fd,"User %s not found.\n", argv[3]);
10670       ast_cli(fd,"\n");
10671    }
10672 
10673    return RESULT_SUCCESS;
10674 }

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

CLI Command 'SIP Show Users'.

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

09878 {
09879    regex_t regexbuf;
09880    int havepattern = FALSE;
09881 
09882 #define FORMAT  "%-25.25s  %-15.15s  %-15.15s  %-15.15s  %-5.5s%-10.10s\n"
09883 
09884    switch (argc) {
09885    case 5:
09886       if (!strcasecmp(argv[3], "like")) {
09887          if (regcomp(&regexbuf, argv[4], REG_EXTENDED | REG_NOSUB))
09888             return RESULT_SHOWUSAGE;
09889          havepattern = TRUE;
09890       } else
09891          return RESULT_SHOWUSAGE;
09892    case 3:
09893       break;
09894    default:
09895       return RESULT_SHOWUSAGE;
09896    }
09897 
09898    ast_cli(fd, FORMAT, "Username", "Secret", "Accountcode", "Def.Context", "ACL", "NAT");
09899    ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do {
09900       ASTOBJ_RDLOCK(iterator);
09901 
09902       if (havepattern && regexec(&regexbuf, iterator->name, 0, NULL, 0)) {
09903          ASTOBJ_UNLOCK(iterator);
09904          continue;
09905       }
09906 
09907       ast_cli(fd, FORMAT, iterator->name, 
09908          iterator->secret, 
09909          iterator->accountcode,
09910          iterator->context,
09911          iterator->ha ? "Yes" : "No",
09912          nat2str(ast_test_flag(&iterator->flags[0], SIP_NAT)));
09913       ASTOBJ_UNLOCK(iterator);
09914    } while (0)
09915    );
09916 
09917    if (havepattern)
09918       regfree(&regexbuf);
09919 
09920    return RESULT_SUCCESS;
09921 #undef FORMAT
09922 }

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

17874 {
17875    char *cdest;
17876    char *extension, *host, *port;
17877    char tmp[80];
17878    
17879    cdest = ast_strdupa(dest);
17880    
17881    extension = strsep(&cdest, "@");
17882    host = strsep(&cdest, ":");
17883    port = strsep(&cdest, ":");
17884    if (ast_strlen_zero(extension)) {
17885       ast_log(LOG_ERROR, "Missing mandatory argument: extension\n");
17886       return 0;
17887    }
17888 
17889    /* we'll issue the redirect message here */
17890    if (!host) {
17891       char *localtmp;
17892       ast_copy_string(tmp, get_header(&p->initreq, "To"), sizeof(tmp));
17893       if (ast_strlen_zero(tmp)) {
17894          ast_log(LOG_ERROR, "Cannot retrieve the 'To' header from the original SIP request!\n");
17895          return 0;
17896       }
17897       if ((localtmp = strcasestr(tmp, "sip:")) && (localtmp = strchr(localtmp, '@'))) {
17898          char lhost[80], lport[80];
17899          memset(lhost, 0, sizeof(lhost));
17900          memset(lport, 0, sizeof(lport));
17901          localtmp++;
17902          /* This is okey because lhost and lport are as big as tmp */
17903          sscanf(localtmp, "%[^<>:; ]:%[^<>:; ]", lhost, lport);
17904          if (ast_strlen_zero(lhost)) {
17905             ast_log(LOG_ERROR, "Can't find the host address\n");
17906             return 0;
17907          }
17908          host = ast_strdupa(lhost);
17909          if (!ast_strlen_zero(lport)) {
17910             port = ast_strdupa(lport);
17911          }
17912       }
17913    }
17914 
17915    ast_string_field_build(p, our_contact, "Transfer <sip:%s@%s%s%s>", extension, host, port ? ":" : "", port ? port : "");
17916    transmit_response_reliable(p, "302 Moved Temporarily", &p->initreq);
17917 
17918    sip_scheddestroy(p, SIP_TRANS_TIMEOUT);   /* Make sure we stop send this reply. */
17919    sip_alreadygone(p);
17920    return 0;
17921 }

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

15478 {
15479    struct sip_request req;
15480    struct sockaddr_in sin = { 0, };
15481    struct sip_pvt *p;
15482    int res;
15483    socklen_t len = sizeof(sin);
15484    int nounlock;
15485    int recount = 0;
15486    int lockretry;
15487 
15488    memset(&req, 0, sizeof(req));
15489    res = recvfrom(sipsock, req.data, sizeof(req.data) - 1, 0, (struct sockaddr *)&sin, &len);
15490    if (res < 0) {
15491 #if !defined(__FreeBSD__)
15492       if (errno == EAGAIN)
15493          ast_log(LOG_NOTICE, "SIP: Received packet with bad UDP checksum\n");
15494       else 
15495 #endif
15496       if (errno != ECONNREFUSED)
15497          ast_log(LOG_WARNING, "Recv error: %s\n", strerror(errno));
15498       return 1;
15499    }
15500    if (option_debug && res == sizeof(req.data) - 1)
15501       ast_log(LOG_DEBUG, "Received packet exceeds buffer. Data is possibly lost\n");
15502 
15503    req.data[res] = '\0';
15504    req.len = res;
15505    if(sip_debug_test_addr(&sin)) /* Set the debug flag early on packet level */
15506       ast_set_flag(&req, SIP_PKT_DEBUG);
15507    if (pedanticsipchecking)
15508       req.len = lws2sws(req.data, req.len);  /* Fix multiline headers */
15509    if (ast_test_flag(&req, SIP_PKT_DEBUG))
15510       ast_verbose("\n<--- SIP read from %s:%d --->\n%s\n<------------->\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port), req.data);
15511 
15512    if(parse_request(&req) == -1) /* Bad packet, can't parse */
15513       return 1;
15514 
15515    req.method = find_sip_method(req.rlPart1);
15516 
15517    if (ast_test_flag(&req, SIP_PKT_DEBUG))
15518       ast_verbose("--- (%d headers %d lines)%s ---\n", req.headers, req.lines, (req.headers + req.lines == 0) ? " Nat keepalive" : "");
15519 
15520    if (req.headers < 2) /* Must have at least two headers */
15521       return 1;
15522 
15523    /* Process request, with netlock held, and with usual deadlock avoidance */
15524    for (lockretry = 100; lockretry > 0; lockretry--) {
15525       ast_mutex_lock(&netlock);
15526 
15527       /* Find the active SIP dialog or create a new one */
15528       p = find_call(&req, &sin, req.method); /* returns p locked */
15529       if (p == NULL) {
15530          if (option_debug)
15531             ast_log(LOG_DEBUG, "Invalid SIP message - rejected , no callid, len %d\n", req.len);
15532          ast_mutex_unlock(&netlock);
15533          return 1;
15534       }
15535       /* Go ahead and lock the owner if it has one -- we may need it */
15536       /* becaues this is deadlock-prone, we need to try and unlock if failed */
15537       if (!p->owner || !ast_channel_trylock(p->owner))
15538          break;   /* locking succeeded */
15539       if (option_debug)
15540          ast_log(LOG_DEBUG, "Failed to grab owner channel lock, trying again. (SIP call %s)\n", p->callid);
15541       ast_mutex_unlock(&p->lock);
15542       ast_mutex_unlock(&netlock);
15543       /* Sleep for a very short amount of time */
15544       usleep(1);
15545    }
15546    p->recv = sin;
15547 
15548    if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) /* This is a request or response, note what it was for */
15549       append_history(p, "Rx", "%s / %s / %s", req.data, get_header(&req, "CSeq"), req.rlPart2);
15550 
15551    if (!lockretry) {
15552       if (p->owner)
15553          ast_log(LOG_ERROR, "We could NOT get the channel lock for %s! \n", S_OR(p->owner->name, "- no channel name ??? - "));
15554       ast_log(LOG_ERROR, "SIP transaction failed: %s \n", p->callid);
15555       if (req.method != SIP_ACK)
15556          transmit_response(p, "503 Server error", &req); /* We must respond according to RFC 3261 sec 12.2 */
15557       /* XXX We could add retry-after to make sure they come back */
15558       append_history(p, "LockFail", "Owner lock failed, transaction failed.");
15559       return 1;
15560    }
15561    nounlock = 0;
15562    if (handle_request(p, &req, &sin, &recount, &nounlock) == -1) {
15563       /* Request failed */
15564       if (option_debug)
15565          ast_log(LOG_DEBUG, "SIP message could not be handled, bad request: %-70.70s\n", p->callid[0] ? p->callid : "<no callid>");
15566    }
15567       
15568    if (p->owner && !nounlock)
15569       ast_channel_unlock(p->owner);
15570    ast_mutex_unlock(&p->lock);
15571    ast_mutex_unlock(&netlock);
15572    if (recount)
15573       ast_update_use_count();
15574 
15575    return 1;
15576 }

static void stop_media_flows ( struct sip_pvt p  )  [static]

Immediately stop RTP, VRTP and UDPTL as applicable.

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

12696 {
12697    /* Immediately stop RTP, VRTP and UDPTL as applicable */
12698    if (p->rtp)
12699       ast_rtp_stop(p->rtp);
12700    if (p->vrtp)
12701       ast_rtp_stop(p->vrtp);
12702    if (p->udptl)
12703       ast_udptl_stop(p->udptl);
12704 }

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

Show subscription type in string format.

Definition at line 10814 of file chan_sip.c.

References subscription_types, cfsubscription_types::text, and type.

Referenced by __sip_show_channels(), and sip_show_channel().

10815 {
10816    int i;
10817 
10818    for (i = 1; (i < (sizeof(subscription_types) / sizeof(subscription_types[0]))); i++) {
10819       if (subscription_types[i].type == subtype) {
10820          return subscription_types[i].text;
10821       }
10822    }
10823    return subscription_types[0].text;
10824 }

static int t38_get_rate ( int  t38cap  )  [static]

Get Max T.38 Transmission rate from T38 capabilities.

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

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

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

Create temporary peer (used in autocreatepeer mode).

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

16619 {
16620    struct sip_peer *peer;
16621 
16622    if (!(peer = ast_calloc(1, sizeof(*peer))))
16623       return NULL;
16624 
16625    apeerobjs++;
16626    ASTOBJ_INIT(peer);
16627    set_peer_defaults(peer);
16628 
16629    ast_copy_string(peer->name, name, sizeof(peer->name));
16630 
16631    ast_set_flag(&peer->flags[1], SIP_PAGE2_SELFDESTRUCT);
16632    ast_set_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC);
16633    peer->prefs = default_prefs;
16634    reg_source_db(peer);
16635 
16636    return peer;
16637 }

static void temp_pvt_cleanup ( void *  data  )  [static]

Definition at line 6058 of file chan_sip.c.

References ast_string_field_free_memory, and free.

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

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

Convert transfer mode to text string.

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

09825 {
09826    if (mode == TRANSFER_OPENFORALL)
09827       return "open";
09828    else if (mode == TRANSFER_CLOSED)
09829       return "closed";
09830    return "strict";
09831 }

static void transmit_fake_auth_response ( struct sip_pvt p,
struct sip_request req,
int  reliable 
) [static]

Send a fake 401 Unauthorized response when the administrator wants to hide the names of local users/peers from fishers.

Definition at line 8645 of file chan_sip.c.

References ast_random(), ast_string_field_build, and transmit_response_with_auth().

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

08646 {
08647    ast_string_field_build(p, randdata, "%08lx", ast_random()); /* Create nonce for challenge */
08648    transmit_response_with_auth(p, "401 Unauthorized", req, p->randdata, reliable, "WWW-Authenticate", 0);
08649 }

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

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

Referenced by sip_senddigit_end().

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

static int transmit_info_with_vidupdate ( struct sip_pvt p  )  [static]

Send SIP INFO with video update request.

Definition at line 7841 of file chan_sip.c.

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

Referenced by sip_indicate().

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

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 7090 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(), sip_call(), and sip_poke_peer().

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

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

Transmit text with SIP MESSAGE method.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Transmit response, no retransmits.

Definition at line 6119 of file chan_sip.c.

References __transmit_response(), and XMIT_UNRELIABLE.

06120 {
06121    return __transmit_response(p, msg, req, XMIT_UNRELIABLE);
06122 }

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

06139 {
06140    return __transmit_response(p, msg, req, XMIT_CRITICAL);
06141 }

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

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

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

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

Referenced by handle_request(), and handle_request_options().

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

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

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

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

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

Referenced by register_verify().

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

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

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

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

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

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

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

Referenced by handle_request_invite().

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

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

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

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

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

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

18201 {
18202    struct sip_pvt *p, *pl;
18203    
18204    /* First, take us out of the channel type list */
18205    ast_channel_unregister(&sip_tech);
18206 
18207    /* Unregister dial plan functions */
18208    ast_custom_function_unregister(&sipchaninfo_function);
18209    ast_custom_function_unregister(&sippeer_function);
18210    ast_custom_function_unregister(&sip_header_function);
18211    ast_custom_function_unregister(&checksipdomain_function);
18212 
18213    /* Unregister dial plan applications */
18214    ast_unregister_application(app_dtmfmode);
18215    ast_unregister_application(app_sipaddheader);
18216 
18217    /* Unregister CLI commands */
18218    ast_cli_unregister_multiple(cli_sip, sizeof(cli_sip) / sizeof(struct ast_cli_entry));
18219 
18220    /* Disconnect from the RTP subsystem */
18221    ast_rtp_proto_unregister(&sip_rtp);
18222 
18223    /* Disconnect from UDPTL */
18224    ast_udptl_proto_unregister(&sip_udptl);
18225 
18226    /* Unregister AMI actions */
18227    ast_manager_unregister("SIPpeers");
18228    ast_manager_unregister("SIPshowpeer");
18229 
18230    ast_mutex_lock(&iflock);
18231    /* Hangup all interfaces if they have an owner */
18232    for (p = iflist; p ; p = p->next) {
18233       if (p->owner)
18234          ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD);
18235    }
18236    ast_mutex_unlock(&iflock);
18237 
18238    ast_mutex_lock(&monlock);
18239    if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP) && (monitor_thread != AST_PTHREADT_NULL)) {
18240       pthread_cancel(monitor_thread);
18241       pthread_kill(monitor_thread, SIGURG);
18242       pthread_join(monitor_thread, NULL);
18243    }
18244    monitor_thread = AST_PTHREADT_STOP;
18245    ast_mutex_unlock(&monlock);
18246 
18247 restartdestroy:
18248    ast_mutex_lock(&iflock);
18249    /* Destroy all the interfaces and free their memory */
18250    p = iflist;
18251    while (p) {
18252       pl = p;
18253       p = p->next;
18254       if (__sip_destroy(pl, TRUE) < 0) {
18255          /* Something is still bridged, let it react to getting a hangup */
18256          iflist = p;
18257          ast_mutex_unlock(&iflock);
18258          usleep(1);
18259          goto restartdestroy;
18260       }
18261    }
18262    iflist = NULL;
18263    ast_mutex_unlock(&iflock);
18264 
18265    /* Free memory for local network address mask */
18266    ast_free_ha(localaddr);
18267 
18268    ASTOBJ_CONTAINER_DESTROYALL(&userl, sip_destroy_user);
18269    ASTOBJ_CONTAINER_DESTROY(&userl);
18270    ASTOBJ_CONTAINER_DESTROYALL(&peerl, sip_destroy_peer);
18271    ASTOBJ_CONTAINER_DESTROY(&peerl);
18272    ASTOBJ_CONTAINER_DESTROYALL(&regl, sip_registry_destroy);
18273    ASTOBJ_CONTAINER_DESTROY(&regl);
18274 
18275    clear_realm_authentication(authl);
18276    clear_sip_domains();
18277    close(sipsock);
18278    sched_context_destroy(sched);
18279       
18280    return 0;
18281 }

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

char* app_sipaddheader = "SIPAddHeader" [static]

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

struct ast_cli_entry cli_sip[] [static]

Definition at line 18036 of file chan_sip.c.

Initial value:

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

Definition at line 18026 of file chan_sip.c.

Initial value:

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

Definition at line 18031 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 11733 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 17763 of file chan_sip.c.

char* descrip_sipaddheader [static]

Definition at line 17769 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 11750 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 10373 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 9924 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 11742 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 11746 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 11682 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 11724 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 11706 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 11702 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 11677 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 11710 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 11697 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 11763 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 11719 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 11714 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 11729 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 11767 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 11759 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 11692 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 11687 of file chan_sip.c.

Definition at line 11825 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 11755 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 12004 of file chan_sip.c.

Structure to declare a dialplan function: SIPPEER.

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

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

Definition at line 17767 of file chan_sip.c.

struct ast_user_list userl [static]

The user list: Users and friends.


Generated on Thu Oct 8 21:57:44 2009 for Asterisk - the Open Source PBX by  doxygen 1.5.8