Sun Jun 12 16:37:53 2011

Asterisk developer's documentation


chan_sip.c File Reference

Implementation of Session Initiation Protocol. More...

#include "asterisk.h"
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <errno.h>
#include <stdlib.h>
#include <fcntl.h>
#include <netdb.h>
#include <signal.h>
#include <sys/signal.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <arpa/inet.h>
#include <netinet/ip.h>
#include <regex.h>
#include "asterisk/lock.h"
#include "asterisk/channel.h"
#include "asterisk/config.h"
#include "asterisk/logger.h"
#include "asterisk/module.h"
#include "asterisk/pbx.h"
#include "asterisk/options.h"
#include "asterisk/sched.h"
#include "asterisk/io.h"
#include "asterisk/rtp.h"
#include "asterisk/udptl.h"
#include "asterisk/acl.h"
#include "asterisk/manager.h"
#include "asterisk/callerid.h"
#include "asterisk/cli.h"
#include "asterisk/app.h"
#include "asterisk/musiconhold.h"
#include "asterisk/dsp.h"
#include "asterisk/features.h"
#include "asterisk/srv.h"
#include "asterisk/astdb.h"
#include "asterisk/causes.h"
#include "asterisk/utils.h"
#include "asterisk/file.h"
#include "asterisk/astobj.h"
#include "asterisk/devicestate.h"
#include "asterisk/linkedlists.h"
#include "asterisk/stringfields.h"
#include "asterisk/monitor.h"
#include "asterisk/localtime.h"
#include "asterisk/abstract_jb.h"
#include "asterisk/compiler.h"
#include "asterisk/threadstorage.h"
#include "asterisk/translate.h"

Go to the source code of this file.

Data Structures

struct  ast_peer_list
 The peer list: Peers and Friends. More...
struct  ast_register_list
 The register list: Other SIP proxys we register with and place calls to. More...
struct  ast_user_list
 The user list: Users and friends. More...
struct  c_referstatusstring
struct  cfsip_methods
struct  cfsip_options
 List of well-known SIP options. If we get this in a require, we should check the list and answer accordingly. More...
struct  cfsubscription_types
struct  domain
 Domain data structure. More...
struct  sip_auth
 sip_auth: Credentials for authentication to other SIP services More...
struct  sip_dual
 structure used in transfers More...
struct  sip_history
 sip_history: Structure for saving transactions within a SIP dialog More...
struct  sip_invite_param
 Parameters to the transmit_invite function. More...
struct  sip_peer
 Structure for SIP peer data, we place calls to peers if registered or fixed IP address (host). More...
struct  sip_pkt
 sip packet - raw format for outbound packets that are sent or scheduled for transmission More...
struct  sip_pvt
 sip_pvt: PVT structures are used for each SIP dialog, ie. a call, a registration, a subscribe More...
struct  sip_refer
 Structure to handle SIP transfers. Dynamically allocated when needed. More...
struct  sip_registry
 Registrations with other SIP proxies. More...
struct  sip_request
 sip_request: The data grabbed from the UDP socket More...
struct  sip_route
 Structure to save routing information for a SIP session. More...
struct  sip_user
 Structure for SIP user data. User's place calls to us. More...
struct  t38properties
 T.38 channel settings (at some point we need to make this alloc'ed. More...

Defines

#define ALLOWED_METHODS   "INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY"
 SIP Methods we support.
#define append_history(p, event, fmt, args...)   append_history_full(p, "%-15s " fmt, event, ## args)
 Append to SIP dialog history.
#define CALLERID_UNKNOWN   "Unknown"
#define CAN_CREATE_DIALOG   1
#define CAN_CREATE_DIALOG_UNSUPPORTED_METHOD   2
#define CAN_NOT_CREATE_DIALOG   0
#define CHECK_AUTH_BUF_INITLEN   256
#define DEC_CALL_LIMIT   0
#define DEC_CALL_RINGING   2
#define DEFAULT_ALLOW_EXT_DOM   TRUE
#define DEFAULT_ALLOWGUEST   TRUE
#define DEFAULT_AUTOCREATEPEER   FALSE
#define DEFAULT_CALLERID   "asterisk"
#define DEFAULT_COMPACTHEADERS   FALSE
#define DEFAULT_CONTEXT   "default"
#define DEFAULT_DEFAULT_EXPIRY   120
#define DEFAULT_EXPIRY   900
#define DEFAULT_FREQ_NOTOK   10 * 1000
#define DEFAULT_FREQ_OK   60 * 1000
#define DEFAULT_MAX_CALL_BITRATE   (384)
#define DEFAULT_MAX_EXPIRY   3600
#define DEFAULT_MAX_FORWARDS   "70"
#define DEFAULT_MAXMS   2000
#define DEFAULT_MIN_EXPIRY   60
#define DEFAULT_MOHINTERPRET   "default"
#define DEFAULT_MOHSUGGEST   ""
#define DEFAULT_MWITIME   10
#define DEFAULT_NOTIFYMIME   "application/simple-message-summary"
#define DEFAULT_NOTIFYRINGING   TRUE
#define DEFAULT_PEDANTIC   FALSE
#define DEFAULT_QUALIFY   FALSE
#define DEFAULT_REALM   "asterisk"
#define DEFAULT_REGISTRATION_TIMEOUT   20
#define DEFAULT_RETRANS   1000
#define DEFAULT_SRVLOOKUP   TRUE
#define DEFAULT_T1MIN   100
#define DEFAULT_TOS_AUDIO   0
#define DEFAULT_TOS_SIP   0
#define DEFAULT_TOS_VIDEO   0
#define DEFAULT_TRANS_TIMEOUT   -1
#define DEFAULT_USERAGENT   "Asterisk PBX"
#define DEFAULT_VMEXTEN   "asterisk"
#define EXPIRY_GUARD_LIMIT   30
#define EXPIRY_GUARD_MIN   500
#define EXPIRY_GUARD_PCT   0.20
#define EXPIRY_GUARD_SECS   15
#define FALSE   0
#define FLAG_FATAL   (1 << 1)
#define FLAG_RESPONSE   (1 << 0)
#define FORMAT   "%-15.15s %-10.10s %-11.11s %5.5d/%5.5d %-15.15s %-3.3s %-3.3s %-15.15s %-10.10s\n"
#define FORMAT   "%-30.30s %-12.12s %8d %-20.20s %-25.25s\n"
#define FORMAT   "%-40.40s %-20.20s %-16.16s\n"
#define FORMAT   "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8d %-10s %-10s\n"
#define FORMAT   "%-25.25s %-15.15s %-15.15s %-15.15s %-5.5s%-10.10s\n"
#define FORMAT   "%-25.25s %-15.15s %-15.15s \n"
#define FORMAT2   "%-15.15s %-10.10s %-11.11s %-11.11s %-15.15s %-7.7s %-15.15s\n"
#define FORMAT2   "%-30.30s %-12.12s %8.8s %-20.20s %-25.25s\n"
#define FORMAT2   "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8s %-10s %-10s\n"
#define FORMAT2   "%-25.25s %-15.15s %-15.15s \n"
#define FORMAT3   "%-15.15s %-10.10s %-11.11s %-15.15s %-13.13s %-15.15s %-10.10s\n"
#define INC_CALL_LIMIT   1
#define INC_CALL_RINGING   3
#define INITIAL_CSEQ   101
#define IPTOS_MINCOST   0x02
#define MAX(a, b)   ((a) > (b) ? (a) : (b))
#define MAX_AUTHTRIES   3
#define MAX_HISTORY_ENTRIES   50
#define MAX_RETRANS   6
#define NO_RTP   0
#define NOT_SUPPORTED   0
#define RTP   1
#define SDP_MAX_RTPMAP_CODECS   32
#define SDP_SAMPLE_RATE(x)   8000
#define SIP_ALREADYGONE   (1 << 0)
#define SIP_CALL_LIMIT   (1 << 28)
#define SIP_CAN_REINVITE   (1 << 20)
#define SIP_CAN_REINVITE_NAT   (2 << 20)
#define SIP_DEFER_BYE_ON_TRANSFER   (1 << 15)
#define SIP_DTMF   (3 << 16)
#define SIP_DTMF_AUTO   (3 << 16)
#define SIP_DTMF_INBAND   (1 << 16)
#define SIP_DTMF_INFO   (2 << 16)
#define SIP_DTMF_RFC2833   (0 << 16)
#define SIP_FLAGS_TO_COPY
#define SIP_FREE_BIT   (1 << 14)
#define SIP_G726_NONSTANDARD   (1 << 31)
#define SIP_GOTREFER   (1 << 7)
#define SIP_INC_COUNT   (1 << 30)
#define SIP_INSECURE_INVITE   (1 << 24)
#define SIP_INSECURE_PORT   (1 << 23)
#define SIP_MAX_HEADERS   64
#define SIP_MAX_LINES   64
#define SIP_MAX_PACKET   4096
#define SIP_NAT   (3 << 18)
#define SIP_NAT_ALWAYS   (3 << 18)
#define SIP_NAT_NEVER   (0 << 18)
#define SIP_NAT_RFC3581   (1 << 18)
#define SIP_NAT_ROUTE   (2 << 18)
#define SIP_NEEDDESTROY   (1 << 1)
#define SIP_NEEDREINVITE   (1 << 5)
#define SIP_NO_HISTORY   (1 << 27)
#define SIP_NOVIDEO   (1 << 2)
#define SIP_OPT_100REL   (1 << 1)
#define SIP_OPT_EARLY_SESSION   (1 << 3)
#define SIP_OPT_EVENTLIST   (1 << 11)
#define SIP_OPT_GRUU   (1 << 12)
#define SIP_OPT_HISTINFO   (1 << 15)
#define SIP_OPT_JOIN   (1 << 4)
#define SIP_OPT_NOREFERSUB   (1 << 14)
#define SIP_OPT_PATH   (1 << 5)
#define SIP_OPT_PRECONDITION   (1 << 7)
#define SIP_OPT_PREF   (1 << 6)
#define SIP_OPT_PRIVACY   (1 << 8)
#define SIP_OPT_REPLACES   (1 << 0)
#define SIP_OPT_RESPRIORITY   (1 << 16)
#define SIP_OPT_SDP_ANAT   (1 << 9)
#define SIP_OPT_SEC_AGREE   (1 << 10)
#define SIP_OPT_TARGET_DIALOG   (1 << 13)
#define SIP_OPT_TIMER   (1 << 2)
#define SIP_OUTGOING   (1 << 13)
#define SIP_PAGE2_ALLOWOVERLAP   (1 << 17)
#define SIP_PAGE2_ALLOWSUBSCRIBE   (1 << 16)
#define SIP_PAGE2_BUGGY_MWI   (1 << 26)
#define SIP_PAGE2_CALL_ONHOLD   (3 << 23)
#define SIP_PAGE2_CALL_ONHOLD_ACTIVE   (1 << 23)
#define SIP_PAGE2_CALL_ONHOLD_INACTIVE   (3 << 23)
#define SIP_PAGE2_CALL_ONHOLD_ONEDIR   (2 << 23)
#define SIP_PAGE2_DEBUG   (3 << 11)
#define SIP_PAGE2_DEBUG_CONFIG   (1 << 11)
#define SIP_PAGE2_DEBUG_CONSOLE   (1 << 12)
#define SIP_PAGE2_DYNAMIC   (1 << 13)
#define SIP_PAGE2_FLAGS_TO_COPY
#define SIP_PAGE2_IGNOREREGEXPIRE   (1 << 10)
#define SIP_PAGE2_INC_RINGING   (1 << 19)
#define SIP_PAGE2_OUTGOING_CALL   (1 << 27)
#define SIP_PAGE2_RFC2833_COMPENSATE   (1 << 25)
#define SIP_PAGE2_RT_FROMCONTACT   (1 << 4)
#define SIP_PAGE2_RTAUTOCLEAR   (1 << 2)
#define SIP_PAGE2_RTCACHEFRIENDS   (1 << 0)
#define SIP_PAGE2_RTSAVE_SYSNAME   (1 << 5)
#define SIP_PAGE2_RTUPDATE   (1 << 1)
#define SIP_PAGE2_SELFDESTRUCT   (1 << 14)
#define SIP_PAGE2_STATECHANGEQUEUE   (1 << 9)
#define SIP_PAGE2_SUBSCRIBEMWIONLY   (1 << 18)
#define SIP_PAGE2_T38SUPPORT   (7 << 20)
#define SIP_PAGE2_T38SUPPORT_RTP   (2 << 20)
#define SIP_PAGE2_T38SUPPORT_TCP   (4 << 20)
#define SIP_PAGE2_T38SUPPORT_UDPTL   (1 << 20)
#define SIP_PAGE2_UDPTL_DESTINATION   (1 << 28)
#define SIP_PAGE2_VIDEOSUPPORT   (1 << 15)
#define SIP_PENDINGBYE   (1 << 6)
#define SIP_PKT_DEBUG   (1 << 0)
#define SIP_PKT_IGNORE   (1 << 2)
#define SIP_PKT_IGNORE_REQ   (1 << 4)
#define SIP_PKT_IGNORE_RESP   (1 << 3)
#define SIP_PKT_WITH_TOTAG   (1 << 1)
#define SIP_PROG_INBAND   (3 << 25)
#define SIP_PROG_INBAND_NEVER   (0 << 25)
#define SIP_PROG_INBAND_NO   (1 << 25)
#define SIP_PROG_INBAND_YES   (2 << 25)
#define SIP_PROGRESS_SENT   (1 << 4)
#define SIP_PROMISCREDIR   (1 << 8)
#define SIP_REALTIME   (1 << 11)
#define SIP_REINVITE   (7 << 20)
#define SIP_REINVITE_UPDATE   (4 << 20)
#define SIP_RINGING   (1 << 3)
#define SIP_SENDRPID   (1 << 29)
#define SIP_TRANS_TIMEOUT   32000
#define SIP_TRUSTRPID   (1 << 9)
#define SIP_USECLIENTCODE   (1 << 12)
#define SIP_USEREQPHONE   (1 << 10)
#define SIPBUFSIZE   512
#define sipdebug   ast_test_flag(&global_flags[1], SIP_PAGE2_DEBUG)
#define sipdebug_config   ast_test_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONFIG)
#define sipdebug_console   ast_test_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE)
#define STANDARD_SIP_PORT   5060
 Standard SIP port from RFC 3261. DO NOT CHANGE THIS.
#define SUPPORTED   1
#define SUPPORTED_EXTENSIONS   "replaces"
 SIP Extensions we support.
#define T38FAX_FILL_BIT_REMOVAL   (1 << 0)
#define T38FAX_RATE_12000   (1 << 12)
#define T38FAX_RATE_14400   (1 << 13)
#define T38FAX_RATE_2400   (1 << 8)
#define T38FAX_RATE_4800   (1 << 9)
#define T38FAX_RATE_7200   (1 << 10)
#define T38FAX_RATE_9600   (1 << 11)
#define T38FAX_RATE_MANAGEMENT_LOCAL_TCF   (1 << 3)
#define T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF   (0 << 3)
#define T38FAX_TRANSCODING_JBIG   (1 << 2)
#define T38FAX_TRANSCODING_MMR   (1 << 1)
#define T38FAX_UDP_EC_FEC   (1 << 4)
#define T38FAX_UDP_EC_NONE   (0 << 4)
#define T38FAX_UDP_EC_REDUNDANCY   (2 << 4)
#define T38FAX_VERSION   (3 << 6)
#define T38FAX_VERSION_0   (0 << 6)
#define T38FAX_VERSION_1   (1 << 6)
#define TRUE   1
#define UNLINK(element, head, prev)
#define VIDEO_CODEC_MASK   0x1fc0000
#define XMIT_ERROR   -2

Enumerations

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

Functions

static const char * __get_header (const struct sip_request *req, const char *name, int *start)
static void __sip_ack (struct sip_pvt *p, int seqno, int resp, int sipmethod)
 Acknowledges receipt of a packet and stops retransmission called with p locked.
static int __sip_autodestruct (const void *data)
 Kill a SIP dialog (called by scheduler).
static int __sip_destroy (struct sip_pvt *p, int lockowner)
 Execute destruction of SIP dialog structure, release memory.
static int __sip_do_register (struct sip_registry *r)
 Register with SIP proxy.
static void __sip_pretend_ack (struct sip_pvt *p)
 Pretend to ack all packets called with p locked.
static int __sip_reliable_xmit (struct sip_pvt *p, int seqno, int resp, char *data, int len, int fatal, int sipmethod)
 Transmit packet with retransmits.
static int __sip_semi_ack (struct sip_pvt *p, int seqno, int resp, int sipmethod)
 Acks receipt of packet, keep it around (used for provisional responses).
static int __sip_show_channels (int fd, int argc, char *argv[], int subscriptions)
 SIP show channels CLI (main function).
static int __sip_xmit (struct sip_pvt *p, char *data, int len)
 Transmit SIP message.
static int __transmit_response (struct sip_pvt *p, const char *msg, const struct sip_request *req, enum xmittype reliable)
 Base transmit response function.
static int _sip_show_peer (int type, int fd, struct mansession *s, const struct message *m, int argc, const char *argv[])
 Show one peer in detail (main function).
static int _sip_show_peers (int fd, int *total, struct mansession *s, const struct message *m, int argc, const char *argv[])
 _sip_show_peers: Execute sip show peers command
static int acf_channel_read (struct ast_channel *chan, char *funcname, char *preparse, char *buf, size_t buflen)
static void add_blank (struct sip_request *req)
 add a blank line if no body
static void add_codec_to_sdp (const struct sip_pvt *p, int codec, int sample_rate, char **m_buf, size_t *m_size, char **a_buf, size_t *a_size, int debug, int *min_packet_size)
 Add codec offer to SDP offer/answer body in INVITE or 200 OK.
static int add_digit (struct sip_request *req, char digit, unsigned int duration)
 Add DTMF INFO tone to sip message.
static int add_header (struct sip_request *req, const char *var, const char *value)
 Add header to SIP message.
static int add_header_contentLength (struct sip_request *req, int len)
 Add 'Content-Length' header to SIP message.
static int add_line (struct sip_request *req, const char *line)
 Add content (not header) to SIP message.
static void add_noncodec_to_sdp (const struct sip_pvt *p, int format, int sample_rate, char **m_buf, size_t *m_size, char **a_buf, size_t *a_size, int debug)
 Add RFC 2833 DTMF offer to SDP.
static struct sip_authadd_realm_authentication (struct sip_auth *authlist, char *configuration, int lineno)
 Add realm authentication in list.
static void add_route (struct sip_request *req, struct sip_route *route)
 Add route header into request per learned route.
static enum sip_result add_sdp (struct sip_request *resp, struct sip_pvt *p)
 Add Session Description Protocol message.
static int add_sip_domain (const char *domain, const enum domain_mode mode, const char *context)
 Add SIP domain to list of domains we are responsible for.
static int add_t38_sdp (struct sip_request *resp, struct sip_pvt *p)
 Add T.38 Session Description Protocol message.
static int add_text (struct sip_request *req, const char *text)
 Add text body to SIP message.
static int add_vidupdate (struct sip_request *req)
 add XML encoded media control with update
static void append_date (struct sip_request *req)
 Append date to SIP message.
static void append_history_full (struct sip_pvt *p, const char *fmt,...)
 Append to SIP dialog history with arg list.
static void static void append_history_va (struct sip_pvt *p, const char *fmt, va_list ap)
 Append to SIP dialog history with arg list.
 AST_LIST_HEAD_NOLOCK (sip_history_head, sip_history)
static AST_LIST_HEAD_STATIC (domain_list, domain)
 AST_MODULE_INFO (ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT,"Session Initiation Protocol (SIP)",.load=load_module,.unload=unload_module,.reload=reload,)
 AST_MUTEX_DEFINE_STATIC (sip_reload_lock)
 AST_MUTEX_DEFINE_STATIC (monlock)
 AST_MUTEX_DEFINE_STATIC (netlock)
 Protect the monitoring thread, so only one process can kill or start it, and not when it's doing something critical.
 AST_MUTEX_DEFINE_STATIC (iflock)
 Protect the SIP dialog list (of sip_pvt's).
static void ast_quiet_chan (struct ast_channel *chan)
 Turn off generator data XXX Does this function belong in the SIP channel?
static int ast_sip_ouraddrfor (struct in_addr *them, struct in_addr *us)
 NAT fix - decide which IP address to use for ASterisk server?
 AST_THREADSTORAGE (check_auth_buf, check_auth_buf_init)
 AST_THREADSTORAGE_CUSTOM (ts_temp_pvt, temp_pvt_init, temp_pvt_cleanup)
 A per-thread temporary pvt structure.
static int attempt_transfer (struct sip_dual *transferer, struct sip_dual *target)
 Attempt transfer of SIP call This fix for attended transfers on a local PBX.
static int auto_congest (const void *nothing)
 Scheduled congestion on a call.
static void build_callid_pvt (struct sip_pvt *pvt)
 Build SIP Call-ID value for a non-REGISTER transaction.
static void build_callid_registry (struct sip_registry *reg, struct in_addr ourip, const char *fromdomain)
 Build SIP Call-ID value for a REGISTER transaction.
static void build_contact (struct sip_pvt *p)
 Build contact header - the contact header we send out.
static struct sip_peerbuild_peer (const char *name, struct ast_variable *v, struct ast_variable *alt, int realtime)
 Build peer from configuration (file or realtime static/dynamic).
static int build_reply_digest (struct sip_pvt *p, int method, char *digest, int digest_len)
 Build reply digest.
static void build_route (struct sip_pvt *p, struct sip_request *req, int backwards)
 Build route list from Record-Route header.
static void build_rpid (struct sip_pvt *p)
 Build the Remote Party-ID & From using callingpres options.
static struct sip_userbuild_user (const char *name, struct ast_variable *v, struct ast_variable *alt, int realtime)
 Initiate a SIP user structure from configuration (configuration or realtime).
static void build_via (struct sip_pvt *p)
 Build a Via header for a request.
static int cb_extensionstate (char *context, char *exten, int state, void *data, char *cid_num, char *cid_name)
 Callback for the devicestate notification (SUBSCRIBE) support subsystem.
static void change_hold_state (struct sip_pvt *dialog, struct sip_request *req, int holdstate, int sendonly)
 Change hold state for a call.
static enum check_auth_result check_auth (struct sip_pvt *p, struct sip_request *req, const char *username, const char *secret, const char *md5secret, int sipmethod, char *uri, enum xmittype reliable, int ignore)
 Check user authorization from peer definition Some actions, like REGISTER and INVITEs from peers require authentication (if peer have secret set).
static void check_pendings (struct sip_pvt *p)
 Check pending actions on SIP call.
static int check_sip_domain (const char *domain, char *context, size_t len)
 check_sip_domain: Check if domain part of uri is local to our server
static int check_user (struct sip_pvt *p, struct sip_request *req, int sipmethod, char *uri, enum xmittype reliable, struct sockaddr_in *sin)
 Find user If we get a match, this will add a reference pointer to the user object in ASTOBJ, that needs to be unreferenced.
static enum check_auth_result check_user_full (struct sip_pvt *p, struct sip_request *req, int sipmethod, char *uri, enum xmittype reliable, struct sockaddr_in *sin, struct sip_peer **authpeer)
 Check if matching user or peer is defined Match user on From: user name and peer on IP/port This is used on first invite (not re-invites) and subscribe requests.
static void check_via (struct sip_pvt *p, const struct sip_request *req)
 check Via: header for hostname, port and rport request/answer
static void cleanup_stale_contexts (char *new, char *old)
 Destroy disused contexts between reloads Only used in reload_config so the code for regcontext doesn't get ugly.
static int clear_realm_authentication (struct sip_auth *authlist)
 Clear realm authentication list (at reload).
static void clear_sip_domains (void)
 Clear our domain list (at reload).
static char * complete_sip_debug_peer (const char *line, const char *word, int pos, int state)
 Support routine for 'sip debug peer' CLI.
static char * complete_sip_peer (const char *word, int state, int flags2)
 Do completion on peer name.
static char * complete_sip_prune_realtime_peer (const char *line, const char *word, int pos, int state)
 Support routine for 'sip prune realtime peer' CLI.
static char * complete_sip_prune_realtime_user (const char *line, const char *word, int pos, int state)
 Support routine for 'sip prune realtime user' CLI.
static char * complete_sip_show_peer (const char *line, const char *word, int pos, int state)
 Support routine for 'sip show peer' CLI.
static char * complete_sip_show_user (const char *line, const char *word, int pos, int state)
 Support routine for 'sip show user' CLI.
static char * complete_sip_user (const char *word, int state, int flags2)
 Do completion on user name.
static char * complete_sipch (const char *line, const char *word, int pos, int state)
 Support routine for 'sip show channel' CLI.
static char * complete_sipnotify (const char *line, const char *word, int pos, int state)
 Support routine for 'sip notify' CLI.
static int copy_all_header (struct sip_request *req, const struct sip_request *orig, const char *field)
 Copy all headers from one request to another.
static int copy_header (struct sip_request *req, const struct sip_request *orig, const char *field)
 Copy one header field from one request to another.
static void copy_request (struct sip_request *dst, const struct sip_request *src)
 copy SIP request (mostly used to save request for responses)
static int copy_via_headers (struct sip_pvt *p, struct sip_request *req, const struct sip_request *orig, const char *field)
 Copy SIP VIA Headers from the request to the response.
static int create_addr (struct sip_pvt *dialog, const char *opeer)
 create address structure from peer name Or, if peer not found, find it in the global DNS returns TRUE (-1) on failure, FALSE on success
static int create_addr_from_peer (struct sip_pvt *dialog, struct sip_peer *peer)
 Create address structure from peer reference. return -1 on error, 0 on success.
static void destroy_association (struct sip_peer *peer)
 Remove registration data from realtime database or AST/DB when registration expires.
static int determine_firstline_parts (struct sip_request *req)
 Parse first line of incoming SIP request.
static void * 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
Todo:
SIP over TLS
Todo:
Better support of forking
Todo:
VIA branch tag transaction checking
Todo:
Transaction support

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

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

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

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

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

Definition in file chan_sip.c.


Define Documentation

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

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

#define CALLERID_UNKNOWN   "Unknown"

Definition at line 200 of file chan_sip.c.

Referenced by initreqprep().

#define CAN_CREATE_DIALOG   1

Definition at line 369 of file chan_sip.c.

Referenced by find_call().

#define CAN_CREATE_DIALOG_UNSUPPORTED_METHOD   2

Definition at line 370 of file chan_sip.c.

Referenced by find_call().

#define CAN_NOT_CREATE_DIALOG   0

Definition at line 368 of file chan_sip.c.

#define CHECK_AUTH_BUF_INITLEN   256

Definition at line 8403 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 6444 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 4254 of file chan_sip.c.

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

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

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

References SIP_REGISTER, and transmit_register().

Referenced by sip_reregister().

07500 {
07501    int res;
07502 
07503    res = transmit_register(r, SIP_REGISTER, NULL, NULL);
07504    return res;
07505 }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Add DTMF INFO tone to sip message.

Definition at line 6211 of file chan_sip.c.

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

Referenced by transmit_info_with_digit().

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

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

Add header to SIP message.

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

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

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

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

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

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

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

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

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

Add route header into request per learned route.

Definition at line 5767 of file chan_sip.c.

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

Referenced by reqprep().

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

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

Add Session Description Protocol message.

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

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

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

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

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

Add T.38 Session Description Protocol message.

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

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

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

Add text body to SIP message.

Definition at line 6200 of file chan_sip.c.

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

Referenced by transmit_message_with_text().

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

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

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

Referenced by transmit_info_with_vidupdate().

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

static void append_date ( struct sip_request req  )  [static]

Append date to SIP message.

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

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

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

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

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

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

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

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

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

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

Referenced by transmit_register().

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

static void build_contact ( struct sip_pvt p  )  [static]

Build contact header - the contact header we send out.

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

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

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

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

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

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

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

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

static void build_rpid ( struct sip_pvt p  )  [static]

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

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

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

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

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

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

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

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

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

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

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

static void check_pendings ( struct sip_pvt p  )  [static]

Check pending actions on SIP call.

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

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

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

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

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

References check_user_full().

Referenced by handle_request_invite().

09710 {
09711    return check_user_full(p, req, sipmethod, uri, reliable, sin, NULL);
09712 }

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

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

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

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

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

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

Referenced by reload_config().

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

static int clear_realm_authentication ( struct sip_auth authlist  )  [static]

Clear realm authentication list (at reload).

Definition at line 16436 of file chan_sip.c.

References free, and sip_auth::next.

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

16437 {
16438    struct sip_auth *a = authlist;
16439    struct sip_auth *b;
16440 
16441    while (a) {
16442       b = a;
16443       a = a->next;
16444       free(b);
16445    }
16446 
16447    return 1;
16448 }

static void clear_sip_domains ( void   )  [static]

Clear our domain list (at reload).

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

16366 {
16367    struct domain *d;
16368 
16369    AST_LIST_LOCK(&domain_list);
16370    while ((d = AST_LIST_REMOVE_HEAD(&domain_list, list)))
16371       free(d);
16372    AST_LIST_UNLOCK(&domain_list);
16373 }

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

References complete_sip_peer().

10966 {
10967    if (pos == 3)
10968       return complete_sip_peer(word, state, 0);
10969 
10970    return NULL;
10971 }

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

Do completion on peer name.

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

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

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

References complete_sip_peer(), and SIP_PAGE2_RTCACHEFRIENDS.

11034 {
11035    if (pos == 4)
11036       return complete_sip_peer(word, state, SIP_PAGE2_RTCACHEFRIENDS);
11037    return NULL;
11038 }

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

References complete_sip_user(), and SIP_PAGE2_RTCACHEFRIENDS.

11042 {
11043    if (pos == 4)
11044       return complete_sip_user(word, state, SIP_PAGE2_RTCACHEFRIENDS);
11045 
11046    return NULL;
11047 }

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

References complete_sip_peer().

10957 {
10958    if (pos == 3)
10959       return complete_sip_peer(word, state, 0);
10960 
10961    return NULL;
10962 }

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

References complete_sip_user().

10995 {
10996    if (pos == 3)
10997       return complete_sip_user(word, state, 0);
10998 
10999    return NULL;
11000 }

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

Do completion on user name.

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

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

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

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

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

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

Support routine for 'sip notify' CLI.

Definition at line 11003 of file chan_sip.c.

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

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

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

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

Referenced by respprep().

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

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

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

Referenced by reqprep(), and respprep().

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

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

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

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

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

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

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

static int determine_firstline_parts ( struct sip_request req  )  [static]

Parse first line of incoming SIP request.

Definition at line 6767 of file chan_sip.c.

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

Referenced by parse_request().

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

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

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

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

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

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

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

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

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

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

Print domain mode to cli.

Definition at line 10342 of file chan_sip.c.

References SIP_DOMAIN_AUTO, and SIP_DOMAIN_CONFIG.

Referenced by sip_show_domains().

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

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

Convert DTMF mode to printable string.

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

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

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

Expire registration of SIP peer.

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

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

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

Check Contact: URI of SIP message.

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

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

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

References aliases.

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

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

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

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

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

Referenced by build_reply_digest().

16452 {
16453    struct sip_auth *a;
16454 
16455    for (a = authlist; a; a = a->next) {
16456       if (!strcasecmp(a->realm, realm))
16457          break;
16458    }
16459 
16460    return a;
16461 }

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

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

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

References subscription_types, and type.

Referenced by transmit_state_notify().

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

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

References free, and sip_route::next.

Referenced by __sip_destroy(), and build_route().

08275 {
08276    struct sip_route *next;
08277 
08278    while (route) {
08279       next = route->next;
08280       free(route);
08281       route = next;
08282    }
08283 }

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

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

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

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

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

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

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

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

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

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

Generate 32 byte random string for callid's etc.

Definition at line 4407 of file chan_sip.c.

References ast_random().

Referenced by build_callid_pvt(), and build_callid_registry().

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

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

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

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

Get a specific line from the message body.

Definition at line 4201 of file chan_sip.c.

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

Referenced by handle_request_info().

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

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

Referenced by get_body(), and get_sdp_iterate().

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

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

Get caller id name from SIP headers.

Definition at line 9309 of file chan_sip.c.

Referenced by check_user_full().

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

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

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

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

Get header from SIP request.

Definition at line 4290 of file chan_sip.c.

References __get_header().

04291 {
04292    int start = 0;
04293    return __get_header(req, name, &start);
04294 }

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

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

Referenced by handle_request_notify(), and receive_message().

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

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

Get referring dnis.

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

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

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

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

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

References AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED.

Referenced by check_user_full().

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

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

Get a line from an SDP message body.

Definition at line 4193 of file chan_sip.c.

References get_sdp_iterate().

04194 {
04195    int dummy = 0;
04196 
04197    return get_sdp_iterate(&dummy, req, name);
04198 }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Handle incoming BYE request.

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

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

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

Handle incoming CANCEL request.

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

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

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

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

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 13753 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_CONTROL_SRCCHANGE, 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_control(), 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().

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

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

Handle incoming MESSAGE request.

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

14898 {
14899    if (!ast_test_flag(req, SIP_PKT_IGNORE)) {
14900       if (ast_test_flag(req, SIP_PKT_DEBUG))
14901          ast_verbose("Receiving message!\n");
14902       receive_message(p, req);
14903    } else
14904       transmit_response(p, "202 Accepted", req);
14905    return 1;
14906 }

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

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

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

Handle incoming OPTIONS request.

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

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

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

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

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

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

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

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

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

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

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

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

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

Handle qualification responses (OPTIONS).

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

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

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

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

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

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

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

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

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

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

Initialize SIP response, based on SIP request.

Definition at line 5859 of file chan_sip.c.

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

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

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

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

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

Convert Insecure setting to printable string.

Definition at line 10138 of file chan_sip.c.

Referenced by _sip_show_peer().

10139 {
10140    if (port && invite)
10141       return "port,invite";
10142    else if (port)
10143       return "port";
10144    else if (invite)
10145       return "invite";
10146    else
10147       return "no";
10148 }

static void list_route ( struct sip_route route  )  [static]

List all routes - mostly for debugging.

Definition at line 8286 of file chan_sip.c.

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

Referenced by build_route().

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

static int load_module ( void   )  [static]

PBX load module - initialization.

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

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

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

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

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

References t.

Referenced by sipsock_read().

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

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

Make our SIP dialog tag.

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

04442 {
04443    snprintf(tagbuf, len, "as%08lx", ast_random());
04444 }

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

Show SIP peers in the manager API.

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

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

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

Show SIP peers in the manager API.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Print call group and pickup group.

Definition at line 10115 of file chan_sip.c.

References ast_cli(), and ast_print_group().

Referenced by _sip_show_peer(), and sip_show_user().

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

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

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

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

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

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

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

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

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

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

Convert registration state status to string.

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

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

static int reload ( void   )  [static]

Part of Asterisk module interface.

Definition at line 18025 of file chan_sip.c.

References sip_reload().

18026 {
18027    return sip_reload(0, 0, NULL);
18028 }

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

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

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

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

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

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

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

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

static int restart_monitor ( void   )  [static]

Start the channel monitor thread.

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

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

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

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

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

Set destination from SIP URI.

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

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

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

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

static void set_peer_defaults ( struct sip_peer peer  )  [static]

Set peer defaults before configuring specific configurations.

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

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

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

Add a SIP header to an outbound INVITE.

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

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

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

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

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

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

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

Turn on SIP debugging (CLI command).

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

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

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

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

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

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

Enable SIP Debugging in CLI.

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

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

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

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

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

Enable SIP History logging (CLI).

Definition at line 11463 of file chan_sip.c.

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

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

static int sip_do_reload ( enum channelreloadreason  reason  )  [static]

Reload module.

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

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

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

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

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

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

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

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

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

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

17929 {
17930    struct sip_pvt *p = chan->tech_pvt;
17931    return p->peercapability ? p->peercapability : p->capability;  
17932 }

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

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

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

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

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

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

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

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

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

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_SRCCHANGE, 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_change_source(), ast_rtp_update_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_update_source(p->rtp);
03958       ast_moh_start(ast, data, p->mohinterpret);
03959       break;
03960    case AST_CONTROL_UNHOLD:
03961       ast_rtp_update_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_update_source(p->rtp);
03973       break;
03974    case AST_CONTROL_SRCCHANGE:
03975       ast_rtp_change_source(p->rtp);
03976       break;
03977    case -1:
03978       res = -1;
03979       break;
03980    default:
03981       ast_log(LOG_WARNING, "Don't know how to indicate condition %d\n", condition);
03982       res = -1;
03983       break;
03984    }
03985    ast_mutex_unlock(&p->lock);
03986    return res;
03987 }

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

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

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

Disable SIP Debugging in CLI.

Definition at line 11444 of file chan_sip.c.

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

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

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

Definition at line 11453 of file chan_sip.c.

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

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

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

Disable SIP History logging (CLI).

Definition at line 11474 of file chan_sip.c.

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

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

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

Cli command to send SIP notify to peer.

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

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

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

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

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

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

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

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

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

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

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

React to lack of answer to Qualify poke.

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

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

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

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

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

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

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

Remove temporary realtime objects from memory (CLI).

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

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

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

Read SIP RTP from channel.

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

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

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

07754 {
07755    p->refer = ast_calloc(1, sizeof(struct sip_refer)); 
07756    return p->refer ? 1 : 0;
07757 }

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

Registration timeout, register again.

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

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

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

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

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

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

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

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

Referenced by handle_response_invite().

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

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

Force reload of module from cli.

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

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

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

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

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

Update registration with SIP Proxy.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Show details of one active dialog.

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

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

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

Show active SIP channels.

Definition at line 10843 of file chan_sip.c.

References __sip_show_channels().

10844 {
10845         return __sip_show_channels(fd, argc, argv, 0);
10846 }

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

CLI command to list local domains.

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

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

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

Show history details of one dialog.

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

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

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

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

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

List all allocated SIP Objects (realtime or static).

Definition at line 10101 of file chan_sip.c.

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

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

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

Show one peer in detail.

Definition at line 10407 of file chan_sip.c.

References _sip_show_peer().

10408 {
10409    return _sip_show_peer(0, fd, NULL, NULL, argc, (const char **) argv);
10410 }

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

CLI Show Peers command.

Definition at line 9957 of file chan_sip.c.

References _sip_show_peers().

09958 {
09959    return _sip_show_peers(fd, NULL, NULL, NULL, argc, (const char **) argv);
09960 }

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

Show SIP Registry (registrations with other SIP proxies.

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

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

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

List global settings for the SIP channel.

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

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

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

Show active SIP subscriptions.

Definition at line 10849 of file chan_sip.c.

References __sip_show_channels().

10850 {
10851         return __sip_show_channels(fd, argc, argv, 1);
10852 }

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

Show one user in detail.

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

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

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

CLI Command 'SIP Show Users'.

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

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

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

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

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

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

static void stop_media_flows ( struct sip_pvt p  )  [static]

Immediately stop RTP, VRTP and UDPTL as applicable.

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

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

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

Show subscription type in string format.

Definition at line 10817 of file chan_sip.c.

References subscription_types, cfsubscription_types::text, and type.

Referenced by __sip_show_channels(), and sip_show_channel().

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

static int t38_get_rate ( int  t38cap  )  [static]

Get Max T.38 Transmission rate from T38 capabilities.

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

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

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

Create temporary peer (used in autocreatepeer mode).

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

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

static void temp_pvt_cleanup ( void *  data  )  [static]

Definition at line 6061 of file chan_sip.c.

References ast_string_field_free_memory, and free.

06062 {
06063    struct sip_pvt *p = data;
06064 
06065    ast_string_field_free_memory(p);
06066 
06067    free(data);
06068 }

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

Convert transfer mode to text string.

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

09828 {
09829    if (mode == TRANSFER_OPENFORALL)
09830       return "open";
09831    else if (mode == TRANSFER_CLOSED)
09832       return "closed";
09833    return "strict";
09834 }

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

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

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

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

Referenced by sip_senddigit_end().

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

static int transmit_info_with_vidupdate ( struct sip_pvt p  )  [static]

Send SIP INFO with video update request.

Definition at line 7844 of file chan_sip.c.

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

Referenced by sip_indicate().

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

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

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

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

Transmit text with SIP MESSAGE method.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Transmit response, no retransmits.

Definition at line 6122 of file chan_sip.c.

References __transmit_response(), and XMIT_UNRELIABLE.

06123 {
06124    return __transmit_response(p, msg, req, XMIT_UNRELIABLE);
06125 }

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

06142 {
06143    return __transmit_response(p, msg, req, XMIT_CRITICAL);
06144 }

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

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

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

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

Referenced by handle_request(), and handle_request_options().

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

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

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

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

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

Referenced by register_verify().

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

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

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

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

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

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

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

Referenced by handle_request_invite().

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

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

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

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

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

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

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

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

char* app_sipaddheader = "SIPAddHeader" [static]

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

struct ast_cli_entry cli_sip[] [static]

Definition at line 18040 of file chan_sip.c.

Initial value:

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

Definition at line 18030 of file chan_sip.c.

Initial value:

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

Definition at line 18035 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 11736 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 17767 of file chan_sip.c.

char* descrip_sipaddheader [static]

Definition at line 17773 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 11753 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 10376 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 9927 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 11745 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 11749 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 11685 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 11727 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 11709 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 11705 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 11680 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 11713 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 11700 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 11766 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 11722 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 11717 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 11732 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 11770 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 11762 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 11695 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 11690 of file chan_sip.c.

Definition at line 11828 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 11758 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 12007 of file chan_sip.c.

Structure to declare a dialplan function: SIPPEER.

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

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

Definition at line 17771 of file chan_sip.c.

struct ast_user_list userl [static]

The user list: Users and friends.


Generated on Sun Jun 12 16:37:55 2011 for Asterisk - the Open Source PBX by  doxygen 1.5.6