Mon Nov 24 15:34:31 2008

Asterisk developer's documentation


chan_sip.c File Reference

Implementation of Session Initiation Protocol. More...

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

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 FORMAT3H   "%-15.15s %-10.10s %-11.11s %-15.15s %-13.13s %-15.15s %-10.10s %-6s\n"
#define FORMAT3L   "%-15.15s %-10.10s %-11.11s %-15.15s %-13.13s %-15.15s %-10.10s %6d\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_DIALOG_ESTABLISHED   (1 << 29)
#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_TCP   (1 << 30)
#define SIP_PAGE2_TCP_CONNECTED   (1 << 31)
#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 int __set_address_from_contact (const char *fullcontact, struct sockaddr_in *sin)
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)
 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, int devstate_only)
 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_typesfind_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.
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, int devstate_only)
 realtime_peer: Get peer from realtime storage Checks the "sippeers" realtime family from extconfig.conf
static void realtime_update_peer (const char *peername, struct sockaddr_in *sin, const char *username, const char *fullcontact, int expirey)
 Update peer object in realtime storage If the Asterisk system name is set in asterisk.conf, we will use that name and store that in the "regserver" field in the sippeers table to facilitate multi-server setups.
static struct sip_userrealtime_user (const char *username)
 Load user from realtime storage Loads user from "sipusers" category in realtime (extconfig.conf) Users are matched on From: user name (the domain in skipped).
static void receive_message (struct sip_pvt *p, struct sip_request *req)
 Receive SIP MESSAGE method messages.
static char * referstatus2str (enum referstatus rstatus)
 Convert transfer status to string.
static void reg_source_db (struct sip_peer *peer)
 Get registration details from Asterisk DB.
static void register_peer_exten (struct sip_peer *peer, int onoff)
 Automatically add peer extension to dial plan.
static enum check_auth_result register_verify (struct sip_pvt *p, struct sockaddr_in *sin, struct sip_request *req, char *uri)
 Verify registration of user
  • Registration is done in several steps, first a REGISTER without auth to get a challenge (nonce) then a second one with auth
  • Registration requests are only matched with peers that are marked as "dynamic".

static char * regstate2str (enum sipregistrystate regstate)
 Convert registration state status to string.
static int reload (void)
 Part of Asterisk module interface.
static int reload_config (enum channelreloadreason reason)
 Re-read SIP.conf config file.
static int reply_digest (struct sip_pvt *p, struct sip_request *req, char *header, int sipmethod, char *digest, int digest_len)
 reply to authentication for outbound registrations
static int reqprep (struct sip_request *req, struct sip_pvt *p, int sipmethod, int seqno, int newbranch)
 Initialize a SIP request message (not the initial one in a dialog).
static int respprep (struct sip_request *resp, struct sip_pvt *p, const char *msg, const struct sip_request *req)
 Prepare SIP response packet.
static int restart_monitor (void)
 Start the channel monitor thread.
static int retrans_pkt (const void *data)
 Retransmit SIP message if no answer (Called from scheduler).
static int send_request (struct sip_pvt *p, struct sip_request *req, enum xmittype reliable, int seqno)
 Send SIP Request to the other part of the dialogue.
static int send_response (struct sip_pvt *p, struct sip_request *req, enum xmittype reliable, int seqno)
 Transmit response on SIP request.
static int set_address_from_contact (struct sip_pvt *pvt)
 Change the other partys IP address based on given contact.
static void set_destination (struct sip_pvt *p, char *uri)
 Set destination from SIP URI.
static void set_insecure_flags (struct ast_flags *flags, const char *value, int lineno)
 Parse the "insecure" setting from sip.conf or from realtime.
static void set_peer_defaults (struct sip_peer *peer)
 Set peer defaults before configuring specific configurations.
static int sip_addheader (struct ast_channel *chan, void *data)
 Add a SIP header to an outbound INVITE.
static int sip_addrcmp (char *name, struct sockaddr_in *sin)
 Support routine for find_peer.
static struct sip_pvtsip_alloc (ast_string_field callid, struct sockaddr_in *sin, int useglobal_nat, const int intended_method)
 Allocate SIP_PVT structure and set defaults.
static void sip_alreadygone (struct sip_pvt *dialog)
static int sip_answer (struct ast_channel *ast)
 sip_answer: Answer SIP call , send 200 OK on Invite Part of PBX interface
static int sip_call (struct ast_channel *ast, char *dest, int timeout)
 Initiate SIP call from PBX used from the dial() application.
static int sip_cancel_destroy (struct sip_pvt *p)
 Cancel destruction of SIP dialog.
static int sip_debug_test_addr (const struct sockaddr_in *addr)
 See if we pass debug IP filter.
static int sip_debug_test_pvt (struct sip_pvt *p)
 Test PVT for debugging output.
static void sip_destroy (struct sip_pvt *p)
 Destroy SIP call structure.
static void sip_destroy_peer (struct sip_peer *peer)
 Destroy peer object from memory.
static void sip_destroy_user (struct sip_user *user)
 Remove user object from in-memory storage.
static int sip_devicestate (void *data)
 Part of PBX channel interface.
static int sip_do_debug (int fd, int argc, char *argv[])
 Turn on SIP debugging (CLI command).
static int sip_do_debug_deprecated (int fd, int argc, char *argv[])
static int sip_do_debug_ip (int fd, int argc, char *argv[])
 Enable SIP Debugging in CLI.
static int sip_do_debug_peer (int fd, int argc, char *argv[])
 sip_do_debug_peer: Turn on SIP debugging with peer mask
static int sip_do_history (int fd, int argc, char *argv[])
 Enable SIP History logging (CLI).
static int sip_do_reload (enum channelreloadreason reason)
 Reload module.
static int sip_dtmfmode (struct ast_channel *chan, void *data)
 Set the DTMFmode for an outbound SIP call (application).
static void sip_dump_history (struct sip_pvt *dialog)
 Dump SIP history to debug log file at end of lifespan for SIP dialog.
static int sip_fixup (struct ast_channel *oldchan, struct ast_channel *newchan)
 sip_fixup: Fix up a channel: If a channel is consumed, this is called. Basically update any ->owner links
static int sip_get_codec (struct ast_channel *chan)
 Return SIP UA's codec (part of the RTP interface).
static enum ast_rtp_get_result sip_get_rtp_peer (struct ast_channel *chan, struct ast_rtp **rtp)
 Returns null if we can't reinvite audio (part of RTP interface).
static struct ast_udptlsip_get_udptl_peer (struct ast_channel *chan)
static enum ast_rtp_get_result sip_get_vrtp_peer (struct ast_channel *chan, struct ast_rtp **rtp)
 Returns null if we can't reinvite video (part of RTP interface).
static int sip_handle_t38_reinvite (struct ast_channel *chan, struct sip_pvt *pvt, int reinvite)
 Handle T38 reinvite.
static int sip_hangup (struct ast_channel *ast)
 sip_hangup: Hangup SIP call Part of PBX interface, called from ast_hangup
static int sip_indicate (struct ast_channel *ast, int condition, const void *data, size_t datalen)
 Play indication to user With SIP a lot of indications is sent as messages, letting the device play the indication - busy signal, congestion etc.
static const char * sip_nat_mode (const struct sip_pvt *p)
 Display SIP nat mode.
static struct ast_channelsip_new (struct sip_pvt *i, int state, const char *title)
 Initiate a call in the SIP channel called from sip_request_call (calls from the pbx ) for outbound channels and from handle_request_invite for inbound channels.
static int sip_no_debug (int fd, int argc, char *argv[])
 Disable SIP Debugging in CLI.
static int sip_no_debug_deprecated (int fd, int argc, char *argv[])
static int sip_no_history (int fd, int argc, char *argv[])
 Disable SIP History logging (CLI).
static int sip_notify (int fd, int argc, char *argv[])
 Cli command to send SIP notify to peer.
static int sip_park (struct ast_channel *chan1, struct ast_channel *chan2, struct sip_request *req, int seqno)
 Park a call using the subsystem in res_features.c This is executed in a separate thread.
static void * sip_park_thread (void *stuff)
 Park SIP call support function Starts in a new thread, then parks the call XXX Should we add a wait period after streaming audio and before hangup?? Sometimes the audio can't be heard before hangup.
static void sip_peer_hold (struct sip_pvt *p, int hold)
 Change onhold state of a peer using a pvt structure.
static void sip_poke_all_peers (void)
 Send a poke to all known peers Space them out 100 ms apart XXX We might have a cool algorithm for this or use random - any suggestions?
static int sip_poke_noanswer (const void *data)
 React to lack of answer to Qualify poke.
static int sip_poke_peer (struct sip_peer *peer)
 Check availability of peer, also keep NAT open.
static int sip_poke_peer_s (const void *data)
 Poke peer (send qualify to check if peer is alive and well).
static int sip_prune_realtime (int fd, int argc, char *argv[])
 Remove temporary realtime objects from memory (CLI).
static struct ast_framesip_read (struct ast_channel *ast)
 Read SIP RTP from channel.
static struct sockaddr_in * sip_real_dst (const struct sip_pvt *p)
 The real destination address for a write.
static int sip_refer_allocate (struct sip_pvt *p)
 Allocate SIP refer structure.
static int sip_reg_timeout (const void *data)
 Registration timeout, register again.
static int sip_register (char *value, int lineno)
 Parse register=> line in sip.conf and add to registry.
static void sip_registry_destroy (struct sip_registry *reg)
 Destroy registry object Objects created with the register= statement in static configuration.
static int sip_reinvite_retry (const void *data)
 Reset the NEEDREINVITE flag after waiting when we get 491 on a Re-invite to avoid race conditions between asterisk servers. Called from the scheduler.
static int sip_reload (int fd, int argc, char *argv[])
 Force reload of module from cli.
static struct ast_channelsip_request_call (const char *type, int format, void *data, int *cause)
 PBX interface function -build SIP pvt structure SIP calls initiated by the PBX arrive here.
static int sip_reregister (const void *data)
 Update registration with SIP Proxy.
static struct ast_framesip_rtp_read (struct ast_channel *ast, struct sip_pvt *p, int *faxdetect)
 Read RTP from network.
static void sip_scheddestroy (struct sip_pvt *p, int ms)
 Schedule destruction of SIP dialog.
static void sip_send_all_registers (void)
 Send all known registrations.
static int sip_send_mwi_to_peer (struct sip_peer *peer)
 Send message waiting indication to alert peer that they've got voicemail.
static int sip_senddigit_begin (struct ast_channel *ast, char digit)
static int sip_senddigit_end (struct ast_channel *ast, char digit, unsigned int duration)
 Send DTMF character on SIP channel within one call, we're able to transmit in many methods simultaneously.
static int sip_sendtext (struct ast_channel *ast, const char *text)
 Send SIP MESSAGE text within a call Called from PBX core sendtext() application.
static int sip_set_rtp_peer (struct ast_channel *chan, struct ast_rtp *rtp, struct ast_rtp *vrtp, int codecs, int nat_active)
 Set the RTP peer for this call.
static int sip_set_udptl_peer (struct ast_channel *chan, struct ast_udptl *udptl)
static int sip_show_channel (int fd, int argc, char *argv[])
 Show details of one active dialog.
static int sip_show_channels (int fd, int argc, char *argv[])
 Show active SIP channels.
static int sip_show_domains (int fd, int argc, char *argv[])
 CLI command to list local domains.
static int sip_show_history (int fd, int argc, char *argv[])
 Show history details of one dialog.
static int sip_show_inuse (int fd, int argc, char *argv[])
 CLI Command to show calls within limits set by call_limit.
static int sip_show_objects (int fd, int argc, char *argv[])
 List all allocated SIP Objects (realtime or static).
static int sip_show_peer (int fd, int argc, char *argv[])
 Show one peer in detail.
static int sip_show_peers (int fd, int argc, char *argv[])
 CLI Show Peers command.
static int sip_show_registry (int fd, int argc, char *argv[])
 Show SIP Registry (registrations with other SIP proxies.
static int sip_show_settings (int fd, int argc, char *argv[])
 List global settings for the SIP channel.
static int sip_show_subscriptions (int fd, int argc, char *argv[])
 Show active SIP subscriptions.
static int sip_show_user (int fd, int argc, char *argv[])
 Show one user in detail.
static int sip_show_users (int fd, int argc, char *argv[])
 CLI Command 'SIP Show Users'.
static int sip_sipredirect (struct sip_pvt *p, const char *dest)
 Transfer call before connect with a 302 redirect.
static int sip_transfer (struct ast_channel *ast, const char *dest)
 Transfer SIP call.
static int sip_uri_cmp (const char *input1, const char *input2)
static int sip_uri_headers_cmp (const char *input1, const char *input2)
 helper routine for sip_uri_cmp
static int sip_uri_params_cmp (const char *input1, const char *input2)
 helper routine for sip_uri_cmp
static int sip_write (struct ast_channel *ast, struct ast_frame *frame)
 Send frame to media channel (rtp).
static int sipsock_read (int *id, int fd, short events, void *ignore)
 Read data from SIP socket.
static int siptcpsock_accept (int *id, int fd, short events, void *ignore)
 Accept incoming TCP connections.
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.
ast_custom_function sippeer_function
 Structure to declare a dialplan function: SIPPEER.
static int sipsock = -1
static int * sipsock_read_id
static int siptcpsock = -1
static int * siptcpsock_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 and TLS support Configuration file sip.conf

Todo:
SIP over TLS

Better support of forking

VIA branch tag transaction checking

Transaction support

Overview of the handling of SIP sessions
The SIP channel handles several types of SIP sessions, or dialogs, not all of them being "telephone calls".
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

Definition in file chan_sip.c.


Define Documentation

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

SIP Methods we support.

Definition at line 475 of file chan_sip.c.

Referenced by respprep(), transmit_invite(), transmit_notify_with_sipfrag(), transmit_refer(), transmit_reinvite_with_sdp(), and transmit_reinvite_with_t38_sdp().

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

Append to SIP dialog history.

Returns:
Always returns 0

Definition at line 1869 of file chan_sip.c.

Referenced by __sip_autodestruct(), __sip_reliable_xmit(), auto_congest(), build_reply_digest(), cb_extensionstate(), change_hold_state(), check_auth(), do_register_auth(), handle_invite_replaces(), handle_request(), handle_request_bye(), handle_request_invite(), handle_request_refer(), handle_request_register(), handle_request_subscribe(), handle_response_invite(), local_attended_transfer(), retrans_pkt(), send_request(), send_response(), sip_cancel_destroy(), sip_fixup(), sip_hangup(), sip_new(), sip_park_thread(), sip_reregister(), sip_scheddestroy(), sip_set_rtp_peer(), sipsock_read(), transmit_register(), transmit_reinvite_with_sdp(), and transmit_response_with_auth().

#define CALLERID_UNKNOWN   "Unknown"

Definition at line 199 of file chan_sip.c.

Referenced by initreqprep().

#define CAN_CREATE_DIALOG   1

Definition at line 368 of file chan_sip.c.

#define CAN_CREATE_DIALOG_UNSUPPORTED_METHOD   2

Definition at line 369 of file chan_sip.c.

#define CAN_NOT_CREATE_DIALOG   0

Definition at line 367 of file chan_sip.c.

#define CHECK_AUTH_BUF_INITLEN   256

Definition at line 8515 of file chan_sip.c.

Referenced by check_auth().

#define DEC_CALL_LIMIT   0

Definition at line 609 of file chan_sip.c.

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

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

#define DEFAULT_ALLOWGUEST   TRUE

Definition at line 501 of file chan_sip.c.

#define DEFAULT_AUTOCREATEPEER   FALSE

Definition at line 511 of file chan_sip.c.

#define DEFAULT_CALLERID   "asterisk"

Definition at line 498 of file chan_sip.c.

#define DEFAULT_COMPACTHEADERS   FALSE

Definition at line 503 of file chan_sip.c.

#define DEFAULT_CONTEXT   "default"

Definition at line 494 of file chan_sip.c.

#define DEFAULT_DEFAULT_EXPIRY   120

Definition at line 171 of file chan_sip.c.

#define DEFAULT_EXPIRY   900

Expire slowly

Definition at line 188 of file chan_sip.c.

#define DEFAULT_FREQ_NOTOK   10 * 1000

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

Definition at line 203 of file chan_sip.c.

#define DEFAULT_FREQ_OK   60 * 1000

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

Definition at line 202 of file chan_sip.c.

#define DEFAULT_MAX_CALL_BITRATE   (384)

Max bitrate for video

Definition at line 514 of file chan_sip.c.

#define DEFAULT_MAX_EXPIRY   3600

Definition at line 173 of file chan_sip.c.

#define DEFAULT_MAX_FORWARDS   "70"

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

#define DEFAULT_MIN_EXPIRY   60

Definition at line 172 of file chan_sip.c.

#define DEFAULT_MOHINTERPRET   "default"

Definition at line 495 of file chan_sip.c.

#define DEFAULT_MOHSUGGEST   ""

Definition at line 496 of file chan_sip.c.

#define DEFAULT_MWITIME   10

Definition at line 500 of file chan_sip.c.

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

Definition at line 499 of file chan_sip.c.

#define DEFAULT_NOTIFYRINGING   TRUE

Definition at line 509 of file chan_sip.c.

#define DEFAULT_PEDANTIC   FALSE

Definition at line 510 of file chan_sip.c.

#define DEFAULT_QUALIFY   FALSE

Definition at line 512 of file chan_sip.c.

#define DEFAULT_REALM   "asterisk"

Definition at line 508 of file chan_sip.c.

#define DEFAULT_REGISTRATION_TIMEOUT   20

Definition at line 174 of file chan_sip.c.

#define DEFAULT_RETRANS   1000

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

Definition at line 205 of file chan_sip.c.

#define DEFAULT_SRVLOOKUP   TRUE

Recommended setting is ON

Definition at line 502 of file chan_sip.c.

#define DEFAULT_T1MIN   100

100 MS for minimal roundtrip time

Definition at line 513 of file chan_sip.c.

#define DEFAULT_TOS_AUDIO   0

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

Definition at line 505 of file chan_sip.c.

#define DEFAULT_TOS_SIP   0

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

Definition at line 504 of file chan_sip.c.

#define DEFAULT_TOS_VIDEO   0

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

Definition at line 506 of file chan_sip.c.

#define DEFAULT_TRANS_TIMEOUT   -1

Definition at line 210 of file chan_sip.c.

Referenced by __sip_autodestruct(), cb_extensionstate(), check_auth(), check_pendings(), handle_invite_replaces(), handle_request(), handle_request_bye(), handle_request_cancel(), handle_request_info(), handle_request_invite(), handle_request_notify(), handle_request_options(), handle_request_register(), handle_response_invite(), handle_response_register(), receive_message(), sip_hangup(), sip_notify(), and sip_send_mwi_to_peer().

#define DEFAULT_USERAGENT   "Asterisk PBX"

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

Definition at line 516 of file chan_sip.c.

#define DEFAULT_VMEXTEN   "asterisk"

Definition at line 497 of file chan_sip.c.

#define EXPIRY_GUARD_LIMIT   30

Below here, we use EXPIRY_GUARD_PCT instead of EXPIRY_GUARD_SECS

Definition at line 180 of file chan_sip.c.

Referenced by handle_response_register().

#define EXPIRY_GUARD_MIN   500

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

Definition at line 182 of file chan_sip.c.

Referenced by handle_response_register().

#define EXPIRY_GUARD_PCT   0.20

Percentage of expires timeout to use when below EXPIRY_GUARD_LIMIT

Definition at line 186 of file chan_sip.c.

Referenced by handle_response_register().

#define EXPIRY_GUARD_SECS   15

How long before expiry do we reregister

Definition at line 179 of file chan_sip.c.

Referenced by handle_response_register().

#define FALSE   0

Definition at line 153 of file chan_sip.c.

#define FLAG_FATAL   (1 << 1)

Definition at line 1032 of file chan_sip.c.

Referenced by __sip_reliable_xmit(), and retrans_pkt().

#define FLAG_RESPONSE   (1 << 0)

Definition at line 1031 of file chan_sip.c.

Referenced by __sip_ack(), __sip_pretend_ack(), __sip_reliable_xmit(), __sip_semi_ack(), handle_request(), and retrans_pkt().

#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 FORMAT3H   "%-15.15s %-10.10s %-11.11s %-15.15s %-13.13s %-15.15s %-10.10s %-6s\n"

Referenced by __sip_show_channels().

#define FORMAT3L   "%-15.15s %-10.10s %-11.11s %-15.15s %-13.13s %-15.15s %-10.10s %6d\n"

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

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

#define IPTOS_MINCOST   0x02

Definition at line 166 of file chan_sip.c.

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

Definition at line 196 of file chan_sip.c.

#define MAX_AUTHTRIES   3

Try authentication three times, then fail

Definition at line 211 of file chan_sip.c.

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

#define MAX_HISTORY_ENTRIES   50

Max entires in the history list for a sip_pvt

Definition at line 1029 of file chan_sip.c.

Referenced by append_history_va().

#define MAX_RETRANS   6

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

Definition at line 206 of file chan_sip.c.

#define NO_RTP   0

Definition at line 235 of file chan_sip.c.

#define NOT_SUPPORTED   0

Definition at line 408 of file chan_sip.c.

#define RTP   1

Definition at line 234 of file chan_sip.c.

#define SDP_MAX_RTPMAP_CODECS   32

Maximum number of codecs allowed in received SDP

Definition at line 217 of file chan_sip.c.

Referenced by process_sdp().

#define SDP_SAMPLE_RATE (  )     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 6532 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 __sip_autodestruct(), 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(), 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)

DTMF Support: four settings, uses two bits

Definition at line 732 of file chan_sip.c.

Referenced by _sip_show_peer(), check_user_full(), create_addr_from_peer(), handle_common_options(), handle_request_invite(), process_sdp(), sip_alloc(), sip_dtmfmode(), sip_new(), sip_rtp_read(), sip_senddigit_begin(), sip_senddigit_end(), sip_show_channel(), and sip_show_settings().

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

DTMF Support: RTP DTMF - "rfc2833"

Definition at line 733 of file chan_sip.c.

Referenced by check_user_full(), create_addr_from_peer(), dtmfmode2str(), handle_common_options(), handle_request_invite(), process_sdp(), sip_alloc(), sip_dtmfmode(), sip_rtp_read(), sip_senddigit_begin(), and sip_senddigit_end().

#define SIP_FLAGS_TO_COPY

Value:

Definition at line 762 of file chan_sip.c.

Referenced by build_user(), check_user_full(), create_addr_from_peer(), set_peer_defaults(), sip_alloc(), and sip_poke_peer().

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

Got a refer?

Definition at line 723 of file chan_sip.c.

Referenced by handle_request_refer(), local_attended_transfer(), sip_handle_t38_reinvite(), sip_read(), sip_set_rtp_peer(), and sip_set_udptl_peer().

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

#define SIP_MAX_HEADERS   64

Max amount of SIP headers to read

Definition at line 213 of file chan_sip.c.

Referenced by add_header(), and parse_request().

#define SIP_MAX_LINES   64

Max amount of lines in SIP attachment (like SDP)

Definition at line 214 of file chan_sip.c.

Referenced by add_line(), and parse_request().

#define SIP_MAX_PACKET   4096

Also from RFC 3261 (2543), should sub headers tho

Definition at line 215 of file chan_sip.c.

#define SIP_NAT   (3 << 18)

four settings, uses two bits

Definition at line 738 of file chan_sip.c.

Referenced by _sip_show_peer(), build_via(), copy_via_headers(), create_addr_from_peer(), handle_common_options(), process_sdp(), register_verify(), sip_alloc(), sip_nat_mode(), sip_real_dst(), sip_show_channel(), sip_show_settings(), sip_show_users(), and transmit_response_using_temp().

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

#define SIP_NAT_ROUTE   (2 << 18)

NAT Only ROUTE

Definition at line 741 of file chan_sip.c.

Referenced by _sip_show_peers(), check_user_full(), check_via(), create_addr_from_peer(), handle_common_options(), nat2str(), parse_register_contact(), send_request(), set_address_from_contact(), sip_alloc(), sip_nat_mode(), sip_real_dst(), and transmit_response_using_temp().

#define SIP_NEEDDESTROY   (1 << 1)

if we need to be destroyed by the monitor thread

Definition at line 717 of file chan_sip.c.

Referenced by __sip_show_channels(), do_monitor(), handle_request(), handle_request_refer(), handle_request_subscribe(), handle_response(), handle_response_invite(), handle_response_peerpoke(), handle_response_refer(), handle_response_register(), retrans_pkt(), sip_hangup(), sip_reg_timeout(), and sip_show_channel().

#define SIP_NEEDREINVITE   (1 << 5)

Do we need to send another reinvite?

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

Suppress recording request/response history

Definition at line 756 of file chan_sip.c.

Referenced by append_history_full(), do_register_auth(), handle_request_bye(), handle_request_invite(), send_request(), send_response(), sip_alloc(), sip_hangup(), sip_new(), sip_reregister(), sip_scheddestroy(), sip_set_rtp_peer(), sipsock_read(), transmit_register(), transmit_reinvite_with_sdp(), and transmit_response_using_temp().

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

#define SIP_OPT_EARLY_SESSION   (1 << 3)

Definition at line 413 of file chan_sip.c.

#define SIP_OPT_EVENTLIST   (1 << 11)

Definition at line 421 of file chan_sip.c.

#define SIP_OPT_GRUU   (1 << 12)

Definition at line 422 of file chan_sip.c.

#define SIP_OPT_HISTINFO   (1 << 15)

Definition at line 425 of file chan_sip.c.

#define SIP_OPT_JOIN   (1 << 4)

Definition at line 414 of file chan_sip.c.

#define SIP_OPT_NOREFERSUB   (1 << 14)

Definition at line 424 of file chan_sip.c.

#define SIP_OPT_PATH   (1 << 5)

Definition at line 415 of file chan_sip.c.

#define SIP_OPT_PRECONDITION   (1 << 7)

Definition at line 417 of file chan_sip.c.

#define SIP_OPT_PREF   (1 << 6)

Definition at line 416 of file chan_sip.c.

#define SIP_OPT_PRIVACY   (1 << 8)

Definition at line 418 of file chan_sip.c.

#define SIP_OPT_REPLACES   (1 << 0)

Definition at line 410 of file chan_sip.c.

Referenced by handle_request_invite().

#define SIP_OPT_RESPRIORITY   (1 << 16)

Definition at line 426 of file chan_sip.c.

#define SIP_OPT_SDP_ANAT   (1 << 9)

Definition at line 419 of file chan_sip.c.

#define SIP_OPT_SEC_AGREE   (1 << 10)

Definition at line 420 of file chan_sip.c.

#define SIP_OPT_TARGET_DIALOG   (1 << 13)

Definition at line 423 of file chan_sip.c.

#define SIP_OPT_TIMER   (1 << 2)

Definition at line 412 of file chan_sip.c.

#define SIP_OUTGOING   (1 << 13)

Direction of the last transaction in this dialog

Definition at line 729 of file chan_sip.c.

Referenced by handle_request_bye(), handle_request_invite(), handle_request_refer(), handle_response(), handle_response_invite(), reqprep(), respprep(), sip_call(), sip_hangup(), sip_indicate(), sip_poke_peer(), sip_send_mwi_to_peer(), sip_show_channel(), sip_write(), transmit_refer(), transmit_register(), transmit_reinvite_with_sdp(), transmit_reinvite_with_t38_sdp(), and transmit_response_with_sdp().

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

Call states

Definition at line 791 of file chan_sip.c.

Referenced by __sip_destroy(), __sip_show_channels(), add_sdp(), change_hold_state(), handle_request_cancel(), handle_request_invite(), process_sdp(), sip_hangup(), and update_call_counter().

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

#define SIP_PAGE2_DEBUG_CONSOLE   (1 << 12)

Definition at line 779 of file chan_sip.c.

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

#define SIP_PAGE2_DIALOG_ESTABLISHED   (1 << 29)

29: Has a dialog been established?

Definition at line 799 of file chan_sip.c.

Referenced by find_call(), handle_request_bye(), handle_request_invite(), handle_request_subscribe(), handle_response(), handle_response_invite(), and sip_answer().

#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

Value:

Definition at line 803 of file chan_sip.c.

Referenced by build_user(), check_user_full(), create_addr_from_peer(), set_peer_defaults(), sip_alloc(), and sip_poke_peer().

#define SIP_PAGE2_IGNOREREGEXPIRE   (1 << 10)

Definition at line 776 of file chan_sip.c.

Referenced by build_peer(), destroy_association(), 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 get_sip_pvt_byid_locked(), sip_request_call(), and update_call_counter().

#define SIP_PAGE2_RFC2833_COMPENSATE   (1 << 25)

25: ????

Definition at line 795 of file chan_sip.c.

Referenced by create_addr_from_peer(), handle_common_options(), handle_request_invite(), process_sdp(), sip_alloc(), and sip_show_settings().

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

#define SIP_PAGE2_RTCACHEFRIENDS   (1 << 0)

Definition at line 769 of file chan_sip.c.

Referenced by build_peer(), complete_sip_prune_realtime_peer(), complete_sip_prune_realtime_user(), parse_register_contact(), sip_prune_realtime(), sip_show_settings(), update_call_counter(), and update_peer().

#define SIP_PAGE2_RTSAVE_SYSNAME   (1 << 5)

Definition at line 773 of file chan_sip.c.

Referenced by realtime_update_peer(), and sip_show_settings().

#define SIP_PAGE2_RTUPDATE   (1 << 1)

Definition at line 770 of file chan_sip.c.

Referenced by 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_TCP   (1 << 30)

30: Should we use TCP with this peer

Definition at line 800 of file chan_sip.c.

Referenced by __sip_xmit(), _sip_show_peer(), build_via(), create_addr_from_peer(), parse_register_contact(), sip_poke_peer(), and sipsock_read().

#define SIP_PAGE2_TCP_CONNECTED   (1 << 31)

31: Is this TCP peer connected

Definition at line 801 of file chan_sip.c.

Referenced by __sip_xmit(), create_addr_from_peer(), expire_register(), parse_register_contact(), and sip_poke_peer().

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

Definition at line 782 of file chan_sip.c.

Referenced by _sip_show_peer(), _sip_show_peers(), check_user_full(), create_addr_from_peer(), handle_common_options(), sip_alloc(), and sip_show_settings().

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

Debug this packet

Definition at line 808 of file chan_sip.c.

Referenced by handle_request(), handle_request_message(), handle_request_refer(), handle_request_register(), handle_request_subscribe(), handle_response(), initialize_initreq(), and sipsock_read().

#define SIP_PKT_IGNORE   (1 << 2)

This is a re-transmit, ignore it

Definition at line 810 of file chan_sip.c.

Referenced by check_auth(), check_user_full(), handle_request(), handle_request_bye(), handle_request_invite(), handle_request_message(), handle_request_refer(), handle_request_subscribe(), handle_response(), handle_response_invite(), and register_verify().

#define SIP_PKT_IGNORE_REQ   (1 << 4)

Req ignore - ???

Definition at line 812 of file chan_sip.c.

Referenced by handle_request().

#define SIP_PKT_IGNORE_RESP   (1 << 3)

Resp ignore - ???

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

Flag for realtime users

Definition at line 727 of file chan_sip.c.

Referenced by _sip_show_peer(), _sip_show_peers(), build_peer(), parse_register_contact(), sip_destroy_peer(), sip_destroy_user(), update_call_counter(), and update_peer().

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

#define SIPBUFSIZE   512

Definition at line 160 of file chan_sip.c.

Referenced by __sip_show_channels(), add_route(), add_sdp(), extract_uri(), handle_request_refer(), initreqprep(), parse_moved_contact(), parse_ok_contact(), parse_register_contact(), process_sdp(), respprep(), sip_call(), sip_new(), sip_show_channel(), sip_show_settings(), transmit_invite(), and transmit_notify_with_sipfrag().

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

Definition at line 840 of file chan_sip.c.

Referenced by __sip_ack(), __sip_reliable_xmit(), __sip_semi_ack(), add_sip_domain(), build_reply_digest(), check_auth(), handle_request_info(), handle_request_invite(), handle_request_notify(), handle_request_refer(), handle_request_subscribe(), handle_response(), handle_response_register(), local_attended_transfer(), parse_request(), parse_sip_options(), reqprep(), retrans_pkt(), sip_addheader(), sip_call(), sip_debug_test_addr(), sip_debug_test_pvt(), sip_dump_history(), sip_hangup(), sip_poke_peer(), sip_reregister(), transmit_invite(), transmit_refer(), transmit_register(), transmit_reinvite_with_sdp(), transmit_reinvite_with_t38_sdp(), and update_call_counter().

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

Definition at line 841 of file chan_sip.c.

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

Definition at line 842 of file chan_sip.c.

Referenced by sip_do_debug(), and sip_do_debug_deprecated().

#define STANDARD_SIP_PORT   5060

Standard SIP port from RFC 3261. DO NOT CHANGE THIS.

Definition at line 481 of file chan_sip.c.

Referenced by __set_address_from_contact(), build_contact(), build_peer(), check_via(), create_addr(), initreqprep(), parse_register_contact(), set_destination(), set_peer_defaults(), sip_show_registry(), and transmit_register().

#define SUPPORTED   1

Define SIP option tags, used in Require: and Supported: headers We need to be aware of these properties in the phones to use the replace: header. We should not do that without knowing that the other end supports it... This is nothing we can configure, we learn by the dialog Supported: header on the REGISTER (peer) or the INVITE (other devices) We are not using many of these today, but will in the future. This is documented in RFC 3261

Definition at line 407 of file chan_sip.c.

#define SUPPORTED_EXTENSIONS   "replaces"

SIP Extensions we support.

Definition at line 478 of file chan_sip.c.

Referenced by respprep(), transmit_invite(), transmit_notify_with_sipfrag(), transmit_refer(), transmit_reinvite_with_sdp(), and transmit_reinvite_with_t38_sdp().

#define T38FAX_FILL_BIT_REMOVAL   (1 << 0)

Default: 0 (unset)

Definition at line 815 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 834 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 835 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 830 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 831 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 832 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 833 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 820 of file chan_sip.c.

Referenced by add_t38_sdp(), and process_sdp().

#define T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF   (0 << 3)

Definition at line 819 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 817 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 816 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 823 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 822 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 824 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 826 of file chan_sip.c.

Referenced by add_t38_sdp().

#define T38FAX_VERSION_0   (0 << 6)

Version 0

Definition at line 827 of file chan_sip.c.

Referenced by add_t38_sdp(), and process_sdp().

#define T38FAX_VERSION_1   (1 << 6)

Version 1

Definition at line 828 of file chan_sip.c.

Referenced by add_t38_sdp(), and process_sdp().

#define TRUE   1

Definition at line 157 of file chan_sip.c.

#define UNLINK ( element,
head,
prev   ) 

--- some list management macros.

Definition at line 1616 of file chan_sip.c.

Referenced by __sip_ack(), and __sip_destroy().

#define VIDEO_CODEC_MASK   0x1fc0000

Video codecs from H.261 thru AST_FORMAT_MAX_VIDEO

Definition at line 164 of file chan_sip.c.

#define XMIT_ERROR   -2

Definition at line 162 of file chan_sip.c.

Referenced by __sip_reliable_xmit(), __sip_xmit(), handle_response_invite(), retrans_pkt(), sip_call(), and sip_poke_peer().


Enumeration Type Documentation

enum check_auth_result

Authentication result from check_auth* functions.

Enumerator:
AUTH_SUCCESSFUL 
AUTH_CHALLENGE_SENT 
AUTH_SECRET_FAILED 
AUTH_USERNAME_MISMATCH 
AUTH_NOT_FOUND 
AUTH_FAKE_AUTH 
AUTH_UNKNOWN_DOMAIN 
AUTH_PEER_NOT_DYNAMIC 
AUTH_ACL_FAILED 

Definition at line 343 of file chan_sip.c.

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

enum domain_mode

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

enum invitestates

States for the INVITE transaction, not the dialog.

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

Definition at line 254 of file chan_sip.c.

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

enum parse_register_result

Enumerator:
PARSE_REGISTER_FAILED 
PARSE_REGISTER_UPDATE 
PARSE_REGISTER_QUERY 

Definition at line 281 of file chan_sip.c.

enum referstatus

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

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

enum sip_auth_type

Authentication types - proxy or www authentication.

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

Definition at line 337 of file chan_sip.c.

00337                    {
00338    PROXY_AUTH,
00339    WWW_AUTH,
00340 };

enum sip_result

Enumerator:
AST_SUCCESS 
AST_FAILURE 

Definition at line 246 of file chan_sip.c.

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

enum sipmethod

SIP Request methods known by Asterisk.

Enumerator:
SIP_UNKNOWN 
SIP_RESPONSE 
SIP_REGISTER 
SIP_OPTIONS 
SIP_NOTIFY 
SIP_INVITE 
SIP_ACK 
SIP_PRACK 
SIP_BYE 
SIP_REFER 
SIP_SUBSCRIBE 
SIP_MESSAGE 
SIP_UPDATE 
SIP_INFO 
SIP_CANCEL 
SIP_PUBLISH 
SIP_PING 

Definition at line 312 of file chan_sip.c.

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

enum sipregistrystate

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

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

Definition at line 356 of file chan_sip.c.

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

enum subscriptiontype

Enumerator:
NONE 
XPIDF_XML 
DIALOG_INFO_XML 
CPIM_PIDF_XML 
PIDF_XML 
MWI_NOTIFICATION 

Definition at line 287 of file chan_sip.c.

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

enum t38state

T38 States for a call.

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

Definition at line 845 of file chan_sip.c.

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

enum transfermodes

Authorization scheme for call transfers.

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

Definition at line 240 of file chan_sip.c.

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

enum xmittype

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

Definition at line 274 of file chan_sip.c.

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


Function Documentation

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

Definition at line 4325 of file chan_sip.c.

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

04326 {
04327    int pass;
04328 
04329    /*
04330     * Technically you can place arbitrary whitespace both before and after the ':' in
04331     * a header, although RFC3261 clearly says you shouldn't before, and place just
04332     * one afterwards.  If you shouldn't do it, what absolute idiot decided it was 
04333     * a good idea to say you can do it, and if you can do it, why in the hell would.
04334     * you say you shouldn't.
04335     * Anyways, pedanticsipchecking controls whether we allow spaces before ':',
04336     * and we always allow spaces after that for compatibility.
04337     */
04338    for (pass = 0; name && pass < 2;pass++) {
04339       int x, len = strlen(name);
04340       for (x=*start; x<req->headers; x++) {
04341          if (!strncasecmp(req->header[x], name, len)) {
04342             char *r = req->header[x] + len;  /* skip name */
04343             if (pedanticsipchecking)
04344                r = ast_skip_blanks(r);
04345 
04346             if (*r == ':') {
04347                *start = x+1;
04348                return ast_skip_blanks(r+1);
04349             }
04350          }
04351       }
04352       if (pass == 0) /* Try aliases */
04353          name = find_alias(name, NULL);
04354    }
04355 
04356    /* Don't return NULL, so get_header is always a valid pointer */
04357    return "";
04358 }

static int __set_address_from_contact ( const char *  fullcontact,
struct sockaddr_in *  sin 
) [static]

Definition at line 8154 of file chan_sip.c.

References ahp, ast_gethostbyname(), ast_log(), hp, LOG_NOTICE, STANDARD_SIP_PORT, and strsep().

Referenced by build_peer(), and set_address_from_contact().

08155 {
08156    struct hostent *hp;
08157    struct ast_hostent ahp;
08158    int port;
08159    char *c, *host, *pt;
08160    char contact_buf[256];
08161    char *contact;
08162 
08163    /* Work on a copy */
08164    ast_copy_string(contact_buf, fullcontact, sizeof(contact_buf));
08165    contact = contact_buf;
08166 
08167    /* Make sure it's a SIP URL */
08168    if (strncasecmp(contact, "sip:", 4)) {
08169       ast_log(LOG_NOTICE, "'%s' is not a valid SIP contact (missing sip:) trying to use anyway\n", contact);
08170    } else
08171       contact += 4;
08172 
08173    /* Ditch arguments */
08174    /* XXX this code is replicated also shortly below */
08175 
08176    /* Grab host */
08177    host = strchr(contact, '@');
08178    if (!host) {   /* No username part */
08179       host = contact;
08180       c = NULL;
08181    } else {
08182       *host++ = '\0';
08183    }
08184    pt = strchr(host, ':');
08185    if (pt) {
08186       *pt++ = '\0';
08187       port = atoi(pt);
08188    } else
08189       port = STANDARD_SIP_PORT;
08190 
08191    contact = strsep(&contact, ";"); /* trim ; and beyond in username part */
08192    host = strsep(&host, ";");    /* trim ; and beyond in host/domain part */
08193 
08194    /* XXX This could block for a long time XXX */
08195    /* We should only do this if it's a name, not an IP */
08196    hp = ast_gethostbyname(host, &ahp);
08197    if (!hp)  {
08198       ast_log(LOG_WARNING, "Invalid host name in Contact: (can't resolve in DNS) : '%s'\n", host);
08199       return -1;
08200    }
08201    sin->sin_family = AF_INET;
08202    memcpy(&sin->sin_addr, hp->h_addr, sizeof(sin->sin_addr));
08203    sin->sin_port = htons(port);
08204 
08205    return 0;
08206 }

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 2169 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, sched, sip_pkt::seqno, sip_methods, sipdebug, cfsip_methods::text, TRUE, and UNLINK.

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

02170 {
02171    struct sip_pkt *cur, *prev = NULL;
02172 
02173    /* Just in case... */
02174    char *msg;
02175    int res = FALSE;
02176 
02177    msg = sip_methods[sipmethod].text;
02178 
02179    for (cur = p->packets; cur; prev = cur, cur = cur->next) {
02180       if ((cur->seqno == seqno) && ((ast_test_flag(cur, FLAG_RESPONSE)) == resp) &&
02181          ((ast_test_flag(cur, FLAG_RESPONSE)) || 
02182           (!strncasecmp(msg, cur->data, strlen(msg)) && (cur->data[strlen(msg)] < 33)))) {
02183          if (!resp && (seqno == p->pendinginvite)) {
02184             if (option_debug)
02185                ast_log(LOG_DEBUG, "Acked pending invite %d\n", p->pendinginvite);
02186             p->pendinginvite = 0;
02187          }
02188          /* this is our baby */
02189          res = TRUE;
02190          UNLINK(cur, p->packets, prev);
02191          if (cur->retransid > -1) {
02192             if (sipdebug && option_debug > 3)
02193                ast_log(LOG_DEBUG, "** SIP TIMER: Cancelling retransmit of packet (reply received) Retransid #%d\n", cur->retransid);
02194          }
02195          /* This odd section is designed to thwart a 
02196           * race condition in the packet scheduler. There are
02197           * two conditions under which deleting the packet from the
02198           * scheduler can fail.
02199           *
02200           * 1. The packet has been removed from the scheduler because retransmission
02201           * is being attempted. The problem is that if the packet is currently attempting
02202           * retransmission and we are at this point in the code, then that MUST mean
02203           * that retrans_pkt is waiting on p's lock. Therefore we will relinquish the
02204           * lock temporarily to allow retransmission.
02205           *
02206           * 2. The packet has reached its maximum number of retransmissions and has
02207           * been permanently removed from the packet scheduler. If this is the case, then
02208           * the packet's retransid will be set to -1. The atomicity of the setting and checking
02209           * of the retransid to -1 is ensured since in both cases p's lock is held.
02210           */
02211          while (cur->retransid > -1 && ast_sched_del(sched, cur->retransid)) {
02212             DEADLOCK_AVOIDANCE(&p->lock);
02213          }
02214          free(cur);
02215          break;
02216       }
02217    }
02218    if (option_debug)
02219       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");
02220 }

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

Kill a SIP dialog (called by scheduler).

Definition at line 2092 of file chan_sip.c.

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

Referenced by sip_scheddestroy().

02093 {
02094    struct sip_pvt *p = (struct sip_pvt *)data;
02095 
02096    /* If this is a subscription, tell the phone that we got a timeout */
02097    if (p->subscribed) {
02098       transmit_state_notify(p, AST_EXTENSION_DEACTIVATED, 1, TRUE);  /* Send last notification */
02099       p->subscribed = NONE;
02100       append_history(p, "Subscribestatus", "timeout");
02101       if (option_debug > 2)
02102          ast_log(LOG_DEBUG, "Re-scheduled destruction of SIP subsription %s\n", p->callid ? p->callid : "<unknown>");
02103       return 10000;  /* Reschedule this destruction so that we know that it's gone */
02104    }
02105 
02106    /* If there are packets still waiting for delivery, delay the destruction */
02107    if (p->packets) {
02108       if (option_debug > 2)
02109          ast_log(LOG_DEBUG, "Re-scheduled destruction of SIP call %s\n", p->callid ? p->callid : "<unknown>");
02110       append_history(p, "ReliableXmit", "timeout");
02111       return 10000;
02112    }
02113 
02114    /* If we're destroying a subscription, dereference peer object too */
02115    if (p->subscribed == MWI_NOTIFICATION && p->relatedpeer)
02116       ASTOBJ_UNREF(p->relatedpeer,sip_destroy_peer);
02117 
02118    /* Reset schedule ID */
02119    p->autokillid = -1;
02120 
02121    if (option_debug)
02122       ast_log(LOG_DEBUG, "Auto destroying SIP dialog '%s'\n", p->callid);
02123    append_history(p, "AutoDestroy", "%s", p->callid);
02124    if (p->owner) {
02125       ast_log(LOG_WARNING, "Autodestruct on dialog '%s' with owner in place (Method: %s)\n", p->callid, sip_methods[p->method].text);
02126       ast_queue_hangup(p->owner);
02127    } else if (p->refer && !ast_test_flag(&p->flags[0], SIP_ALREADYGONE)) {
02128       if (option_debug > 2)
02129          ast_log(LOG_DEBUG, "Finally hanging up channel after transfer: %s\n", p->callid);
02130       transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, 1);
02131       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
02132    } else
02133       sip_destroy(p);
02134    return 0;
02135 }

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

Execute destruction of SIP dialog structure, release memory.

Definition at line 3101 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_rtp_destroy(), ast_rtp_get_bridged(), AST_SCHED_DEL, AST_SOFTHANGUP_DEV, ast_test_flag, ast_udptl_destroy(), ast_verbose(), ASTOBJ_UNREF, DEC_CALL_LIMIT, sip_pvt::flags, free, free_old_route(), iflist, LOG_DEBUG, sip_pvt::method, sip_peer::mwipvt, sip_pvt::next, option_debug, sip_pvt::owner, sip_pvt::relatedpeer, sip_pkt::retransid, sip_pvt::rtp, sched, sip_debug_test_pvt(), sip_destroy_peer(), sip_dump_history(), SIP_INC_COUNT, sip_methods, SIP_PAGE2_CALL_ONHOLD, sip_registry_destroy(), ast_channel::tech_pvt, UNLINK, update_call_counter(), and sip_pvt::vrtp.

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

03102 {
03103    struct sip_pvt *cur, *prev = NULL;
03104    struct sip_pkt *cp;
03105 
03106    /* We absolutely cannot destroy the rtp struct while a bridge is active or we WILL crash */
03107    if (p->rtp && ast_rtp_get_bridged(p->rtp)) {
03108       ast_verbose("Bridge still active.  Delaying destroy of SIP dialog '%s' Method: %s\n", p->callid, sip_methods[p->method].text);
03109       return -1;
03110    }
03111 
03112    if (p->vrtp && ast_rtp_get_bridged(p->vrtp)) {
03113       ast_verbose("Bridge still active.  Delaying destroy of SIP dialog '%s' Method: %s\n", p->callid, sip_methods[p->method].text);
03114       return -1;
03115    }
03116 
03117    if (sip_debug_test_pvt(p) || option_debug > 2)
03118       ast_verbose("Really destroying SIP dialog '%s' Method: %s\n", p->callid, sip_methods[p->method].text);
03119 
03120    if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) {
03121       update_call_counter(p, DEC_CALL_LIMIT);
03122       if (option_debug > 1)
03123          ast_log(LOG_DEBUG, "This call did not properly clean up call limits. Call ID %s\n", p->callid);
03124    }
03125 
03126    /* Unlink us from the owner if we have one */
03127    if (p->owner) {
03128       if (lockowner)
03129          ast_channel_lock(p->owner);
03130       if (option_debug)
03131          ast_log(LOG_DEBUG, "Detaching from %s\n", p->owner->name);
03132       p->owner->tech_pvt = NULL;
03133       /* Make sure that the channel knows its backend is going away */
03134       p->owner->_softhangup |= AST_SOFTHANGUP_DEV;
03135       if (lockowner)
03136          ast_channel_unlock(p->owner);
03137       /* Give the channel a chance to react before deallocation */
03138       usleep(1);
03139    }
03140 
03141    /* Remove link from peer to subscription of MWI */
03142    if (p->relatedpeer) {
03143       if (p->relatedpeer->mwipvt == p) {
03144          p->relatedpeer->mwipvt = NULL;
03145       }
03146       ASTOBJ_UNREF(p->relatedpeer, sip_destroy_peer);
03147    }
03148 
03149    if (dumphistory)
03150       sip_dump_history(p);
03151 
03152    if (p->options)
03153       free(p->options);
03154 
03155    if (p->stateid > -1)
03156       ast_extension_state_del(p->stateid, NULL);
03157    AST_SCHED_DEL(sched, p->initid);
03158    AST_SCHED_DEL(sched, p->waitid);
03159    AST_SCHED_DEL(sched, p->autokillid);
03160 
03161    if (p->rtp) {
03162       ast_rtp_destroy(p->rtp);
03163    }
03164    if (p->vrtp) {
03165       ast_rtp_destroy(p->vrtp);
03166    }
03167    if (p->udptl)
03168       ast_udptl_destroy(p->udptl);
03169    if (p->refer)
03170       free(p->refer);
03171    if (p->route) {
03172       free_old_route(p->route);
03173       p->route = NULL;
03174    }
03175    if (p->registry) {
03176       if (p->registry->call == p)
03177          p->registry->call = NULL;
03178       ASTOBJ_UNREF(p->registry, sip_registry_destroy);
03179    }
03180 
03181    /* Clear history */
03182    if (p->history) {
03183       struct sip_history *hist;
03184       while ( (hist = AST_LIST_REMOVE_HEAD(p->history, list)) ) {
03185          free(hist);
03186          p->history_entries--;
03187       }
03188       free(p->history);
03189       p->history = NULL;
03190    }
03191 
03192    for (prev = NULL, cur = iflist; cur; prev = cur, cur = cur->next) {
03193       if (cur == p) {
03194          UNLINK(cur, iflist, prev);
03195          break;
03196       }
03197    }
03198    if (!cur) {
03199       ast_log(LOG_WARNING, "Trying to destroy \"%s\", not found in dialog list?!?! \n", p->callid);
03200       return 0;
03201    } 
03202 
03203    /* remove all current packets in this dialog */
03204    while((cp = p->packets)) {
03205       p->packets = p->packets->next;
03206       AST_SCHED_DEL(sched, cp->retransid);
03207       free(cp);
03208    }
03209    if (p->chanvars) {
03210       ast_variables_destroy(p->chanvars);
03211       p->chanvars = NULL;
03212    }
03213    ast_mutex_destroy(&p->lock);
03214 
03215    ast_string_field_free_memory(p);
03216 
03217    free(p);
03218    return 0;
03219 }

static int __sip_do_register ( struct sip_registry r  )  [static]

Register with SIP proxy.

Definition at line 7587 of file chan_sip.c.

References SIP_REGISTER, and transmit_register().

Referenced by sip_reregister().

07588 {
07589    int res;
07590 
07591    res = transmit_register(r, SIP_REGISTER, NULL, NULL);
07592    return res;
07593 }

static void __sip_pretend_ack ( struct sip_pvt p  )  [static]

Pretend to ack all packets called with p locked.

Definition at line 2224 of file chan_sip.c.

References __sip_ack(), ast_log(), ast_test_flag, sip_pkt::data, find_sip_method(), FLAG_RESPONSE, LOG_WARNING, sip_pkt::method, sip_pvt::packets, sip_pkt::seqno, and sip_methods.

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

02225 {
02226    struct sip_pkt *cur = NULL;
02227 
02228    while (p->packets) {
02229       int method;
02230       if (cur == p->packets) {
02231          ast_log(LOG_WARNING, "Have a packet that doesn't want to give up! %s\n", sip_methods[cur->method].text);
02232          return;
02233       }
02234       cur = p->packets;
02235       method = (cur->method) ? cur->method : find_sip_method(cur->data);
02236       __sip_ack(p, cur->seqno, ast_test_flag(cur, FLAG_RESPONSE), method);
02237    }
02238 }

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 2045 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, DEFAULT_RETRANS, FLAG_FATAL, FLAG_RESPONSE, LOG_DEBUG, option_debug, sip_pkt::owner, sip_pvt::packets, sip_pvt::pendinginvite, retrans_pkt(), sched, SIP_INVITE, sipdebug, sip_pvt::timer_t1, and XMIT_ERROR.

Referenced by send_request(), and send_response().

02046 {
02047    struct sip_pkt *pkt;
02048    int siptimer_a = DEFAULT_RETRANS;
02049    int xmitres = 0;
02050 
02051    if (!(pkt = ast_calloc(1, sizeof(*pkt) + len + 1)))
02052       return AST_FAILURE;
02053    memcpy(pkt->data, data, len);
02054    pkt->method = sipmethod;
02055    pkt->packetlen = len;
02056    pkt->next = p->packets;
02057    pkt->owner = p;
02058    pkt->seqno = seqno;
02059    if (resp)
02060       ast_set_flag(pkt, FLAG_RESPONSE);
02061    pkt->data[len] = '\0';
02062    pkt->timer_t1 = p->timer_t1;  /* Set SIP timer T1 */
02063    pkt->retransid = -1;
02064    if (fatal)
02065       ast_set_flag(pkt, FLAG_FATAL);
02066    if (pkt->timer_t1)
02067       siptimer_a = pkt->timer_t1 * 2;
02068 
02069    if (option_debug > 3 && sipdebug)
02070       ast_log(LOG_DEBUG, "*** SIP TIMER: Initializing retransmit timer on packet: Id  #%d\n", pkt->retransid);
02071    pkt->retransid = -1;
02072    pkt->next = p->packets;
02073    p->packets = pkt;
02074    if (sipmethod == SIP_INVITE) {
02075       /* Note this is a pending invite */
02076       p->pendinginvite = seqno;
02077    }
02078 
02079    xmitres = __sip_xmit(pkt->owner, pkt->data, pkt->packetlen);   /* Send packet */
02080 
02081    if (xmitres == XMIT_ERROR) {  /* Serious network trouble, no need to try again */
02082       append_history(pkt->owner, "XmitErr", "%s", (ast_test_flag(pkt, FLAG_FATAL)) ? "(Critical)" : "(Non-critical)");
02083       return AST_FAILURE;
02084    } else {
02085       /* Schedule retransmission */
02086       pkt->retransid = ast_sched_add_variable(sched, siptimer_a, retrans_pkt, pkt, 1);
02087       return AST_SUCCESS;
02088    }
02089 }

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 2241 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, sched, sip_pkt::seqno, sip_methods, sipdebug, and cfsip_methods::text.

Referenced by handle_response().

02242 {
02243    struct sip_pkt *cur;
02244    int res = -1;
02245 
02246    for (cur = p->packets; cur; cur = cur->next) {
02247       if (cur->seqno == seqno && ast_test_flag(cur, FLAG_RESPONSE) == resp &&
02248          (ast_test_flag(cur, FLAG_RESPONSE) || method_match(sipmethod, cur->data))) {
02249          /* this is our baby */
02250          if (cur->retransid > -1) {
02251             if (option_debug > 3 && sipdebug)
02252                ast_log(LOG_DEBUG, "*** SIP TIMER: Cancelling retransmission #%d - %s (got response)\n", cur->retransid, sip_methods[sipmethod].text);
02253          }
02254          AST_SCHED_DEL(sched, cur->retransid);
02255          res = 0;
02256          break;
02257       }
02258    }
02259    if (option_debug)
02260       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");
02261    return res;
02262 }

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

SIP show channels CLI (main function).

Definition at line 10978 of file chan_sip.c.

References ast_cli(), ast_getformatname_multiple(), ast_inet_ntoa(), ast_mutex_lock(), ast_test_flag, sip_pvt::flags, FORMAT, FORMAT2, FORMAT3H, sip_pvt::icseq, iflist, sip_pvt::lastmsg, ast_channel::nativeformats, sip_pvt::next, NONE, sip_pvt::ocseq, sip_pvt::owner, sip_pvt::refer, referstatus2str(), RESULT_SHOWUSAGE, S_OR, sip_pvt::sa, SIP_NEEDDESTROY, SIP_PAGE2_CALL_ONHOLD, SIPBUFSIZE, sip_refer::status, and sip_pvt::subscribed.

Referenced by sip_show_channels(), and sip_show_subscriptions().

10979 {
10980 #define FORMAT3L "%-15.15s  %-10.10s  %-11.11s  %-15.15s  %-13.13s  %-15.15s %-10.10s %6d\n"
10981 #define FORMAT3H "%-15.15s  %-10.10s  %-11.11s  %-15.15s  %-13.13s  %-15.15s %-10.10s %-6s\n"
10982 #define FORMAT2  "%-15.15s  %-10.10s  %-11.11s  %-11.11s  %-15.15s  %-7.7s  %-15.15s\n"
10983 #define FORMAT   "%-15.15s  %-10.10s  %-11.11s  %5.5d/%5.5d  %-15.15s  %-3.3s %-3.3s  %-15.15s %-10.10s\n"
10984    struct sip_pvt *cur;
10985    int numchans = 0;
10986    char *referstatus = NULL;
10987 
10988    if (argc != 3)
10989       return RESULT_SHOWUSAGE;
10990    ast_mutex_lock(&iflock);
10991    cur = iflist;
10992    if (!subscriptions)
10993       ast_cli(fd, FORMAT2, "Peer", "User/ANR", "Call ID", "Seq (Tx/Rx)", "Format", "Hold", "Last Message");
10994    else 
10995       ast_cli(fd, FORMAT3H, "Peer", "User", "Call ID", "Extension", "Last state", "Type", "Mailbox", "Expiry");
10996    for (; cur; cur = cur->next) {
10997       referstatus = "";
10998       if (cur->refer) { /* SIP transfer in progress */
10999          referstatus = referstatus2str(cur->refer->status);
11000       }
11001       if (cur->subscribed == NONE && !subscriptions) {
11002          char formatbuf[SIPBUFSIZE/2];
11003          ast_cli(fd, FORMAT, ast_inet_ntoa(cur->sa.sin_addr), 
11004             S_OR(cur->username, S_OR(cur->cid_num, "(None)")),
11005             cur->callid, 
11006             cur->ocseq, cur->icseq,
11007             ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->owner ? cur->owner->nativeformats : 0),
11008             ast_test_flag(&cur->flags[1], SIP_PAGE2_CALL_ONHOLD) ? "Yes" : "No",
11009             ast_test_flag(&cur->flags[0], SIP_NEEDDESTROY) ? "(d)" : "",
11010             cur->lastmsg ,
11011             referstatus
11012          );
11013          numchans++;
11014       }
11015       if (cur->subscribed != NONE && subscriptions) {
11016          ast_cli(fd, FORMAT3L, ast_inet_ntoa(cur->sa.sin_addr),
11017             S_OR(cur->username, S_OR(cur->cid_num, "(None)")), 
11018                cur->callid,
11019             /* the 'complete' exten/context is hidden in the refer_to field for subscriptions */
11020             cur->subscribed == MWI_NOTIFICATION ? "--" : cur->subscribeuri,
11021             cur->subscribed == MWI_NOTIFICATION ? "<none>" : ast_extension_state2str(cur->laststate), 
11022             subscription_type2str(cur->subscribed),
11023             cur->subscribed == MWI_NOTIFICATION ? (cur->relatedpeer ? cur->relatedpeer->mailbox : "<none>") : "<none>",
11024             cur->expiry
11025 );
11026          numchans++;
11027       }
11028    }
11029    ast_mutex_unlock(&iflock);
11030    if (!subscriptions)
11031       ast_cli(fd, "%d active SIP channel%s\n", numchans, (numchans != 1) ? "s" : "");
11032    else
11033       ast_cli(fd, "%d active SIP subscription%s\n", numchans, (numchans != 1) ? "s" : "");
11034    return RESULT_SUCCESS;
11035 #undef FORMAT
11036 #undef FORMAT2
11037 #undef FORMAT3
11038 }

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

Transmit SIP message.

Definition at line 1783 of file chan_sip.c.

References ast_inet_ntoa(), ast_log(), ast_set_flag, ast_test_flag, errno, sip_pvt::flags, LOG_ERROR, LOG_WARNING, SIP_PAGE2_TCP, SIP_PAGE2_TCP_CONNECTED, sip_real_dst(), sipsock, sip_pvt::sockfd, and XMIT_ERROR.

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

01784 {
01785    int res;
01786    const struct sockaddr_in *dst = sip_real_dst(p);
01787    /* This is a  TCP connection*/
01788    if (ast_test_flag(&p->flags[1], SIP_PAGE2_TCP)) {
01789       if (!ast_test_flag(&p->flags[1], SIP_PAGE2_TCP_CONNECTED)) {
01790          if (connect(p->sockfd, (const struct sockaddr *)dst, sizeof(struct sockaddr_in)) == 0) {
01791             ast_set_flag(&p->flags[1], SIP_PAGE2_TCP_CONNECTED);
01792          } else if (errno == EISCONN) {
01793             ast_set_flag(&p->flags[1], SIP_PAGE2_TCP_CONNECTED);
01794          } else {
01795             ast_log(LOG_ERROR, "Connect Failed Sock: %i %s:%d %s\n",p->sockfd,ast_inet_ntoa(dst->sin_addr), ntohs(dst->sin_port), strerror(errno));
01796          }
01797       }
01798       res = write(p->sockfd, data, len);
01799    } else
01800       res = sendto(sipsock, data, len, 0, (const struct sockaddr *)dst, sizeof(struct sockaddr_in));
01801 
01802    if (res == -1) {
01803       switch (errno) {
01804       case EBADF:       /* Bad file descriptor - seems like this is generated when the host exist, but doesn't accept the UDP packet */
01805       case EHOSTUNREACH:   /* Host can't be reached */
01806       case ENETDOWN:       /* Inteface down */
01807       case ENETUNREACH: /* Network failure */
01808       case ECONNREFUSED:      /* ICMP port unreachable */ 
01809          res = XMIT_ERROR; /* Don't bother with trying to transmit again */
01810       }
01811    }
01812    if (res != len)
01813       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));
01814    return res;
01815 }

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

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

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

06127 {
06128    struct sip_request resp;
06129    int seqno = 0;
06130 
06131    if (reliable && (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1)) {
06132       ast_log(LOG_WARNING, "Unable to determine sequence number from '%s'\n", get_header(req, "CSeq"));
06133       return -1;
06134    }
06135    respprep(&resp, p, msg, req);
06136    add_header_contentLength(&resp, 0);
06137    /* If we are cancelling an incoming invite for some reason, add information
06138       about the reason why we are doing this in clear text */
06139    if (p->method == SIP_INVITE && msg[0] != '1' && p->owner && p->owner->hangupcause) {
06140       char buf[10];
06141 
06142       add_header(&resp, "X-Asterisk-HangupCause", ast_cause2str(p->owner->hangupcause));
06143       snprintf(buf, sizeof(buf), "%d", p->owner->hangupcause);
06144       add_header(&resp, "X-Asterisk-HangupCauseCode", buf);
06145    }
06146    return send_response(p, &resp, reliable, seqno);
06147 }

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 10535 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, 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, S_OR, sched, 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_TCP, 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().

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

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 10085 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, s, SIP_NAT_ROUTE, SIP_PAGE2_DYNAMIC, SIP_PAGE2_VIDEOSUPPORT, SIP_REALTIME, and TRUE.

Referenced by manager_sip_show_peers(), and sip_show_peers().

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

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

Definition at line 15187 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(), LOG_ERROR, parse(), sip_pvt::rtp, sip_tech, sip_tech_info, ast_channel::tech, ast_channel::tech_pvt, type, and sip_pvt::vrtp.

15188 {
15189    struct ast_rtp_quality qos;
15190    struct sip_pvt *p = chan->tech_pvt;
15191    char *all = "", *parse = ast_strdupa(preparse);
15192    AST_DECLARE_APP_ARGS(args,
15193       AST_APP_ARG(param);
15194       AST_APP_ARG(type);
15195       AST_APP_ARG(field);
15196    );
15197    AST_STANDARD_APP_ARGS(args, parse);
15198 
15199    /* Sanity check */
15200    if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) {
15201       ast_log(LOG_ERROR, "Cannot call %s on a non-SIP channel\n", funcname);
15202       return 0;
15203    }
15204 
15205    if (strcasecmp(args.param, "rtpqos"))
15206       return 0;
15207 
15208    /* Default arguments of audio,all */
15209    if (ast_strlen_zero(args.type))
15210       args.type = "audio";
15211    if (ast_strlen_zero(args.field))
15212       args.field = "all";
15213 
15214    memset(buf, 0, buflen);
15215    memset(&qos, 0, sizeof(qos));
15216 
15217    if (strcasecmp(args.type, "AUDIO") == 0) {
15218       all = ast_rtp_get_quality(p->rtp, &qos);
15219    } else if (strcasecmp(args.type, "VIDEO") == 0) {
15220       all = ast_rtp_get_quality(p->vrtp, &qos);
15221    }
15222 
15223    if (strcasecmp(args.field, "local_ssrc") == 0)
15224       snprintf(buf, buflen, "%u", qos.local_ssrc);
15225    else if (strcasecmp(args.field, "local_lostpackets") == 0)
15226       snprintf(buf, buflen, "%u", qos.local_lostpackets);
15227    else if (strcasecmp(args.field, "local_jitter") == 0)
15228       snprintf(buf, buflen, "%.0lf", qos.local_jitter * 1000.0);
15229    else if (strcasecmp(args.field, "local_count") == 0)
15230       snprintf(buf, buflen, "%u", qos.local_count);
15231    else if (strcasecmp(args.field, "remote_ssrc") == 0)
15232       snprintf(buf, buflen, "%u", qos.remote_ssrc);
15233    else if (strcasecmp(args.field, "remote_lostpackets") == 0)
15234       snprintf(buf, buflen, "%u", qos.remote_lostpackets);
15235    else if (strcasecmp(args.field, "remote_jitter") == 0)
15236       snprintf(buf, buflen, "%.0lf", qos.remote_jitter * 1000.0);
15237    else if (strcasecmp(args.field, "remote_count") == 0)
15238       snprintf(buf, buflen, "%u", qos.remote_count);
15239    else if (strcasecmp(args.field, "rtt") == 0)
15240       snprintf(buf, buflen, "%.0lf", qos.rtt * 1000.0);
15241    else if (strcasecmp(args.field, "all") == 0)
15242       ast_copy_string(buf, all, buflen);
15243    else {
15244       ast_log(LOG_WARNING, "Unrecognized argument '%s' to %s\n", preparse, funcname);
15245       return -1;
15246    }
15247    return 0;
15248 }

static void add_blank ( struct sip_request req  )  [static]

add a blank line if no body

Definition at line 2275 of file chan_sip.c.

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

Referenced by send_request(), and send_response().

02276 {
02277    if (!req->lines) {
02278       /* Add extra empty return. add_header() reserves 4 bytes so cannot be truncated */
02279       snprintf(req->data + req->len, sizeof(req->data) - req->len, "\r\n");
02280       req->len += strlen(req->data + req->len);
02281    }
02282 }

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 6331 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(), sip_pvt::flags, fmt, sip_pvt::rtp, and SIP_G726_NONSTANDARD.

Referenced by add_sdp().

06334 {
06335    int rtp_code;
06336    struct ast_format_list fmt;
06337 
06338 
06339    if (debug)
06340       ast_verbose("Adding codec 0x%x (%s) to SDP\n", codec, ast_getformatname(codec));
06341    if ((rtp_code = ast_rtp_lookup_code(p->rtp, 1, codec)) == -1)
06342       return;
06343 
06344    if (p->rtp) {
06345       struct ast_codec_pref *pref = ast_rtp_codec_getpref(p->rtp);
06346       fmt = ast_codec_pref_getsize(pref, codec);
06347    } 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 */
06348       return;
06349    ast_build_string(m_buf, m_size, " %d", rtp_code);
06350    ast_build_string(a_buf, a_size, "a=rtpmap:%d %s/%d\r\n", rtp_code,
06351           ast_rtp_lookup_mime_subtype(1, codec,
06352                        ast_test_flag(&p->flags[0], SIP_G726_NONSTANDARD) ? AST_RTP_OPT_G726_NONSTANDARD : 0),
06353           sample_rate);
06354    if (codec == AST_FORMAT_G729A) {
06355       /* Indicate that we don't support VAD (G.729 annex B) */
06356       ast_build_string(a_buf, a_size, "a=fmtp:%d annexb=no\r\n", rtp_code);
06357    } else if (codec == AST_FORMAT_G723_1) {
06358       /* Indicate that we don't support VAD (G.723.1 annex A) */
06359       ast_build_string(a_buf, a_size, "a=fmtp:%d annexa=no\r\n", rtp_code);
06360    } else if (codec == AST_FORMAT_ILBC) {
06361       /* Add information about us using only 20/30 ms packetization */
06362       ast_build_string(a_buf, a_size, "a=fmtp:%d mode=%d\r\n", rtp_code, fmt.cur_ms);
06363    }
06364 
06365    if (fmt.cur_ms && (fmt.cur_ms < *min_packet_size))
06366       *min_packet_size = fmt.cur_ms;
06367 
06368    /* Our first codec packetization processed cannot be less than zero */
06369    if ((*min_packet_size) == 0  && fmt.cur_ms)
06370       *min_packet_size = fmt.cur_ms;
06371 }

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

Add DTMF INFO tone to sip message.

Definition at line 6299 of file chan_sip.c.

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

Referenced by transmit_info_with_digit().

06300 {
06301    char tmp[256];
06302 
06303    snprintf(tmp, sizeof(tmp), "Signal=%c\r\nDuration=%u\r\n", digit, duration);
06304    add_header(req, "Content-Type", "application/dtmf-relay");
06305    add_header_contentLength(req, strlen(tmp));
06306    add_line(req, tmp);
06307    return 0;
06308 }

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

Add header to SIP message.

Definition at line 5693 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, and SIP_MAX_HEADERS.

05694 {
05695    int maxlen = sizeof(req->data) - 4 - req->len; /* 4 bytes are for two \r\n ? */
05696 
05697    if (req->headers == SIP_MAX_HEADERS) {
05698       ast_log(LOG_WARNING, "Out of SIP header space\n");
05699       return -1;
05700    }
05701 
05702    if (req->lines) {
05703       ast_log(LOG_WARNING, "Can't add more headers when lines have been added\n");
05704       return -1;
05705    }
05706 
05707    if (maxlen <= 0) {
05708       ast_log(LOG_WARNING, "Out of space, can't add anymore (%s:%s)\n", var, value);
05709       return -1;
05710    }
05711 
05712    req->header[req->headers] = req->data + req->len;
05713 
05714    if (compactheaders)
05715       var = find_alias(var, var);
05716 
05717    snprintf(req->header[req->headers], maxlen, "%s: %s\r\n", var, value);
05718    req->len += strlen(req->header[req->headers]);
05719    req->headers++;
05720 
05721    return 0;   
05722 }

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

Add 'Content-Length' header to SIP message.

Definition at line 5725 of file chan_sip.c.

References add_header().

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

05726 {
05727    char clen[10];
05728 
05729    snprintf(clen, sizeof(clen), "%d", len);
05730    return add_header(req, "Content-Length", clen);
05731 }

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

Add content (not header) to SIP message.

Definition at line 5734 of file chan_sip.c.

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

05735 {
05736    if (req->lines == SIP_MAX_LINES)  {
05737       ast_log(LOG_WARNING, "Out of SIP line space\n");
05738       return -1;
05739    }
05740    if (!req->lines) {
05741       /* Add extra empty return */
05742       snprintf(req->data + req->len, sizeof(req->data) - req->len, "\r\n");
05743       req->len += strlen(req->data + req->len);
05744    }
05745    if (req->len >= sizeof(req->data) - 4) {
05746       ast_log(LOG_WARNING, "Out of space, can't add anymore\n");
05747       return -1;
05748    }
05749    req->line[req->lines] = req->data + req->len;
05750    snprintf(req->line[req->lines], sizeof(req->data) - req->len, "%s", line);
05751    req->len += strlen(req->line[req->lines]);
05752    req->lines++;
05753    return 0;   
05754 }

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

06510 {
06511    int rtp_code;
06512 
06513    if (debug)
06514       ast_verbose("Adding non-codec 0x%x (%s) to SDP\n", format, ast_rtp_lookup_mime_subtype(0, format, 0));
06515    if ((rtp_code = ast_rtp_lookup_code(p->rtp, 0, format)) == -1)
06516       return;
06517 
06518    ast_build_string(m_buf, m_size, " %d", rtp_code);
06519    ast_build_string(a_buf, a_size, "a=rtpmap:%d %s/%d\r\n", rtp_code,
06520           ast_rtp_lookup_mime_subtype(0, format, 0),
06521           sample_rate);
06522    if (format == AST_RTP_DTMF)
06523       /* Indicate we support DTMF and FLASH... */
06524       ast_build_string(a_buf, a_size, "a=fmtp:%d 0-16\r\n", rtp_code);
06525 }

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

Add realm authentication in list.

Definition at line 16873 of file chan_sip.c.

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

Referenced by build_peer().

16874 {
16875    char authcopy[256];
16876    char *username=NULL, *realm=NULL, *secret=NULL, *md5secret=NULL;
16877    char *stringp;
16878    struct sip_auth *a, *b, *auth;
16879 
16880    if (ast_strlen_zero(configuration))
16881       return authlist;
16882 
16883    if (option_debug)
16884       ast_log(LOG_DEBUG, "Auth config ::  %s\n", configuration);
16885 
16886    ast_copy_string(authcopy, configuration, sizeof(authcopy));
16887    stringp = authcopy;
16888 
16889    username = stringp;
16890    realm = strrchr(stringp, '@');
16891    if (realm)
16892       *realm++ = '\0';
16893    if (ast_strlen_zero(username) || ast_strlen_zero(realm)) {
16894       ast_log(LOG_WARNING, "Format for authentication entry is user[:secret]@realm at line %d\n", lineno);
16895       return authlist;
16896    }
16897    stringp = username;
16898    username = strsep(&stringp, ":");
16899    if (username) {
16900       secret = strsep(&stringp, ":");
16901       if (!secret) {
16902          stringp = username;
16903          md5secret = strsep(&stringp,"#");
16904       }
16905    }
16906    if (!(auth = ast_calloc(1, sizeof(*auth))))
16907       return authlist;
16908 
16909    ast_copy_string(auth->realm, realm, sizeof(auth->realm));
16910    ast_copy_string(auth->username, username, sizeof(auth->username));
16911    if (secret)
16912       ast_copy_string(auth->secret, secret, sizeof(auth->secret));
16913    if (md5secret)
16914       ast_copy_string(auth->md5secret, md5secret, sizeof(auth->md5secret));
16915 
16916    /* find the end of the list */
16917    for (b = NULL, a = authlist; a ; b = a, a = a->next)
16918       ;
16919    if (b)
16920       b->next = auth;   /* Add structure add end of list */
16921    else
16922       authlist = auth;
16923 
16924    if (option_verbose > 2)
16925       ast_verbose("Added authentication for realm %s\n", realm);
16926 
16927    return authlist;
16928 
16929 }

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

Add route header into request per learned route.

Definition at line 5855 of file chan_sip.c.

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

Referenced by reqprep().

05856 {
05857    char r[SIPBUFSIZE*2], *p;
05858    int n, rem = sizeof(r);
05859 
05860    if (!route)
05861       return;
05862 
05863    p = r;
05864    for (;route ; route = route->next) {
05865       n = strlen(route->hop);
05866       if (rem < n+3) /* we need room for ",<route>" */
05867          break;
05868       if (p != r) {  /* add a separator after fist route */
05869          *p++ = ',';
05870          --rem;
05871       }
05872       *p++ = '<';
05873       ast_copy_string(p, route->hop, rem); /* cannot fail */
05874       p += n;
05875       *p++ = '>';
05876       rem -= (n+2);
05877    }
05878    *p = '\0';
05879    add_header(req, "Route", r);
05880 }

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

Add Session Description Protocol message.

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

06536 {
06537    int len = 0;
06538    int alreadysent = 0;
06539 
06540    struct sockaddr_in sin;
06541    struct sockaddr_in vsin;
06542    struct sockaddr_in dest;
06543    struct sockaddr_in vdest = { 0, };
06544 
06545    /* SDP fields */
06546    char *version =   "v=0\r\n";     /* Protocol version */
06547    char *subject =   "s=session\r\n";  /* Subject of the session */
06548    char owner[256];           /* Session owner/creator */
06549    char connection[256];            /* Connection data */
06550    char *stime = "t=0 0\r\n";          /* Time the session is active */
06551    char bandwidth[256] = "";        /* Max bitrate */
06552    char *hold;
06553    char m_audio[256];            /* Media declaration line for audio */
06554    char m_video[256];            /* Media declaration line for video */
06555    char a_audio[1024];           /* Attributes for audio */
06556    char a_video[1024];           /* Attributes for video */
06557    char *m_audio_next = m_audio;
06558    char *m_video_next = m_video;
06559    size_t m_audio_left = sizeof(m_audio);
06560    size_t m_video_left = sizeof(m_video);
06561    char *a_audio_next = a_audio;
06562    char *a_video_next = a_video;
06563    size_t a_audio_left = sizeof(a_audio);
06564    size_t a_video_left = sizeof(a_video);
06565 
06566    int x;
06567    int capability;
06568    int needvideo = FALSE;
06569    int debug = sip_debug_test_pvt(p);
06570    int min_audio_packet_size = 0;
06571    int min_video_packet_size = 0;
06572 
06573    m_video[0] = '\0';   /* Reset the video media string if it's not needed */
06574 
06575    if (!p->rtp) {
06576       ast_log(LOG_WARNING, "No way to add SDP without an RTP structure\n");
06577       return AST_FAILURE;
06578    }
06579 
06580    /* Set RTP Session ID and version */
06581    if (!p->sessionid) {
06582       p->sessionid = getpid();
06583       p->sessionversion = p->sessionid;
06584    } else
06585       p->sessionversion++;
06586 
06587    /* Get our addresses */
06588    ast_rtp_get_us(p->rtp, &sin);
06589    if (p->vrtp)
06590       ast_rtp_get_us(p->vrtp, &vsin);
06591 
06592    /* Is this a re-invite to move the media out, then use the original offer from caller  */
06593    if (p->redirip.sin_addr.s_addr) {
06594       dest.sin_port = p->redirip.sin_port;
06595       dest.sin_addr = p->redirip.sin_addr;
06596    } else {
06597       dest.sin_addr = p->ourip;
06598       dest.sin_port = sin.sin_port;
06599    }
06600 
06601    capability = p->jointcapability;
06602 
06603 
06604    if (option_debug > 1) {
06605       char codecbuf[SIPBUFSIZE];
06606       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");
06607       ast_log(LOG_DEBUG, "** Our prefcodec: %s \n", ast_getformatname_multiple(codecbuf, sizeof(codecbuf), p->prefcodec));
06608    }
06609    
06610 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS
06611    if (ast_test_flag(&p->t38.t38support, SIP_PAGE2_T38SUPPORT_RTP)) {
06612       ast_build_string(&m_audio_next, &m_audio_left, " %d", 191);
06613       ast_build_string(&a_audio_next, &a_audio_left, "a=rtpmap:%d %s/%d\r\n", 191, "t38", 8000);
06614    }
06615 #endif
06616 
06617    /* Check if we need video in this call */
06618    if ((capability & AST_FORMAT_VIDEO_MASK) && !ast_test_flag(&p->flags[0], SIP_NOVIDEO)) {
06619       if (p->vrtp) {
06620          needvideo = TRUE;
06621          if (option_debug > 1)
06622             ast_log(LOG_DEBUG, "This call needs video offers!\n");
06623       } else if (option_debug > 1)
06624          ast_log(LOG_DEBUG, "This call needs video offers, but there's no video support enabled!\n");
06625    }
06626       
06627 
06628    /* Ok, we need video. Let's add what we need for video and set codecs.
06629       Video is handled differently than audio since we can not transcode. */
06630    if (needvideo) {
06631       /* Determine video destination */
06632       if (p->vredirip.sin_addr.s_addr) {
06633          vdest.sin_addr = p->vredirip.sin_addr;
06634          vdest.sin_port = p->vredirip.sin_port;
06635       } else {
06636          vdest.sin_addr = p->ourip;
06637          vdest.sin_port = vsin.sin_port;
06638       }
06639       ast_build_string(&m_video_next, &m_video_left, "m=video %d RTP/AVP", ntohs(vdest.sin_port));
06640 
06641       /* Build max bitrate string */
06642       if (p->maxcallbitrate)
06643          snprintf(bandwidth, sizeof(bandwidth), "b=CT:%d\r\n", p->maxcallbitrate);
06644       if (debug) 
06645          ast_verbose("Video is at %s port %d\n", ast_inet_ntoa(p->ourip), ntohs(vsin.sin_port));   
06646    }
06647 
06648    if (debug) 
06649       ast_verbose("Audio is at %s port %d\n", ast_inet_ntoa(p->ourip), ntohs(sin.sin_port)); 
06650 
06651    /* Start building generic SDP headers */
06652 
06653    /* We break with the "recommendation" and send our IP, in order that our
06654       peer doesn't have to ast_gethostbyname() us */
06655 
06656    snprintf(owner, sizeof(owner), "o=root %d %d IN IP4 %s\r\n", p->sessionid, p->sessionversion, ast_inet_ntoa(dest.sin_addr));
06657    snprintf(connection, sizeof(connection), "c=IN IP4 %s\r\n", ast_inet_ntoa(dest.sin_addr));
06658    ast_build_string(&m_audio_next, &m_audio_left, "m=audio %d RTP/AVP", ntohs(dest.sin_port));
06659 
06660    if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) == SIP_PAGE2_CALL_ONHOLD_ONEDIR)
06661       hold = "a=recvonly\r\n";
06662    else if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) == SIP_PAGE2_CALL_ONHOLD_INACTIVE)
06663       hold = "a=inactive\r\n";
06664    else
06665       hold = "a=sendrecv\r\n";
06666 
06667    /* Now, start adding audio codecs. These are added in this order:
06668       - First what was requested by the calling channel
06669       - Then preferences in order from sip.conf device config for this peer/user
06670       - Then other codecs in capabilities, including video
06671    */
06672 
06673    /* Prefer the audio codec we were requested to use, first, no matter what 
06674       Note that p->prefcodec can include video codecs, so mask them out
06675     */
06676    if (capability & p->prefcodec) {
06677       int codec = p->prefcodec & AST_FORMAT_AUDIO_MASK;
06678 
06679       add_codec_to_sdp(p, codec, SDP_SAMPLE_RATE(codec),
06680              &m_audio_next, &m_audio_left,
06681              &a_audio_next, &a_audio_left,
06682              debug, &min_audio_packet_size);
06683       alreadysent |= codec;
06684    }
06685 
06686    /* Start by sending our preferred audio codecs */
06687    for (x = 0; x < 32; x++) {
06688       int codec;
06689 
06690       if (!(codec = ast_codec_pref_index(&p->prefs, x)))
06691          break; 
06692 
06693       if (!(capability & codec))
06694          continue;
06695 
06696       if (alreadysent & codec)
06697          continue;
06698 
06699       add_codec_to_sdp(p, codec, SDP_SAMPLE_RATE(codec),
06700              &m_audio_next, &m_audio_left,
06701              &a_audio_next, &a_audio_left,
06702              debug, &min_audio_packet_size);
06703       alreadysent |= codec;
06704    }
06705 
06706    /* Now send any other common audio and video codecs, and non-codec formats: */
06707    for (x = 1; x <= (needvideo ? AST_FORMAT_MAX_VIDEO : AST_FORMAT_MAX_AUDIO); x <<= 1) {
06708       if (!(capability & x))  /* Codec not requested */
06709          continue;
06710 
06711       if (alreadysent & x) /* Already added to SDP */
06712          continue;
06713 
06714       if (x <= AST_FORMAT_MAX_AUDIO)
06715          add_codec_to_sdp(p, x, SDP_SAMPLE_RATE(x),
06716                 &m_audio_next, &m_audio_left,
06717                 &a_audio_next, &a_audio_left,
06718                 debug, &min_audio_packet_size);
06719       else 
06720          add_codec_to_sdp(p, x, 90000,
06721                 &m_video_next, &m_video_left,
06722                 &a_video_next, &a_video_left,
06723                 debug, &min_video_packet_size);
06724    }
06725 
06726    /* Now add DTMF RFC2833 telephony-event as a codec */
06727    for (x = 1; x <= AST_RTP_MAX; x <<= 1) {
06728       if (!(p->jointnoncodeccapability & x))
06729          continue;
06730 
06731       add_noncodec_to_sdp(p, x, 8000,
06732                 &m_audio_next, &m_audio_left,
06733                 &a_audio_next, &a_audio_left,
06734                 debug);
06735    }
06736 
06737    if (option_debug > 2)
06738       ast_log(LOG_DEBUG, "-- Done with adding codecs to SDP\n");
06739 
06740    if (!p->owner || !ast_internal_timing_enabled(p->owner))
06741       ast_build_string(&a_audio_next, &a_audio_left, "a=silenceSupp:off - - - -\r\n");
06742 
06743    if (min_audio_packet_size)
06744       ast_build_string(&a_audio_next, &a_audio_left, "a=ptime:%d\r\n", min_audio_packet_size);
06745 
06746    if (min_video_packet_size)
06747       ast_build_string(&a_video_next, &a_video_left, "a=ptime:%d\r\n", min_video_packet_size);
06748 
06749    if ((m_audio_left < 2) || (m_video_left < 2) || (a_audio_left == 0) || (a_video_left == 0))
06750       ast_log(LOG_WARNING, "SIP SDP may be truncated due to undersized buffer!!\n");
06751 
06752    ast_build_string(&m_audio_next, &m_audio_left, "\r\n");
06753    if (needvideo)
06754       ast_build_string(&m_video_next, &m_video_left, "\r\n");
06755 
06756    len = strlen(version) + strlen(subject) + strlen(owner) + strlen(connection) + strlen(stime) + strlen(m_audio) + strlen(a_audio) + strlen(hold);
06757    if (needvideo) /* only if video response is appropriate */
06758       len += strlen(m_video) + strlen(a_video) + strlen(bandwidth) + strlen(hold);
06759 
06760    add_header(resp, "Content-Type", "application/sdp");
06761    add_header_contentLength(resp, len);
06762    add_line(resp, version);
06763    add_line(resp, owner);
06764    add_line(resp, subject);
06765    add_line(resp, connection);
06766    if (needvideo)    /* only if video response is appropriate */
06767       add_line(resp, bandwidth);
06768    add_line(resp, stime);
06769    add_line(resp, m_audio);
06770    add_line(resp, a_audio);
06771    add_line(resp, hold);
06772    if (needvideo) { /* only if video response is appropriate */
06773       add_line(resp, m_video);
06774       add_line(resp, a_video);
06775       add_line(resp, hold);   /* Repeat hold for the video stream */
06776    }
06777 
06778    /* Update lastrtprx when we send our SDP */
06779    p->lastrtprx = p->lastrtptx = time(NULL); /* XXX why both ? */
06780 
06781    if (option_debug > 2) {
06782       char buf[SIPBUFSIZE];
06783       ast_log(LOG_DEBUG, "Done building SDP. Settling with this capability: %s\n", ast_getformatname_multiple(buf, SIPBUFSIZE, capability));
06784    }
06785 
06786    return AST_SUCCESS;
06787 }

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

References ast_calloc, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), ast_strlen_zero(), LOG_DEBUG, and sipdebug.

16810 {
16811    struct domain *d;
16812 
16813    if (ast_strlen_zero(domain)) {
16814       ast_log(LOG_WARNING, "Zero length domain.\n");
16815       return 1;
16816    }
16817 
16818    if (!(d = ast_calloc(1, sizeof(*d))))
16819       return 0;
16820 
16821    ast_copy_string(d->domain, domain, sizeof(d->domain));
16822 
16823    if (!ast_strlen_zero(context))
16824       ast_copy_string(d->context, context, sizeof(d->context));
16825 
16826    d->mode = mode;
16827 
16828    AST_LIST_LOCK(&domain_list);
16829    AST_LIST_INSERT_TAIL(&domain_list, d, list);
16830    AST_LIST_UNLOCK(&domain_list);
16831 
16832    if (sipdebug)  
16833       ast_log(LOG_DEBUG, "Added local SIP domain '%s'\n", domain);
16834 
16835    return 1;
16836 }

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

Add T.38 Session Description Protocol message.

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

06411 {
06412    int len = 0;
06413    int x = 0;
06414    struct sockaddr_in udptlsin;
06415    char v[256] = "";
06416    char s[256] = "";
06417    char o[256] = "";
06418    char c[256] = "";
06419    char t[256] = "";
06420    char m_modem[256];
06421    char a_modem[1024];
06422    char *m_modem_next = m_modem;
06423    size_t m_modem_left = sizeof(m_modem);
06424    char *a_modem_next = a_modem;
06425    size_t a_modem_left = sizeof(a_modem);
06426    struct sockaddr_in udptldest = { 0, };
06427    int debug;
06428    
06429    debug = sip_debug_test_pvt(p);
06430    len = 0;
06431    if (!p->udptl) {
06432       ast_log(LOG_WARNING, "No way to add SDP without an UDPTL structure\n");
06433       return -1;
06434    }
06435    
06436    if (!p->sessionid) {
06437       p->sessionid = getpid();
06438       p->sessionversion = p->sessionid;
06439    } else
06440       p->sessionversion++;
06441    
06442    /* Our T.38 end is */
06443    ast_udptl_get_us(p->udptl, &udptlsin);
06444    
06445    /* Determine T.38 UDPTL destination */
06446    if (p->udptlredirip.sin_addr.s_addr) {
06447       udptldest.sin_port = p->udptlredirip.sin_port;
06448       udptldest.sin_addr = p->udptlredirip.sin_addr;
06449    } else {
06450       udptldest.sin_addr = p->ourip;
06451       udptldest.sin_port = udptlsin.sin_port;
06452    }
06453    
06454    if (debug) 
06455       ast_log(LOG_DEBUG, "T.38 UDPTL is at %s port %d\n", ast_inet_ntoa(p->ourip), ntohs(udptlsin.sin_port));
06456    
06457    /* We break with the "recommendation" and send our IP, in order that our
06458       peer doesn't have to ast_gethostbyname() us */
06459    
06460    if (debug) {
06461       ast_log(LOG_DEBUG, "Our T38 capability (%d), peer T38 capability (%d), joint capability (%d)\n",
06462          p->t38.capability,
06463          p->t38.peercapability,
06464          p->t38.jointcapability);
06465    }
06466    snprintf(v, sizeof(v), "v=0\r\n");
06467    snprintf(o, sizeof(o), "o=root %d %d IN IP4 %s\r\n", p->sessionid, p->sessionversion, ast_inet_ntoa(udptldest.sin_addr));
06468    snprintf(s, sizeof(s), "s=session\r\n");
06469    snprintf(c, sizeof(c), "c=IN IP4 %s\r\n", ast_inet_ntoa(udptldest.sin_addr));
06470    snprintf(t, sizeof(t), "t=0 0\r\n");
06471    ast_build_string(&m_modem_next, &m_modem_left, "m=image %d udptl t38\r\n", ntohs(udptldest.sin_port));
06472    
06473    if ((p->t38.jointcapability & T38FAX_VERSION) == T38FAX_VERSION_0)
06474       ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxVersion:0\r\n");
06475    if ((p->t38.jointcapability & T38FAX_VERSION) == T38FAX_VERSION_1)
06476       ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxVersion:1\r\n");
06477    if ((x = t38_get_rate(p->t38.jointcapability)))
06478       ast_build_string(&a_modem_next, &a_modem_left, "a=T38MaxBitRate:%d\r\n",x);
06479    ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxFillBitRemoval:%d\r\n", (p->t38.jointcapability & T38FAX_FILL_BIT_REMOVAL) ? 1 : 0);
06480    ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxTranscodingMMR:%d\r\n", (p->t38.jointcapability & T38FAX_TRANSCODING_MMR) ? 1 : 0);
06481    ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxTranscodingJBIG:%d\r\n", (p->t38.jointcapability & T38FAX_TRANSCODING_JBIG) ? 1 : 0);
06482    ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxRateManagement:%s\r\n", (p->t38.jointcapability & T38FAX_RATE_MANAGEMENT_LOCAL_TCF) ? "localTCF" : "transferredTCF");
06483    x = ast_udptl_get_local_max_datagram(p->udptl);
06484    ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxMaxBuffer:%d\r\n",x);
06485    ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxMaxDatagram:%d\r\n",x);
06486    if (p->t38.jointcapability != T38FAX_UDP_EC_NONE)
06487       ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxUdpEC:%s\r\n", (p->t38.jointcapability & T38FAX_UDP_EC_REDUNDANCY) ? "t38UDPRedundancy" : "t38UDPFEC");
06488    len = strlen(v) + strlen(s) + strlen(o) + strlen(c) + strlen(t) + strlen(m_modem) + strlen(a_modem);
06489    add_header(resp, "Content-Type", "application/sdp");
06490    add_header_contentLength(resp, len);
06491    add_line(resp, v);
06492    add_line(resp, o);
06493    add_line(resp, s);
06494    add_line(resp, c);
06495    add_line(resp, t);
06496    add_line(resp, m_modem);
06497    add_line(resp, a_modem);
06498    
06499    /* Update lastrtprx when we send our SDP */
06500    p->lastrtprx = p->lastrtptx = time(NULL);
06501    
06502    return 0;
06503 }

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

Add text body to SIP message.

Definition at line 6288 of file chan_sip.c.

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

Referenced by transmit_message_with_text().

06289 {
06290    /* XXX Convert \n's to \r\n's XXX */
06291    add_header(req, "Content-Type", "text/plain");
06292    add_header_contentLength(req, strlen(text));
06293    add_line(req, text);
06294    return 0;
06295 }

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

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

Referenced by transmit_info_with_vidupdate().

06313 {
06314    const char *xml_is_a_huge_waste_of_space =
06315       "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\r\n"
06316       " <media_control>\r\n"
06317       "  <vc_primitive>\r\n"
06318       "   <to_encoder>\r\n"
06319       "    <picture_fast_update>\r\n"
06320       "    </picture_fast_update>\r\n"
06321       "   </to_encoder>\r\n"
06322       "  </vc_primitive>\r\n"
06323       " </media_control>\r\n";
06324    add_header(req, "Content-Type", "application/media_control+xml");
06325    add_header_contentLength(req, strlen(xml_is_a_huge_waste_of_space));
06326    add_line(req, xml_is_a_huge_waste_of_space);
06327    return 0;
06328 }

static void append_date ( struct sip_request req  )  [static]

Append date to SIP message.

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

06236 {
06237    char tmpdat[256];
06238    struct tm tm;
06239    time_t t = time(NULL);
06240 
06241    gmtime_r(&t, &tm);
06242    strftime(tmpdat, sizeof(tmpdat), "%a, %d %b %Y %T GMT", &tm);
06243    add_header(req, "Date", tmpdat);
06244 }

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

Append to SIP dialog history with arg list.

Definition at line 1902 of file chan_sip.c.

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

01903 {
01904    va_list ap;
01905 
01906    if (!p)
01907       return;
01908 
01909    if (ast_test_flag(&p->flags[0], SIP_NO_HISTORY) 
01910       && !recordhistory && !dumphistory) {
01911       return;
01912    }
01913 
01914    va_start(ap, fmt);
01915    append_history_va(p, fmt, ap);
01916    va_end(ap);
01917 
01918    return;
01919 }

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

01876 {
01877    char buf[80], *c = buf; /* max history length */
01878    struct sip_history *hist;
01879    int l;
01880 
01881    vsnprintf(buf, sizeof(buf), fmt, ap);
01882    strsep(&c, "\r\n"); /* Trim up everything after \r or \n */
01883    l = strlen(buf) + 1;
01884    if (!(hist = ast_calloc(1, sizeof(*hist) + l)))
01885       return;
01886    if (!p->history && !(p->history = ast_calloc(1, sizeof(*p->history)))) {
01887       free(hist);
01888       return;
01889    }
01890    memcpy(hist->event, buf, l);
01891    if (p->history_entries == MAX_HISTORY_ENTRIES) {
01892       struct sip_history *oldest;
01893       oldest = AST_LIST_REMOVE_HEAD(p->history, list);
01894       p->history_entries--;
01895       free(oldest);
01896    }
01897    AST_LIST_INSERT_TAIL(p->history, hist, list);
01898    p->history_entries++;
01899 }

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

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

Referenced by attempt_transfer(), and handle_invite_replaces().

13441 {
13442    if (chan && chan->_state == AST_STATE_UP) {
13443       if (ast_test_flag(chan, AST_FLAG_MOH))
13444          ast_moh_stop(chan);
13445       else if (chan->generatordata)
13446          ast_deactivate_generator(chan);
13447    }
13448 }

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

References ahp, ast_apply_ha(), ast_gethostbyname(), ast_inet_ntoa(), ast_log(), ast_ouraddrfor(), AST_SUCCESS, externexpire, externhost, 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().

01836 {
01837    struct sockaddr_in theirs, ours;
01838 
01839    /* Get our local information */
01840    ast_ouraddrfor(them, us);
01841    theirs.sin_addr = *them;
01842    ours.sin_addr = *us;
01843 
01844    if (localaddr && externip.sin_addr.s_addr &&
01845        (ast_apply_ha(localaddr, &theirs)) &&
01846        (!global_matchexterniplocally || !ast_apply_ha(localaddr, &ours))) {
01847       if (externexpire && time(NULL) >= externexpire) {
01848          struct ast_hostent ahp;
01849          struct hostent *hp;
01850 
01851          externexpire = time(NULL) + externrefresh;
01852          if ((hp = ast_gethostbyname(externhost, &ahp))) {
01853             memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr));
01854          } else
01855             ast_log(LOG_NOTICE, "Warning: Re-lookup of '%s' failed!\n", externhost);
01856       }
01857       *us = externip.sin_addr;
01858       if (option_debug) {
01859          ast_log(LOG_DEBUG, "Target address %s is not local, substituting externip\n", 
01860             ast_inet_ntoa(*(struct in_addr *)&them->s_addr));
01861       }
01862    } else if (bindaddr.sin_addr.s_addr)
01863       *us = bindaddr.sin_addr;
01864    return AST_SUCCESS;
01865 }

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

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

13453 {
13454    int res = 0;
13455    struct ast_channel *peera = NULL,   
13456       *peerb = NULL,
13457       *peerc = NULL,
13458       *peerd = NULL;
13459 
13460 
13461    /* We will try to connect the transferee with the target and hangup
13462       all channels to the transferer */   
13463    if (option_debug > 3) {
13464       ast_log(LOG_DEBUG, "Sip transfer:--------------------\n");
13465       if (transferer->chan1)
13466          ast_log(LOG_DEBUG, "-- Transferer to PBX channel: %s State %s\n", transferer->chan1->name, ast_state2str(transferer->chan1->_state));
13467       else
13468          ast_log(LOG_DEBUG, "-- No transferer first channel - odd??? \n");
13469       if (target->chan1)
13470          ast_log(LOG_DEBUG, "-- Transferer to PBX second channel (target): %s State %s\n", target->chan1->name, ast_state2str(target->chan1->_state));
13471       else
13472          ast_log(LOG_DEBUG, "-- No target first channel ---\n");
13473       if (transferer->chan2)
13474          ast_log(LOG_DEBUG, "-- Bridged call to transferee: %s State %s\n", transferer->chan2->name, ast_state2str(transferer->chan2->_state));
13475       else
13476          ast_log(LOG_DEBUG, "-- No bridged call to transferee\n");
13477       if (target->chan2)
13478          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)");
13479       else
13480          ast_log(LOG_DEBUG, "-- No target second channel ---\n");
13481       ast_log(LOG_DEBUG, "-- END Sip transfer:--------------------\n");
13482    }
13483    if (transferer->chan2) { /* We have a bridge on the transferer's channel */
13484       peera = transferer->chan1; /* Transferer - PBX -> transferee channel * the one we hangup */
13485       peerb = target->chan1;     /* Transferer - PBX -> target channel - This will get lost in masq */
13486       peerc = transferer->chan2; /* Asterisk to Transferee */
13487       peerd = target->chan2;     /* Asterisk to Target */
13488       if (option_debug > 2)
13489          ast_log(LOG_DEBUG, "SIP transfer: Four channels to handle\n");
13490    } else if (target->chan2) {   /* Transferer has no bridge (IVR), but transferee */
13491       peera = target->chan1;     /* Transferer to PBX -> target channel */
13492       peerb = transferer->chan1; /* Transferer to IVR*/
13493       peerc = target->chan2;     /* Asterisk to Target */
13494       peerd = transferer->chan2; /* Nothing */
13495       if (option_debug > 2)
13496          ast_log(LOG_DEBUG, "SIP transfer: Three channels to handle\n");
13497    }
13498 
13499    if (peera && peerb && peerc && (peerb != peerc)) {
13500       ast_quiet_chan(peera);     /* Stop generators */
13501       ast_quiet_chan(peerb);  
13502       ast_quiet_chan(peerc);
13503       if (peerd)
13504          ast_quiet_chan(peerd);
13505 
13506       if (option_debug > 3)
13507          ast_log(LOG_DEBUG, "SIP transfer: trying to masquerade %s into %s\n", peerc->name, peerb->name);
13508       if (ast_channel_masquerade(peerb, peerc)) {
13509          ast_log(LOG_WARNING, "Failed to masquerade %s into %s\n", peerb->name, peerc->name);
13510          res = -1;
13511       } else
13512          ast_log(LOG_DEBUG, "SIP transfer: Succeeded to masquerade channels.\n");
13513       return res;
13514    } else {
13515       ast_log(LOG_NOTICE, "SIP Transfer attempted with no appropriate bridged calls to transfer\n");
13516       if (transferer->chan1)
13517          ast_softhangup_nolock(transferer->chan1, AST_SOFTHANGUP_DEV);
13518       if (target->chan1)
13519          ast_softhangup_nolock(target->chan1, AST_SOFTHANGUP_DEV);
13520       return -2;
13521    }
13522    return 0;
13523 }

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

Scheduled congestion on a call.

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

02965 {
02966    struct sip_pvt *p = (struct sip_pvt *)nothing;
02967 
02968    ast_mutex_lock(&p->lock);
02969    p->initid = -1;
02970    if (p->owner) {
02971       /* XXX fails on possible deadlock */
02972       if (!ast_channel_trylock(p->owner)) {
02973          ast_log(LOG_NOTICE, "Auto-congesting %s\n", p->owner->name);
02974          append_history(p, "Cong", "Auto-congesting (timer)");
02975          ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
02976          ast_channel_unlock(p->owner);
02977       }
02978    }
02979    ast_mutex_unlock(&p->lock);
02980    return 0;
02981 }

static void build_callid_pvt ( struct sip_pvt pvt  )  [static]

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

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

04492 {
04493    char buf[33];
04494 
04495    const char *host = S_OR(pvt->fromdomain, ast_inet_ntoa(pvt->ourip));
04496    
04497    ast_string_field_build(pvt, callid, "%s@%s", generate_random_string(buf, sizeof(buf)), host);
04498 
04499 }

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

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

Referenced by transmit_register().

04503 {
04504    char buf[33];
04505 
04506    const char *host = S_OR(fromdomain, ast_inet_ntoa(ourip));
04507 
04508    ast_string_field_build(reg, callid, "%s@%s", generate_random_string(buf, sizeof(buf)), host);
04509 }

static void build_contact ( struct sip_pvt p  )  [static]

Build contact header - the contact header we send out.

Definition at line 6958 of file chan_sip.c.

References ast_inet_ntoa(), ast_string_field_build, ast_strlen_zero(), 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().

06959 {
06960    /* Construct Contact: header */
06961    if (ourport != STANDARD_SIP_PORT)
06962       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);
06963    else
06964       ast_string_field_build(p, our_contact, "<sip:%s%s%s>", p->exten, ast_strlen_zero(p->exten) ? "" : "@", ast_inet_ntoa(p->ourip));
06965 }

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

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

Definition at line 17140 of file chan_sip.c.

References __set_address_from_contact(), 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, global_flags, sip_peer::ha, handle_common_options(), sip_peer::language, sip_peer::lastmsgssent, ast_variable::lineno, LOG_DEBUG, 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, sched, 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, sip_peer::sockfd, STANDARD_SIP_PORT, sip_peer::subscribecontext, sip_peer::tohost, TRANSFER_CLOSED, TRANSFER_OPENFORALL, TRUE, sip_peer::username, ast_variable::value, and sip_peer::vmexten.

17141 {
17142    struct sip_peer *peer = NULL;
17143    struct ast_ha *oldha = NULL;
17144    int obproxyfound=0;
17145    int found=0;
17146    int firstpass=1;
17147    int format=0;     /* Ama flags */
17148    time_t regseconds = 0;
17149    char *varname = NULL, *varval = NULL;
17150    struct ast_variable *tmpvar = NULL;
17151    struct ast_flags peerflags[2] = {{(0)}};
17152    struct ast_flags mask[2] = {{(0)}};
17153    char fullcontact[sizeof(peer->fullcontact)] = "";
17154 
17155    if (!realtime || ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS))
17156       /* Note we do NOT use find_peer here, to avoid realtime recursion */
17157       /* We also use a case-sensitive comparison (unlike find_peer) so
17158          that case changes made to the peer name will be properly handled
17159          during reload
17160       */
17161       peer = ASTOBJ_CONTAINER_FIND_UNLINK_FULL(&peerl, name, name, 0, 0, strcmp);
17162 
17163    if (peer) {
17164       /* Already in the list, remove it and it will be added back (or FREE'd)  */
17165       found = 1;
17166       if (!(peer->objflags & ASTOBJ_FLAG_MARKED))
17167          firstpass = 0;
17168    } else {
17169       if (!(peer = ast_calloc(1, sizeof(*peer))))
17170          return NULL;
17171 
17172       if (realtime && !ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS))
17173          rpeerobjs++;
17174       else
17175          speerobjs++;
17176       ASTOBJ_INIT(peer);
17177    }
17178    /* Note that our peer HAS had its reference count incrased */
17179    if (firstpass) {
17180       peer->lastmsgssent = -1;
17181       oldha = peer->ha;
17182       peer->ha = NULL;
17183       set_peer_defaults(peer);   /* Set peer defaults */
17184    }
17185    if (!found && name)
17186          ast_copy_string(peer->name, name, sizeof(peer->name));
17187 
17188    /* If we have channel variables, remove them (reload) */
17189    if (peer->chanvars) {
17190       ast_variables_destroy(peer->chanvars);
17191       peer->chanvars = NULL;
17192       /* XXX should unregister ? */
17193    }
17194 
17195    /* If we have realm authentication information, remove them (reload) */
17196    clear_realm_authentication(peer->auth);
17197    peer->auth = NULL;
17198    peer->sockfd = -1;
17199 
17200    for (; v || ((v = alt) && !(alt=NULL)); v = v->next) {
17201       if (handle_common_options(&peerflags[0], &mask[0], v))
17202          continue;
17203       if (realtime && !strcasecmp(v->name, "regseconds")) {
17204          ast_get_time_t(v->value, &regseconds, 0, NULL);
17205       } else if (realtime && !strcasecmp(v->name, "ipaddr") && !ast_strlen_zero(v->value) ) {
17206          inet_aton(v->value, &(peer->addr.sin_addr));
17207       } else if (realtime && !strcasecmp(v->name, "name"))
17208          ast_copy_string(peer->name, v->value, sizeof(peer->name));
17209       else if (realtime && !strcasecmp(v->name, "fullcontact")) {
17210          /* Reconstruct field, because realtime separates our value at the ';' */
17211          if (!ast_strlen_zero(fullcontact)) {
17212             strncat(fullcontact, ";", sizeof(fullcontact) - strlen(fullcontact) - 1);
17213             strncat(fullcontact, v->value, sizeof(fullcontact) - strlen(fullcontact) - 1);
17214          } else {
17215             ast_copy_string(fullcontact, v->value, sizeof(fullcontact));
17216             ast_set_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT);
17217          }
17218       } else if (!strcasecmp(v->name, "secret")) 
17219          ast_copy_string(peer->secret, v->value, sizeof(peer->secret));
17220       else if (!strcasecmp(v->name, "md5secret")) 
17221          ast_copy_string(peer->md5secret, v->value, sizeof(peer->md5secret));
17222       else if (!strcasecmp(v->name, "auth"))
17223          peer->auth = add_realm_authentication(peer->auth, v->value, v->lineno);
17224       else if (!strcasecmp(v->name, "callerid")) {
17225          ast_callerid_split(v->value, peer->cid_name, sizeof(peer->cid_name), peer->cid_num, sizeof(peer->cid_num));
17226       } else if (!strcasecmp(v->name, "fullname")) {
17227          ast_copy_string(peer->cid_name, v->value, sizeof(peer->cid_name));
17228       } else if (!strcasecmp(v->name, "cid_number")) {
17229          ast_copy_string(peer->cid_num, v->value, sizeof(peer->cid_num));
17230       } else if (!strcasecmp(v->name, "context")) {
17231          ast_copy_string(peer->context, v->value, sizeof(peer->context));
17232       } else if (!strcasecmp(v->name, "subscribecontext")) {
17233          ast_copy_string(peer->subscribecontext, v->value, sizeof(peer->subscribecontext));
17234       } else if (!strcasecmp(v->name, "fromdomain")) {
17235          ast_copy_string(peer->fromdomain, v->value, sizeof(peer->fromdomain));
17236       } else if (!strcasecmp(v->name, "usereqphone")) {
17237          ast_set2_flag(&peer->flags[0], ast_true(v->value), SIP_USEREQPHONE);
17238       } else if (!strcasecmp(v->name, "fromuser")) {
17239          ast_copy_string(peer->fromuser, v->value, sizeof(peer->fromuser));
17240       } else if (!strcasecmp(v->name, "host") || !strcasecmp(v->name, "outboundproxy")) {
17241          if (!strcasecmp(v->value, "dynamic")) {
17242             if (!strcasecmp(v->name, "outboundproxy") || obproxyfound) {
17243                ast_log(LOG_WARNING, "You can't have a dynamic outbound proxy, you big silly head at line %d.\n", v->lineno);
17244             } else {
17245                /* They'll register with us */
17246                if (!found || !ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)) {
17247                   /* Initialize stuff if this is a new peer, or if it used to be
17248                    * non-dynamic before the reload. */
17249                   memset(&peer->addr.sin_addr, 0, 4);
17250                   if (peer->addr.sin_port) {
17251                      /* If we've already got a port, make it the default rather than absolute */
17252                      peer->defaddr.sin_port = peer->addr.sin_port;
17253                      peer->addr.sin_port = 0;
17254                   }
17255                }
17256                ast_set_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC);
17257             }
17258          } else {
17259             /* Non-dynamic.  Make sure we become that way if we're not */
17260             if (!AST_SCHED_DEL(sched, peer->expire)) {
17261                struct sip_peer *peer_ptr = peer;
17262                ASTOBJ_UNREF(peer_ptr, sip_destroy_peer);
17263             }
17264             ast_clear_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC);
17265             if (!obproxyfound || !strcasecmp(v->name, "outboundproxy")) {
17266                if (ast_get_ip_or_srv(&peer->addr, v->value, srvlookup ? "_sip._udp" : NULL)) {
17267                   ASTOBJ_UNREF(peer, sip_destroy_peer);
17268                   return NULL;
17269                }
17270             }
17271             if (!strcasecmp(v->name, "outboundproxy"))
17272                obproxyfound=1;
17273             else {
17274                ast_copy_string(peer->tohost, v->value, sizeof(peer->tohost));
17275                if (!peer->addr.sin_port)
17276                   peer->addr.sin_port = htons(STANDARD_SIP_PORT);
17277             }
17278          }
17279       } else if (!strcasecmp(v->name, "defaultip")) {
17280          if (ast_get_ip(&peer->defaddr, v->value)) {
17281             ASTOBJ_UNREF(peer, sip_destroy_peer);
17282             return NULL;
17283          }
17284       } else if (!strcasecmp(v->name, "permit") || !strcasecmp(v->name, "deny")) {
17285          peer->ha = ast_append_ha(v->name, v->value, peer->ha);
17286       } else if (!strcasecmp(v->name, "port")) {
17287          if (!realtime && ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC))
17288             peer->defaddr.sin_port = htons(atoi(v->value));
17289          else
17290             peer->addr.sin_port = htons(atoi(v->value));
17291       } else if (!strcasecmp(v->name, "callingpres")) {
17292          peer->callingpres = ast_parse_caller_presentation(v->value);
17293          if (peer->callingpres == -1)
17294             peer->callingpres = atoi(v->value);
17295       } else if (!strcasecmp(v->name, "username")) {
17296          ast_copy_string(peer->username, v->value, sizeof(peer->username));
17297       } else if (!strcasecmp(v->name, "language")) {
17298          ast_copy_string(peer->language, v->value, sizeof(peer->language));
17299       } else if (!strcasecmp(v->name, "regexten")) {
17300          ast_copy_string(peer->regexten, v->value, sizeof(peer->regexten));
17301       } else if (!strcasecmp(v->name, "call-limit") || !strcasecmp(v->name, "incominglimit")) {
17302          peer->call_limit = atoi(v->value);
17303          if (peer->call_limit < 0)
17304             peer->call_limit = 0;
17305       } else if (!strcasecmp(v->name, "amaflags")) {
17306          format = ast_cdr_amaflags2int(v->value);
17307          if (format < 0) {
17308             ast_log(LOG_WARNING, "Invalid AMA Flags for peer: %s at line %d\n", v->value, v->lineno);
17309          } else {
17310             peer->amaflags = format;
17311          }
17312       } else if (!strcasecmp(v->name, "accountcode")) {
17313          ast_copy_string(peer->accountcode, v->value, sizeof(peer->accountcode));
17314       } else if (!strcasecmp(v->name, "mohinterpret")
17315          || !strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) {
17316          ast_copy_string(peer->mohinterpret, v->value, sizeof(peer->mohinterpret));
17317       } else if (!strcasecmp(v->name, "mohsuggest")) {
17318          ast_copy_string(peer->mohsuggest, v->value, sizeof(peer->mohsuggest));
17319       } else if (!strcasecmp(v->name, "mailbox")) {
17320          ast_copy_string(peer->mailbox, v->value, sizeof(peer->mailbox));
17321       } else if (!strcasecmp(v->name, "hasvoicemail")) {
17322          /* People expect that if 'hasvoicemail' is set, that the mailbox will
17323           * be also set, even if not explicitly specified. */
17324          if (ast_true(v->value) && ast_strlen_zero(peer->mailbox)) {
17325             ast_copy_string(peer->mailbox, name, sizeof(peer->mailbox));
17326          }
17327       } else if (!strcasecmp(v->name, "subscribemwi")) {
17328          ast_set2_flag(&peer->flags[1], ast_true(v->value), SIP_PAGE2_SUBSCRIBEMWIONLY);
17329       } else if (!strcasecmp(v->name, "vmexten")) {
17330          ast_copy_string(peer->vmexten, v->value, sizeof(peer->vmexten));
17331       } else if (!strcasecmp(v->name, "callgroup")) {
17332          peer->callgroup = ast_get_group(v->value);
17333       } else if (!strcasecmp(v->name, "allowtransfer")) {
17334          peer->allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED;
17335       } else if (!strcasecmp(v->name, "pickupgroup")) {
17336          peer->pickupgroup = ast_get_group(v->value);
17337       } else if (!strcasecmp(v->name, "allow")) {
17338          ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1);
17339       } else if (!strcasecmp(v->name, "disallow")) {
17340          ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0);
17341       } else if (!strcasecmp(v->name, "autoframing")) {
17342          peer->autoframing = ast_true(v->value);
17343       } else if (!strcasecmp(v->name, "rtptimeout")) {
17344          if ((sscanf(v->value, "%d", &peer->rtptimeout) != 1) || (peer->rtptimeout < 0)) {
17345             ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d.  Using default.\n", v->value, v->lineno);
17346             peer->rtptimeout = global_rtptimeout;
17347          }
17348       } else if (!strcasecmp(v->name, "rtpholdtimeout")) {
17349          if ((sscanf(v->value, "%d", &peer->rtpholdtimeout) != 1) || (peer->rtpholdtimeout < 0)) {
17350             ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d.  Using default.\n", v->value, v->lineno);
17351             peer->rtpholdtimeout = global_rtpholdtimeout;
17352          }
17353       } else if (!strcasecmp(v->name, "rtpkeepalive")) {
17354          if ((sscanf(v->value, "%d", &peer->rtpkeepalive) != 1) || (peer->rtpkeepalive < 0)) {
17355             ast_log(LOG_WARNING, "'%s' is not a valid RTP keepalive time at line %d.  Using default.\n", v->value, v->lineno);
17356             peer->rtpkeepalive = global_rtpkeepalive;
17357          }
17358       } else if (!strcasecmp(v->name, "setvar")) {
17359          /* Set peer channel variable */
17360          varname = ast_strdupa(v->value);
17361          if ((varval = strchr(varname, '='))) {
17362             *varval++ = '\0';
17363             if ((tmpvar = ast_variable_new(varname, varval))) {
17364                tmpvar->next = peer->chanvars;
17365                peer->chanvars = tmpvar;
17366             }
17367          }
17368       } else if (!strcasecmp(v->name, "qualify")) {
17369          if (!strcasecmp(v->value, "no")) {
17370             peer->maxms = 0;
17371          } else if (!strcasecmp(v->value, "yes")) {
17372             peer->maxms = default_qualify ? default_qualify : DEFAULT_MAXMS;
17373          } else if (sscanf(v->value, "%d", &peer->maxms) != 1) {
17374             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);
17375             peer->maxms = 0;
17376          }
17377       } else if (!strcasecmp(v->name, "maxcallbitrate")) {
17378          peer->maxcallbitrate = atoi(v->value);
17379          if (peer->maxcallbitrate < 0)
17380             peer->maxcallbitrate = default_maxcallbitrate;
17381       }
17382    }
17383    if (!ast_strlen_zero(fullcontact)) {
17384       ast_copy_string(peer->fullcontact, fullcontact, sizeof(peer->fullcontact));
17385       /* We have a hostname in the fullcontact, but if we don't have an
17386        * address listed on the entry (or if it's 'dynamic'), then we need to
17387        * parse the entry to obtain the IP address, so a dynamic host can be
17388        * contacted immediately after reload (as opposed to waiting for it to
17389        * register once again). */
17390       __set_address_from_contact(fullcontact, &peer->addr);
17391    }
17392 
17393    if (!ast_test_flag(&global_flags[1], SIP_PAGE2_IGNOREREGEXPIRE) && ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC) && realtime) {
17394       time_t nowtime = time(NULL);
17395 
17396       if ((nowtime - regseconds) > 0) {
17397          destroy_association(peer);
17398          memset(&peer->addr, 0, sizeof(peer->addr));
17399          if (option_debug)
17400             ast_log(LOG_DEBUG, "Bah, we're expired (%d/%d/%d)!\n", (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
17401       }
17402    }
17403    ast_copy_flags(&peer->flags[0], &peerflags[0], mask[0].flags);
17404    ast_copy_flags(&peer->flags[1], &peerflags[1], mask[1].flags);
17405    if (ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE))
17406       global_allowsubscribe = TRUE; /* No global ban any more */
17407    if (!found && ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC) && !ast_test_flag(&peer->flags[0], SIP_REALTIME))
17408       reg_source_db(peer);
17409    ASTOBJ_UNMARK(peer);
17410    ast_free_ha(oldha);
17411    return peer;
17412 }

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 11737 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, sip_auth::md5secret, sip_pvt::noncecount, sip_pvt::peerauth, 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().

11738 {
11739    char a1[256];
11740    char a2[256];
11741    char a1_hash[256];
11742    char a2_hash[256];
11743    char resp[256];
11744    char resp_hash[256];
11745    char uri[256];
11746    char opaque[256] = "";
11747    char cnonce[80];
11748    const char *username;
11749    const char *secret;
11750    const char *md5secret;
11751    struct sip_auth *auth = NULL; /* Realm authentication */
11752 
11753    if (!ast_strlen_zero(p->domain))
11754       ast_copy_string(uri, p->domain, sizeof(uri));
11755    else if (!ast_strlen_zero(p->uri))
11756       ast_copy_string(uri, p->uri, sizeof(uri));
11757    else
11758       snprintf(uri, sizeof(uri), "sip:%s@%s",p->username, ast_inet_ntoa(p->sa.sin_addr));
11759 
11760    snprintf(cnonce, sizeof(cnonce), "%08lx", ast_random());
11761 
11762    /* Check if we have separate auth credentials */
11763    if(!(auth = find_realm_authentication(p->peerauth, p->realm))) /* Start with peer list */
11764       auth = find_realm_authentication(authl, p->realm); /* If not, global list */
11765 
11766    if (auth) {
11767       ast_log(LOG_DEBUG, "use realm [%s] from peer [%s][%s]\n", auth->username, p->peername, p->username);
11768       username = auth->username;
11769       secret = auth->secret;
11770       md5secret = auth->md5secret;
11771       if (sipdebug)
11772          ast_log(LOG_DEBUG,"Using realm %s authentication for call %s\n", p->realm, p->callid);
11773    } else {
11774       /* No authentication, use peer or register= config */
11775       username = p->authname;
11776       secret =  p->peersecret;
11777       md5secret = p->peermd5secret;
11778    }
11779    if (ast_strlen_zero(username))   /* We have no authentication */
11780       return -1;
11781 
11782    /* Calculate SIP digest response */
11783    snprintf(a1,sizeof(a1),"%s:%s:%s", username, p->realm, secret);
11784    snprintf(a2,sizeof(a2),"%s:%s", sip_methods[method].text, uri);
11785    if (!ast_strlen_zero(md5secret))
11786       ast_copy_string(a1_hash, md5secret, sizeof(a1_hash));
11787    else
11788       ast_md5_hash(a1_hash,a1);
11789    ast_md5_hash(a2_hash,a2);
11790 
11791    p->noncecount++;
11792    if (!ast_strlen_zero(p->qop))
11793       snprintf(resp,sizeof(resp),"%s:%s:%08x:%s:%s:%s", a1_hash, p->nonce, p->noncecount, cnonce, "auth", a2_hash);
11794    else
11795       snprintf(resp,sizeof(resp),"%s:%s:%s", a1_hash, p->nonce, a2_hash);
11796    ast_md5_hash(resp_hash, resp);
11797 
11798    /* only include the opaque string if it's set */
11799    if (!ast_strlen_zero(p->opaque)) {
11800      snprintf(opaque, sizeof(opaque), ", opaque=\"%s\"", p->opaque);
11801    }
11802 
11803    /* XXX We hard code our qop to "auth" for now.  XXX */
11804    if (!ast_strlen_zero(p->qop))
11805       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);
11806    else
11807       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);
11808 
11809    append_history(p, "AuthResp", "Auth response sent for %s in realm %s - nc %d", username, p->realm, p->noncecount);
11810 
11811    return 0;
11812 }

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

08410 {
08411    struct sip_route *thishop, *head, *tail;
08412    int start = 0;
08413    int len;
08414    const char *rr, *contact, *c;
08415 
08416    /* Once a persistant route is set, don't fool with it */
08417    if (p->route && p->route_persistant) {
08418       if (option_debug)
08419          ast_log(LOG_DEBUG, "build_route: Retaining previous route: <%s>\n", p->route->hop);
08420       return;
08421    }
08422 
08423    if (p->route) {
08424       free_old_route(p->route);
08425       p->route = NULL;
08426    }
08427 
08428    /* We only want to create the route set the first time this is called */
08429    p->route_persistant = 1;
08430    
08431    /* Build a tailq, then assign it to p->route when done.
08432     * If backwards, we add entries from the head so they end up
08433     * in reverse order. However, we do need to maintain a correct
08434     * tail pointer because the contact is always at the end.
08435     */
08436    head = NULL;
08437    tail = head;
08438    /* 1st we pass through all the hops in any Record-Route headers */
08439    for (;;) {
08440       /* Each Record-Route header */
08441       rr = __get_header(req, "Record-Route", &start);
08442       if (*rr == '\0')
08443          break;
08444       for (; (rr = strchr(rr, '<')) ; rr += len) { /* Each route entry */
08445          ++rr;
08446          len = strcspn(rr, ">") + 1;
08447          /* Make a struct route */
08448          if ((thishop = ast_malloc(sizeof(*thishop) + len))) {
08449             /* ast_calloc is not needed because all fields are initialized in this block */
08450             ast_copy_string(thishop->hop, rr, len);
08451             if (option_debug > 1)
08452                ast_log(LOG_DEBUG, "build_route: Record-Route hop: <%s>\n", thishop->hop);
08453             /* Link in */
08454             if (backwards) {
08455                /* Link in at head so they end up in reverse order */
08456                thishop->next = head;
08457                head = thishop;
08458                /* If this was the first then it'll be the tail */
08459                if (!tail)
08460                   tail = thishop;
08461             } else {
08462                thishop->next = NULL;
08463                /* Link in at the end */
08464                if (tail)
08465                   tail->next = thishop;
08466                else
08467                   head = thishop;
08468                tail = thishop;
08469             }
08470          }
08471       }
08472    }
08473 
08474    /* Only append the contact if we are dealing with a strict router */
08475    if (!head || (!ast_strlen_zero(head->hop) && strstr(head->hop,";lr") == NULL) ) {
08476       /* 2nd append the Contact: if there is one */
08477       /* Can be multiple Contact headers, comma separated values - we just take the first */
08478       contact = get_header(req, "Contact");
08479       if (!ast_strlen_zero(contact)) {
08480          if (option_debug > 1)
08481             ast_log(LOG_DEBUG, "build_route: Contact hop: %s\n", contact);
08482          /* Look for <: delimited address */
08483          c = strchr(contact, '<');
08484          if (c) {
08485             /* Take to > */
08486             ++c;
08487             len = strcspn(c, ">") + 1;
08488          } else {
08489             /* No <> - just take the lot */
08490             c = contact;
08491             len = strlen(contact) + 1;
08492          }
08493          if ((thishop = ast_malloc(sizeof(*thishop) + len))) {
08494             /* ast_calloc is not needed because all fields are initialized in this block */
08495             ast_copy_string(thishop->hop, c, len);
08496             thishop->next = NULL;
08497             /* Goes at the end */
08498             if (tail)
08499                tail->next = thishop;
08500             else
08501                head = thishop;
08502          }
08503       }
08504    }
08505 
08506    /* Store as new route */
08507    p->route = head;
08508 
08509    /* For debugging dump what we ended up with */
08510    if (sip_debug_test_pvt(p))
08511       list_route(p->route);
08512 }

static void build_rpid ( struct sip_pvt p  )  [static]

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

Definition at line 6968 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, sip_pvt::ourip, sip_pvt::owner, S_OR, sip_pvt::tag, and TRUE.

Referenced by initreqprep().

06969 {
06970    int send_pres_tags = TRUE;
06971    const char *privacy=NULL;
06972    const char *screen=NULL;
06973    char buf[256];
06974    const char *clid = default_callerid;
06975    const char *clin = NULL;
06976    const char *fromdomain;
06977 
06978    if (!ast_strlen_zero(p->rpid) || !ast_strlen_zero(p->rpid_from))  
06979       return;
06980 
06981    if (p->owner && p->owner->cid.cid_num)
06982       clid = p->owner->cid.cid_num;
06983    if (p->owner && p->owner->cid.cid_name)
06984       clin = p->owner->cid.cid_name;
06985    if (ast_strlen_zero(clin))
06986       clin = clid;
06987 
06988    switch (p->callingpres) {
06989    case AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED:
06990       privacy = "off";
06991       screen = "no";
06992       break;
06993    case AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN:
06994       privacy = "off";
06995       screen = "yes";
06996       break;
06997    case AST_PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN:
06998       privacy = "off";
06999       screen = "no";
07000       break;
07001    case AST_PRES_ALLOWED_NETWORK_NUMBER:
07002       privacy = "off";
07003       screen = "yes";
07004       break;
07005    case AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED:
07006       privacy = "full";
07007       screen = "no";
07008       break;
07009    case AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN:
07010       privacy = "full";
07011       screen = "yes";
07012       break;
07013    case AST_PRES_PROHIB_USER_NUMBER_FAILED_SCREEN:
07014       privacy = "full";
07015       screen = "no";
07016       break;
07017    case AST_PRES_PROHIB_NETWORK_NUMBER:
07018       privacy = "full";
07019       screen = "yes";
07020       break;
07021    case AST_PRES_NUMBER_NOT_AVAILABLE:
07022       send_pres_tags = FALSE;
07023       break;
07024    default:
07025       ast_log(LOG_WARNING, "Unsupported callingpres (%d)\n", p->callingpres);
07026       if ((p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED)
07027          privacy = "full";
07028       else
07029          privacy = "off";
07030       screen = "no";
07031       break;
07032    }
07033    
07034    fromdomain = S_OR(p->fromdomain, ast_inet_ntoa(p->ourip));
07035 
07036    snprintf(buf, sizeof(buf), "\"%s\" <sip:%s@%s>", clin, clid, fromdomain);
07037    if (send_pres_tags)
07038       snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), ";privacy=%s;screen=%s", privacy, screen);
07039    ast_string_field_set(p, rpid, buf);
07040 
07041    ast_string_field_build(p, rpid_from, "\"%s\" <sip:%s@%s>;tag=%s", clin,
07042                 S_OR(p->fromuser, clid),
07043                 fromdomain, p->tag);
07044 }

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

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

Definition at line 16960 of file chan_sip.c.

References 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, default_prefs, ast_flags::flags, format, global_flags, handle_common_options(), ast_variable::lineno, ast_variable::name, ast_variable::next, SIP_FLAGS_TO_COPY, SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PAGE2_FLAGS_TO_COPY, TRANSFER_CLOSED, TRANSFER_OPENFORALL, TRUE, and ast_variable::value.

16961 {
16962    struct sip_user *user;
16963    int format;
16964    struct ast_ha *oldha = NULL;
16965    char *varname = NULL, *varval = NULL;
16966    struct ast_variable *tmpvar = NULL;
16967    struct ast_flags userflags[2] = {{(0)}};
16968    struct ast_flags mask[2] = {{(0)}};
16969 
16970 
16971    if (!(user = ast_calloc(1, sizeof(*user))))
16972       return NULL;
16973       
16974    suserobjs++;
16975    ASTOBJ_INIT(user);
16976    ast_copy_string(user->name, name, sizeof(user->name));
16977    oldha = user->ha;
16978    user->ha = NULL;
16979    ast_copy_flags(&user->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY);
16980    ast_copy_flags(&user->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY);
16981    user->capability = global_capability;
16982    user->allowtransfer = global_allowtransfer;
16983    user->maxcallbitrate = default_maxcallbitrate;
16984    user->autoframing = global_autoframing;
16985    user->prefs = default_prefs;
16986    /* set default context */
16987    strcpy(user->context, default_context);
16988    strcpy(user->language, default_language);
16989    strcpy(user->mohinterpret, default_mohinterpret);
16990    strcpy(user->mohsuggest, default_mohsuggest);
16991    /* First we walk through the v parameters list and then the alt parameters list */
16992    for (; v || ((v = alt) && !(alt=NULL)); v = v->next) {
16993       if (handle_common_options(&userflags[0], &mask[0], v))
16994          continue;
16995 
16996       if (!strcasecmp(v->name, "context")) {
16997          ast_copy_string(user->context, v->value, sizeof(user->context));
16998       } else if (!strcasecmp(v->name, "subscribecontext")) {
16999          ast_copy_string(user->subscribecontext, v->value, sizeof(user->subscribecontext));
17000       } else if (!strcasecmp(v->name, "setvar")) {
17001          varname = ast_strdupa(v->value);
17002          if ((varval = strchr(varname,'='))) {
17003             *varval++ = '\0';
17004             if ((tmpvar = ast_variable_new(varname, varval))) {
17005                tmpvar->next = user->chanvars;
17006                user->chanvars = tmpvar;
17007             }
17008          }
17009       } else if (!strcasecmp(v->name, "permit") ||
17010                !strcasecmp(v->name, "deny")) {
17011          user->ha = ast_append_ha(v->name, v->value, user->ha);
17012       } else if (!strcasecmp(v->name, "allowtransfer")) {
17013          user->allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED;
17014       } else if (!strcasecmp(v->name, "secret")) {
17015          ast_copy_string(user->secret, v->value, sizeof(user->secret)); 
17016       } else if (!strcasecmp(v->name, "md5secret")) {
17017          ast_copy_string(user->md5secret, v->value, sizeof(user->md5secret));
17018       } else if (!strcasecmp(v->name, "callerid")) {
17019          ast_callerid_split(v->value, user->cid_name, sizeof(user->cid_name), user->cid_num, sizeof(user->cid_num));
17020       } else if (!strcasecmp(v->name, "fullname")) {
17021          ast_copy_string(user->cid_name, v->value, sizeof(user->cid_name));
17022       } else if (!strcasecmp(v->name, "cid_number")) {
17023          ast_copy_string(user->cid_num, v->value, sizeof(user->cid_num));
17024       } else if (!strcasecmp(v->name, "callgroup")) {
17025          user->callgroup = ast_get_group(v->value);
17026       } else if (!strcasecmp(v->name, "pickupgroup")) {
17027          user->pickupgroup = ast_get_group(v->value);
17028       } else if (!strcasecmp(v->name, "language")) {
17029          ast_copy_string(user->language, v->value, sizeof(user->language));
17030       } else if (!strcasecmp(v->name, "mohinterpret") 
17031          || !strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) {
17032          ast_copy_string(user->mohinterpret, v->value, sizeof(user->mohinterpret));
17033       } else if (!strcasecmp(v->name, "mohsuggest")) {
17034          ast_copy_string(user->mohsuggest, v->value, sizeof(user->mohsuggest));
17035       } else if (!strcasecmp(v->name, "accountcode")) {
17036          ast_copy_string(user->accountcode, v->value, sizeof(user->accountcode));
17037       } else if (!strcasecmp(v->name, "call-limit")) {
17038          user->call_limit = atoi(v->value);
17039          if (user->call_limit < 0)
17040             user->call_limit = 0;
17041       } else if (!strcasecmp(v->name, "amaflags")) {
17042          format = ast_cdr_amaflags2int(v->value);
17043          if (format < 0) {
17044             ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
17045          } else {
17046             user->amaflags = format;
17047          }
17048       } else if (!strcasecmp(v->name, "allow")) {
17049          ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1);
17050       } else if (!strcasecmp(v->name, "disallow")) {
17051          ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 0);
17052       } else if (!strcasecmp(v->name, "autoframing")) {
17053          user->autoframing = ast_true(v->value);
17054       } else if (!strcasecmp(v->name, "callingpres")) {
17055          user->callingpres = ast_parse_caller_presentation(v->value);
17056          if (user->callingpres == -1)
17057             user->callingpres = atoi(v->value);
17058       } else if (!strcasecmp(v->name, "maxcallbitrate")) {
17059          user->maxcallbitrate = atoi(v->value);
17060          if (user->maxcallbitrate < 0)
17061             user->maxcallbitrate = default_maxcallbitrate;
17062       }
17063       /* We can't just report unknown options here because this may be a
17064        * type=friend entry.  All user options are valid for a peer, but not
17065        * the other way around.  */
17066    }
17067    ast_copy_flags(&user->flags[0], &userflags[0], mask[0].flags);
17068    ast_copy_flags(&user->flags[1], &userflags[1], mask[1].flags);
17069    if (ast_test_flag(&user->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE))
17070       global_allowsubscribe = TRUE; /* No global ban any more */
17071    ast_free_ha(oldha);
17072    return user;
17073 }

static void build_via ( struct sip_pvt p  )  [static]

Build a Via header for a request.

Definition at line 1819 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, SIP_NAT_RFC3581, and SIP_PAGE2_TCP.

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

01820 {
01821    /* Work around buggy UNIDEN UIP200 firmware */
01822    const char *rport = ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_RFC3581 ? ";rport" : "";
01823 
01824    /* z9hG4bK is a magic cookie.  See RFC 3261 section 8.1.1.7 */
01825    ast_string_field_build(p, via, "SIP/2.0/%s %s:%d;branch=z9hG4bK%08x%s",
01826           ast_test_flag(&p->flags[1], SIP_PAGE2_TCP) ? "TCP" : "UDP", ast_inet_ntoa(p->ourip), ourport, p->branch, rport);
01827 }

static int cb_extensionstate ( char *  context,
char *  exten,
int  state,
void *  data 
) [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 8717 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, 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().

08718 {
08719    struct sip_pvt *p = data;
08720 
08721    ast_mutex_lock(&p->lock);
08722 
08723    switch(state) {
08724    case AST_EXTENSION_DEACTIVATED:  /* Retry after a while */
08725    case AST_EXTENSION_REMOVED:   /* Extension is gone */
08726       if (p->autokillid > -1 && sip_cancel_destroy(p))   /* Remove subscription expiry for renewals */
08727          ast_log(LOG_WARNING, "Unable to cancel SIP destruction.  Expect bad things.\n");
08728       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);  /* Delete subscription in 32 secs */
08729       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);
08730       p->stateid = -1;
08731       p->subscribed = NONE;
08732       append_history(p, "Subscribestatus", "%s", state == AST_EXTENSION_REMOVED ? "HintRemoved" : "Deactivated");
08733       break;
08734    default: /* Tell user */
08735       p->laststate = state;
08736       break;
08737    }
08738    if (p->subscribed != NONE) {  /* Only send state NOTIFY if we know the format */
08739       if (!p->pendinginvite) {
08740          transmit_state_notify(p, state, 1, FALSE);
08741       } else {
08742          /* We already have a NOTIFY sent that is not answered. Queue the state up.
08743             if many state changes happen meanwhile, we will only send a notification of the last one */
08744          ast_set_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE);
08745       }
08746    }
08747    if (option_verbose > 1)
08748       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,
08749             ast_test_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE) ? "(queued)" : "");
08750 
08751    
08752    ast_mutex_unlock(&p->lock);
08753 
08754    return 0;
08755 }

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

05063 {
05064    if (global_notifyhold && (!holdstate || !ast_test_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD)))
05065       sip_peer_hold(dialog, holdstate);
05066    if (global_callevents)
05067       manager_event(EVENT_FLAG_CALL, holdstate ? "Hold" : "Unhold",
05068                "Channel: %s\r\n"
05069                "Uniqueid: %s\r\n",
05070                dialog->owner->name, 
05071                dialog->owner->uniqueid);
05072    append_history(dialog, holdstate ? "Hold" : "Unhold", "%s", req->data);
05073    if (!holdstate) {    /* Put off remote hold */
05074       ast_clear_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD);   /* Clear both flags */
05075       return;
05076    }
05077    /* No address for RTP, we're on hold */
05078 
05079    if (sendonly == 1)   /* One directional hold (sendonly/recvonly) */
05080       ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_ONEDIR);
05081    else if (sendonly == 2) /* Inactive stream */
05082       ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_INACTIVE);
05083    else
05084       ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_ACTIVE);
05085    return;
05086 }

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

08525 {
08526    const char *response = "407 Proxy Authentication Required";
08527    const char *reqheader = "Proxy-Authorization";
08528    const char *respheader = "Proxy-Authenticate";
08529    const char *authtoken;
08530    char a1_hash[256];
08531    char resp_hash[256]="";
08532    char *c;
08533    int  wrongnonce = FALSE;
08534    int  good_response;
08535    const char *usednonce = p->randdata;
08536    struct ast_dynamic_str *buf;
08537    int res;
08538 
08539    /* table of recognised keywords, and their value in the digest */
08540    enum keys { K_RESP, K_URI, K_USER, K_NONCE, K_LAST };
08541    struct x {
08542       const char *key;
08543       const char *s;
08544    } *i, keys[] = {
08545       [K_RESP] = { "response=", "" },
08546       [K_URI] = { "uri=", "" },
08547       [K_USER] = { "username=", "" },
08548       [K_NONCE] = { "nonce=", "" },
08549       [K_LAST] = { NULL, NULL}
08550    };
08551 
08552    /* Always OK if no secret */
08553    if (ast_strlen_zero(secret) && ast_strlen_zero(md5secret))
08554       return AUTH_SUCCESSFUL;
08555    if (sipmethod == SIP_REGISTER || sipmethod == SIP_SUBSCRIBE) {
08556       /* On a REGISTER, we have to use 401 and its family of headers instead of 407 and its family
08557          of headers -- GO SIP!  Whoo hoo!  Two things that do the same thing but are used in
08558          different circumstances! What a surprise. */
08559       response = "401 Unauthorized";
08560       reqheader = "Authorization";
08561       respheader = "WWW-Authenticate";
08562    }
08563    authtoken =  get_header(req, reqheader);  
08564    if (ignore && !ast_strlen_zero(p->randdata) && ast_strlen_zero(authtoken)) {
08565       /* This is a retransmitted invite/register/etc, don't reconstruct authentication
08566          information */
08567       if (!reliable) {
08568          /* Resend message if this was NOT a reliable delivery.   Otherwise the
08569             retransmission should get it */
08570          transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0);
08571          /* Schedule auto destroy in 32 seconds (according to RFC 3261) */
08572          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
08573       }
08574       return AUTH_CHALLENGE_SENT;
08575    } else if (ast_strlen_zero(p->randdata) || ast_strlen_zero(authtoken)) {
08576       /* We have no auth, so issue challenge and request authentication */
08577       ast_string_field_build(p, randdata, "%08lx", ast_random()); /* Create nonce for challenge */
08578       transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0);
08579       /* Schedule auto destroy in 32 seconds */
08580       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
08581       return AUTH_CHALLENGE_SENT;
08582    } 
08583 
08584    /* --- We have auth, so check it */
08585 
08586    /* Whoever came up with the authentication section of SIP can suck my %&#$&* for not putting
08587          an example in the spec of just what it is you're doing a hash on. */
08588 
08589    if (!(buf = ast_dynamic_str_thread_get(&check_auth_buf, CHECK_AUTH_BUF_INITLEN)))
08590       return AUTH_SECRET_FAILED; /*! XXX \todo need a better return code here */
08591 
08592    /* Make a copy of the response and parse it */
08593    res = ast_dynamic_str_thread_set(&buf, 0, &check_auth_buf, "%s", authtoken);
08594 
08595    if (res == AST_DYNSTR_BUILD_FAILED)
08596       return AUTH_SECRET_FAILED; /*! XXX \todo need a better return code here */
08597 
08598    c = buf->str;
08599 
08600    while(c && *(c = ast_skip_blanks(c)) ) { /* lookup for keys */
08601       for (i = keys; i->key != NULL; i++) {
08602          const char *separator = ",";  /* default */
08603 
08604          if (strncasecmp(c, i->key, strlen(i->key)) != 0)
08605             continue;
08606          /* Found. Skip keyword, take text in quotes or up to the separator. */
08607          c += strlen(i->key);
08608          if (*c == '"') { /* in quotes. Skip first and look for last */
08609             c++;
08610             separator = "\"";
08611          }
08612          i->s = c;
08613          strsep(&c, separator);
08614          break;
08615       }
08616       if (i->key == NULL) /* not found, jump after space or comma */
08617          strsep(&c, " ,");
08618    }
08619 
08620    /* Verify that digest username matches  the username we auth as */
08621    if (strcmp(username, keys[K_USER].s)) {
08622       ast_log(LOG_WARNING, "username mismatch, have <%s>, digest has <%s>\n",
08623          username, keys[K_USER].s);
08624       /* Oops, we're trying something here */
08625       return AUTH_USERNAME_MISMATCH;
08626    }
08627 
08628    /* Verify nonce from request matches our nonce.  If not, send 401 with new nonce */
08629    if (strcasecmp(p->randdata, keys[K_NONCE].s)) { /* XXX it was 'n'casecmp ? */
08630       wrongnonce = TRUE;
08631       usednonce = keys[K_NONCE].s;
08632    }
08633 
08634    if (!ast_strlen_zero(md5secret))
08635       ast_copy_string(a1_hash, md5secret, sizeof(a1_hash));
08636    else {
08637       char a1[256];
08638       snprintf(a1, sizeof(a1), "%s:%s:%s", username, global_realm, secret);
08639       ast_md5_hash(a1_hash, a1);
08640    }
08641 
08642    /* compute the expected response to compare with what we received */
08643    {
08644       char a2[256];
08645       char a2_hash[256];
08646       char resp[256];
08647 
08648       snprintf(a2, sizeof(a2), "%s:%s", sip_methods[sipmethod].text,
08649             S_OR(keys[K_URI].s, uri));
08650       ast_md5_hash(a2_hash, a2);
08651       snprintf(resp, sizeof(resp), "%s:%s:%s", a1_hash, usednonce, a2_hash);
08652       ast_md5_hash(resp_hash, resp);
08653    }
08654 
08655    good_response = keys[K_RESP].s &&
08656          !strncasecmp(keys[K_RESP].s, resp_hash, strlen(resp_hash));
08657    if (wrongnonce) {
08658       if (good_response) {
08659          if (sipdebug)
08660             ast_log(LOG_NOTICE, "Correct auth, but based on stale nonce received from '%s'\n", get_header(req, "To"));
08661          /* We got working auth token, based on stale nonce . */
08662          ast_string_field_build(p, randdata, "%08lx", ast_random());
08663          transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, TRUE);
08664       } else {
08665          /* Everything was wrong, so give the device one more try with a new challenge */
08666          if (!ast_test_flag(req, SIP_PKT_IGNORE)) {
08667             if (sipdebug)
08668                ast_log(LOG_NOTICE, "Bad authentication received from '%s'\n", get_header(req, "To"));
08669             ast_string_field_build(p, randdata, "%08lx", ast_random());
08670          } else {
08671             if (sipdebug)
08672                ast_log(LOG_NOTICE, "Duplicate authentication received from '%s'\n", get_header(req, "To"));
08673          }
08674          transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, FALSE);
08675       }
08676 
08677       /* Schedule auto destroy in 32 seconds */
08678       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
08679       return AUTH_CHALLENGE_SENT;
08680    } 
08681    if (good_response) {
08682       append_history(p, "AuthOK", "Auth challenge succesful for %s", username);
08683       return AUTH_SUCCESSFUL;
08684    }
08685 
08686    /* Ok, we have a bad username/secret pair */
08687    /* Tell the UAS not to re-send this authentication data, because
08688       it will continue to fail
08689    */
08690 
08691    return AUTH_SECRET_FAILED;
08692 }

static void check_pendings ( struct sip_pvt p  )  [static]

Check pending actions on SIP call.

Definition at line 12207 of file chan_sip.c.

References ast_clear_flag, ast_log(), ast_test_flag, DEFAULT_TRANS_TIMEOUT, FALSE, sip_pvt::flags, INV_CALLING, INV_EARLY_MEDIA, INV_PROCEEDING, sip_pvt::invitestate, LOG_DEBUG, 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().

12208 {
12209    if (ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) {
12210       /* if we can't BYE, then this is really a pending CANCEL */
12211       if (p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA)
12212          transmit_request(p, SIP_CANCEL, p->lastinvite, XMIT_RELIABLE, FALSE);
12213          /* Actually don't destroy us yet, wait for the 487 on our original 
12214             INVITE, but do set an autodestruct just in case we never get it. */
12215       else {
12216          /* We have a pending outbound invite, don't send someting
12217             new in-transaction */
12218          if (p->pendinginvite)
12219             return;
12220 
12221          /* Perhaps there is an SD change INVITE outstanding */
12222          transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, TRUE);
12223       }
12224       ast_clear_flag(&p->flags[0], SIP_PENDINGBYE);   
12225       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
12226    } else if (ast_test_flag(&p->flags[0], SIP_NEEDREINVITE)) {
12227       /* if we can't REINVITE, hold it for later */
12228       if (p->pendinginvite || p->invitestate == INV_CALLING || p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA || p->waitid > 0) {
12229          if (option_debug)
12230             ast_log(LOG_DEBUG, "NOT Sending pending reinvite (yet) on '%s'\n", p->callid);
12231       } else {
12232          if (option_debug)
12233             ast_log(LOG_DEBUG, "Sending pending reinvite on '%s'\n", p->callid);
12234          /* Didn't get to reinvite yet, so do it now */
12235          transmit_reinvite_with_sdp(p);
12236          ast_clear_flag(&p->flags[0], SIP_NEEDREINVITE); 
12237       }
12238    }
12239 }

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

16840 {
16841    struct domain *d;
16842    int result = 0;
16843 
16844    AST_LIST_LOCK(&domain_list);
16845    AST_LIST_TRAVERSE(&domain_list, d, list) {
16846       if (strcasecmp(d->domain, domain))
16847          continue;
16848 
16849       if (len && !ast_strlen_zero(d->context))
16850          ast_copy_string(context, d->context, len);
16851       
16852       result = 1;
16853       break;
16854    }
16855    AST_LIST_UNLOCK(&domain_list);
16856 
16857    return result;
16858 }

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

References check_user_full().

Referenced by handle_request_invite().

09832 {
09833    return check_user_full(p, req, sipmethod, uri, reliable, sin, NULL);
09834 }

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

References sip_peer::accountcode, sip_user::accountcode, accountcode, sip_user::allowtransfer, sip_peer::amaflags, sip_user::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, build_contact(), sip_peer::call_limit, sip_user::call_limit, sip_peer::callgroup, sip_user::callgroup, sip_peer::callingpres, sip_user::callingpres, sip_peer::capability, sip_user::capability, sip_peer::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, context, sip_user::context, debug, do_setnat(), exten, find_peer(), find_user(), sip_peer::flags, sip_user::flags, sip_peer::fullcontact, get_calleridname(), get_header(), get_in_brackets(), get_rpid_num(), sip_user::ha, sip_peer::language, sip_user::language, language, sip_peer::lastms, LOG_NOTICE, sip_peer::maxcallbitrate, sip_user::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_peer::pickupgroup, sip_user::pickupgroup, sip_peer::prefs, sip_user::prefs, 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, strsep(), sip_peer::subscribecontext, sip_user::subscribecontext, t, sip_peer::username, and username.

Referenced by check_user(), and handle_request_subscribe().

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

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

References ahp, ast_gethostbyname(), ast_inet_ntoa(), ast_log(), ast_set_flag, ast_verbose(), sip_pvt::flags, get_header(), hp, 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().

09380 {
09381    char via[512];
09382    char *c, *pt;
09383    struct hostent *hp;
09384    struct ast_hostent ahp;
09385 
09386    ast_copy_string(via, get_header(req, "Via"), sizeof(via));
09387 
09388    /* Work on the leftmost value of the topmost Via header */
09389    c = strchr(via, ',');
09390    if (c)
09391       *c = '\0';
09392 
09393    /* Check for rport */
09394    c = strstr(via, ";rport");
09395    if (c && (c[6] != '=')) /* rport query, not answer */
09396       ast_set_flag(&p->flags[0], SIP_NAT_ROUTE);
09397 
09398    c = strchr(via, ';');
09399    if (c) 
09400       *c = '\0';
09401 
09402    c = strchr(via, ' ');
09403    if (c) {
09404       *c = '\0';
09405       c = ast_skip_blanks(c+1);
09406       if ((strcasecmp(via, "SIP/2.0/UDP")) && (strcasecmp(via, "SIP/2.0/TCP"))) {
09407          ast_log(LOG_WARNING, "Don't know how to respond via '%s'\n", via);
09408          return;
09409       }
09410       pt = strchr(c, ':');
09411       if (pt)
09412          *pt++ = '\0';  /* remember port pointer */
09413       hp = ast_gethostbyname(c, &ahp);
09414       if (!hp) {
09415          ast_log(LOG_WARNING, "'%s' is not a valid host\n", c);
09416          return;
09417       }
09418       memset(&p->sa, 0, sizeof(p->sa));
09419       p->sa.sin_family = AF_INET;
09420       memcpy(&p->sa.sin_addr, hp->h_addr, sizeof(p->sa.sin_addr));
09421       p->sa.sin_port = htons(pt ? atoi(pt) : STANDARD_SIP_PORT);
09422 
09423       if (sip_debug_test_pvt(p)) {
09424          const struct sockaddr_in *dst = sip_real_dst(p);
09425          ast_verbose("Sending to %s : %d (%s)\n", ast_inet_ntoa(dst->sin_addr), ntohs(dst->sin_port), sip_nat_mode(p));
09426       }
09427    }
09428 }

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

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

10276 {
10277    char *oldcontext, *newcontext, *stalecontext, *stringp, newlist[AST_MAX_CONTEXT];
10278 
10279    while ((oldcontext = strsep(&old, "&"))) {
10280       stalecontext = '\0';
10281       ast_copy_string(newlist, new, sizeof(newlist));
10282       stringp = newlist;
10283       while ((newcontext = strsep(&stringp, "&"))) {
10284          if (strcmp(newcontext, oldcontext) == 0) {
10285             /* This is not the context you're looking for */
10286             stalecontext = '\0';
10287             break;
10288          } else if (strcmp(newcontext, oldcontext)) {
10289             stalecontext = oldcontext;
10290          }
10291          
10292       }
10293       if (stalecontext)
10294          ast_context_destroy(ast_context_find(stalecontext), "SIP");
10295    }
10296 }

static int clear_realm_authentication ( struct sip_auth authlist  )  [static]

Clear realm authentication list (at reload).

Definition at line 16932 of file chan_sip.c.

References free, and sip_auth::next.

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

16933 {
16934    struct sip_auth *a = authlist;
16935    struct sip_auth *b;
16936 
16937    while (a) {
16938       b = a;
16939       a = a->next;
16940       free(b);
16941    }
16942 
16943    return 1;
16944 }

static void clear_sip_domains ( void   )  [static]

Clear our domain list (at reload).

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

16862 {
16863    struct domain *d;
16864 
16865    AST_LIST_LOCK(&domain_list);
16866    while ((d = AST_LIST_REMOVE_HEAD(&domain_list, list)))
16867       free(d);
16868    AST_LIST_UNLOCK(&domain_list);
16869 }

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

References complete_sip_peer().

11091 {
11092    if (pos == 3)
11093       return complete_sip_peer(word, state, 0);
11094 
11095    return NULL;
11096 }

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

Do completion on peer name.

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

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

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

References complete_sip_peer(), and SIP_PAGE2_RTCACHEFRIENDS.

11159 {
11160    if (pos == 4)
11161       return complete_sip_peer(word, state, SIP_PAGE2_RTCACHEFRIENDS);
11162    return NULL;
11163 }

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

References complete_sip_user(), and SIP_PAGE2_RTCACHEFRIENDS.

11167 {
11168    if (pos == 4)
11169       return complete_sip_user(word, state, SIP_PAGE2_RTCACHEFRIENDS);
11170 
11171    return NULL;
11172 }

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

References complete_sip_peer().

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

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

References complete_sip_user().

11120 {
11121    if (pos == 3)
11122       return complete_sip_user(word, state, 0);
11123 
11124    return NULL;
11125 }

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

Do completion on user name.

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

11100 {
11101    char *result = NULL;
11102    int wordlen = strlen(word);
11103    int which = 0;
11104 
11105    ASTOBJ_CONTAINER_TRAVERSE(&userl, !result, do {
11106       /* locking of the object is not required because only the name and flags are being compared */
11107       if (!strncasecmp(word, iterator->name, wordlen)) {
11108          if (flags2 && !ast_test_flag(&iterator->flags[1], flags2))
11109             continue;
11110          if (++which > state) {
11111             result = ast_strdup(iterator->name);
11112          }
11113       }
11114    } while(0) );
11115    return result;
11116 }

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

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

11042 {
11043    int which=0;
11044    struct sip_pvt *cur;
11045    char *c = NULL;
11046    int wordlen = strlen(word);
11047 
11048    if (pos != 3) {
11049       return NULL;
11050    }
11051 
11052    ast_mutex_lock(&iflock);
11053    for (cur = iflist; cur; cur = cur->next) {
11054       if (!strncasecmp(word, cur->callid, wordlen) && ++which > state) {
11055          c = ast_strdup(cur->callid);
11056          break;
11057       }
11058    }
11059    ast_mutex_unlock(&iflock);
11060    return c;
11061 }

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

Support routine for 'sip notify' CLI.

Definition at line 11128 of file chan_sip.c.

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

11129 {
11130    char *c = NULL;
11131 
11132    if (pos == 2) {
11133       int which = 0;
11134       char *cat = NULL;
11135       int wordlen = strlen(word);
11136 
11137       /* do completion for notify type */
11138 
11139       if (!notify_types)
11140          return NULL;
11141       
11142       while ( (cat = ast_category_browse(notify_types, cat)) ) {
11143          if (!strncasecmp(word, cat, wordlen) && ++which > state) {
11144             c = ast_strdup(cat);
11145             break;
11146          }
11147       }
11148       return c;
11149    }
11150 
11151    if (pos > 2)
11152       return complete_sip_peer(word, state, 0);
11153 
11154    return NULL;
11155 }

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

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

Referenced by respprep().

05769 {
05770    int start = 0;
05771    int copied = 0;
05772    for (;;) {
05773       const char *tmp = __get_header(orig, field, &start);
05774 
05775       if (ast_strlen_zero(tmp))
05776          break;
05777       /* Add what we're responding to */
05778       add_header(req, field, tmp);
05779       copied++;
05780    }
05781    return copied ? 0 : -1;
05782 }

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

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

Referenced by reqprep(), and respprep().

05758 {
05759    const char *tmp = get_header(orig, field);
05760 
05761    if (!ast_strlen_zero(tmp)) /* Add what we're responding to */
05762       return add_header(req, field, tmp);
05763    ast_log(LOG_NOTICE, "No field '%s' present to copy\n", field);
05764    return -1;
05765 }

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

References offset.

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

06812 {
06813    long offset;
06814    int x;
06815    offset = ((void *)dst) - ((void *)src);
06816    /* First copy stuff */
06817    memcpy(dst, src, sizeof(*dst));
06818    /* Now fix pointer arithmetic */
06819    for (x=0; x < src->headers; x++)
06820       dst->header[x] += offset;
06821    for (x=0; x < src->lines; x++)
06822       dst->line[x] += offset;
06823    dst->rlPart1 += offset;
06824    dst->rlPart2 += offset;
06825 }

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

05791 {
05792    int copied = 0;
05793    int start = 0;
05794 
05795    for (;;) {
05796       char new[512];
05797       const char *oh = __get_header(orig, field, &start);
05798 
05799       if (ast_strlen_zero(oh))
05800          break;
05801 
05802       if (!copied) { /* Only check for empty rport in topmost via header */
05803          char leftmost[512], *others, *rport;
05804 
05805          /* Only work on leftmost value */
05806          ast_copy_string(leftmost, oh, sizeof(leftmost));
05807          others = strchr(leftmost, ',');
05808          if (others)
05809              *others++ = '\0';
05810 
05811          /* Find ;rport;  (empty request) */
05812          rport = strstr(leftmost, ";rport");
05813          if (rport && *(rport+6) == '=') 
05814             rport = NULL;     /* We already have a parameter to rport */
05815 
05816          /* Check rport if NAT=yes or NAT=rfc3581 (which is the default setting)  */
05817          if (rport && ((ast_test_flag(&p->flags[0], SIP_NAT) == SIP_NAT_ALWAYS) || (ast_test_flag(&p->flags[0], SIP_NAT) == SIP_NAT_RFC3581))) {
05818             /* We need to add received port - rport */
05819             char *end;
05820 
05821             rport = strstr(leftmost, ";rport");
05822 
05823             if (rport) {
05824                end = strchr(rport + 1, ';');
05825                if (end)
05826                   memmove(rport, end, strlen(end) + 1);
05827                else
05828                   *rport = '\0';
05829             }
05830 
05831             /* Add rport to first VIA header if requested */
05832             snprintf(new, sizeof(new), "%s;received=%s;rport=%d%s%s",
05833                leftmost, ast_inet_ntoa(p->recv.sin_addr),
05834                ntohs(p->recv.sin_port),
05835                others ? "," : "", others ? others : "");
05836          } else {
05837             /* We should *always* add a received to the topmost via */
05838             snprintf(new, sizeof(new), "%s;received=%s%s%s",
05839                leftmost, ast_inet_ntoa(p->recv.sin_addr),
05840                others ? "," : "", others ? others : "");
05841          }
05842          oh = new;   /* the header to copy */
05843       }  /* else add the following via headers untouched */
05844       add_header(req, field, oh);
05845       copied++;
05846    }
05847    if (!copied) {
05848       ast_log(LOG_NOTICE, "No header field '%s' present to copy\n", field);
05849       return -1;
05850    }
05851    return 0;
05852 }

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

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

02911 {
02912    struct hostent *hp;
02913    struct ast_hostent ahp;
02914    struct sip_peer *p;
02915    char *port;
02916    int portno;
02917    char host[MAXHOSTNAMELEN], *hostn;
02918    char peer[256];
02919 
02920    ast_copy_string(peer, opeer, sizeof(peer));
02921    port = strchr(peer, ':');
02922    if (port)
02923       *port++ = '\0';
02924    dialog->sa.sin_family = AF_INET;
02925    dialog->timer_t1 = 500; /* Default SIP retransmission timer T1 (RFC 3261) */
02926    p = find_peer(peer, NULL, 1, 0);
02927 
02928    if (p) {
02929       int res = create_addr_from_peer(dialog, p);
02930       if (port) {
02931          portno = atoi(port);
02932          dialog->sa.sin_port = dialog->recv.sin_port = htons(portno);
02933       }
02934       ASTOBJ_UNREF(p, sip_destroy_peer);
02935       return res;
02936    }
02937    hostn = peer;
02938    portno = port ? atoi(port) : STANDARD_SIP_PORT;
02939    if (srvlookup) {
02940       char service[MAXHOSTNAMELEN];
02941       int tportno;
02942       int ret;
02943 
02944       snprintf(service, sizeof(service), "_sip._udp.%s", peer);
02945       ret = ast_get_srv(NULL, host, sizeof(host), &tportno, service);
02946       if (ret > 0) {
02947          hostn = host;
02948          portno = tportno;
02949       }
02950    }
02951    hp = ast_gethostbyname(hostn, &ahp);
02952    if (!hp) {
02953       ast_log(LOG_WARNING, "No such host: %s\n", peer);
02954       return -1;
02955    }
02956    ast_string_field_set(dialog, tohost, peer);
02957    memcpy(&dialog->sa.sin_addr, hp->h_addr, sizeof(dialog->sa.sin_addr));
02958    dialog->sa.sin_port = htons(portno);
02959    dialog->recv = dialog->sa;
02960    return 0;
02961 }

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 2799 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::auth, 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, 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_pvt::peerauth, 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_TCP, SIP_PAGE2_TCP_CONNECTED, SIP_PAGE2_VIDEOSUPPORT, sip_peer::sockfd, sip_pvt::sockfd, 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().

02800 {
02801    if ((peer->addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr) &&
02802        (!peer->maxms || ((peer->lastms >= 0)  && (peer->lastms <= peer->maxms)))) {
02803       dialog->sa = (peer->addr.sin_addr.s_addr) ? peer->addr : peer->defaddr;
02804       dialog->recv = dialog->sa;
02805    } else 
02806       return -1;
02807 
02808    ast_copy_flags(&dialog->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY);
02809    ast_copy_flags(&dialog->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY);
02810    ast_copy_flags(&dialog->flags[1], &peer->flags[1], SIP_PAGE2_TCP | SIP_PAGE2_TCP_CONNECTED);
02811    dialog->sockfd = peer->sockfd;
02812    dialog->capability = peer->capability;
02813    if ((!ast_test_flag(&dialog->flags[1], SIP_PAGE2_VIDEOSUPPORT) || !(dialog->capability & AST_FORMAT_VIDEO_MASK)) && dialog->vrtp) {
02814       ast_rtp_destroy(dialog->vrtp);
02815       dialog->vrtp = NULL;
02816    }
02817    dialog->prefs = peer->prefs;
02818    if (ast_test_flag(&dialog->flags[1], SIP_PAGE2_T38SUPPORT)) {
02819       dialog->t38.capability = global_t38_capability;
02820       if (dialog->udptl) {
02821          if (ast_udptl_get_error_correction_scheme(dialog->udptl) == UDPTL_ERROR_CORRECTION_FEC )
02822             dialog->t38.capability |= T38FAX_UDP_EC_FEC;
02823          else if (ast_udptl_get_error_correction_scheme(dialog->udptl) == UDPTL_ERROR_CORRECTION_REDUNDANCY )
02824             dialog->t38.capability |= T38FAX_UDP_EC_REDUNDANCY;
02825          else if (ast_udptl_get_error_correction_scheme(dialog->udptl) == UDPTL_ERROR_CORRECTION_NONE )
02826             dialog->t38.capability |= T38FAX_UDP_EC_NONE;
02827          dialog->t38.capability |= T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF;
02828          if (option_debug > 1)
02829             ast_log(LOG_DEBUG,"Our T38 capability (%d)\n", dialog->t38.capability);
02830       }
02831       dialog->t38.jointcapability = dialog->t38.capability;
02832    } else if (dialog->udptl) {
02833       ast_udptl_destroy(dialog->udptl);
02834       dialog->udptl = NULL;
02835    }
02836    do_setnat(dialog, ast_test_flag(&dialog->flags[0], SIP_NAT) & SIP_NAT_ROUTE );
02837 
02838    if (dialog->rtp) {
02839       ast_rtp_setdtmf(dialog->rtp, ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833);
02840       ast_rtp_setdtmfcompensate(dialog->rtp, ast_test_flag(&dialog->flags[1], SIP_PAGE2_RFC2833_COMPENSATE));
02841       ast_rtp_set_rtptimeout(dialog->rtp, peer->rtptimeout);
02842       ast_rtp_set_rtpholdtimeout(dialog->rtp, peer->rtpholdtimeout);
02843       ast_rtp_set_rtpkeepalive(dialog->rtp, peer->rtpkeepalive);
02844       /* Set Frame packetization */
02845       ast_rtp_codec_setpref(dialog->rtp, &dialog->prefs);
02846       dialog->autoframing = peer->autoframing;
02847    }
02848    if (dialog->vrtp) {
02849       ast_rtp_setdtmf(dialog->vrtp, 0);
02850       ast_rtp_setdtmfcompensate(dialog->vrtp, 0);
02851       ast_rtp_set_rtptimeout(dialog->vrtp, peer->rtptimeout);
02852       ast_rtp_set_rtpholdtimeout(dialog->vrtp, peer->rtpholdtimeout);
02853       ast_rtp_set_rtpkeepalive(dialog->vrtp, peer->rtpkeepalive);
02854    }
02855 
02856    ast_string_field_set(dialog, peername, peer->name);
02857    ast_string_field_set(dialog, authname, peer->username);
02858    ast_string_field_set(dialog, username, peer->username);
02859    ast_string_field_set(dialog, peersecret, peer->secret);
02860    ast_string_field_set(dialog, peermd5secret, peer->md5secret);
02861    ast_string_field_set(dialog, mohsuggest, peer->mohsuggest);
02862    ast_string_field_set(dialog, mohinterpret, peer->mohinterpret);
02863    ast_string_field_set(dialog, tohost, peer->tohost);
02864    ast_string_field_set(dialog, fullcontact, peer->fullcontact);
02865    if (!dialog->initreq.headers && !ast_strlen_zero(peer->fromdomain)) {
02866       char *tmpcall;
02867       char *c;
02868       tmpcall = ast_strdupa(dialog->callid);
02869       c = strchr(tmpcall, '@');
02870       if (c) {
02871          *c = '\0';
02872          ast_string_field_build(dialog, callid, "%s@%s", tmpcall, peer->fromdomain);
02873       }
02874    }
02875    if (ast_strlen_zero(dialog->tohost))
02876       ast_string_field_set(dialog, tohost, ast_inet_ntoa(dialog->sa.sin_addr));
02877    if (!ast_strlen_zero(peer->fromdomain))
02878       ast_string_field_set(dialog, fromdomain, peer->fromdomain);
02879    if (!ast_strlen_zero(peer->fromuser))
02880       ast_string_field_set(dialog, fromuser, peer->fromuser);
02881    if (!ast_strlen_zero(peer->language))
02882       ast_string_field_set(dialog, language, peer->language);
02883    dialog->maxtime = peer->maxms;
02884    dialog->callgroup = peer->callgroup;
02885    dialog->pickupgroup = peer->pickupgroup;
02886    dialog->peerauth = peer->auth;
02887    dialog->allowtransfer = peer->allowtransfer;
02888    /* Set timer T1 to RTT for this peer (if known by qualify=) */
02889    /* Minimum is settable or default to 100 ms */
02890    if (peer->maxms && peer->lastms)
02891       dialog->timer_t1 = peer->lastms < global_t1min ? global_t1min : peer->lastms;
02892    if ((ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) ||
02893        (ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_AUTO))
02894       dialog->noncodeccapability |= AST_RTP_DTMF;
02895    else
02896       dialog->noncodeccapability &= ~AST_RTP_DTMF;
02897    dialog->jointnoncodeccapability = dialog->noncodeccapability;
02898    ast_string_field_set(dialog, context, peer->context);
02899    dialog->rtptimeout = peer->rtptimeout;
02900    if (peer->call_limit)
02901       ast_set_flag(&dialog->flags[0], SIP_CALL_LIMIT);
02902    dialog->maxcallbitrate = peer->maxcallbitrate;
02903    
02904    return 0;
02905 }

static void destroy_association ( struct sip_peer peer  )  [static]

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

Definition at line 7999 of file chan_sip.c.

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

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

08000 {
08001    if (!ast_test_flag(&global_flags[1], SIP_PAGE2_IGNOREREGEXPIRE)) {
08002       if (ast_test_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT))
08003          ast_update_realtime("sippeers", "name", peer->name, "fullcontact", "", "ipaddr", "", "port", "", "regseconds", "0", "username", "", "regserver", "", NULL);
08004       else 
08005          ast_db_del("SIP/Registry", peer->name);
08006    }
08007 }

static int determine_firstline_parts ( struct sip_request req  )  [static]

Parse first line of incoming SIP request.

Definition at line 6855 of file chan_sip.c.

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

Referenced by parse_request().

06856 {
06857    char *e = ast_skip_blanks(req->header[0]);   /* there shouldn't be any */
06858 
06859    if (!*e)
06860       return -1;
06861    req->rlPart1 = e; /* method or protocol */
06862    e = ast_skip_nonblanks(e);
06863    if (*e)
06864       *e++ = '\0';
06865    /* Get URI or status code */
06866    e = ast_skip_blanks(e);
06867    if ( !*e )
06868       return -1;
06869    ast_trim_blanks(e);
06870 
06871    if (!strcasecmp(req->rlPart1, "SIP/2.0") ) { /* We have a response */
06872       if (strlen(e) < 3)   /* status code is 3 digits */
06873          return -1;
06874       req->rlPart2 = e;
06875    } else { /* We have a request */
06876       if ( *e == '<' ) { /* XXX the spec says it must not be in <> ! */
06877          ast_log(LOG_WARNING, "bogus uri in <> %s\n", e);
06878          e++;
06879          if (!*e)
06880             return -1; 
06881       }
06882       req->rlPart2 = e; /* URI */
06883       e = ast_skip_nonblanks(e);
06884       if (*e)
06885          *e++ = '\0';
06886       e = ast_skip_blanks(e);
06887       if (strcasecmp(e, "SIP/2.0") ) {
06888          ast_log(LOG_WARNING, "Bad request protocol %s\n", e);
06889          return -1;
06890       }
06891    }
06892    return 1;
06893 }

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 16128 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_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_SOFTHANGUP_DEV, ast_softhangup_nolock(), AST_STATE_UP, ast_test_flag, ast_verbose(), DEADLOCK_AVOIDANCE, FALSE, sip_pvt::flags, iflist, io, sip_pvt::lock, LOG_NOTICE, sip_pvt::next, option_verbose, sip_pvt::owner, sip_pvt::packets, sip_do_reload(), SIP_NEEDDESTROY, sipsock, sipsock_read(), siptcpsock, siptcpsock_accept(), t, T38_ENABLED, and VERBOSE_PREFIX_1.

16129 {
16130    int res;
16131    struct sip_pvt *sip;
16132    struct sip_peer *peer = NULL;
16133    time_t t;
16134    int fastrestart = FALSE;
16135    int lastpeernum = -1;
16136    int curpeernum;
16137    int reloading;
16138 
16139    /* Add an I/O event to our SIP UDP socket */
16140    if (sipsock > -1) 
16141       sipsock_read_id = ast_io_add(io, sipsock, sipsock_read, AST_IO_IN, NULL);
16142    if (siptcpsock > -1) 
16143       siptcpsock_read_id = ast_io_add(io, siptcpsock, siptcpsock_accept, AST_IO_IN, NULL);
16144    
16145    /* From here on out, we die whenever asked */
16146    for(;;) {
16147       /* Check for a reload request */
16148       ast_mutex_lock(&sip_reload_lock);
16149       reloading = sip_reloading;
16150       sip_reloading = FALSE;
16151       ast_mutex_unlock(&sip_reload_lock);
16152       if (reloading) {
16153          if (option_verbose > 0)
16154             ast_verbose(VERBOSE_PREFIX_1 "Reloading SIP\n");
16155          sip_do_reload(sip_reloadreason);
16156 
16157          /* Change the I/O fd of our UDP socket */
16158          if (sipsock > -1) {
16159             if (sipsock_read_id)
16160                sipsock_read_id = ast_io_change(io, sipsock_read_id, sipsock, NULL, 0, NULL);
16161             else
16162                sipsock_read_id = ast_io_add(io, sipsock, sipsock_read, AST_IO_IN, NULL);
16163          } else if (sipsock_read_id) {
16164             ast_io_remove(io, sipsock_read_id);
16165             sipsock_read_id = NULL;
16166          }
16167 
16168          if (siptcpsock > -1) {
16169             if (siptcpsock_read_id)
16170                siptcpsock_read_id = ast_io_change(io, siptcpsock_read_id, siptcpsock, NULL, 0, NULL);
16171             else
16172                siptcpsock_read_id = ast_io_add(io, siptcpsock, siptcpsock_accept, AST_IO_IN, NULL);
16173          }
16174       }
16175 restartsearch:    
16176       /* Check for interfaces needing to be killed */
16177       ast_mutex_lock(&iflock);
16178       t = time(NULL);
16179       /* don't scan the interface list if it hasn't been a reasonable period
16180          of time since the last time we did it (when MWI is being sent, we can
16181          get back to this point every millisecond or less)
16182       */
16183       for (sip = iflist; !fastrestart && sip; sip = sip->next) {
16184          /*! \note If we can't get a lock on an interface, skip it and come
16185           * back later. Note that there is the possibility of a deadlock with
16186           * sip_hangup otherwise, because sip_hangup is called with the channel
16187           * locked first, and the iface lock is attempted second.
16188           */
16189          if (ast_mutex_trylock(&sip->lock))
16190             continue;
16191 
16192          /* Check RTP timeouts and kill calls if we have a timeout set and do not get RTP */
16193          if (sip->rtp && sip->owner &&
16194              (sip->owner->_state == AST_STATE_UP) &&
16195              !sip->redirip.sin_addr.s_addr &&
16196              sip->t38.state != T38_ENABLED) {
16197             if (sip->lastrtptx &&
16198                 ast_rtp_get_rtpkeepalive(sip->rtp) &&
16199                 (t > sip->lastrtptx + ast_rtp_get_rtpkeepalive(sip->rtp))) {
16200                /* Need to send an empty RTP packet */
16201                sip->lastrtptx = time(NULL);
16202                ast_rtp_sendcng(sip->rtp, 0);
16203             }
16204             if (sip->lastrtprx &&
16205                (ast_rtp_get_rtptimeout(sip->rtp) || ast_rtp_get_rtpholdtimeout(sip->rtp)) &&
16206                 (t > sip->lastrtprx + ast_rtp_get_rtptimeout(sip->rtp))) {
16207                /* Might be a timeout now -- see if we're on hold */
16208                struct sockaddr_in sin;
16209                ast_rtp_get_peer(sip->rtp, &sin);
16210                if (sin.sin_addr.s_addr || 
16211                    (ast_rtp_get_rtpholdtimeout(sip->rtp) &&
16212                     (t > sip->lastrtprx + ast_rtp_get_rtpholdtimeout(sip->rtp)))) {
16213                   /* Needs a hangup */
16214                   if (ast_rtp_get_rtptimeout(sip->rtp)) {
16215                      while (sip->owner && ast_channel_trylock(sip->owner)) {
16216                         DEADLOCK_AVOIDANCE(&sip->lock);
16217                      }
16218                      if (sip->owner) {
16219                         ast_log(LOG_NOTICE,
16220                            "Disconnecting call '%s' for lack of RTP activity in %ld seconds\n",
16221                            sip->owner->name,
16222                            (long) (t - sip->lastrtprx));
16223                         /* Issue a softhangup */
16224                         ast_softhangup_nolock(sip->owner, AST_SOFTHANGUP_DEV);
16225                         ast_channel_unlock(sip->owner);
16226                         /* forget the timeouts for this call, since a hangup
16227                            has already been requested and we don't want to
16228                            repeatedly request hangups
16229                         */
16230                         ast_rtp_set_rtptimeout(sip->rtp, 0);
16231                         ast_rtp_set_rtpholdtimeout(sip->rtp, 0);
16232                         if (sip->vrtp) {
16233                            ast_rtp_set_rtptimeout(sip->vrtp, 0);
16234                            ast_rtp_set_rtpholdtimeout(sip->vrtp, 0);
16235                         }
16236                      }
16237                   }
16238                }
16239             }
16240          }
16241          /* If we have sessions that needs to be destroyed, do it now */
16242          if (ast_test_flag(&sip->flags[0], SIP_NEEDDESTROY) && !sip->packets &&
16243              !sip->owner) {
16244             ast_mutex_unlock(&sip->lock);
16245             __sip_destroy(sip, 1);
16246             ast_mutex_unlock(&iflock);
16247             usleep(1);
16248             goto restartsearch;
16249          }
16250          ast_mutex_unlock(&sip->lock);
16251       }
16252       ast_mutex_unlock(&iflock);
16253 
16254       /* XXX TODO The scheduler usage in this module does not have sufficient 
16255        * synchronization being done between running the scheduler and places 
16256        * scheduling tasks.  As it is written, any scheduled item may not run 
16257        * any sooner than about  1 second, regardless of whether a sooner time 
16258        * was asked for. */
16259 
16260       pthread_testcancel();
16261       /* Wait for sched or io */
16262       res = ast_sched_wait(sched);
16263       if ((res < 0) || (res > 1000))
16264          res = 1000;
16265       /* If we might need to send more mailboxes, don't wait long at all.*/
16266       if (fastrestart)
16267          res = 1;
16268       res = ast_io_wait(io, res);
16269       if (option_debug && res > 20)
16270          ast_log(LOG_DEBUG, "chan_sip: ast_io_wait ran %d all at once\n", res);
16271       ast_mutex_lock(&monlock);
16272       res = ast_sched_runq(sched);
16273       if (option_debug && res >= 20)
16274          ast_log(LOG_DEBUG, "chan_sip: ast_sched_runq ran %d all at once\n", res);
16275 
16276       /* Send MWI notifications to peers - static and cached realtime peers */
16277       t = time(NULL);
16278       fastrestart = FALSE;
16279       curpeernum = 0;
16280       peer = NULL;
16281       /* Find next peer that needs mwi */
16282       ASTOBJ_CONTAINER_TRAVERSE(&peerl, !peer, do {
16283          if ((curpeernum > lastpeernum) && does_peer_need_mwi(iterator)) {
16284             fastrestart = TRUE;
16285             lastpeernum = curpeernum;
16286             peer = ASTOBJ_REF(iterator);
16287          };
16288          curpeernum++;
16289       } while (0)
16290       );
16291       /* Send MWI to the peer */
16292       if (peer) {
16293          ASTOBJ_WRLOCK(peer);
16294          sip_send_mwi_to_peer(peer);
16295          ASTOBJ_UNLOCK(peer);
16296          ASTOBJ_UNREF(peer,sip_destroy_peer);
16297       } else {
16298          /* Reset where we come from */
16299          lastpeernum = -1;
16300       }
16301       ast_mutex_unlock(&monlock);
16302    }
16303    /* Never reached */
16304    return NULL;
16305    
16306 }

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

11639 {
11640    char digest[1024];
11641 
11642    if (!p->options && !(p->options = ast_calloc(1, sizeof(*p->options))))
11643       return -2;
11644 
11645    p->authtries++;
11646    if (option_debug > 1)
11647       ast_log(LOG_DEBUG, "Auth attempt %d on %s\n", p->authtries, sip_methods[sipmethod].text);
11648    memset(digest, 0, sizeof(digest));
11649    if (reply_digest(p, req, header, sipmethod, digest, sizeof(digest) )) {
11650       /* No way to authenticate */
11651       return -1;
11652    }
11653    /* Now we have a reply digest */
11654    p->options->auth = digest;
11655    p->options->authheader = respheader;
11656    return transmit_invite(p, sipmethod, sipmethod == SIP_INVITE, init); 
11657 }

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

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

Referenced by handle_response_register().

11618 {
11619    char digest[1024];
11620    p->authtries++;
11621    memset(digest,0,sizeof(digest));
11622    if (reply_digest(p, req, header, SIP_REGISTER, digest, sizeof(digest))) {
11623       /* There's nothing to use for authentication */
11624       /* No digest challenge in request */
11625       if (sip_debug_test_pvt(p) && p->registry)
11626          ast_verbose("No authentication challenge, sending blank registration to domain/host name %s\n", p->registry->hostname);
11627          /* No old challenge */
11628       return -1;
11629    }
11630    if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY))
11631       append_history(p, "RegistryAuth", "Try: %d", p->authtries);
11632    if (sip_debug_test_pvt(p) && p->registry)
11633       ast_verbose("Responding to challenge, registration to domain/host name %s\n", p->registry->hostname);
11634    return transmit_register(p->registry, SIP_REGISTER, digest, respheader); 
11635 }

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

Set nat mode on the various data sockets.

Definition at line 2775 of file chan_sip.c.

References ast_log(), ast_rtp_setnat(), ast_udptl_setnat(), LOG_DEBUG, 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().

02776 {
02777    const char *mode = natflags ? "On" : "Off";
02778 
02779    if (p->rtp) {
02780       if (option_debug)
02781          ast_log(LOG_DEBUG, "Setting NAT on RTP to %s\n", mode);
02782       ast_rtp_setnat(p->rtp, natflags);
02783    }
02784    if (p->vrtp) {
02785       if (option_debug)
02786          ast_log(LOG_DEBUG, "Setting NAT on VRTP to %s\n", mode);
02787       ast_rtp_setnat(p->vrtp, natflags);
02788    }
02789    if (p->udptl) {
02790       if (option_debug)
02791          ast_log(LOG_DEBUG, "Setting NAT on UDPTL to %s\n", mode);
02792       ast_udptl_setnat(p->udptl, natflags);
02793    }
02794 }

static int does_peer_need_mwi ( struct sip_peer peer  )  [static]

Check whether peer needs a new MWI notification check.

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

16108 {
16109    time_t t = time(NULL);
16110 
16111    if (ast_test_flag(&peer->flags[1], SIP_PAGE2_SUBSCRIBEMWIONLY) &&
16112        !peer->mwipvt) { /* We don't have a subscription */
16113       peer->lastmsgcheck = t; /* Reset timer */
16114       return FALSE;
16115    }
16116 
16117    if (!ast_strlen_zero(peer->mailbox) && (t - peer->lastmsgcheck) > global_mwitime)
16118       return TRUE;
16119 
16120    return FALSE;
16121 }

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

Print domain mode to cli.

Definition at line 10464 of file chan_sip.c.

References SIP_DOMAIN_AUTO, and SIP_DOMAIN_CONFIG.

Referenced by sip_show_domains().

10465 {
10466    switch (mode) {
10467    case SIP_DOMAIN_AUTO:
10468       return "[Automatic]";
10469    case SIP_DOMAIN_CONFIG:
10470       return "[Configured]";
10471    }
10472 
10473    return "";
10474 }

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

Convert DTMF mode to printable string.

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

10245 {
10246    switch (mode) {
10247    case SIP_DTMF_RFC2833:
10248       return "rfc2833";
10249    case SIP_DTMF_INFO:
10250       return "info";
10251    case SIP_DTMF_INBAND:
10252       return "inband";
10253    case SIP_DTMF_AUTO:
10254       return "auto";
10255    }
10256    return "<error>";
10257 }

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

Expire registration of SIP peer.

Definition at line 8010 of file chan_sip.c.

References sip_peer::addr, ast_clear_flag, 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, SIP_PAGE2_SELFDESTRUCT, SIP_PAGE2_TCP_CONNECTED, and sip_peer::sockfd.

Referenced by parse_register_contact(), and reg_source_db().

08011 {
08012    struct sip_peer *peer = (struct sip_peer *)data;
08013    
08014    if (!peer)     /* Hmmm. We have no peer. Weird. */
08015       return 0;
08016 
08017    memset(&peer->addr, 0, sizeof(peer->addr));
08018    if (peer->sockfd > 0) {
08019       close(peer->sockfd);
08020       ast_clear_flag(&peer->flags[1], SIP_PAGE2_TCP_CONNECTED);
08021    }
08022 
08023    destroy_association(peer); /* remove registration data from storage */
08024    
08025    manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name);
08026    register_peer_exten(peer, FALSE);   /* Remove regexten */
08027    peer->expire = -1;
08028    ast_device_state_changed("SIP/%s", peer->name);
08029 
08030    /* Do we need to release this peer from memory? 
08031       Only for realtime peers and autocreated peers
08032    */
08033    if (ast_test_flag(&peer->flags[1], SIP_PAGE2_SELFDESTRUCT) ||
08034        ast_test_flag(&peer->flags[1], SIP_PAGE2_RTAUTOCLEAR)) {
08035       struct sip_peer *peer_ptr = peer_ptr;
08036       peer_ptr = ASTOBJ_CONTAINER_UNLINK(&peerl, peer);
08037       if (peer_ptr) {
08038          ASTOBJ_UNREF(peer_ptr, sip_destroy_peer);
08039       }
08040    }
08041 
08042    ASTOBJ_UNREF(peer, sip_destroy_peer);
08043 
08044    return 0;
08045 }

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

Check Contact: URI of SIP message.

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

06946 {
06947    char stripped[SIPBUFSIZE];
06948    char *c;
06949 
06950    ast_copy_string(stripped, get_header(req, "Contact"), sizeof(stripped));
06951    c = get_in_brackets(stripped);
06952    c = strsep(&c, ";"); /* trim ; and beyond */
06953    if (!ast_strlen_zero(c))
06954       ast_string_field_set(p, uri, c);
06955 }

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

References aliases.

04289 {
04290    /*! \brief Structure for conversion between compressed SIP and "normal" SIP */
04291    static const struct cfalias {
04292       char * const fullname;
04293       char * const shortname;
04294    } aliases[] = {
04295       { "Content-Type",  "c" },
04296       { "Content-Encoding",    "e" },
04297       { "From",       "f" },
04298       { "Call-ID",       "i" },
04299       { "Contact",       "m" },
04300       { "Content-Length",   "l" },
04301       { "Subject",       "s" },
04302       { "To",         "t" },
04303       { "Supported",     "k" },
04304       { "Refer-To",      "r" },
04305       { "Referred-By",   "b" },
04306       { "Allow-Events",  "u" },
04307       { "Event",      "o" },
04308       { "Via",     "v" },
04309       { "Accept-Contact",      "a" },
04310       { "Reject-Contact",      "j" },
04311       { "Request-Disposition", "d" },
04312       { "Session-Expires",     "x" },
04313       { "Identity",            "y" },
04314       { "Identity-Info",       "n" },
04315    };
04316    int x;
04317 
04318    for (x=0; x<sizeof(aliases) / sizeof(aliases[0]); x++) 
04319       if (!strcasecmp(aliases[x].fullname, name))
04320          return aliases[x].shortname;
04321 
04322    return _default;
04323 }

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

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

Definition at line 4648 of file chan_sip.c.

References ast_log(), ast_mutex_lock(), ast_set_flag, ast_strlen_zero(), ast_test_flag, FALSE, sip_pvt::flags, get_header(), gettag(), iflist, LOG_DEBUG, sip_request::method, sip_pvt::next, option_debug, SIP_PAGE2_DIALOG_ESTABLISHED, SIP_PKT_WITH_TOTAG, SIP_REGISTER, SIP_RESPONSE, and sip_pvt::tag.

Referenced by sipsock_read().

04649 {
04650    struct sip_pvt *p = NULL;
04651    char *tag = "";   /* note, tag is never NULL */
04652    char totag[128];
04653    char fromtag[128];
04654    const char *callid = get_header(req, "Call-ID");
04655    const char *from = get_header(req, "From");
04656    const char *to = get_header(req, "To");
04657    const char *cseq = get_header(req, "Cseq");
04658 
04659    /* Call-ID, to, from and Cseq are required by RFC 3261. (Max-forwards and via too - ignored now) */
04660    /* get_header always returns non-NULL so we must use ast_strlen_zero() */
04661    if (ast_strlen_zero(callid) || ast_strlen_zero(to) ||
04662          ast_strlen_zero(from) || ast_strlen_zero(cseq))
04663       return NULL;   /* Invalid packet */
04664 
04665    if (pedanticsipchecking) {
04666       /* In principle Call-ID's uniquely identify a call, but with a forking SIP proxy
04667          we need more to identify a branch - so we have to check branch, from
04668          and to tags to identify a call leg.
04669          For Asterisk to behave correctly, you need to turn on pedanticsipchecking
04670          in sip.conf
04671          */
04672       if (gettag(req, "To", totag, sizeof(totag)))
04673          ast_set_flag(req, SIP_PKT_WITH_TOTAG); /* Used in handle_request/response */
04674       gettag(req, "From", fromtag, sizeof(fromtag));
04675 
04676       tag = (req->method == SIP_RESPONSE) ? totag : fromtag;
04677 
04678       if (option_debug > 4 )
04679          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);
04680    }
04681 
04682    ast_mutex_lock(&iflock);
04683    for (p = iflist; p; p = p->next) {
04684       /* In pedantic, we do not want packets with bad syntax to be connected to a PVT */
04685       int found = FALSE;
04686       if (ast_strlen_zero(p->callid))
04687          continue;
04688       if (req->method == SIP_REGISTER)
04689          found = (!strcmp(p->callid, callid));
04690       else {
04691          found = !strcmp(p->callid, callid);
04692          if (pedanticsipchecking && found) {
04693             found = ast_strlen_zero(tag) || ast_strlen_zero(p->theirtag) || !ast_test_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED) || !strcmp(p->theirtag, tag);
04694          }
04695       }
04696 
04697       if (option_debug > 4)
04698          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);
04699 
04700       /* If we get a new request within an existing to-tag - check the to tag as well */
04701       if (pedanticsipchecking && found  && req->method != SIP_RESPONSE) {  /* SIP Request */
04702          if (p->tag[0] == '\0' && totag[0]) {
04703             /* We have no to tag, but they have. Wrong dialog */
04704             found = FALSE;
04705          } else if (totag[0]) {        /* Both have tags, compare them */
04706             if (strcmp(totag, p->tag)) {
04707                found = FALSE;    /* This is not our packet */
04708             }
04709          }
04710          if (!found && option_debug > 4)
04711             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);
04712       }
04713       if (found) {
04714          /* Found the call */
04715          ast_mutex_lock(&p->lock);
04716          ast_mutex_unlock(&iflock);
04717          return p;
04718       }
04719    }
04720    ast_mutex_unlock(&iflock);
04721 
04722    /* See if the method is capable of creating a dialog */
04723    if (sip_methods[intended_method].can_create == CAN_CREATE_DIALOG) {
04724       if (intended_method == SIP_REFER) {
04725          /* We do support REFER, but not outside of a dialog yet */
04726          transmit_response_using_temp(callid, sin, 1, intended_method, req, "603 Declined (no dialog)");
04727       } else if (intended_method == SIP_NOTIFY) {
04728          /* We do not support out-of-dialog NOTIFY either,
04729             like voicemail notification, so cancel that early */
04730          transmit_response_using_temp(callid, sin, 1, intended_method, req, "489 Bad event");
04731       } else {
04732          /* Ok, time to create a new SIP dialog object, a pvt */
04733          if ((p = sip_alloc(callid, sin, 1, intended_method)))  {
04734             /* Ok, we've created a dialog, let's go and process it */
04735             ast_mutex_lock(&p->lock);
04736          } else {
04737             /* We have a memory or file/socket error (can't allocate RTP sockets or something) so we're not
04738                getting a dialog from sip_alloc. 
04739    
04740                Without a dialog we can't retransmit and handle ACKs and all that, but at least
04741                send an error message.
04742    
04743                Sorry, we apologize for the inconvienience
04744             */
04745             transmit_response_using_temp(callid, sin, 1, intended_method, req, "500 Server internal error");
04746             if (option_debug > 3)
04747                ast_log(LOG_DEBUG, "Failed allocating SIP dialog, sending 500 Server internal error and giving up\n");
04748          }
04749       }
04750       return p;
04751    } else if( sip_methods[intended_method].can_create == CAN_CREATE_DIALOG_UNSUPPORTED_METHOD) {
04752       /* A method we do not support, let's take it on the volley */
04753       transmit_response_using_temp(callid, sin, 1, intended_method, req, "501 Method Not Implemented");
04754    } else if (intended_method != SIP_RESPONSE && intended_method != SIP_ACK) {
04755       /* This is a request outside of a dialog that we don't know about 
04756          ...never reply to an ACK!
04757       */
04758       transmit_response_using_temp(callid, sin, 1, intended_method, req, "481 Call leg/transaction does not exist");
04759    }
04760    /* We do not respond to responses for dialogs that we don't know about, we just drop
04761       the session quickly */
04762 
04763    return p;
04764 }

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

References s.

Referenced by get_in_brackets().

02340 {
02341         char last_char = '\0';
02342         const char *s;
02343         for (s = start; *s && s != lim; last_char = *s++) {
02344                 if (*s == '"' && last_char != '\\')
02345                         break;
02346         }
02347         return s;
02348 }

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

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

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

02688 {
02689    struct sip_peer *p = NULL;
02690 
02691    if (peer)
02692       p = ASTOBJ_CONTAINER_FIND(&peerl, peer);
02693    else
02694       p = ASTOBJ_CONTAINER_FIND_FULL(&peerl, sin, name, sip_addr_hashfunc, 1, sip_addrcmp);
02695 
02696    if (!p && (realtime || devstate_only))
02697       p = realtime_peer(peer, sin, devstate_only);
02698 
02699    return p;
02700 }

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

Find authentication for a specific realm.

Definition at line 16947 of file chan_sip.c.

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

Referenced by build_reply_digest().

16948 {
16949    struct sip_auth *a;
16950 
16951    for (a = authlist; a; a = a->next) {
16952       if (!strcasecmp(a->realm, realm))
16953          break;
16954    }
16955 
16956    return a;
16957 }

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

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

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

04971 {
04972    const char *content_type;
04973    const char *content_length;
04974    const char *search;
04975    char *boundary;
04976    unsigned int x;
04977    int boundaryisquoted = FALSE;
04978    int found_application_sdp = FALSE;
04979    int found_end_of_headers = FALSE;
04980 
04981    content_length = get_header(req, "Content-Length");
04982 
04983    if (!ast_strlen_zero(content_length)) {
04984       if (sscanf(content_length, "%ud", &x) != 1) {
04985          ast_log(LOG_WARNING, "Invalid Content-Length: %s\n", content_length);
04986          return 0;
04987       }
04988 
04989       /* Content-Length of zero means there can't possibly be an
04990          SDP here, even if the Content-Type says there is */
04991       if (x == 0)
04992          return 0;
04993    }
04994 
04995    content_type = get_header(req, "Content-Type");
04996 
04997    /* if the body contains only SDP, this is easy */
04998    if (!strncasecmp(content_type, "application/sdp", 15)) {
04999       req->sdp_start = 0;
05000       req->sdp_end = req->lines;
05001       return req->lines ? 1 : 0;
05002    }
05003 
05004    /* if it's not multipart/mixed, there cannot be an SDP */
05005    if (strncasecmp(content_type, "multipart/mixed", 15))
05006       return 0;
05007 
05008    /* if there is no boundary marker, it's invalid */
05009    if ((search = strcasestr(content_type, ";boundary=")))
05010       search += 10;
05011    else if ((search = strcasestr(content_type, "; boundary=")))
05012       search += 11;
05013    else
05014       return 0;
05015 
05016    if (ast_strlen_zero(search))
05017       return 0;
05018 
05019    /* If the boundary is quoted with ", remove quote */
05020    if (*search == '\"')  {
05021       search++;
05022       boundaryisquoted = TRUE;
05023    }
05024 
05025    /* make a duplicate of the string, with two extra characters
05026       at the beginning */
05027    boundary = ast_strdupa(search - 2);
05028    boundary[0] = boundary[1] = '-';
05029    /* Remove final quote */
05030    if (boundaryisquoted)
05031       boundary[strlen(boundary) - 1] = '\0';
05032 
05033    /* search for the boundary marker, the empty line delimiting headers from
05034       sdp part and the end boundry if it exists */
05035 
05036    for (x = 0; x < (req->lines ); x++) {
05037       if(!strncasecmp(req->line[x], boundary, strlen(boundary))){
05038          if(found_application_sdp && found_end_of_headers){
05039             req->sdp_end = x-1;
05040             return 1;
05041          }
05042          found_application_sdp = FALSE;
05043       }
05044       if(!strcasecmp(req->line[x], "Content-Type: application/sdp"))
05045          found_application_sdp = TRUE;
05046       
05047       if(strlen(req->line[x]) == 0 ){
05048          if(found_application_sdp && !found_end_of_headers){
05049             req->sdp_start = x;
05050             found_end_of_headers = TRUE;
05051          }
05052       }
05053    }
05054    if(found_application_sdp && found_end_of_headers) {
05055       req->sdp_end = x;
05056       return TRUE;
05057    }
05058    return FALSE;
05059 }

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

find_sip_method: Find SIP method from header

Definition at line 1691 of file chan_sip.c.

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

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

01692 {
01693    int i, res = 0;
01694    
01695    if (ast_strlen_zero(msg))
01696       return 0;
01697    for (i = 1; i < (sizeof(sip_methods) / sizeof(sip_methods[0])) && !res; i++) {
01698       if (method_match(i, msg))
01699          res = sip_methods[i].id;
01700    }
01701    return res;
01702 }

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

Find subscription type in array.

Definition at line 10953 of file chan_sip.c.

References subscription_types, and type.

Referenced by transmit_state_notify().

10954 {
10955    int i;
10956 
10957    for (i = 1; (i < (sizeof(subscription_types) / sizeof(subscription_types[0]))); i++) {
10958       if (subscription_types[i].type == subtype) {
10959          return &subscription_types[i];
10960       }
10961    }
10962    return &subscription_types[0];
10963 }

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

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

References ASTOBJ_CONTAINER_FIND, realtime_user(), and userl.

02767 {
02768    struct sip_user *u = ASTOBJ_CONTAINER_FIND(&userl, name);
02769    if (!u && realtime)
02770       u = realtime_user(name);
02771    return u;
02772 }

static void free_old_route ( struct sip_route route  )  [static]

Remove route from route list.

Definition at line 8386 of file chan_sip.c.

References free, and sip_route::next.

Referenced by __sip_destroy(), and build_route().

08387 {
08388    struct sip_route *next;
08389 
08390    while (route) {
08391       next = route->next;
08392       free(route);
08393       route = next;
08394    }
08395 }

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

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

11974 {
11975    if (ast_strlen_zero(data)) {
11976       ast_log(LOG_WARNING, "CHECKSIPDOMAIN requires an argument - A domain name\n");
11977       return -1;
11978    }
11979    if (check_sip_domain(data, NULL, 0))
11980       ast_copy_string(buf, data, len);
11981    else
11982       buf[0] = '\0';
11983    return 0;
11984 }

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 11909 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, sip_tech, sip_tech_info, ast_channel::tech, and ast_channel::tech_pvt.

11910 {
11911    struct sip_pvt *p;
11912    const char *content = NULL;
11913    AST_DECLARE_APP_ARGS(args,
11914       AST_APP_ARG(header);
11915       AST_APP_ARG(number);
11916    );
11917    int i, number, start = 0;
11918 
11919    if (ast_strlen_zero(data)) {
11920       ast_log(LOG_WARNING, "This function requires a header name.\n");
11921       return -1;
11922    }
11923 
11924    ast_channel_lock(chan);
11925    if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) {
11926       ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n");
11927       ast_channel_unlock(chan);
11928       return -1;
11929    }
11930 
11931    AST_STANDARD_APP_ARGS(args, data);
11932    if (!args.number) {
11933       number = 1;
11934    } else {
11935       sscanf(args.number, "%d", &number);
11936       if (number < 1)
11937          number = 1;
11938    }
11939 
11940    p = chan->tech_pvt;
11941 
11942    /* If there is no private structure, this channel is no longer alive */
11943    if (!p) {
11944       ast_channel_unlock(chan);
11945       return -1;
11946    }
11947 
11948    for (i = 0; i < number; i++)
11949       content = __get_header(&p->initreq, args.header, &start);
11950 
11951    if (ast_strlen_zero(content)) {
11952       ast_channel_unlock(chan);
11953       return -1;
11954    }
11955 
11956    ast_copy_string(buf, content, len);
11957    ast_channel_unlock(chan);
11958 
11959    return 0;
11960 }

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

References ast_channel_lock, ast_channel_unlock, ast_inet_ntoa(), ast_log(), 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.

12089 {
12090    struct sip_pvt *p;
12091 
12092    *buf = 0;
12093    
12094    if (!data) {
12095       ast_log(LOG_WARNING, "This function requires a parameter name.\n");
12096       return -1;
12097    }
12098 
12099    ast_channel_lock(chan);
12100    if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) {
12101       ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n");
12102       ast_channel_unlock(chan);
12103       return -1;
12104    }
12105 
12106    p = chan->tech_pvt;
12107 
12108    /* If there is no private structure, this channel is no longer alive */
12109    if (!p) {
12110       ast_channel_unlock(chan);
12111       return -1;
12112    }
12113 
12114    if (!strcasecmp(data, "peerip")) {
12115       ast_copy_string(buf, p->sa.sin_addr.s_addr ? ast_inet_ntoa(p->sa.sin_addr) : "", len);
12116    } else  if (!strcasecmp(data, "recvip")) {
12117       ast_copy_string(buf, p->recv.sin_addr.s_addr ? ast_inet_ntoa(p->recv.sin_addr) : "", len);
12118    } else  if (!strcasecmp(data, "from")) {
12119       ast_copy_string(buf, p->from, len);
12120    } else  if (!strcasecmp(data, "uri")) {
12121       ast_copy_string(buf, p->uri, len);
12122    } else  if (!strcasecmp(data, "useragent")) {
12123       ast_copy_string(buf, p->useragent, len);
12124    } else  if (!strcasecmp(data, "peername")) {
12125       ast_copy_string(buf, p->peername, len);
12126    } else if (!strcasecmp(data, "t38passthrough")) {
12127       if (p->t38.state == T38_DISABLED)
12128          ast_copy_string(buf, "0", sizeof("0"));
12129       else    /* T38 is offered or enabled in this call */
12130          ast_copy_string(buf, "1", sizeof("1"));
12131    } else {
12132       ast_channel_unlock(chan);
12133       return -1;
12134    }
12135    ast_channel_unlock(chan);
12136 
12137    return 0;
12138 }

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

11999 {
12000    struct sip_peer *peer;
12001    char *colname;
12002 
12003    if ((colname = strchr(data, ':')))  /*! \todo Will be deprecated after 1.4 */
12004       *colname++ = '\0';
12005    else if ((colname = strchr(data, '|')))
12006       *colname++ = '\0';
12007    else
12008       colname = "ip";
12009 
12010    if (!(peer = find_peer(data, NULL, 1, 0)))
12011       return -1;
12012 
12013    if (!strcasecmp(colname, "ip")) {
12014       ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "", len);
12015    } else  if (!strcasecmp(colname, "status")) {
12016       peer_status(peer, buf, len);
12017    } else  if (!strcasecmp(colname, "language")) {
12018       ast_copy_string(buf, peer->language, len);
12019    } else  if (!strcasecmp(colname, "regexten")) {
12020       ast_copy_string(buf, peer->regexten, len);
12021    } else  if (!strcasecmp(colname, "limit")) {
12022       snprintf(buf, len, "%d", peer->call_limit);
12023    } else  if (!strcasecmp(colname, "curcalls")) {
12024       snprintf(buf, len, "%d", peer->inUse);
12025    } else  if (!strcasecmp(colname, "accountcode")) {
12026       ast_copy_string(buf, peer->accountcode, len);
12027    } else  if (!strcasecmp(colname, "useragent")) {
12028       ast_copy_string(buf, peer->useragent, len);
12029    } else  if (!strcasecmp(colname, "mailbox")) {
12030       ast_copy_string(buf, peer->mailbox, len);
12031    } else  if (!strcasecmp(colname, "context")) {
12032       ast_copy_string(buf, peer->context, len);
12033    } else  if (!strcasecmp(colname, "expire")) {
12034       snprintf(buf, len, "%d", peer->expire);
12035    } else  if (!strcasecmp(colname, "dynamic")) {
12036       ast_copy_string(buf, (ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC) ? "yes" : "no"), len);
12037    } else  if (!strcasecmp(colname, "callerid_name")) {
12038       ast_copy_string(buf, peer->cid_name, len);
12039    } else  if (!strcasecmp(colname, "callerid_num")) {
12040       ast_copy_string(buf, peer->cid_num, len);
12041    } else  if (!strcasecmp(colname, "codecs")) {
12042       ast_getformatname_multiple(buf, len -1, peer->capability);
12043    } else  if (!strncasecmp(colname, "codec[", 6)) {
12044       char *codecnum;
12045       int index = 0, codec = 0;
12046       
12047       codecnum = colname + 6; /* move past the '[' */
12048       codecnum = strsep(&codecnum, "]"); /* trim trailing ']' if any */
12049       index = atoi(codecnum);
12050       if((codec = ast_codec_pref_index(&peer->prefs, index))) {
12051          ast_copy_string(buf, ast_getformatname(codec), len);
12052       }
12053    }
12054 
12055    ASTOBJ_UNREF(peer, sip_destroy_peer);
12056 
12057    return 0;
12058 }

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

Generate 32 byte random string for callid's etc.

Definition at line 4478 of file chan_sip.c.

References ast_random().

Referenced by build_callid_pvt(), and build_callid_registry().

04479 {
04480    long val[4];
04481    int x;
04482 
04483    for (x=0; x<4; x++)
04484       val[x] = ast_random();
04485    snprintf(buf, size, "%08lx%08lx%08lx%08lx", val[0], val[1], val[2], val[3]);
04486 
04487    return buf;
04488 }

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 9319 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(), context, get_header(), get_in_brackets(), sip_pvt::initreq, LOG_DEBUG, 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().

09320 {
09321    char tmp[256] = "", *c, *a;
09322    struct sip_request *req = oreq ? oreq : &p->initreq;
09323    struct sip_refer *referdata = NULL;
09324    const char *transfer_context = NULL;
09325    
09326    if (!p->refer && !sip_refer_allocate(p))
09327       return -1;
09328 
09329    referdata = p->refer;
09330 
09331    ast_copy_string(tmp, get_header(req, "Also"), sizeof(tmp));
09332    c = get_in_brackets(tmp);
09333 
09334    if (pedanticsipchecking)
09335       ast_uri_decode(c);
09336    
09337    if (strncasecmp(c, "sip:", 4)) {
09338       ast_log(LOG_WARNING, "Huh?  Not a SIP header in Also: transfer (%s)?\n", c);
09339       return -1;
09340    }
09341    c += 4;
09342    if ((a = strchr(c, ';')))  /* Remove arguments */
09343       *a = '\0';
09344    
09345    if ((a = strchr(c, '@'))) {   /* Separate Domain */
09346       *a++ = '\0';
09347       ast_copy_string(referdata->refer_to_domain, a, sizeof(referdata->refer_to_domain));
09348    }
09349    
09350    if (sip_debug_test_pvt(p))
09351       ast_verbose("Looking for %s in %s\n", c, p->context);
09352 
09353    if (p->owner)  /* Mimic behaviour in res_features.c */
09354       transfer_context = pbx_builtin_getvar_helper(p->owner, "TRANSFER_CONTEXT");
09355 
09356    /* By default, use the context in the channel sending the REFER */
09357    if (ast_strlen_zero(transfer_context)) {
09358       transfer_context = S_OR(p->owner->macrocontext,
09359                S_OR(p->context, default_context));
09360    }
09361    if (ast_exists_extension(NULL, transfer_context, c, 1, NULL)) {
09362       /* This is a blind transfer */
09363       if (option_debug)
09364          ast_log(LOG_DEBUG,"SIP Bye-also transfer to Extension %s@%s \n", c, transfer_context);
09365       ast_copy_string(referdata->refer_to, c, sizeof(referdata->refer_to));
09366       ast_copy_string(referdata->referred_by, "", sizeof(referdata->referred_by));
09367       ast_copy_string(referdata->refer_contact, "", sizeof(referdata->refer_contact));
09368       referdata->refer_call = NULL;
09369       /* Set new context */
09370       ast_string_field_set(p, context, transfer_context);
09371       return 0;
09372    } else if (ast_canmatch_extension(NULL, p->context, c, 1, NULL)) {
09373       return 1;
09374    }
09375 
09376    return -1;
09377 }

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

Get a specific line from the message body.

Definition at line 4272 of file chan_sip.c.

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

Referenced by handle_request_info().

04273 {
04274    int x;
04275    int len = strlen(name);
04276    char *r;
04277 
04278    for (x = 0; x < req->lines; x++) {
04279       r = get_body_by_line(req->line[x], name, len);
04280       if (r[0] != '\0')
04281          return r;
04282    }
04283 
04284    return "";
04285 }

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

Referenced by get_body(), and get_sdp_iterate().

04239 {
04240    if (strncasecmp(line, name, nameLen) == 0 && line[nameLen] == '=')
04241       return ast_skip_blanks(line + nameLen + 1);
04242 
04243    return "";
04244 }

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

Get caller id name from SIP headers.

Definition at line 9431 of file chan_sip.c.

Referenced by check_user_full().

09432 {
09433    const char *end = strchr(input,'<');   /* first_bracket */
09434    const char *tmp = strchr(input,'"');   /* first quote */
09435    int bytes = 0;
09436    int maxbytes = outputsize - 1;
09437 
09438    if (!end || end == input)  /* we require a part in brackets */
09439       return NULL;
09440 
09441    end--; /* move just before "<" */
09442 
09443    if (tmp && tmp <= end) {
09444       /* The quote (tmp) precedes the bracket (end+1).
09445        * Find the matching quote and return the content.
09446        */
09447       end = strchr(tmp+1, '"');
09448       if (!end)
09449          return NULL;
09450       bytes = (int) (end - tmp);
09451       /* protect the output buffer */
09452       if (bytes > maxbytes)
09453          bytes = maxbytes;
09454       ast_copy_string(output, tmp + 1, bytes);
09455    } else {
09456       /* No quoted string, or it is inside brackets. */
09457       /* clear the empty characters in the begining*/
09458       input = ast_skip_blanks(input);
09459       /* clear the empty characters in the end */
09460       while(*end && *end < 33 && end > input)
09461          end--;
09462       if (end >= input) {
09463          bytes = (int) (end - input) + 2;
09464          /* protect the output buffer */
09465          if (bytes > maxbytes)
09466             bytes = maxbytes;
09467          ast_copy_string(output, input, bytes);
09468       } else
09469          return NULL;
09470    }
09471    return output;
09472 }

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 8966 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(), context, exten, get_header(), get_in_brackets(), global_flags, sip_pvt::initreq, LOG_DEBUG, 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, and strsep().

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

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

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

Get header from SIP request.

Definition at line 4361 of file chan_sip.c.

References __get_header().

04362 {
04363    int start = 0;
04364    return __get_header(req, name, &start);
04365 }

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

02362 {
02363    const char *parse = tmp;
02364    char *first_bracket;
02365 
02366    /*
02367     * Skip any quoted text until we find the part in brackets.
02368          * On any error give up and return the full string.
02369          */
02370         while ( (first_bracket = strchr(parse, '<')) ) {
02371                 char *first_quote = strchr(parse, '"');
02372 
02373       if (!first_quote || first_quote > first_bracket)
02374          break; /* no need to look at quoted part */
02375       /* the bracket is within quotes, so ignore it */
02376       parse = find_closing_quote(first_quote + 1, NULL);
02377       if (!*parse) { /* not found, return full string ? */
02378          /* XXX or be robust and return in-bracket part ? */
02379          ast_log(LOG_WARNING, "No closing quote found in '%s'\n", tmp);
02380          break;
02381       }
02382       parse++;
02383    }
02384    if (first_bracket) {
02385       char *second_bracket = strchr(first_bracket + 1, '>');
02386       if (second_bracket) {
02387          *second_bracket = '\0';
02388          tmp = first_bracket + 1;
02389       } else {
02390          ast_log(LOG_WARNING, "No closing bracket found in '%s'\n", tmp);
02391       }
02392    }
02393    return tmp;
02394 }

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

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

Referenced by handle_request_notify(), and receive_message().

09838 {
09839    int x;
09840    int y;
09841 
09842    buf[0] = '\0';
09843    y = len - strlen(buf) - 5;
09844    if (y < 0)
09845       y = 0;
09846    for (x=0;x<req->lines;x++) {
09847       strncat(buf, req->line[x], y); /* safe */
09848       y -= strlen(req->line[x]) + 1;
09849       if (y < 0)
09850          y = 0;
09851       if (y != 0)
09852          strcat(buf, "\n"); /* safe */
09853    }
09854    return 0;
09855 }

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

Get referring dnis.

Definition at line 8937 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, sip_debug_test_pvt(), and strsep().

Referenced by handle_request_invite().

08938 {
08939    char tmp[256], *c, *a;
08940    struct sip_request *req;
08941    
08942    req = oreq;
08943    if (!req)
08944       req = &p->initreq;
08945    ast_copy_string(tmp, get_header(req, "Diversion"), sizeof(tmp));
08946    if (ast_strlen_zero(tmp))
08947       return 0;
08948    c = get_in_brackets(tmp);
08949    if (strncasecmp(c, "sip:", 4)) {
08950       ast_log(LOG_WARNING, "Huh?  Not an RDNIS SIP header (%s)?\n", c);
08951       return -1;
08952    }
08953    c += 4;
08954    a = c;
08955    strsep(&a, "@;"); /* trim anything after @ or ; */
08956    if (sip_debug_test_pvt(p))
08957       ast_verbose("RDNIS is %s\n", c);
08958    ast_string_field_set(p, rdnis, c);
08959 
08960    return 0;
08961 }

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

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

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

References AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED.

Referenced by check_user_full().

09479 {
09480    char *start;
09481    char *end;
09482 
09483    start = strchr(input,':');
09484    if (!start) {
09485       output[0] = '\0';
09486       return 0;
09487    }
09488    start++;
09489 
09490    /* we found "number" */
09491    ast_copy_string(output,start,maxlen);
09492    output[maxlen-1] = '\0';
09493 
09494    end = strchr(output,'@');
09495    if (end)
09496       *end = '\0';
09497    else
09498       output[0] = '\0';
09499    if (strstr(input,"privacy=full") || strstr(input,"privacy=uri"))
09500       return AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED;
09501 
09502    return 0;
09503 }

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

Get a line from an SDP message body.

Definition at line 4264 of file chan_sip.c.

References get_sdp_iterate().

04265 {
04266    int dummy = 0;
04267 
04268    return get_sdp_iterate(&dummy, req, name);
04269 }

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

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

04251 {
04252    int len = strlen(name);
04253 
04254    while (*start < req->sdp_end) {
04255       const char *r = get_body_by_line(req->line[(*start)++], name, len);
04256       if (r[0] != '\0')
04257          return r;
04258    }
04259 
04260    return "";
04261 }

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

Lock interface lock and find matching pvt lock.

Definition at line 9091 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_PAGE2_OUTGOING_CALL, and sip_pvt::tag.

Referenced by handle_request_invite(), and local_attended_transfer().

09092 {
09093    struct sip_pvt *sip_pvt_ptr;
09094 
09095    ast_mutex_lock(&iflock);
09096 
09097    if (option_debug > 3 && totag)
09098       ast_log(LOG_DEBUG, "Looking for callid %s (fromtag %s totag %s)\n", callid, fromtag ? fromtag : "<no fromtag>", totag ? totag : "<no totag>");
09099 
09100    /* Search interfaces and find the match */
09101    for (sip_pvt_ptr = iflist; sip_pvt_ptr; sip_pvt_ptr = sip_pvt_ptr->next) {
09102       if (!strcmp(sip_pvt_ptr->callid, callid)) {
09103          int match = 1;
09104 
09105          /* Go ahead and lock it (and its owner) before returning */
09106          ast_mutex_lock(&sip_pvt_ptr->lock);
09107 
09108          /* Check if tags match. If not, this is not the call we want
09109             (With a forking SIP proxy, several call legs share the
09110             call id, but have different tags)
09111          */
09112          if (pedanticsipchecking) {
09113             const char *pvt_fromtag, *pvt_totag;
09114 
09115             if (ast_test_flag(&sip_pvt_ptr->flags[1], SIP_PAGE2_OUTGOING_CALL)) {
09116                /* Outgoing call tags : from is "our", to is "their" */
09117                pvt_fromtag = sip_pvt_ptr->tag ;
09118                pvt_totag = sip_pvt_ptr->theirtag ;
09119             } else {
09120                /* Incoming call tags : from is "their", to is "our" */
09121                pvt_fromtag = sip_pvt_ptr->theirtag ;
09122                pvt_totag = sip_pvt_ptr->tag ;
09123             }
09124             if (ast_strlen_zero(fromtag) || strcmp(fromtag, pvt_fromtag) || (!ast_strlen_zero(totag) && strcmp(totag, pvt_totag)))
09125                match = 0;
09126          }
09127 
09128          if (!match) {
09129             ast_mutex_unlock(&sip_pvt_ptr->lock);
09130             continue;
09131          }
09132 
09133          if (option_debug > 3 && totag)             
09134             ast_log(LOG_DEBUG, "Matched %s call - their tag is %s Our tag is %s\n",
09135                ast_test_flag(&sip_pvt_ptr->flags[1], SIP_PAGE2_OUTGOING_CALL) ? "OUTGOING": "INCOMING",
09136                sip_pvt_ptr->theirtag, sip_pvt_ptr->tag);
09137 
09138          /* deadlock avoidance... */
09139          while (sip_pvt_ptr->owner && ast_channel_trylock(sip_pvt_ptr->owner)) {
09140             DEADLOCK_AVOIDANCE(&sip_pvt_ptr->lock);
09141          }
09142          break;
09143       }
09144    }
09145    ast_mutex_unlock(&iflock);
09146    if (option_debug > 3 && !sip_pvt_ptr)
09147       ast_log(LOG_DEBUG, "Found no match for callid %s to-tag %s from-tag %s\n", callid, totag, fromtag);
09148    return sip_pvt_ptr;
09149 }

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

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

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

13531 {
13532    const char *thetag;
13533 
13534    if (!tagbuf)
13535       return NULL;
13536    tagbuf[0] = '\0';    /* reset the buffer */
13537    thetag = get_header(req, header);
13538    thetag = strcasestr(thetag, ";tag=");
13539    if (thetag) {
13540       thetag += 5;
13541       ast_copy_string(tagbuf, thetag, tagbufsize);
13542       return strsep(&tagbuf, ";");
13543    }
13544    return NULL;
13545 }

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

References ast_clear_flag, ast_false(), ast_log(), ast_set2_flag, ast_set_flag, ast_true(), ast_channel::flags, ast_variable::lineno, 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(), and build_user().

16697 {
16698    int res = 1;
16699 
16700    if (!strcasecmp(v->name, "trustrpid")) {
16701       ast_set_flag(&mask[0], SIP_TRUSTRPID);
16702       ast_set2_flag(&flags[0], ast_true(v->value), SIP_TRUSTRPID);
16703    } else if (!strcasecmp(v->name, "sendrpid")) {
16704       ast_set_flag(&mask[0], SIP_SENDRPID);
16705       ast_set2_flag(&flags[0], ast_true(v->value), SIP_SENDRPID);
16706    } else if (!strcasecmp(v->name, "g726nonstandard")) {
16707       ast_set_flag(&mask[0], SIP_G726_NONSTANDARD);
16708       ast_set2_flag(&flags[0], ast_true(v->value), SIP_G726_NONSTANDARD);
16709    } else if (!strcasecmp(v->name, "useclientcode")) {
16710       ast_set_flag(&mask[0], SIP_USECLIENTCODE);
16711       ast_set2_flag(&flags[0], ast_true(v->value), SIP_USECLIENTCODE);
16712    } else if (!strcasecmp(v->name, "dtmfmode")) {
16713       ast_set_flag(&mask[0], SIP_DTMF);
16714       ast_clear_flag(&flags[0], SIP_DTMF);
16715       if (!strcasecmp(v->value, "inband"))
16716          ast_set_flag(&flags[0], SIP_DTMF_INBAND);
16717       else if (!strcasecmp(v->value, "rfc2833"))
16718          ast_set_flag(&flags[0], SIP_DTMF_RFC2833);
16719       else if (!strcasecmp(v->value, "info"))
16720          ast_set_flag(&flags[0], SIP_DTMF_INFO);
16721       else if (!strcasecmp(v->value, "auto"))
16722          ast_set_flag(&flags[0], SIP_DTMF_AUTO);
16723       else {
16724          ast_log(LOG_WARNING, "Unknown dtmf mode '%s' on line %d, using rfc2833\n", v->value, v->lineno);
16725          ast_set_flag(&flags[0], SIP_DTMF_RFC2833);
16726       }
16727    } else if (!strcasecmp(v->name, "nat")) {
16728       ast_set_flag(&mask[0], SIP_NAT);
16729       ast_clear_flag(&flags[0], SIP_NAT);
16730       if (!strcasecmp(v->value, "never"))
16731          ast_set_flag(&flags[0], SIP_NAT_NEVER);
16732       else if (!strcasecmp(v->value, "route"))
16733          ast_set_flag(&flags[0], SIP_NAT_ROUTE);
16734       else if (ast_true(v->value))
16735          ast_set_flag(&flags[0], SIP_NAT_ALWAYS);
16736       else
16737          ast_set_flag(&flags[0], SIP_NAT_RFC3581);
16738    } else if (!strcasecmp(v->name, "canreinvite")) {
16739       ast_set_flag(&mask[0], SIP_REINVITE);
16740       ast_clear_flag(&flags[0], SIP_REINVITE);
16741       if(ast_true(v->value)) {
16742          ast_set_flag(&flags[0], SIP_CAN_REINVITE | SIP_CAN_REINVITE_NAT);
16743       } else if (!ast_false(v->value)) {
16744          char buf[64];
16745          char *word, *next = buf;
16746 
16747          ast_copy_string(buf, v->value, sizeof(buf));
16748          while ((word = strsep(&next, ","))) {
16749             if(!strcasecmp(word, "update")) {
16750                ast_set_flag(&flags[0], SIP_REINVITE_UPDATE | SIP_CAN_REINVITE);
16751             } else if(!strcasecmp(word, "nonat")) {
16752                ast_set_flag(&flags[0], SIP_CAN_REINVITE);
16753                ast_clear_flag(&flags[0], SIP_CAN_REINVITE_NAT);
16754             } else {
16755                ast_log(LOG_WARNING, "Unknown canreinvite mode '%s' on line %d\n", v->value, v->lineno);
16756             }
16757          }
16758       }
16759    } else if (!strcasecmp(v->name, "insecure")) {
16760       ast_set_flag(&mask[0], SIP_INSECURE_PORT | SIP_INSECURE_INVITE);
16761       ast_clear_flag(&flags[0], SIP_INSECURE_PORT | SIP_INSECURE_INVITE);
16762       set_insecure_flags(flags, v->value, v->lineno);
16763    } else if (!strcasecmp(v->name, "progressinband")) {
16764       ast_set_flag(&mask[0], SIP_PROG_INBAND);
16765       ast_clear_flag(&flags[0], SIP_PROG_INBAND);
16766       if (ast_true(v->value))
16767          ast_set_flag(&flags[0], SIP_PROG_INBAND_YES);
16768       else if (strcasecmp(v->value, "never"))
16769          ast_set_flag(&flags[0], SIP_PROG_INBAND_NO);
16770    } else if (!strcasecmp(v->name, "promiscredir")) {
16771       ast_set_flag(&mask[0], SIP_PROMISCREDIR);
16772       ast_set2_flag(&flags[0], ast_true(v->value), SIP_PROMISCREDIR);
16773    } else if (!strcasecmp(v->name, "videosupport")) {
16774       ast_set_flag(&mask[1], SIP_PAGE2_VIDEOSUPPORT);
16775       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_VIDEOSUPPORT);
16776    } else if (!strcasecmp(v->name, "allowoverlap")) {
16777       ast_set_flag(&mask[1], SIP_PAGE2_ALLOWOVERLAP);
16778       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_ALLOWOVERLAP);
16779    } else if (!strcasecmp(v->name, "allowsubscribe")) {
16780       ast_set_flag(&mask[1], SIP_PAGE2_ALLOWSUBSCRIBE);
16781       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_ALLOWSUBSCRIBE);
16782    } else if (!strcasecmp(v->name, "t38pt_udptl")) {
16783       ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT_UDPTL);
16784       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_T38SUPPORT_UDPTL);
16785 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS
16786    } else if (!strcasecmp(v->name, "t38pt_rtp")) {
16787       ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT_RTP);
16788       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_T38SUPPORT_RTP);
16789    } else if (!strcasecmp(v->name, "t38pt_tcp")) {
16790       ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT_TCP);
16791       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_T38SUPPORT_TCP);
16792 #endif
16793    } else if (!strcasecmp(v->name, "rfc2833compensate")) {
16794       ast_set_flag(&mask[1], SIP_PAGE2_RFC2833_COMPENSATE);
16795       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_RFC2833_COMPENSATE);
16796    } else if (!strcasecmp(v->name, "buggymwi")) {
16797       ast_set_flag(&mask[1], SIP_PAGE2_BUGGY_MWI);
16798       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_BUGGY_MWI);
16799    } else if (!strcasecmp(v->name, "t38pt_usertpsource")) {
16800       ast_set_flag(&mask[1], SIP_PAGE2_UDPTL_DESTINATION);
16801       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_UDPTL_DESTINATION);
16802    } else
16803       res = 0;
16804 
16805    return res;
16806 }

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 13715 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, sip_pvt::lock, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, option_debug, sip_pvt::owner, sip_pvt::refer, sip_refer::refer_call, SIP_DEFER_BYE_ON_TRANSFER, sip_scheddestroy(), transmit_response(), transmit_response_reliable(), transmit_response_with_sdp(), and XMIT_RELIABLE.

Referenced by handle_request_invite().

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

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 15690 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, 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, cfsip_methods::id, sip_pvt::initreq, INV_TERMINATED, len, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, sip_request::method, option_debug, process_sdp(), sip_request::rlPart1, sip_request::rlPart2, 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.

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

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

Handle incoming BYE request.

Definition at line 15251 of file chan_sip.c.

References __sip_pretend_ack(), append_history, ast_async_goto(), ast_bridged_channel(), ast_clear_flag, 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, 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_PAGE2_DIALOG_ESTABLISHED, SIP_PKT_IGNORE, sip_scheddestroy(), stop_media_flows(), transmit_response(), transmit_response_reliable(), and sip_pvt::vrtp.

Referenced by handle_request().

15252 {
15253    struct ast_channel *c=NULL;
15254    int res;
15255    struct ast_channel *bridged_to;
15256    
15257    /* If we have an INCOMING invite that we haven't answered, terminate that transaction */
15258    if (p->pendinginvite && !ast_test_flag(&p->flags[0], SIP_OUTGOING) && !ast_test_flag(req, SIP_PKT_IGNORE) && !p->owner) 
15259       transmit_response_reliable(p, "487 Request Terminated", &p->initreq);
15260 
15261    __sip_pretend_ack(p);
15262 
15263    p->invitestate = INV_TERMINATED;
15264 
15265    copy_request(&p->initreq, req);
15266    check_via(p, req);
15267    sip_alreadygone(p);
15268 
15269    /* Get RTCP quality before end of call */
15270    if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY) || p->owner) {
15271       char *audioqos, *videoqos;
15272       if (p->rtp) {
15273          audioqos = ast_rtp_get_quality(p->rtp, NULL);
15274          if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY))
15275             append_history(p, "RTCPaudio", "Quality:%s", audioqos);
15276          if (p->owner)
15277             pbx_builtin_setvar_helper(p->owner, "RTPAUDIOQOS", audioqos);
15278       }
15279       if (p->vrtp) {
15280          videoqos = ast_rtp_get_quality(p->vrtp, NULL);
15281          if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY))
15282             append_history(p, "RTCPvideo", "Quality:%s", videoqos);
15283          if (p->owner)
15284             pbx_builtin_setvar_helper(p->owner, "RTPVIDEOQOS", videoqos);
15285       }
15286    }
15287 
15288    stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */
15289 
15290    if (!ast_strlen_zero(get_header(req, "Also"))) {
15291       ast_log(LOG_NOTICE, "Client '%s' using deprecated BYE/Also transfer method.  Ask vendor to support REFER instead\n",
15292          ast_inet_ntoa(p->recv.sin_addr));
15293       if (ast_strlen_zero(p->context))
15294          ast_string_field_set(p, context, default_context);
15295       res = get_also_info(p, req);
15296       if (!res) {
15297          c = p->owner;
15298          if (c) {
15299             bridged_to = ast_bridged_channel(c);
15300             if (bridged_to) {
15301                /* Don't actually hangup here... */
15302                ast_queue_control(c, AST_CONTROL_UNHOLD);
15303                ast_async_goto(bridged_to, p->context, p->refer->refer_to,1);
15304             } else
15305                ast_queue_hangup(p->owner);
15306          }
15307       } else {
15308          ast_log(LOG_WARNING, "Invalid transfer information from '%s'\n", ast_inet_ntoa(p->recv.sin_addr));
15309          if (p->owner)
15310             ast_queue_hangup(p->owner);
15311       }
15312    } else if (p->owner) {
15313       ast_queue_hangup(p->owner);
15314       if (option_debug > 2)
15315          ast_log(LOG_DEBUG, "Received bye, issuing owner hangup\n");
15316    } else {
15317       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
15318       if (option_debug > 2)
15319          ast_log(LOG_DEBUG, "Received bye, no owner, selfdestruct soon.\n");
15320    }
15321    ast_clear_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED);
15322    transmit_response(p, "200 OK", req);
15323 
15324    return 1;
15325 }

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

Handle incoming CANCEL request.

Definition at line 15145 of file chan_sip.c.

References __sip_pretend_ack(), ast_log(), ast_queue_hangup(), AST_STATE_UP, ast_test_flag, check_via(), DEC_CALL_LIMIT, DEFAULT_TRANS_TIMEOUT, INV_CANCELLED, INV_TERMINATED, sip_pvt::invitestate, LOG_DEBUG, option_debug, sip_dual::req, 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().

15146 {
15147       
15148    check_via(p, req);
15149    sip_alreadygone(p);
15150 
15151    /* At this point, we could have cancelled the invite at the same time
15152       as the other side sends a CANCEL. Our final reply with error code
15153       might not have been received by the other side before the CANCEL
15154       was sent, so let's just give up retransmissions and waiting for
15155       ACK on our error code. The call is hanging up any way. */
15156    if (p->invitestate == INV_TERMINATED)
15157       __sip_pretend_ack(p);
15158    else
15159       p->invitestate = INV_CANCELLED;
15160    
15161    if (p->owner && p->owner->_state == AST_STATE_UP) {
15162       /* This call is up, cancel is ignored, we need a bye */
15163       transmit_response(p, "200 OK", req);
15164       if (option_debug)
15165          ast_log(LOG_DEBUG, "Got CANCEL on an answered call. Ignoring... \n");
15166       return 0;
15167    }
15168 
15169    if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) 
15170       update_call_counter(p, DEC_CALL_LIMIT);
15171 
15172    stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */
15173    if (p->owner)
15174       ast_queue_hangup(p->owner);
15175    else
15176       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
15177    if (p->initreq.len > 0) {
15178       transmit_response_reliable(p, "487 Request Terminated", &p->initreq);
15179       transmit_response(p, "200 OK", req);
15180       return 1;
15181    } else {
15182       transmit_response(p, "481 Call Leg Does Not Exist", req);
15183       return 0;
15184    }
15185 }

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 11313 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, f, sip_pvt::flags, get_body(), get_header(), sip_pvt::owner, sip_scheddestroy(), SIP_USECLIENTCODE, sipdebug, and transmit_response().

Referenced by handle_request().

11314 {
11315    char buf[1024];
11316    unsigned int event;
11317    const char *c = get_header(req, "Content-Type");
11318 
11319    /* Need to check the media/type */
11320    if (!strcasecmp(c, "application/dtmf-relay") ||
11321          !strcasecmp(c, "application/DTMF") ||
11322        !strcasecmp(c, "application/vnd.nortelnetworks.digits")) {
11323       unsigned int duration = 0;
11324 
11325       /* Try getting the "signal=" part */
11326       if (ast_strlen_zero(c = get_body(req, "Signal")) && ast_strlen_zero(c = get_body(req, "d"))) {
11327          ast_log(LOG_WARNING, "Unable to retrieve DTMF signal from INFO message from %s\n", p->callid);
11328          transmit_response(p, "200 OK", req); /* Should return error */
11329          return;
11330       } else {
11331          ast_copy_string(buf, c, sizeof(buf));
11332       }
11333 
11334       if (!ast_strlen_zero((c = get_body(req, "Duration"))))
11335          duration = atoi(c);
11336       if (!duration)
11337          duration = 100; /* 100 ms */
11338 
11339       if (!p->owner) {  /* not a PBX call */
11340          transmit_response(p, "481 Call leg/transaction does not exist", req);
11341          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
11342          return;
11343       }
11344 
11345       if (ast_strlen_zero(buf)) {
11346          transmit_response(p, "200 OK", req);
11347          return;
11348       }
11349 
11350       if (buf[0] == '*')
11351          event = 10;
11352       else if (buf[0] == '#')
11353          event = 11;
11354       else if ((buf[0] >= 'A') && (buf[0] <= 'D'))
11355          event = 12 + buf[0] - 'A';
11356       else
11357          event = atoi(buf);
11358       if (event == 16) {
11359          /* send a FLASH event */
11360          struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_FLASH, };
11361          ast_queue_frame(p->owner, &f);
11362          if (sipdebug)
11363             ast_verbose("* DTMF-relay event received: FLASH\n");
11364       } else {
11365          /* send a DTMF event */
11366          struct ast_frame f = { AST_FRAME_DTMF, };
11367          if (event < 10) {
11368             f.subclass = '0' + event;
11369          } else if (event < 11) {
11370             f.subclass = '*';
11371          } else if (event < 12) {
11372             f.subclass = '#';
11373          } else if (event < 16) {
11374             f.subclass = 'A' + (event - 12);
11375          }
11376          f.len = duration;
11377          ast_queue_frame(p->owner, &f);
11378          if (sipdebug)
11379             ast_verbose("* DTMF-relay event received: %c\n", f.subclass);
11380       }
11381       transmit_response(p, "200 OK", req);
11382       return;
11383    } else if (!strcasecmp(c, "application/media_control+xml")) {
11384       /* Eh, we'll just assume it's a fast picture update for now */
11385       if (p->owner)
11386          ast_queue_control(p->owner, AST_CONTROL_VIDUPDATE);
11387       transmit_response(p, "200 OK", req);
11388       return;
11389    } else if (!ast_strlen_zero(c = get_header(req, "X-ClientCode"))) {
11390       /* Client code (from SNOM phone) */
11391       if (ast_test_flag(&p->flags[0], SIP_USECLIENTCODE)) {
11392          if (p->owner && p->owner->cdr)
11393             ast_cdr_setuserfield(p->owner, c);
11394          if (p->owner && ast_bridged_channel(p->owner) && ast_bridged_channel(p->owner)->cdr)
11395             ast_cdr_setuserfield(ast_bridged_channel(p->owner), c);
11396          transmit_response(p, "200 OK", req);
11397       } else {
11398          transmit_response(p, "403 Unauthorized", req);
11399       }
11400       return;
11401    } else if (ast_strlen_zero(c = get_header(req, "Content-Length")) || !strcasecmp(c, "0")) {
11402       /* This is probably just a packet making sure the signalling is still up, just send back a 200 OK */
11403       transmit_response(p, "200 OK", req);
11404       return;
11405    }
11406 
11407    /* Other type of INFO message, not really understood by Asterisk */
11408    /* if (get_msg_text(buf, sizeof(buf), req)) { */
11409 
11410    /* Nothing in the header is interesting, now check if content-length is 0 */ 
11411    if (!strcasecmp(get_header(req, "Content-Length"), "0")) { 
11412       transmit_response(p, "200 OK", req); 
11413       return; 
11414    } /* else ... there issomething in the message body, do something with it if you need to */ 
11415 
11416    ast_log(LOG_WARNING, "Unable to parse INFO message from %s. Content %s\n", p->callid, buf);
11417    transmit_response(p, "415 Unsupported media type", req);
11418    return;
11419 }

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

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

Referenced by handle_request().

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

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

Handle incoming MESSAGE request.

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

15329 {
15330    if (!ast_test_flag(req, SIP_PKT_IGNORE)) {
15331       if (ast_test_flag(req, SIP_PKT_DEBUG))
15332          ast_verbose("Receiving message!\n");
15333       receive_message(p, req);
15334    } else
15335       transmit_response(p, "202 Accepted", req);
15336    return 1;
15337 }

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 13548 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, option_debug, sip_scheddestroy(), sipdebug, transmit_response(), and TRUE.

Referenced by handle_request().

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

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

Handle incoming OPTIONS request.

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

13681 {
13682    int res;
13683 
13684 
13685    /* XXX Should we authenticate OPTIONS? XXX */
13686 
13687    if (p->lastinvite) {
13688       /* if this is a request in an active dialog, just confirm that the dialog exists. */
13689       transmit_response_with_allow(p, "200 OK", req, 0);
13690       return 0;
13691    }
13692 
13693    res = get_destination(p, req);
13694    build_contact(p);
13695 
13696    if (ast_strlen_zero(p->context))
13697       ast_string_field_set(p, context, default_context);
13698 
13699    if (ast_shutting_down())
13700       transmit_response_with_allow(p, "503 Unavailable", req, 0);
13701    else if (res < 0)
13702       transmit_response_with_allow(p, "404 Not Found", req, 0);
13703    else 
13704       transmit_response_with_allow(p, "200 OK", req, 0);
13705 
13706    /* Destroy if this OPTIONS was the opening request, but not if
13707       it's in the middle of a normal call flow. */
13708    sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
13709 
13710    return res;
13711 }

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

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

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

15638 {
15639    enum check_auth_result res;
15640 
15641    /* Use this as the basis */
15642    if (ast_test_flag(req, SIP_PKT_DEBUG))
15643       ast_verbose("Using latest REGISTER request as basis request\n");
15644    copy_request(&p->initreq, req);
15645    check_via(p, req);
15646    if ((res = register_verify(p, sin, req, e)) < 0) {
15647       const char *reason;
15648 
15649       switch (res) {
15650       case AUTH_SECRET_FAILED:
15651          reason = "Wrong password";
15652          break;
15653       case AUTH_USERNAME_MISMATCH:
15654          reason = "Username/auth name mismatch";
15655          break;
15656       case AUTH_NOT_FOUND:
15657          reason = "No matching peer found";
15658          break;
15659       case AUTH_UNKNOWN_DOMAIN:
15660          reason = "Not a local domain";
15661          break;
15662       case AUTH_PEER_NOT_DYNAMIC:
15663          reason = "Peer is not supposed to register";
15664          break;
15665       case AUTH_ACL_FAILED:
15666          reason = "Device does not match ACL";
15667          break;
15668       default:
15669          reason = "Unknown failure";
15670          break;
15671       }
15672       ast_log(LOG_NOTICE, "Registration from '%s' failed for '%s' - %s\n",
15673          get_header(req, "To"), ast_inet_ntoa(sin->sin_addr),
15674          reason);
15675       append_history(p, "RegRequest", "Failed : Account %s : %s", get_header(req, "To"), reason);
15676    } else
15677       append_history(p, "RegRequest", "Succeeded : Account %s", get_header(req, "To"));
15678 
15679    if (res < 1) {
15680       /* Destroy the session, but keep us around for just a bit in case they don't
15681          get our 200 OK */
15682       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
15683    }
15684    return res;
15685 }

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 15340 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, sip_peer::mailbox, make_our_tag(), sip_request::method, 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_PAGE2_DIALOG_ESTABLISHED, 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().

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

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 12841 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_strdupa, ast_string_field_build, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_verbose(), 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::laststate, LOG_DEBUG, LOG_NOTICE, MAX_AUTHTRIES, sip_pvt::method, NONE, option_debug, option_verbose, sip_pvt::owner, parse_moved_contact(), sip_pvt::pendinginvite, process_sdp(), sip_pvt::refer, sip_pvt::relatedpeer, 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_DIALOG_ESTABLISHED, SIP_PAGE2_STATECHANGEQUEUE, SIP_PKT_DEBUG, SIP_PKT_IGNORE, SIP_REFER, SIP_REGISTER, SIP_SUBSCRIBE, sipdebug, stop_media_flows(), sip_pvt::subscribed, text, transmit_request(), VERBOSE_PREFIX_3, and XMIT_UNRELIABLE.

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

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 12256 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, MAX_AUTHTRIES, option_debug, sip_pvt::options, sip_pvt::owner, parse_ok_contact(), process_sdp(), PROXY_AUTH, sip_pvt::rtp, sched, set_address_from_contact(), SIP_ACK, sip_alreadygone(), SIP_ALREADYGONE, sip_cancel_destroy(), sip_handle_t38_reinvite(), SIP_INVITE, SIP_NEEDDESTROY, SIP_OUTGOING, SIP_PAGE2_DIALOG_ESTABLISHED, 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().

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

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

Handle qualification responses (OPTIONS).

Definition at line 12774 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, sched, sip_destroy_peer(), SIP_NEEDDESTROY, and sip_poke_peer_s().

Referenced by handle_response().

12775 {
12776    struct sip_peer *peer = p->relatedpeer;
12777    int statechanged, is_reachable, was_reachable;
12778    int pingtime = ast_tvdiff_ms(ast_tvnow(), peer->ps);
12779 
12780    /*
12781     * Compute the response time to a ping (goes in peer->lastms.)
12782     * -1 means did not respond, 0 means unknown,
12783     * 1..maxms is a valid response, >maxms means late response.
12784     */
12785    if (pingtime < 1) /* zero = unknown, so round up to 1 */
12786       pingtime = 1;
12787 
12788    /* Now determine new state and whether it has changed.
12789     * Use some helper variables to simplify the writing
12790     * of the expressions.
12791     */
12792    was_reachable = peer->lastms > 0 && peer->lastms <= peer->maxms;
12793    is_reachable = pingtime <= peer->maxms;
12794    statechanged = peer->lastms == 0 /* yes, unknown before */
12795       || was_reachable != is_reachable;
12796 
12797    peer->lastms = pingtime;
12798    peer->call = NULL;
12799    if (statechanged) {
12800       const char *s = is_reachable ? "Reachable" : "Lagged";
12801 
12802       ast_log(LOG_NOTICE, "Peer '%s' is now %s. (%dms / %dms)\n",
12803          peer->name, s, pingtime, peer->maxms);
12804       ast_device_state_changed("SIP/%s", peer->name);
12805       manager_event(EVENT_FLAG_SYSTEM, "PeerStatus",
12806          "Peer: SIP/%s\r\nPeerStatus: %s\r\nTime: %d\r\n",
12807          peer->name, s, pingtime);
12808    }
12809 
12810    if (!AST_SCHED_DEL(sched, peer->pokeexpire)) {
12811       struct sip_peer *peer_ptr = peer;
12812       ASTOBJ_UNREF(peer_ptr, sip_destroy_peer);
12813    }
12814 
12815    ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12816 
12817    /* Try again eventually */
12818    peer->pokeexpire = ast_sched_add(sched,
12819       is_reachable ? DEFAULT_FREQ_OK : DEFAULT_FREQ_NOTOK,
12820       sip_poke_peer_s, ASTOBJ_REF(peer));
12821 
12822    if (peer->pokeexpire == -1) {
12823       ASTOBJ_UNREF(peer, sip_destroy_peer);
12824    }
12825 }

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

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

12586 {
12587    char *auth = "Proxy-Authenticate";
12588    char *auth2 = "Proxy-Authorization";
12589 
12590    /* If no refer structure exists, then do nothing */
12591    if (!p->refer)
12592       return;
12593 
12594    switch (resp) {
12595    case 202:   /* Transfer accepted */
12596       /* We need  to do something here */
12597       /* The transferee is now sending INVITE to target */
12598       p->refer->status = REFER_ACCEPTED;
12599       /* Now wait for next message */
12600       if (option_debug > 2)
12601          ast_log(LOG_DEBUG, "Got 202 accepted on transfer\n");
12602       /* We should hang along, waiting for NOTIFY's here */
12603       break;
12604 
12605    case 401:   /* Not www-authorized on SIP method */
12606    case 407:   /* Proxy auth */
12607       if (ast_strlen_zero(p->authname)) {
12608          ast_log(LOG_WARNING, "Asked to authenticate REFER to %s:%d but we have no matching peer or realm auth!\n",
12609             ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port));
12610          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
12611       }
12612       if (resp == 401) {
12613          auth = "WWW-Authenticate";
12614          auth2 = "Authorization";
12615       }
12616       if ((p->authtries > 1) || do_proxy_auth(p, req, auth, auth2, SIP_REFER, 0)) {
12617          ast_log(LOG_NOTICE, "Failed to authenticate on REFER to '%s'\n", get_header(&p->initreq, "From"));
12618          p->refer->status = REFER_NOAUTH;
12619          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
12620       }
12621       break;
12622    case 481: /* Call leg does not exist */
12623 
12624       /* A transfer with Replaces did not work */
12625       /* OEJ: We should Set flag, cancel the REFER, go back
12626       to original call - but right now we can't */
12627       ast_log(LOG_WARNING, "Remote host can't match REFER request to call '%s'. Giving up.\n", p->callid);
12628       if (p->owner)
12629          ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
12630       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
12631       break;
12632 
12633    case 500:   /* Server error */
12634    case 501:   /* Method not implemented */
12635       /* Return to the current call onhold */
12636       /* Status flag needed to be reset */
12637       ast_log(LOG_NOTICE, "SIP transfer to %s failed, call miserably fails. \n", p->refer->refer_to);
12638       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
12639       p->refer->status = REFER_FAILED;
12640       break;
12641    case 603:   /* Transfer declined */
12642       ast_log(LOG_NOTICE, "SIP transfer to %s declined, call miserably fails. \n", p->refer->refer_to);
12643       p->refer->status = REFER_FAILED;
12644       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
12645       break;
12646    }
12647 }

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 12650 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, 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, sched, SIP_NEEDDESTROY, sip_registry_destroy(), sip_reregister(), sip_scheddestroy(), sipdebug, strcasestr(), and sip_registry::timeout.

Referenced by handle_response().

12651 {
12652    int expires, expires_ms;
12653    struct sip_registry *r;
12654    r=p->registry;
12655 
12656    switch (resp) {
12657    case 401:   /* Unauthorized */
12658       if ((p->authtries == MAX_AUTHTRIES) || do_register_auth(p, req, "WWW-Authenticate", "Authorization")) {
12659          ast_log(LOG_NOTICE, "Failed to authenticate on REGISTER to '%s@%s' (Tries %d)\n", p->registry->username, p->registry->hostname, p->authtries);
12660          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12661          }
12662       break;
12663    case 403:   /* Forbidden */
12664       ast_log(LOG_WARNING, "Forbidden - wrong password on authentication for REGISTER for '%s' to '%s'\n", p->registry->username, p->registry->hostname);
12665       if (global_regattempts_max)
12666          p->registry->regattempts = global_regattempts_max+1;
12667       AST_SCHED_DEL(sched, r->timeout);
12668       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12669       break;
12670    case 404:   /* Not found */
12671       ast_log(LOG_WARNING, "Got 404 Not found on SIP register to service %s@%s, giving up\n", p->registry->username,p->registry->hostname);
12672       if (global_regattempts_max)
12673          p->registry->regattempts = global_regattempts_max+1;
12674       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12675       r->call = NULL;
12676       AST_SCHED_DEL(sched, r->timeout);
12677       break;
12678    case 407:   /* Proxy auth */
12679       if ((p->authtries == MAX_AUTHTRIES) || do_register_auth(p, req, "Proxy-Authenticate", "Proxy-Authorization")) {
12680          ast_log(LOG_NOTICE, "Failed to authenticate on REGISTER to '%s' (tries '%d')\n", get_header(&p->initreq, "From"), p->authtries);
12681          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12682       }
12683       break;
12684    case 408:   /* Request timeout */
12685       /* Got a timeout response, so reset the counter of failed responses */
12686       r->regattempts = 0;
12687       break;
12688    case 479:   /* SER: Not able to process the URI - address is wrong in register*/
12689       ast_log(LOG_WARNING, "Got error 479 on register to %s@%s, giving up (check config)\n", p->registry->username,p->registry->hostname);
12690       if (global_regattempts_max)
12691          p->registry->regattempts = global_regattempts_max+1;
12692       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12693       r->call = NULL;
12694       AST_SCHED_DEL(sched, r->timeout);
12695       break;
12696    case 200:   /* 200 OK */
12697       if (!r) {
12698          ast_log(LOG_WARNING, "Got 200 OK on REGISTER that isn't a register\n");
12699          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12700          return 0;
12701       }
12702 
12703       r->regstate = REG_STATE_REGISTERED;
12704       r->regtime = time(NULL);      /* Reset time of last succesful registration */
12705       manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelDriver: SIP\r\nDomain: %s\r\nStatus: %s\r\n", r->hostname, regstate2str(r->regstate));
12706       r->regattempts = 0;
12707       if (option_debug)
12708          ast_log(LOG_DEBUG, "Registration successful\n");
12709       if (r->timeout > -1) {
12710          if (option_debug)
12711             ast_log(LOG_DEBUG, "Cancelling timeout %d\n", r->timeout);
12712       }
12713       AST_SCHED_DEL(sched, r->timeout);
12714       r->call = NULL;
12715       p->registry = NULL;
12716       /* Let this one hang around until we have all the responses */
12717       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
12718       /* ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); */
12719 
12720       /* set us up for re-registering */
12721       /* figure out how long we got registered for */
12722       AST_SCHED_DEL(sched, r->expire);
12723       /* according to section 6.13 of RFC, contact headers override
12724          expires headers, so check those first */
12725       expires = 0;
12726 
12727       /* XXX todo: try to save the extra call */
12728       if (!ast_strlen_zero(get_header(req, "Contact"))) {
12729          const char *contact = NULL;
12730          const char *tmptmp = NULL;
12731          int start = 0;
12732          for(;;) {
12733             contact = __get_header(req, "Contact", &start);
12734             /* this loop ensures we get a contact header about our register request */
12735             if(!ast_strlen_zero(contact)) {
12736                if( (tmptmp=strstr(contact, p->our_contact))) {
12737                   contact=tmptmp;
12738                   break;
12739                }
12740             } else
12741                break;
12742          }
12743          tmptmp = strcasestr(contact, "expires=");
12744          if (tmptmp) {
12745             if (sscanf(tmptmp + 8, "%d;", &expires) != 1)
12746                expires = 0;
12747          }
12748 
12749       }
12750       if (!expires) 
12751          expires=atoi(get_header(req, "expires"));
12752       if (!expires)
12753          expires=default_expiry;
12754 
12755       expires_ms = expires * 1000;
12756       if (expires <= EXPIRY_GUARD_LIMIT)
12757          expires_ms -= MAX((expires_ms * EXPIRY_GUARD_PCT),EXPIRY_GUARD_MIN);
12758       else
12759          expires_ms -= EXPIRY_GUARD_SECS * 1000;
12760       if (sipdebug)
12761          ast_log(LOG_NOTICE, "Outbound Registration: Expiry for %s is %d sec (Scheduling reregistration in %d s)\n", r->hostname, expires, expires_ms/1000); 
12762 
12763       r->refresh= (int) expires_ms / 1000;
12764 
12765       /* Schedule re-registration before we expire */
12766       AST_SCHED_DEL(sched, r->expire);
12767       r->expire = ast_sched_add(sched, expires_ms, sip_reregister, r); 
12768       ASTOBJ_UNREF(r, sip_registry_destroy);
12769    }
12770    return 1;
12771 }

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 3472 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_UNREGISTERED, AST_CAUSE_USER_BUSY, ast_log(), LOG_DEBUG, and option_debug.

Referenced by sip_hangup().

03473 {
03474    switch (cause) {
03475       case AST_CAUSE_UNALLOCATED:      /* 1 */
03476       case AST_CAUSE_NO_ROUTE_DESTINATION:   /* 3 IAX2: Can't find extension in context */
03477       case AST_CAUSE_NO_ROUTE_TRANSIT_NET:   /* 2 */
03478          return "404 Not Found";
03479       case AST_CAUSE_CONGESTION:    /* 34 */
03480       case AST_CAUSE_SWITCH_CONGESTION:   /* 42 */
03481          return "503 Service Unavailable";
03482       case AST_CAUSE_NO_USER_RESPONSE: /* 18 */
03483          return "408 Request Timeout";
03484       case AST_CAUSE_NO_ANSWER:     /* 19 */
03485       case AST_CAUSE_UNREGISTERED:        /* 20 */
03486          return "480 Temporarily unavailable";
03487       case AST_CAUSE_CALL_REJECTED:    /* 21 */
03488          return "403 Forbidden";
03489       case AST_CAUSE_NUMBER_CHANGED:      /* 22 */
03490          return "410 Gone";
03491       case AST_CAUSE_NORMAL_UNSPECIFIED:  /* 31 */
03492          return "480 Temporarily unavailable";
03493       case AST_CAUSE_INVALID_NUMBER_FORMAT:
03494          return "484 Address incomplete";
03495       case AST_CAUSE_USER_BUSY:
03496          return "486 Busy here";
03497       case AST_CAUSE_FAILURE:
03498          return "500 Server internal failure";
03499       case AST_CAUSE_FACILITY_REJECTED:   /* 29 */
03500          return "501 Not Implemented";
03501       case AST_CAUSE_CHAN_NOT_IMPLEMENTED:
03502          return "503 Service Unavailable";
03503       /* Used in chan_iax2 */
03504       case AST_CAUSE_DESTINATION_OUT_OF_ORDER:
03505          return "502 Bad Gateway";
03506       case AST_CAUSE_BEARERCAPABILITY_NOTAVAIL: /* Can't find codec to connect to host */
03507          return "488 Not Acceptable Here";
03508          
03509       case AST_CAUSE_NOTDEFINED:
03510       default:
03511          if (option_debug)
03512             ast_log(LOG_DEBUG, "AST hangup cause %d (no match found in SIP)\n", cause);
03513          return NULL;
03514    }
03515 
03516    /* Never reached */
03517    return 0;
03518 }

static int hangup_sip2cause ( int  cause  )  [static]

Convert SIP hangup causes to Asterisk hangup causes.

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

03361 {
03362    /* Possible values taken from causes.h */
03363 
03364    switch(cause) {
03365       case 401:   /* Unauthorized */
03366          return AST_CAUSE_CALL_REJECTED;
03367       case 403:   /* Not found */
03368          return AST_CAUSE_CALL_REJECTED;
03369       case 404:   /* Not found */
03370          return AST_CAUSE_UNALLOCATED;
03371       case 405:   /* Method not allowed */
03372          return AST_CAUSE_INTERWORKING;
03373       case 407:   /* Proxy authentication required */
03374          return AST_CAUSE_CALL_REJECTED;
03375       case 408:   /* No reaction */
03376          return AST_CAUSE_NO_USER_RESPONSE;
03377       case 409:   /* Conflict */
03378          return AST_CAUSE_NORMAL_TEMPORARY_FAILURE;
03379       case 410:   /* Gone */
03380          return AST_CAUSE_UNALLOCATED;
03381       case 411:   /* Length required */
03382          return AST_CAUSE_INTERWORKING;
03383       case 413:   /* Request entity too large */
03384          return AST_CAUSE_INTERWORKING;
03385       case 414:   /* Request URI too large */
03386          return AST_CAUSE_INTERWORKING;
03387       case 415:   /* Unsupported media type */
03388          return AST_CAUSE_INTERWORKING;
03389       case 420:   /* Bad extension */
03390          return AST_CAUSE_NO_ROUTE_DESTINATION;
03391       case 480:   /* No answer */
03392          return AST_CAUSE_NO_ANSWER;
03393       case 481:   /* No answer */
03394          return AST_CAUSE_INTERWORKING;
03395       case 482:   /* Loop detected */
03396          return AST_CAUSE_INTERWORKING;
03397       case 483:   /* Too many hops */
03398          return AST_CAUSE_NO_ANSWER;
03399       case 484:   /* Address incomplete */
03400          return AST_CAUSE_INVALID_NUMBER_FORMAT;
03401       case 485:   /* Ambigous */
03402          return AST_CAUSE_UNALLOCATED;
03403       case 486:   /* Busy everywhere */
03404          return AST_CAUSE_BUSY;
03405       case 487:   /* Request terminated */
03406          return AST_CAUSE_INTERWORKING;
03407       case 488:   /* No codecs approved */
03408          return AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;
03409       case 491:   /* Request pending */
03410          return AST_CAUSE_INTERWORKING;
03411       case 493:   /* Undecipherable */
03412          return AST_CAUSE_INTERWORKING;
03413       case 500:   /* Server internal failure */
03414          return AST_CAUSE_FAILURE;
03415       case 501:   /* Call rejected */
03416          return AST_CAUSE_FACILITY_REJECTED;
03417       case 502:   
03418          return AST_CAUSE_DESTINATION_OUT_OF_ORDER;
03419       case 503:   /* Service unavailable */
03420          return AST_CAUSE_CONGESTION;
03421       case 504:   /* Gateway timeout */
03422          return AST_CAUSE_RECOVERY_ON_TIMER_EXPIRE;
03423       case 505:   /* SIP version not supported */
03424          return AST_CAUSE_INTERWORKING;
03425       case 600:   /* Busy everywhere */
03426          return AST_CAUSE_USER_BUSY;
03427       case 603:   /* Decline */
03428          return AST_CAUSE_CALL_REJECTED;
03429       case 604:   /* Does not exist anywhere */
03430          return AST_CAUSE_UNALLOCATED;
03431       case 606:   /* Not acceptable */
03432          return AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;
03433       default:
03434          return AST_CAUSE_NORMAL;
03435    }
03436    /* Never reached */
03437    return 0;
03438 }

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

Initialize SIP request.

Definition at line 5960 of file chan_sip.c.

References sip_methods, and cfsip_methods::text.

05961 {
05962    /* Initialize a request */
05963    memset(req, 0, sizeof(*req));
05964         req->method = sipmethod;
05965    req->header[0] = req->data;
05966    snprintf(req->header[0], sizeof(req->data), "%s %s SIP/2.0\r\n", sip_methods[sipmethod].text, recip);
05967    req->len = strlen(req->header[0]);
05968    req->headers++;
05969    return 0;
05970 }

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

Initialize SIP response, based on SIP request.

Definition at line 5947 of file chan_sip.c.

References SIP_RESPONSE.

05948 {
05949    /* Initialize a response */
05950    memset(resp, 0, sizeof(*resp));
05951    resp->method = SIP_RESPONSE;
05952    resp->header[0] = resp->data;
05953    snprintf(resp->header[0], sizeof(resp->data), "SIP/2.0 %s\r\n", msg);
05954    resp->len = strlen(resp->header[0]);
05955    resp->headers++;
05956    return 0;
05957 }

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

01656 {
01657    if (p->initreq.headers && option_debug) {
01658       ast_log(LOG_DEBUG, "Initializing already initialized SIP dialog %s (presumably reinvite)\n", p->callid);
01659    }
01660    /* Use this as the basis */
01661    copy_request(&p->initreq, req);
01662    parse_request(&p->initreq);
01663    if (ast_test_flag(req, SIP_PKT_DEBUG))
01664       ast_verbose("%d headers, %d lines\n", p->initreq.headers, p->initreq.lines);
01665 }

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

Initiate new SIP request to peer/user.

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

07048 {
07049    char invite_buf[256] = "";
07050    char *invite = invite_buf;
07051    size_t invite_max = sizeof(invite_buf);
07052    char from[256];
07053    char to[256];
07054    char tmp[SIPBUFSIZE/2];
07055    char tmp2[SIPBUFSIZE/2];
07056    const char *l = NULL, *n = NULL;
07057    const char *urioptions = "";
07058 
07059    if (ast_test_flag(&p->flags[0], SIP_USEREQPHONE)) {
07060       const char *s = p->username;  /* being a string field, cannot be NULL */
07061 
07062       /* Test p->username against allowed characters in AST_DIGIT_ANY
07063          If it matches the allowed characters list, then sipuser = ";user=phone"
07064          If not, then sipuser = ""
07065       */
07066       /* + is allowed in first position in a tel: uri */
07067       if (*s == '+')
07068          s++;
07069       for (; *s; s++) {
07070          if (!strchr(AST_DIGIT_ANYNUM, *s) )
07071             break;
07072       }
07073       /* If we have only digits, add ;user=phone to the uri */
07074       if (*s)
07075          urioptions = ";user=phone";
07076    }
07077 
07078 
07079    snprintf(p->lastmsg, sizeof(p->lastmsg), "Init: %s", sip_methods[sipmethod].text);
07080 
07081    if (p->owner) {
07082       l = p->owner->cid.cid_num;
07083       n = p->owner->cid.cid_name;
07084    }
07085    /* if we are not sending RPID and user wants his callerid restricted */
07086    if (!ast_test_flag(&p->flags[0], SIP_SENDRPID) &&
07087        ((p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED)) {
07088       l = CALLERID_UNKNOWN;
07089       n = l;
07090    }
07091    if (ast_strlen_zero(l))
07092       l = default_callerid;
07093    if (ast_strlen_zero(n))
07094       n = l;
07095    /* Allow user to be overridden */
07096    if (!ast_strlen_zero(p->fromuser))
07097       l = p->fromuser;
07098    else /* Save for any further attempts */
07099       ast_string_field_set(p, fromuser, l);
07100 
07101    /* Allow user to be overridden */
07102    if (!ast_strlen_zero(p->fromname))
07103       n = p->fromname;
07104    else /* Save for any further attempts */
07105       ast_string_field_set(p, fromname, n);
07106 
07107    if (pedanticsipchecking) {
07108       ast_uri_encode(n, tmp, sizeof(tmp), 0);
07109       n = tmp;
07110       ast_uri_encode(l, tmp2, sizeof(tmp2), 0);
07111       l = tmp2;
07112    }
07113 
07114    if (ourport != STANDARD_SIP_PORT && ast_strlen_zero(p->fromdomain))
07115       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);
07116    else
07117       snprintf(from, sizeof(from), "\"%s\" <sip:%s@%s>;tag=%s", n, l, S_OR(p->fromdomain, ast_inet_ntoa(p->ourip)), p->tag);
07118 
07119    /* If we're calling a registered SIP peer, use the fullcontact to dial to the peer */
07120    if (!ast_strlen_zero(p->fullcontact)) {
07121       /* If we have full contact, trust it */
07122       ast_build_string(&invite, &invite_max, "%s", p->fullcontact);
07123    } else {
07124       /* Otherwise, use the username while waiting for registration */
07125       ast_build_string(&invite, &invite_max, "sip:");
07126       if (!ast_strlen_zero(p->username)) {
07127          n = p->username;
07128          if (pedanticsipchecking) {
07129             ast_uri_encode(n, tmp, sizeof(tmp), 0);
07130             n = tmp;
07131          }
07132          ast_build_string(&invite, &invite_max, "%s@", n);
07133       }
07134       ast_build_string(&invite, &invite_max, "%s", p->tohost);
07135       if (ntohs(p->sa.sin_port) != STANDARD_SIP_PORT)
07136          ast_build_string(&invite, &invite_max, ":%d", ntohs(p->sa.sin_port));
07137       ast_build_string(&invite, &invite_max, "%s", urioptions);
07138    }
07139 
07140    /* If custom URI options have been provided, append them */
07141    if (p->options && !ast_strlen_zero(p->options->uri_options))
07142       ast_build_string(&invite, &invite_max, ";%s", p->options->uri_options);
07143    
07144    ast_string_field_set(p, uri, invite_buf);
07145 
07146    if (sipmethod == SIP_NOTIFY && !ast_strlen_zero(p->theirtag)) { 
07147       /* If this is a NOTIFY, use the From: tag in the subscribe (RFC 3265) */
07148       snprintf(to, sizeof(to), "<%s%s>;tag=%s", (strncasecmp(p->uri, "sip:", 4) ? "" : "sip:"), p->uri, p->theirtag);
07149    } else if (p->options && p->options->vxml_url) {
07150       /* If there is a VXML URL append it to the SIP URL */
07151       snprintf(to, sizeof(to), "<%s>;%s", p->uri, p->options->vxml_url);
07152    } else 
07153       snprintf(to, sizeof(to), "<%s>", p->uri);
07154    
07155    init_req(req, sipmethod, p->uri);
07156    snprintf(tmp, sizeof(tmp), "%d %s", ++p->ocseq, sip_methods[sipmethod].text);
07157 
07158    add_header(req, "Via", p->via);
07159    /* SLD: FIXME?: do Route: here too?  I think not cos this is the first request.
07160     * OTOH, then we won't have anything in p->route anyway */
07161    /* Build Remote Party-ID and From */
07162    if (ast_test_flag(&p->flags[0], SIP_SENDRPID) && (sipmethod == SIP_INVITE)) {
07163       build_rpid(p);
07164       add_header(req, "From", p->rpid_from);
07165    } else 
07166       add_header(req, "From", from);
07167    add_header(req, "To", to);
07168    ast_string_field_set(p, exten, l);
07169    build_contact(p);
07170    add_header(req, "Contact", p->our_contact);
07171    add_header(req, "Call-ID", p->callid);
07172    add_header(req, "CSeq", tmp);
07173    if (!ast_strlen_zero(global_useragent))
07174       add_header(req, "User-Agent", global_useragent);
07175    add_header(req, "Max-Forwards", DEFAULT_MAX_FORWARDS);
07176    if (!ast_strlen_zero(p->rpid))
07177       add_header(req, "Remote-Party-ID", p->rpid);
07178 }

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

Convert Insecure setting to printable string.

Definition at line 10260 of file chan_sip.c.

Referenced by _sip_show_peer().

10261 {
10262    if (port && invite)
10263       return "port,invite";
10264    else if (port)
10265       return "port";
10266    else if (invite)
10267       return "invite";
10268    else
10269       return "no";
10270 }

static void list_route ( struct sip_route route  )  [static]

List all routes - mostly for debugging.

Definition at line 8398 of file chan_sip.c.

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

Referenced by build_route().

08399 {
08400    if (!route)
08401       ast_verbose("list_route: no route\n");
08402    else {
08403       for (;route; route = route->next)
08404          ast_verbose("list_route: hop: <%s>\n", route->hop);
08405    }
08406 }

static int load_module ( void   )  [static]

PBX load module - initialization.

Definition at line 18691 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, checksipdomain_function, cli_sip, EVENT_FLAG_SYSTEM, io, io_context_create(), io_context_destroy(), LOG_ERROR, manager_sip_show_peer(), manager_sip_show_peers(), peerl, regl, reload_config(), restart_monitor(), sched, sched_context_create(), sched_context_destroy(), sip_addheader(), sip_dtmfmode(), sip_header_function, sip_poke_all_peers(), sip_rtp, sip_send_all_registers(), sip_tech, sip_udptl, sipchaninfo_function, sippeer_function, and userl.

18692 {
18693    ASTOBJ_CONTAINER_INIT(&userl);   /* User object list */
18694    ASTOBJ_CONTAINER_INIT(&peerl);   /* Peer object list */
18695    ASTOBJ_CONTAINER_INIT(&regl); /* Registry object list */
18696 
18697    if (!(sched = sched_context_create())) {
18698       ast_log(LOG_ERROR, "Unable to create scheduler context\n");
18699       return AST_MODULE_LOAD_FAILURE;
18700    }
18701 
18702    if (!(io = io_context_create())) {
18703       ast_log(LOG_ERROR, "Unable to create I/O context\n");
18704       sched_context_destroy(sched);
18705       return AST_MODULE_LOAD_FAILURE;
18706    }
18707 
18708    sip_reloadreason = CHANNEL_MODULE_LOAD;
18709 
18710    if(reload_config(sip_reloadreason)) /* Load the configuration from sip.conf */
18711       return AST_MODULE_LOAD_DECLINE;
18712 
18713    /* Make sure we can register our sip channel type */
18714    if (ast_channel_register(&sip_tech)) {
18715       ast_log(LOG_ERROR, "Unable to register channel type 'SIP'\n");
18716       io_context_destroy(io);
18717       sched_context_destroy(sched);
18718       return AST_MODULE_LOAD_FAILURE;
18719    }
18720 
18721    /* Register all CLI functions for SIP */
18722    ast_cli_register_multiple(cli_sip, sizeof(cli_sip)/ sizeof(struct ast_cli_entry));
18723 
18724    /* Tell the RTP subdriver that we're here */
18725    ast_rtp_proto_register(&sip_rtp);
18726 
18727    /* Tell the UDPTL subdriver that we're here */
18728    ast_udptl_proto_register(&sip_udptl);
18729 
18730    /* Register dialplan applications */
18731    ast_register_application(app_dtmfmode, sip_dtmfmode, synopsis_dtmfmode, descrip_dtmfmode);
18732    ast_register_application(app_sipaddheader, sip_addheader, synopsis_sipaddheader, descrip_sipaddheader);
18733 
18734    /* Register dialplan functions */
18735    ast_custom_function_register(&sip_header_function);
18736    ast_custom_function_register(&sippeer_function);
18737    ast_custom_function_register(&sipchaninfo_function);
18738    ast_custom_function_register(&checksipdomain_function);
18739 
18740    /* Register manager commands */
18741    ast_manager_register2("SIPpeers", EVENT_FLAG_SYSTEM, manager_sip_show_peers,
18742          "List SIP peers (text format)", mandescr_show_peers);
18743    ast_manager_register2("SIPshowpeer", EVENT_FLAG_SYSTEM, manager_sip_show_peer,
18744          "Show SIP peer (text format)", mandescr_show_peer);
18745 
18746    sip_poke_all_peers();   
18747    sip_send_all_registers();
18748    
18749    /* And start the monitor for the first time */
18750    restart_monitor();
18751 
18752    return AST_MODULE_LOAD_SUCCESS;
18753 }

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

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

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

References t.

Referenced by sipsock_read().

04846 {
04847    int h = 0, t = 0; 
04848    int lws = 0; 
04849 
04850    for (; h < len;) { 
04851       /* Eliminate all CRs */ 
04852       if (msgbuf[h] == '\r') { 
04853          h++; 
04854          continue; 
04855       } 
04856       /* Check for end-of-line */ 
04857       if (msgbuf[h] == '\n') { 
04858          /* Check for end-of-message */ 
04859          if (h + 1 == len) 
04860             break; 
04861          /* Check for a continuation line */ 
04862          if (msgbuf[h + 1] == ' ' || msgbuf[h + 1] == '\t') { 
04863             /* Merge continuation line */ 
04864             h++; 
04865             continue; 
04866          } 
04867          /* Propagate LF and start new line */ 
04868          msgbuf[t++] = msgbuf[h++]; 
04869          lws = 0;
04870          continue; 
04871       } 
04872       if (msgbuf[h] == ' ' || msgbuf[h] == '\t') { 
04873          if (lws) { 
04874             h++; 
04875             continue; 
04876          } 
04877          msgbuf[t++] = msgbuf[h++]; 
04878          lws = 1; 
04879          continue; 
04880       } 
04881       msgbuf[t++] = msgbuf[h++]; 
04882       if (lws) 
04883          lws = 0; 
04884    } 
04885    msgbuf[t] = '\0'; 
04886    return t; 
04887 }

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

Make our SIP dialog tag.

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

04513 {
04514    snprintf(tagbuf, len, "as%08lx", ast_random());
04515 }

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

Show SIP peers in the manager API.

Definition at line 10505 of file chan_sip.c.

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

Referenced by load_module().

10506 {
10507    const char *a[4];
10508    const char *peer;
10509    int ret;
10510 
10511    peer = astman_get_header(m,"Peer");
10512    if (ast_strlen_zero(peer)) {
10513       astman_send_error(s, m, "Peer: <name> missing.");
10514       return 0;
10515    }
10516    a[0] = "sip";
10517    a[1] = "show";
10518    a[2] = "peer";
10519    a[3] = peer;
10520 
10521    ret = _sip_show_peer(1, -1, s, m, 4, a);
10522    astman_append(s, "\r\n\r\n" );
10523    return ret;
10524 }

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

Show SIP peers in the manager API.

Definition at line 10056 of file chan_sip.c.

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

Referenced by load_module().

10057 {
10058    const char *id = astman_get_header(m,"ActionID");
10059    const char *a[] = {"sip", "show", "peers"};
10060    char idtext[256] = "";
10061    int total = 0;
10062 
10063    if (!ast_strlen_zero(id))
10064       snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
10065 
10066    astman_send_ack(s, m, "Peer status list will follow");
10067    /* List the peers in separate manager events */
10068    _sip_show_peers(-1, &total, s, m, 3, a);
10069    /* Send final confirmation */
10070    astman_append(s,
10071    "Event: PeerlistComplete\r\n"
10072    "ListItems: %d\r\n"
10073    "%s"
10074    "\r\n", total, idtext);
10075    return 0;
10076 }

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

References len, sip_methods, and text.

Referenced by __sip_semi_ack(), and find_sip_method().

01682 {
01683    int len = strlen(sip_methods[id].text);
01684    int l_name = name ? strlen(name) : 0;
01685    /* true if the string is long enough, and ends with whitespace, and matches */
01686    return (l_name >= len && name[len] < 33 &&
01687       !strncasecmp(sip_methods[id].text, name, len));
01688 }

static char * nat2str ( int  nat  )  const [static]

Convert NAT setting to text string.

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

09960 {
09961    switch(nat) {
09962    case SIP_NAT_NEVER:
09963       return "No";
09964    case SIP_NAT_ROUTE:
09965       return "Route";
09966    case SIP_NAT_ALWAYS:
09967       return "Always";
09968    case SIP_NAT_RFC3581:
09969       return "RFC3581";
09970    default:
09971       return "Unknown";
09972    }
09973 }

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

Copy SIP request, parse it.

Definition at line 2266 of file chan_sip.c.

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

Referenced by send_request(), and send_response().

02267 {
02268    memset(dst, 0, sizeof(*dst));
02269    memcpy(dst->data, src->data, sizeof(dst->data));
02270    dst->len = src->len;
02271    parse_request(dst);
02272 }

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

Parse 302 Moved temporalily response.

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

12158 {
12159    char tmp[SIPBUFSIZE];
12160    char *s, *e, *uri, *t;
12161    char *domain;
12162 
12163    ast_copy_string(tmp, get_header(req, "Contact"), sizeof(tmp));
12164    if ((t = strchr(tmp, ',')))
12165       *t = '\0';
12166    s = get_in_brackets(tmp);
12167    uri = ast_strdupa(s);
12168    if (ast_test_flag(&p->flags[0], SIP_PROMISCREDIR)) {
12169       if (!strncasecmp(s, "sip:", 4))
12170          s += 4;
12171       e = strchr(s, ';');
12172       if (e)
12173          *e = '\0';
12174       if (option_debug)
12175          ast_log(LOG_DEBUG, "Found promiscuous redirection to 'SIP/%s'\n", s);
12176       if (p->owner)
12177          ast_string_field_build(p->owner, call_forward, "SIP/%s", s);
12178    } else {
12179       e = strchr(tmp, '@');
12180       if (e) {
12181          *e++ = '\0';
12182          domain = e;
12183       } else {
12184          /* No username part */
12185          domain = tmp;
12186       }
12187       e = strchr(s, ';');  /* Strip of parameters in the username part */
12188       if (e)
12189          *e = '\0';
12190       e = strchr(domain, ';');   /* Strip of parameters in the domain part */
12191       if (e)
12192          *e = '\0';
12193    
12194       if (!strncasecmp(s, "sip:", 4))
12195          s += 4;
12196       if (option_debug > 1)
12197          ast_log(LOG_DEBUG, "Received 302 Redirect to extension '%s' (domain %s)\n", s, domain);
12198       if (p->owner) {
12199          pbx_builtin_setvar_helper(p->owner, "SIPREDIRECTURI", uri);
12200          pbx_builtin_setvar_helper(p->owner, "SIPDOMAIN", domain);
12201          ast_string_field_set(p->owner, call_forward, s);
12202       }
12203    }
12204 }

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

08135 {
08136    char contact[SIPBUFSIZE]; 
08137    char *c;
08138 
08139    /* Look for brackets */
08140    ast_copy_string(contact, get_header(req, "Contact"), sizeof(contact));
08141    c = get_in_brackets(contact);
08142 
08143    /* Save full contact to call pvt for later bye or re-invite */
08144    ast_string_field_set(pvt, fullcontact, c);
08145 
08146    /* Save URI for later ACKs, BYE or RE-invites */
08147    ast_string_field_set(pvt, okcontacturi, c);
08148 
08149    /* We should return false for URI:s we can't handle,
08150       like sips:, tel:, mailto:,ldap: etc */
08151    return TRUE;      
08152 }

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

References sip_peer::addr, ahp, ast_db_put(), ast_gethostbyname(), ast_inet_ntoa(), ast_log(), ast_sched_add(), AST_SCHED_DEL, ast_sched_when(), ast_set_flag, 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_pvt::flags, sip_peer::flags, sip_peer::fullcontact, get_header(), get_in_brackets(), hp, inaddrcmp(), sip_peer::lastms, LOG_NOTICE, manager_event(), option_verbose, PARSE_REGISTER_FAILED, PARSE_REGISTER_QUERY, PARSE_REGISTER_UPDATE, sip_pvt::recv, register_peer_exten(), sched, sip_destroy_peer(), SIP_NAT_ROUTE, SIP_PAGE2_RT_FROMCONTACT, SIP_PAGE2_RTCACHEFRIENDS, SIP_PAGE2_TCP, SIP_PAGE2_TCP_CONNECTED, sip_poke_peer(), SIP_REALTIME, SIPBUFSIZE, sip_pvt::sipoptions, sip_peer::sipoptions, sip_pvt::sockfd, sip_peer::sockfd, STANDARD_SIP_PORT, strcasestr(), strsep(), sip_peer::useragent, sip_peer::username, and VERBOSE_PREFIX_3.

Referenced by register_verify().

08224 {
08225    char contact[SIPBUFSIZE]; 
08226    char data[SIPBUFSIZE];
08227    const char *expires = get_header(req, "Expires");
08228    int expiry = atoi(expires);
08229    char *curi, *n, *pt;
08230    int port;
08231    const char *useragent;
08232    struct hostent *hp;
08233    struct ast_hostent ahp;
08234    struct sockaddr_in oldsin;
08235 
08236    ast_copy_string(contact, get_header(req, "Contact"), sizeof(contact));
08237 
08238    if (ast_strlen_zero(expires)) {  /* No expires header */
08239       expires = strcasestr(contact, ";expires=");
08240       if (expires) {
08241          /* XXX bug here, we overwrite the string */
08242          expires = strsep((char **) &expires, ";"); /* trim ; and beyond */
08243          if (sscanf(expires + 9, "%d", &expiry) != 1)
08244             expiry = default_expiry;
08245       } else {
08246          /* Nothing has been specified */
08247          expiry = default_expiry;
08248       }
08249    }
08250 
08251    /* Look for brackets */
08252    curi = contact;
08253    if (strchr(contact, '<') == NULL)   /* No <, check for ; and strip it */
08254       strsep(&curi, ";");  /* This is Header options, not URI options */
08255    curi = get_in_brackets(contact);
08256 
08257    /* if they did not specify Contact: or Expires:, they are querying
08258       what we currently have stored as their contact address, so return
08259       it
08260    */
08261    if (ast_strlen_zero(curi) && ast_strlen_zero(expires)) {
08262       /* If we have an active registration, tell them when the registration is going to expire */
08263       if (peer->expire > -1 && !ast_strlen_zero(peer->fullcontact))
08264          pvt->expiry = ast_sched_when(sched, peer->expire);
08265       return PARSE_REGISTER_QUERY;
08266    } else if (!strcasecmp(curi, "*") || !expiry) { /* Unregister this peer */
08267       /* This means remove all registrations and return OK */
08268       memset(&peer->addr, 0, sizeof(peer->addr));
08269       if (!AST_SCHED_DEL(sched, peer->expire)) {
08270          struct sip_peer *peer_ptr = peer;
08271          ASTOBJ_UNREF(peer_ptr, sip_destroy_peer);
08272       }
08273 
08274       destroy_association(peer);
08275       
08276       register_peer_exten(peer, 0); /* Add extension from regexten= setting in sip.conf */
08277       peer->fullcontact[0] = '\0';
08278       peer->useragent[0] = '\0';
08279       peer->sipoptions = 0;
08280       peer->lastms = 0;
08281 
08282       if (option_verbose > 2)
08283          ast_verbose(VERBOSE_PREFIX_3 "Unregistered SIP '%s'\n", peer->name);
08284          manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unregistered\r\n", peer->name);
08285       return PARSE_REGISTER_UPDATE;
08286    }
08287 
08288    /* Store whatever we got as a contact from the client */
08289    ast_copy_string(peer->fullcontact, curi, sizeof(peer->fullcontact));
08290 
08291    /* For the 200 OK, we should use the received contact */
08292    ast_string_field_build(pvt, our_contact, "<%s>", curi);
08293 
08294    /* Make sure it's a SIP URL */
08295    if (strncasecmp(curi, "sip:", 4)) {
08296       ast_log(LOG_NOTICE, "'%s' is not a valid SIP contact (missing sip:) trying to use anyway\n", curi);
08297    } else
08298       curi += 4;
08299    /* Ditch q */
08300    curi = strsep(&curi, ";");
08301    /* Grab host */
08302    n = strchr(curi, '@');
08303    if (!n) {
08304       n = curi;
08305       curi = NULL;
08306    } else
08307       *n++ = '\0';
08308    pt = strchr(n, ':');
08309    if (pt) {
08310       *pt++ = '\0';
08311       port = atoi(pt);
08312    } else
08313       port = STANDARD_SIP_PORT;
08314    oldsin = peer->addr;
08315    if (!ast_test_flag(&peer->flags[0], SIP_NAT_ROUTE)) {
08316       /* XXX This could block for a long time XXX */
08317       hp = ast_gethostbyname(n, &ahp);
08318       if (!hp)  {
08319          ast_log(LOG_WARNING, "Invalid host '%s'\n", n);
08320          return PARSE_REGISTER_FAILED;
08321       }
08322       peer->addr.sin_family = AF_INET;
08323       memcpy(&peer->addr.sin_addr, hp->h_addr, sizeof(peer->addr.sin_addr));
08324       peer->addr.sin_port = htons(port);
08325    } else {
08326       /* Don't trust the contact field.  Just use what they came to us
08327          with */
08328       peer->addr = pvt->recv;
08329    }
08330 
08331    /* Save SIP options profile */
08332    peer->sipoptions = pvt->sipoptions;
08333 
08334    if (curi && ast_strlen_zero(peer->username))
08335       ast_copy_string(peer->username, curi, sizeof(peer->username));
08336 
08337    if (!AST_SCHED_DEL(sched, peer->expire)) {
08338       struct sip_peer *peer_ptr = peer;
08339       ASTOBJ_UNREF(peer_ptr, sip_destroy_peer);
08340    }
08341    if (expiry > max_expiry)
08342       expiry = max_expiry;
08343    if (expiry < min_expiry)
08344       expiry = min_expiry;
08345    if (ast_test_flag(&peer->flags[0], SIP_REALTIME) && !ast_test_flag(&peer->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) {
08346       peer->expire = -1;
08347    } else {
08348       peer->expire = ast_sched_add(sched, (expiry + 10) * 1000, expire_register, ASTOBJ_REF(peer));
08349       if (peer->expire == -1) {
08350          struct sip_peer *peer_ptr = peer;
08351          ASTOBJ_UNREF(peer_ptr, sip_destroy_peer);
08352       }
08353    }
08354    pvt->expiry = expiry;
08355    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);
08356    if (!ast_test_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT)) 
08357       ast_db_put("SIP/Registry", peer->name, data);
08358    manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Registered\r\n", peer->name);
08359 
08360    /* Is this a new IP address for us? */
08361    if (inaddrcmp(&peer->addr, &oldsin)) {
08362       sip_poke_peer(peer);
08363       if (option_verbose > 2)
08364          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);
08365       register_peer_exten(peer, 1);
08366    }
08367    
08368    /* Save User agent */
08369    useragent = get_header(req, "User-Agent");
08370    if (strcasecmp(useragent, peer->useragent)) {   /* XXX copy if they are different ? */
08371       ast_copy_string(peer->useragent, useragent, sizeof(peer->useragent));
08372       if (option_verbose > 3)
08373          ast_verbose(VERBOSE_PREFIX_3 "Saved useragent \"%s\" for peer %s\n", peer->useragent, peer->name);  
08374    }
08375 
08376    /* Allocate A TCP Soccket of incoming connection*/
08377    if (((!ast_test_flag(&peer->flags[1], SIP_PAGE2_TCP)) || (peer->sockfd != pvt->sockfd)) && (ast_test_flag(&pvt->flags[1], SIP_PAGE2_TCP))) {
08378       ast_set_flag(&peer->flags[1], SIP_PAGE2_TCP);
08379       peer->sockfd=pvt->sockfd;
08380       ast_set_flag(&peer->flags[1], SIP_PAGE2_TCP_CONNECTED);
08381    }
08382    return PARSE_REGISTER_UPDATE;
08383 }

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 4892 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, option_debug, SIP_MAX_HEADERS, SIP_MAX_LINES, and sipdebug.

Referenced by initialize_initreq(), parse_copy(), and sipsock_read().

04893 {
04894    /* Divide fields by NULL's */
04895    char *c;
04896    int f = 0;
04897 
04898    c = req->data;
04899 
04900    /* First header starts immediately */
04901    req->header[f] = c;
04902    while(*c) {
04903       if (*c == '\n') {
04904          /* We've got a new header */
04905          *c = 0;
04906 
04907          if (sipdebug && option_debug > 3)
04908             ast_log(LOG_DEBUG, "Header %d: %s (%d)\n", f, req->header[f], (int) strlen(req->header[f]));
04909          if (ast_strlen_zero(req->header[f])) {
04910             /* Line by itself means we're now in content */
04911             c++;
04912             break;
04913          }
04914          if (f >= SIP_MAX_HEADERS - 1) {
04915             ast_log(LOG_WARNING, "Too many SIP headers. Ignoring.\n");
04916          } else
04917             f++;
04918          req->header[f] = c + 1;
04919       } else if (*c == '\r') {
04920          /* Ignore but eliminate \r's */
04921          *c = 0;
04922       }
04923       c++;
04924    }
04925    /* Check for last header */
04926    if (!ast_strlen_zero(req->header[f])) {
04927       if (sipdebug && option_debug > 3)
04928          ast_log(LOG_DEBUG, "Header %d: %s (%d)\n", f, req->header[f], (int) strlen(req->header[f]));
04929       f++;
04930    }
04931    req->headers = f;
04932    /* Now we process any mime content */
04933    f = 0;
04934    req->line[f] = c;
04935    while(*c) {
04936       if (*c == '\n') {
04937          /* We've got a new line */
04938          *c = 0;
04939          if (sipdebug && option_debug > 3)
04940             ast_log(LOG_DEBUG, "Line: %s (%d)\n", req->line[f], (int) strlen(req->line[f]));
04941          if (f >= SIP_MAX_LINES - 1) {
04942             ast_log(LOG_WARNING, "Too many SDP lines. Ignoring.\n");
04943          } else
04944             f++;
04945          req->line[f] = c + 1;
04946       } else if (*c == '\r') {
04947          /* Ignore and eliminate \r's */
04948          *c = 0;
04949       }
04950       c++;
04951    }
04952    /* Check for last line */
04953    if (!ast_strlen_zero(req->line[f])) 
04954       f++;
04955    req->lines = f;
04956    if (*c) 
04957       ast_log(LOG_WARNING, "Odd content, extra stuff left over ('%s')\n", c);
04958    /* Split up the first line parts */
04959    return determine_firstline_parts(req);
04960 }

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

Parse supported header in incoming packet.

Definition at line 1705 of file chan_sip.c.

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

Referenced by handle_request_invite().

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

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

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

09979 {
09980    int res = 0;
09981    if (peer->maxms) {
09982       if (peer->lastms < 0) {
09983          ast_copy_string(status, "UNREACHABLE", statuslen);
09984       } else if (peer->lastms > peer->maxms) {
09985          snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms);
09986          res = 1;
09987       } else if (peer->lastms) {
09988          snprintf(status, statuslen, "OK (%d ms)", peer->lastms);
09989          res = 1;
09990       } else {
09991          ast_copy_string(status, "UNKNOWN", statuslen);
09992       }
09993    } else { 
09994       ast_copy_string(status, "Unmonitored", statuslen);
09995       /* Checking if port is 0 */
09996       res = -1;
09997    }
09998    return res;
09999 }

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

10447 {
10448    int x, codec;
10449 
10450    for(x = 0; x < 32 ; x++) {
10451       codec = ast_codec_pref_index(pref, x);
10452       if (!codec)
10453          break;
10454       ast_cli(fd, "%s", ast_getformatname(codec));
10455       ast_cli(fd, ":%d", pref->framing[x]);
10456       if (x < 31 && ast_codec_pref_index(pref, x + 1))
10457          ast_cli(fd, ",");
10458    }
10459    if (!x)
10460       ast_cli(fd, "none");
10461 }

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

Print call group and pickup group.

Definition at line 10237 of file chan_sip.c.

References ast_cli(), and ast_print_group().

Referenced by _sip_show_peer(), and sip_show_user().

10238 {
10239    char buf[256];
10240    ast_cli(fd, crlf ? "%s\r\n" : "%s\n", ast_print_group(buf, sizeof(buf), group) );
10241 }

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 5093 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, 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.

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

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

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

References ahp, ast_gethostbyname(), ast_inet_ntoa(), ast_load_realtime(), ast_variables_destroy(), ast_flags::flags, hp, ast_variable::name, ast_variable::next, ast_variable::value, and var.

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

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

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

02421 {
02422    char port[10];
02423    char ipaddr[INET_ADDRSTRLEN];
02424    char regseconds[20];
02425 
02426    char *sysname = ast_config_AST_SYSTEM_NAME;
02427    char *syslabel = NULL;
02428 
02429    time_t nowtime = time(NULL) + expirey;
02430    const char *fc = fullcontact ? "fullcontact" : NULL;
02431    
02432    snprintf(regseconds, sizeof(regseconds), "%d", (int)nowtime);  /* Expiration time */
02433    ast_copy_string(ipaddr, ast_inet_ntoa(sin->sin_addr), sizeof(ipaddr));
02434    snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port));
02435    
02436    if (ast_strlen_zero(sysname)) /* No system name, disable this */
02437       sysname = NULL;
02438    else if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTSAVE_SYSNAME))
02439       syslabel = "regserver";
02440 
02441    if (fc)
02442       ast_update_realtime("sippeers", "name", peername, "ipaddr", ipaddr,
02443          "port", port, "regseconds", regseconds,
02444          "username", username, fc, fullcontact, syslabel, sysname, NULL); /* note fc and syslabel _can_ be NULL */
02445    else
02446       ast_update_realtime("sippeers", "name", peername, "ipaddr", ipaddr,
02447          "port", port, "regseconds", regseconds,
02448          "username", username, syslabel, sysname, NULL); /* note syslabel _can_ be NULL */
02449 }

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

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

References ast_load_realtime(), ast_variables_destroy(), ast_variable::name, ast_variable::next, ast_variable::value, and var.

02723 {
02724    struct ast_variable *var;
02725    struct ast_variable *tmp;
02726    struct sip_user *user = NULL;
02727 
02728    var = ast_load_realtime("sipusers", "name", username, NULL);
02729 
02730    if (!var)
02731       return NULL;
02732 
02733    for (tmp = var; tmp; tmp = tmp->next) {
02734       if (!strcasecmp(tmp->name, "type") &&
02735          !strcasecmp(tmp->value, "peer")) {
02736          ast_variables_destroy(var);
02737          return NULL;
02738       }
02739    }
02740 
02741    user = build_user(username, var, NULL, !ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS));
02742    
02743    if (!user) {   /* No user found */
02744       ast_variables_destroy(var);
02745       return NULL;
02746    }
02747 
02748    if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) {
02749       ast_set_flag(&user->flags[1], SIP_PAGE2_RTCACHEFRIENDS);
02750       suserobjs++;
02751       ASTOBJ_CONTAINER_LINK(&userl,user);
02752    } else {
02753       /* Move counter from s to r... */
02754       suserobjs--;
02755       ruserobjs++;
02756    }
02757    ast_set_flag(&user->flags[0], SIP_REALTIME);
02758    ast_variables_destroy(var);
02759    return user;
02760 }

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

References AST_FRAME_TEXT, ast_log(), ast_queue_frame(), ast_verbose(), DEFAULT_TRANS_TIMEOUT, f, get_header(), get_msg_text(), sip_pvt::owner, sip_debug_test_pvt(), sip_scheddestroy(), and transmit_response().

Referenced by handle_request_message().

09862 {
09863    char buf[1024];
09864    struct ast_frame f;
09865    const char *content_type = get_header(req, "Content-Type");
09866 
09867    if (strncmp(content_type, "text/plain", strlen("text/plain"))) { /* No text/plain attachment */
09868       transmit_response(p, "415 Unsupported Media Type", req); /* Good enough, or? */
09869       if (!p->owner)
09870          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
09871       return;
09872    }
09873 
09874    if (get_msg_text(buf, sizeof(buf), req)) {
09875       ast_log(LOG_WARNING, "Unable to retrieve text from %s\n", p->callid);
09876       transmit_response(p, "202 Accepted", req);
09877       if (!p->owner)
09878          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
09879       return;
09880    }
09881 
09882    if (p->owner) {
09883       if (sip_debug_test_pvt(p))
09884          ast_verbose("Message received: '%s'\n", buf);
09885       memset(&f, 0, sizeof(f));
09886       f.frametype = AST_FRAME_TEXT;
09887       f.subclass = 0;
09888       f.offset = 0;
09889       f.data = buf;
09890       f.datalen = strlen(buf);
09891       ast_queue_frame(p->owner, &f);
09892       transmit_response(p, "202 Accepted", req); /* We respond 202 accepted, since we relay the message */
09893    } else { /* Message outside of a call, we do not support that */
09894       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);
09895       transmit_response(p, "405 Method Not Allowed", req); /* Good enough, or? */
09896       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
09897    }
09898    return;
09899 }

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

Convert transfer status to string.

Definition at line 1640 of file chan_sip.c.

References referstatusstrings, and text.

Referenced by __sip_show_channels().

01641 {
01642    int i = (sizeof(referstatusstrings) / sizeof(referstatusstrings[0]));
01643    int x;
01644 
01645    for (x = 0; x < i; x++) {
01646       if (referstatusstrings[x].status ==  rstatus)
01647          return (char *) referstatusstrings[x].text;
01648    }
01649    return "";
01650 }

static void reg_source_db ( struct sip_peer peer  )  [static]

Get registration details from Asterisk DB.

Definition at line 8062 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(), sched, sip_destroy_peer(), SIP_PAGE2_RT_FROMCONTACT, sip_poke_peer(), sip_poke_peer_s(), sipsock, siptcpsock, strsep(), TRUE, sip_peer::username, and username.

08063 {
08064    char data[256];
08065    struct in_addr in;
08066    int expiry;
08067    int port;
08068    char *scan, *addr, *port_str, *expiry_str, *username, *contact;
08069 
08070    if (ast_test_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT)) 
08071       return;
08072    if (ast_db_get("SIP/Registry", peer->name, data, sizeof(data)))
08073       return;
08074 
08075    scan = data;
08076    addr = strsep(&scan, ":");
08077    port_str = strsep(&scan, ":");
08078    expiry_str = strsep(&scan, ":");
08079    username = strsep(&scan, ":");
08080    contact = scan;   /* Contact include sip: and has to be the last part of the database entry as long as we use : as a separator */
08081 
08082    if (!inet_aton(addr, &in))
08083       return;
08084 
08085    if (port_str)
08086       port = atoi(port_str);
08087    else
08088       return;
08089 
08090    if (expiry_str)
08091       expiry = atoi(expiry_str);
08092    else
08093       return;
08094 
08095    if (username)
08096       ast_copy_string(peer->username, username, sizeof(peer->username));
08097    if (contact)
08098       ast_copy_string(peer->fullcontact, contact, sizeof(peer->fullcontact));
08099 
08100    if (option_debug > 1)
08101       ast_log(LOG_DEBUG, "SIP Seeding peer from astdb: '%s' at %s@%s:%d for %d\n",
08102              peer->name, peer->username, ast_inet_ntoa(in), port, expiry);
08103 
08104    memset(&peer->addr, 0, sizeof(peer->addr));
08105    peer->addr.sin_family = AF_INET;
08106    peer->addr.sin_addr = in;
08107    peer->addr.sin_port = htons(port);
08108    if ((sipsock < 0) || (siptcpsock < 0)){
08109       /* SIP isn't up yet, so schedule a poke only, pretty soon */
08110       if (!AST_SCHED_DEL(sched, peer->pokeexpire)) {
08111          struct sip_peer *peer_ptr = peer;
08112          ASTOBJ_UNREF(peer_ptr, sip_destroy_peer);
08113       }
08114       peer->pokeexpire = ast_sched_add(sched, ast_random() % 5000 + 1, sip_poke_peer_s, ASTOBJ_REF(peer));
08115       if (peer->pokeexpire == -1) {
08116          struct sip_peer *peer_ptr = peer;
08117          ASTOBJ_UNREF(peer_ptr, sip_destroy_peer);
08118       }
08119    } else
08120       sip_poke_peer(peer);
08121    if (!AST_SCHED_DEL(sched, peer->expire)) {
08122       struct sip_peer *peer_ptr = peer;
08123       ASTOBJ_UNREF(peer_ptr, sip_destroy_peer);
08124    }
08125    peer->expire = ast_sched_add(sched, (expiry + 10) * 1000, expire_register, ASTOBJ_REF(peer));
08126    if (peer->expire == -1) {
08127       struct sip_peer *peer_ptr = peer;
08128       ASTOBJ_UNREF(peer_ptr, sip_destroy_peer);
08129    }
08130    register_peer_exten(peer, TRUE);
08131 }

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

Automatically add peer extension to dial plan.

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

02453 {
02454    char multi[256];
02455    char *stringp, *ext, *context;
02456 
02457    /* XXX note that global_regcontext is both a global 'enable' flag and
02458     * the name of the global regexten context, if not specified
02459     * individually.
02460     */
02461    if (ast_strlen_zero(global_regcontext))
02462       return;
02463 
02464    ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi));
02465    stringp = multi;
02466    while ((ext = strsep(&stringp, "&"))) {
02467       if ((context = strchr(ext, '@'))) {
02468          *context++ = '\0';   /* split ext@context */
02469          if (!ast_context_find(context)) {
02470             ast_log(LOG_WARNING, "Context %s must exist in regcontext= in sip.conf!\n", context);
02471             continue;
02472          }
02473       } else {
02474          context = global_regcontext;
02475       }
02476       if (onoff)
02477          ast_add_extension(context, 1, ext, 1, NULL, NULL, "Noop",
02478              ast_strdup(peer->name), ast_free, "SIP");
02479       else
02480          ast_context_remove_extension(context, ext, 1, NULL);
02481    }
02482 }

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

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

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

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

Convert registration state status to string.

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

07540 {
07541    switch(regstate) {
07542    case REG_STATE_FAILED:
07543       return "Failed";
07544    case REG_STATE_UNREGISTERED:
07545       return "Unregistered";
07546    case REG_STATE_REGSENT:
07547       return "Request Sent";
07548    case REG_STATE_AUTHSENT:
07549       return "Auth. Sent";
07550    case REG_STATE_REGISTERED:
07551       return "Registered";
07552    case REG_STATE_REJECTED:
07553       return "Rejected";
07554    case REG_STATE_TIMEOUT:
07555       return "Timeout";
07556    case REG_STATE_NOAUTH:
07557       return "No Authentication";
07558    default:
07559       return "Unknown";
07560    }
07561 }

static int reload ( void   )  [static]

Part of Asterisk module interface.

Definition at line 18577 of file chan_sip.c.

References sip_reload().

18578 {
18579    return sip_reload(0, 0, NULL);
18580 }

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

References ahp, ast_config_load(), ast_log(), AST_MAX_CONTEXT, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, authl, bindaddr, clear_realm_authentication(), clear_sip_domains(), context, FALSE, hp, LOG_DEBUG, LOG_NOTICE, option_debug, regl, and sip_destroy().

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

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

Referenced by do_proxy_auth(), and do_register_auth().

11664 {
11665    char tmp[512];
11666    char *c;
11667    char oldnonce[256];
11668 
11669    /* table of recognised keywords, and places where they should be copied */
11670    const struct x {
11671       const char *key;
11672       int field_index;
11673    } *i, keys[] = {
11674       { "realm=", ast_string_field_index(p, realm) },
11675       { "nonce=", ast_string_field_index(p, nonce) },
11676       { "opaque=", ast_string_field_index(p, opaque) },
11677       { "qop=", ast_string_field_index(p, qop) },
11678       { "domain=", ast_string_field_index(p, domain) },
11679       { NULL, 0 },
11680    };
11681 
11682    ast_copy_string(tmp, get_header(req, header), sizeof(tmp));
11683    if (ast_strlen_zero(tmp)) 
11684       return -1;
11685    if (strncasecmp(tmp, "Digest ", strlen("Digest "))) {
11686       ast_log(LOG_WARNING, "missing Digest.\n");
11687       return -1;
11688    }
11689    c = tmp + strlen("Digest ");
11690    ast_copy_string(oldnonce, p->nonce, sizeof(oldnonce));
11691    while (c && *(c = ast_skip_blanks(c))) {  /* lookup for keys */
11692       for (i = keys; i->key != NULL; i++) {
11693          char *src, *separator;
11694          if (strncasecmp(c, i->key, strlen(i->key)) != 0)
11695             continue;
11696          /* Found. Skip keyword, take text in quotes or up to the separator. */
11697          c += strlen(i->key);
11698          if (*c == '"') {
11699             src = ++c;
11700             separator = "\"";
11701          } else {
11702             src = c;
11703             separator = ",";
11704          }
11705          strsep(&c, separator); /* clear separator and move ptr */
11706          ast_string_field_index_set(p, i->field_index, src);
11707          break;
11708       }
11709       if (i->key == NULL) /* not found, try ',' */
11710          strsep(&c, ",");
11711    }
11712    /* Reset nonce count */
11713    if (strcmp(p->nonce, oldnonce)) 
11714       p->noncecount = 0;
11715 
11716    /* Save auth data for following registrations */
11717    if (p->registry) {
11718       struct sip_registry *r = p->registry;
11719 
11720       if (strcmp(r->nonce, p->nonce)) {
11721          ast_string_field_set(r, realm, p->realm);
11722          ast_string_field_set(r, nonce, p->nonce);
11723          ast_string_field_set(r, domain, p->domain);
11724          ast_string_field_set(r, opaque, p->opaque);
11725          ast_string_field_set(r, qop, p->qop);
11726          r->noncecount = 0;
11727       }
11728    }
11729    return build_reply_digest(p, sipmethod, digest, digest_len); 
11730 }

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

06023 {
06024    struct sip_request *orig = &p->initreq;
06025    char stripped[80];
06026    char tmp[80];
06027    char newto[256];
06028    const char *c;
06029    const char *ot, *of;
06030    int is_strict = FALSE;     /*!< Strict routing flag */
06031 
06032    memset(req, 0, sizeof(struct sip_request));
06033    
06034    snprintf(p->lastmsg, sizeof(p->lastmsg), "Tx: %s", sip_methods[sipmethod].text);
06035    
06036    if (!seqno) {
06037       p->ocseq++;
06038       seqno = p->ocseq;
06039    }
06040    
06041    if (newbranch) {
06042       p->branch ^= ast_random();
06043       build_via(p);
06044    }
06045 
06046    /* Check for strict or loose router */
06047    if (p->route && !ast_strlen_zero(p->route->hop) && strstr(p->route->hop,";lr") == NULL) {
06048       is_strict = TRUE;
06049       if (sipdebug)
06050          ast_log(LOG_DEBUG, "Strict routing enforced for session %s\n", p->callid);
06051    }
06052 
06053    if (sipmethod == SIP_CANCEL)
06054       c = p->initreq.rlPart2; /* Use original URI */
06055    else if (sipmethod == SIP_ACK) {
06056       /* Use URI from Contact: in 200 OK (if INVITE) 
06057       (we only have the contacturi on INVITEs) */
06058       if (!ast_strlen_zero(p->okcontacturi))
06059          c = is_strict ? p->route->hop : p->okcontacturi;
06060       else
06061          c = p->initreq.rlPart2;
06062    } else if (!ast_strlen_zero(p->okcontacturi)) 
06063       c = is_strict ? p->route->hop : p->okcontacturi; /* Use for BYE or REINVITE */
06064    else if (!ast_strlen_zero(p->uri)) 
06065       c = p->uri;
06066    else {
06067       char *n;
06068       /* We have no URI, use To: or From:  header as URI (depending on direction) */
06069       ast_copy_string(stripped, get_header(orig, (ast_test_flag(&p->flags[0], SIP_OUTGOING)) ? "To" : "From"),
06070             sizeof(stripped));
06071       n = get_in_brackets(stripped);
06072       c = strsep(&n, ";"); /* trim ; and beyond */
06073    }  
06074    init_req(req, sipmethod, c);
06075 
06076    snprintf(tmp, sizeof(tmp), "%d %s", seqno, sip_methods[sipmethod].text);
06077 
06078    add_header(req, "Via", p->via);
06079    if (p->route) {
06080       set_destination(p, p->route->hop);
06081       add_route(req, is_strict ? p->route->next : p->route);
06082    }
06083 
06084    ot = get_header(orig, "To");
06085    of = get_header(orig, "From");
06086 
06087    /* Add tag *unless* this is a CANCEL, in which case we need to send it exactly
06088       as our original request, including tag (or presumably lack thereof) */
06089    if (!strcasestr(ot, "tag=") && sipmethod != SIP_CANCEL) {
06090       /* Add the proper tag if we don't have it already.  If they have specified
06091          their tag, use it.  Otherwise, use our own tag */
06092       if (ast_test_flag(&p->flags[0], SIP_OUTGOING) && !ast_strlen_zero(p->theirtag))
06093          snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->theirtag);
06094       else if (!ast_test_flag(&p->flags[0], SIP_OUTGOING))
06095          snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->tag);
06096       else
06097          snprintf(newto, sizeof(newto), "%s", ot);
06098       ot = newto;
06099    }
06100 
06101    if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
06102       add_header(req, "From", of);
06103       add_header(req, "To", ot);
06104    } else {
06105       add_header(req, "From", ot);
06106       add_header(req, "To", of);
06107    }
06108    /* Do not add Contact for MESSAGE, BYE and Cancel requests */
06109    if (sipmethod != SIP_BYE && sipmethod != SIP_CANCEL && sipmethod != SIP_MESSAGE)
06110       add_header(req, "Contact", p->our_contact);
06111 
06112    copy_header(req, orig, "Call-ID");
06113    add_header(req, "CSeq", tmp);
06114 
06115    if (!ast_strlen_zero(global_useragent))
06116       add_header(req, "User-Agent", global_useragent);
06117    add_header(req, "Max-Forwards", DEFAULT_MAX_FORWARDS);
06118 
06119    if (!ast_strlen_zero(p->rpid))
06120       add_header(req, "Remote-Party-ID", p->rpid);
06121 
06122    return 0;
06123 }

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

05975 {
05976    char newto[256];
05977    const char *ot;
05978 
05979    init_resp(resp, msg);
05980    copy_via_headers(p, resp, req, "Via");
05981    if (msg[0] == '1' || msg[0] == '2')
05982       copy_all_header(resp, req, "Record-Route");
05983    copy_header(resp, req, "From");
05984    ot = get_header(req, "To");
05985    if (!strcasestr(ot, "tag=") && strncmp(msg, "100", 3)) {
05986       /* Add the proper tag if we don't have it already.  If they have specified
05987          their tag, use it.  Otherwise, use our own tag */
05988       if (!ast_strlen_zero(p->theirtag) && ast_test_flag(&p->flags[0], SIP_OUTGOING))
05989          snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->theirtag);
05990       else if (p->tag && !ast_test_flag(&p->flags[0], SIP_OUTGOING))
05991          snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->tag);
05992       else
05993          ast_copy_string(newto, ot, sizeof(newto));
05994       ot = newto;
05995    }
05996    add_header(resp, "To", ot);
05997    copy_header(resp, req, "Call-ID");
05998    copy_header(resp, req, "CSeq");
05999    if (!ast_strlen_zero(global_useragent))
06000       add_header(resp, "User-Agent", global_useragent);
06001    add_header(resp, "Allow", ALLOWED_METHODS);
06002    add_header(resp, "Supported", SUPPORTED_EXTENSIONS);
06003    if (msg[0] == '2' && (p->method == SIP_SUBSCRIBE || p->method == SIP_REGISTER)) {
06004       /* For registration responses, we also need expiry and
06005          contact info */
06006       char tmp[256];
06007 
06008       snprintf(tmp, sizeof(tmp), "%d", p->expiry);
06009       add_header(resp, "Expires", tmp);
06010       if (p->expiry) {  /* Only add contact if we have an expiry time */
06011          char contact[SIPBUFSIZE];
06012          snprintf(contact, sizeof(contact), "%s;expires=%d", p->our_contact, p->expiry);
06013          add_header(resp, "Contact", contact);  /* Not when we unregister */
06014       }
06015    } else if (msg[0] != '4' && !ast_strlen_zero(p->our_contact)) {
06016       add_header(resp, "Contact", p->our_contact);
06017    }
06018    return 0;
06019 }

static int restart_monitor ( void   )  [static]

Start the channel monitor thread.

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

16310 {
16311    /* If we're supposed to be stopped -- stay stopped */
16312    if (monitor_thread == AST_PTHREADT_STOP)
16313       return 0;
16314    ast_mutex_lock(&monlock);
16315    if (monitor_thread == pthread_self()) {
16316       ast_mutex_unlock(&monlock);
16317       ast_log(LOG_WARNING, "Cannot kill myself\n");
16318       return -1;
16319    }
16320    if (monitor_thread != AST_PTHREADT_NULL) {
16321       /* Wake up the thread */
16322       pthread_kill(monitor_thread, SIGURG);
16323    } else {
16324       /* Start a new monitor */
16325       if (ast_pthread_create_background(&monitor_thread, NULL, do_monitor, NULL) < 0) {
16326          ast_mutex_unlock(&monlock);
16327          ast_log(LOG_ERROR, "Unable to start monitor thread.\n");
16328          return -1;
16329       }
16330    }
16331    ast_mutex_unlock(&monlock);
16332    return 0;
16333 }

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

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

Definition at line 1922 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, sip_pkt::timer_a, sip_pkt::timer_t1, and XMIT_ERROR.

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

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

02314 {
02315    int res;
02316 
02317    add_blank(req);
02318    if (sip_debug_test_pvt(p)) {
02319       if (ast_test_flag(&p->flags[0], SIP_NAT_ROUTE))
02320          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);
02321       else
02322          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);
02323    }
02324    if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) {
02325       struct sip_request tmp;
02326       parse_copy(&tmp, req);
02327       append_history(p, reliable ? "TxReqRel" : "TxReq", "%s / %s - %s", tmp.data, get_header(&tmp, "CSeq"), sip_methods[tmp.method].text);
02328    }
02329    res = (reliable) ?
02330       __sip_reliable_xmit(p, seqno, 0, req->data, req->len, (reliable == XMIT_CRITICAL), req->method) :
02331       __sip_xmit(p, req->data, req->len);
02332    return res;
02333 }

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 2285 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_debug_test_pvt(), sip_methods, sip_nat_mode(), SIP_NO_HISTORY, sip_real_dst(), SIP_RESPONSE, SIP_UNKNOWN, cfsip_methods::text, and XMIT_CRITICAL.

02286 {
02287    int res;
02288 
02289    add_blank(req);
02290    if (sip_debug_test_pvt(p)) {
02291       const struct sockaddr_in *dst = sip_real_dst(p);
02292 
02293       ast_verbose("\n<--- %sTransmitting (%s) to %s:%d --->\n%s\n<------------>\n",
02294          reliable ? "Reliably " : "", sip_nat_mode(p),
02295          ast_inet_ntoa(dst->sin_addr),
02296          ntohs(dst->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 ? "TxRespRel" : "TxResp", "%s / %s - %s", tmp.data, get_header(&tmp, "CSeq"), 
02302          (tmp.method == SIP_RESPONSE || tmp.method == SIP_UNKNOWN) ? tmp.rlPart2 : sip_methods[tmp.method].text);
02303    }
02304    res = (reliable) ?
02305        __sip_reliable_xmit(p, seqno, 1, req->data, req->len, (reliable == XMIT_CRITICAL), req->method) :
02306       __sip_xmit(p, req->data, req->len);
02307    if (res > 0)
02308       return 0;
02309    return res;
02310 }

static int set_address_from_contact ( struct sip_pvt pvt  )  [static]

Change the other partys IP address based on given contact.

Definition at line 8209 of file chan_sip.c.

References __set_address_from_contact(), ast_test_flag, sip_pvt::flags, sip_pvt::recv, sip_pvt::sa, and SIP_NAT_ROUTE.

Referenced by handle_response_invite().

08210 {
08211    if (ast_test_flag(&pvt->flags[0], SIP_NAT_ROUTE)) {
08212       /* NAT: Don't trust the contact field.  Just use what they came to us
08213          with. */
08214       pvt->sa = pvt->recv;
08215       return 0;
08216    }
08217 
08218    return __set_address_from_contact(pvt->fullcontact, &pvt->sa);
08219 }

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

Set destination from SIP URI.

Definition at line 5883 of file chan_sip.c.

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

Referenced by reqprep().

05884 {
05885    char *h, *maddr, hostname[256];
05886    int port, hn;
05887    struct hostent *hp;
05888    struct ast_hostent ahp;
05889    int debug=sip_debug_test_pvt(p);
05890 
05891    /* Parse uri to h (host) and port - uri is already just the part inside the <> */
05892    /* general form we are expecting is sip[s]:username[:password]@host[:port][;...] */
05893 
05894    if (debug)
05895       ast_verbose("set_destination: Parsing <%s> for address/port to send to\n", uri);
05896 
05897    /* Find and parse hostname */
05898    h = strchr(uri, '@');
05899    if (h)
05900       ++h;
05901    else {
05902       h = uri;
05903       if (strncasecmp(h, "sip:", 4) == 0)
05904          h += 4;
05905       else if (strncasecmp(h, "sips:", 5) == 0)
05906          h += 5;
05907    }
05908    hn = strcspn(h, ":;>") + 1;
05909    if (hn > sizeof(hostname)) 
05910       hn = sizeof(hostname);
05911    ast_copy_string(hostname, h, hn);
05912    /* XXX bug here if string has been trimmed to sizeof(hostname) */
05913    h += hn - 1;
05914 
05915    /* Is "port" present? if not default to STANDARD_SIP_PORT */
05916    if (*h == ':') {
05917       /* Parse port */
05918       ++h;
05919       port = strtol(h, &h, 10);
05920    }
05921    else
05922       port = STANDARD_SIP_PORT;
05923 
05924    /* Got the hostname:port - but maybe there's a "maddr=" to override address? */
05925    maddr = strstr(h, "maddr=");
05926    if (maddr) {
05927       maddr += 6;
05928       hn = strspn(maddr, "0123456789.") + 1;
05929       if (hn > sizeof(hostname))
05930          hn = sizeof(hostname);
05931       ast_copy_string(hostname, maddr, hn);
05932    }
05933    
05934    hp = ast_gethostbyname(hostname, &ahp);
05935    if (hp == NULL)  {
05936       ast_log(LOG_WARNING, "Can't find address for host '%s'\n", hostname);
05937       return;
05938    }
05939    p->sa.sin_family = AF_INET;
05940    memcpy(&p->sa.sin_addr, hp->h_addr, sizeof(p->sa.sin_addr));
05941    p->sa.sin_port = htons(port);
05942    if (debug)
05943       ast_verbose("set_destination: set destination to %s, port %d\n", ast_inet_ntoa(p->sa.sin_addr), port);
05944 }

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

References ast_false(), ast_log(), ast_set_flag, ast_strlen_zero(), ast_true(), ast_channel::flags, SIP_INSECURE_INVITE, SIP_INSECURE_PORT, and strsep().

Referenced by handle_common_options().

16646 {
16647    static int dep_insecure_very = 0;
16648    static int dep_insecure_yes = 0;
16649 
16650    if (ast_strlen_zero(value))
16651       return;
16652 
16653    if (!strcasecmp(value, "very")) {
16654       ast_set_flag(flags, SIP_INSECURE_PORT | SIP_INSECURE_INVITE);
16655       if(!dep_insecure_very) {
16656          if(lineno != -1)
16657             ast_log(LOG_WARNING, "insecure=very at line %d is deprecated; use insecure=port,invite instead\n", lineno);
16658          else
16659             ast_log(LOG_WARNING, "insecure=very is deprecated; use insecure=port,invite instead\n");
16660          dep_insecure_very = 1;
16661       }
16662    }
16663    else if (ast_true(value)) {
16664       ast_set_flag(flags, SIP_INSECURE_PORT);
16665       if(!dep_insecure_yes) {
16666          if(lineno != -1)
16667             ast_log(LOG_WARNING, "insecure=%s at line %d is deprecated; use insecure=port instead\n", value, lineno);
16668          else
16669             ast_log(LOG_WARNING, "insecure=%s is deprecated; use insecure=port instead\n", value);
16670          dep_insecure_yes = 1;
16671       }
16672    }
16673    else if (!ast_false(value)) {
16674       char buf[64];
16675       char *word, *next;
16676       ast_copy_string(buf, value, sizeof(buf));
16677       next = buf;
16678       while ((word = strsep(&next, ","))) {
16679          if (!strcasecmp(word, "port"))
16680             ast_set_flag(flags, SIP_INSECURE_PORT);
16681          else if (!strcasecmp(word, "invite"))
16682             ast_set_flag(flags, SIP_INSECURE_INVITE);
16683          else
16684             ast_log(LOG_WARNING, "Unknown insecure mode '%s' on line %d\n", value, lineno);
16685       }
16686    }
16687 }

static void set_peer_defaults ( struct sip_peer peer  )  [static]

Set peer defaults before configuring specific configurations.

Definition at line 17076 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, global_flags, 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().

17077 {
17078    if (peer->expire == 0) {
17079       /* Don't reset expire or port time during reload 
17080          if we have an active registration 
17081       */
17082       peer->expire = -1;
17083       peer->pokeexpire = -1;
17084       peer->addr.sin_port = htons(STANDARD_SIP_PORT);
17085    }
17086    ast_copy_flags(&peer->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY);
17087    ast_copy_flags(&peer->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY);
17088    strcpy(peer->context, default_context);
17089    strcpy(peer->subscribecontext, default_subscribecontext);
17090    strcpy(peer->language, default_language);
17091    strcpy(peer->mohinterpret, default_mohinterpret);
17092    strcpy(peer->mohsuggest, default_mohsuggest);
17093    peer->addr.sin_family = AF_INET;
17094    peer->defaddr.sin_family = AF_INET;
17095    peer->capability = global_capability;
17096    peer->maxcallbitrate = default_maxcallbitrate;
17097    peer->rtptimeout = global_rtptimeout;
17098    peer->rtpholdtimeout = global_rtpholdtimeout;
17099    peer->rtpkeepalive = global_rtpkeepalive;
17100    peer->allowtransfer = global_allowtransfer;
17101    peer->autoframing = global_autoframing;
17102    strcpy(peer->vmexten, default_vmexten);
17103    peer->secret[0] = '\0';
17104    peer->md5secret[0] = '\0';
17105    peer->cid_num[0] = '\0';
17106    peer->cid_name[0] = '\0';
17107    peer->fromdomain[0] = '\0';
17108    peer->fromuser[0] = '\0';
17109    peer->regexten[0] = '\0';
17110    peer->mailbox[0] = '\0';
17111    peer->callgroup = 0;
17112    peer->pickupgroup = 0;
17113    peer->maxms = default_qualify;
17114    peer->prefs = default_prefs;
17115 }

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

Add a SIP header to an outbound INVITE.

Definition at line 18390 of file chan_sip.c.

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

Referenced by load_module().

18391 {
18392    int no = 0;
18393    int ok = FALSE;
18394    char varbuf[30];
18395    char *inbuf = (char *) data;
18396    
18397    if (ast_strlen_zero(inbuf)) {
18398       ast_log(LOG_WARNING, "This application requires the argument: Header\n");
18399       return 0;
18400    }
18401    ast_channel_lock(chan);
18402 
18403    /* Check for headers */
18404    while (!ok && no <= 50) {
18405       no++;
18406       snprintf(varbuf, sizeof(varbuf), "__SIPADDHEADER%.2d", no);
18407 
18408       /* Compare without the leading underscores */
18409       if( (pbx_builtin_getvar_helper(chan, (const char *) varbuf + 2) == (const char *) NULL) )
18410          ok = TRUE;
18411    }
18412    if (ok) {
18413       pbx_builtin_setvar_helper (chan, varbuf, inbuf);
18414       if (sipdebug)
18415          ast_log(LOG_DEBUG,"SIP Header added \"%s\" as %s\n", inbuf, varbuf);
18416    } else {
18417       ast_log(LOG_WARNING, "Too many SIP headers added, max 50\n");
18418    }
18419    ast_channel_unlock(chan);
18420    return 0;
18421 }

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

Support routine for find_peer.

Definition at line 2675 of file chan_sip.c.

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

Referenced by find_peer().

02676 {
02677    /* We know name is the first field, so we can cast */
02678    struct sip_peer *p = (struct sip_peer *) name;
02679    return   !(!inaddrcmp(&p->addr, sin) || 
02680                (ast_test_flag(&p->flags[0], SIP_INSECURE_PORT) &&
02681                (p->addr.sin_addr.s_addr == sin->sin_addr.s_addr)));
02682 }

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

Allocate SIP_PVT structure and set defaults.

Definition at line 4518 of file chan_sip.c.

References __ourip, 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(), bindaddr, build_callid_pvt(), build_via(), context, default_prefs, do_setnat(), errno, free, global_flags, global_t38_capability, iflist, INITIAL_CSEQ, io, LOG_DEBUG, make_our_tag(), mohinterpret, mohsuggest, NONE, option_debug, sched, 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, T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF, T38FAX_UDP_EC_FEC, T38FAX_UDP_EC_NONE, T38FAX_UDP_EC_REDUNDANCY, text, UDPTL_ERROR_CORRECTION_FEC, UDPTL_ERROR_CORRECTION_NONE, and UDPTL_ERROR_CORRECTION_REDUNDANCY.

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

04520 {
04521    struct sip_pvt *p;
04522 
04523    if (!(p = ast_calloc(1, sizeof(*p))))
04524       return NULL;
04525 
04526    if (ast_string_field_init(p, 512)) {
04527       free(p);
04528       return NULL;
04529    }
04530 
04531    ast_mutex_init(&p->lock);
04532 
04533    p->method = intended_method;
04534    p->initid = -1;
04535    p->waitid = -1;
04536    p->autokillid = -1;
04537    p->subscribed = NONE;
04538    p->stateid = -1;
04539    p->sockfd=-1;  
04540    p->prefs = default_prefs;     /* Set default codecs for this call */
04541 
04542    if (intended_method != SIP_OPTIONS) /* Peerpoke has it's own system */
04543       p->timer_t1 = 500;   /* Default SIP retransmission timer T1 (RFC 3261) */
04544 
04545    if (sin) {
04546       p->sa = *sin;
04547       if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
04548          p->ourip = __ourip;
04549    } else
04550       p->ourip = __ourip;
04551 
04552    /* Copy global flags to this PVT at setup. */
04553    ast_copy_flags(&p->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY);
04554    ast_copy_flags(&p->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY);
04555 
04556    ast_set2_flag(&p->flags[0], !recordhistory, SIP_NO_HISTORY);
04557 
04558    p->branch = ast_random();  
04559    make_our_tag(p->tag, sizeof(p->tag));
04560    p->ocseq = INITIAL_CSEQ;
04561 
04562    if (sip_methods[intended_method].need_rtp) {
04563       p->rtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr.sin_addr);
04564       /* If the global videosupport flag is on, we always create a RTP interface for video */
04565       if (ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT))
04566          p->vrtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr.sin_addr);
04567       if (ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT))
04568          p->udptl = ast_udptl_new_with_bindaddr(sched, io, 0, bindaddr.sin_addr);
04569       if (!p->rtp || (ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) && !p->vrtp)) {
04570          ast_log(LOG_WARNING, "Unable to create RTP audio %s session: %s\n",
04571             ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) ? "and video" : "", strerror(errno));
04572          ast_mutex_destroy(&p->lock);
04573          if (p->chanvars) {
04574             ast_variables_destroy(p->chanvars);
04575             p->chanvars = NULL;
04576          }
04577          free(p);
04578          return NULL;
04579       }
04580       ast_rtp_setdtmf(p->rtp, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833);
04581       ast_rtp_setdtmfcompensate(p->rtp, ast_test_flag(&p->flags[1], SIP_PAGE2_RFC2833_COMPENSATE));
04582       ast_rtp_settos(p->rtp, global_tos_audio);
04583       ast_rtp_set_rtptimeout(p->rtp, global_rtptimeout);
04584       ast_rtp_set_rtpholdtimeout(p->rtp, global_rtpholdtimeout);
04585       ast_rtp_set_rtpkeepalive(p->rtp, global_rtpkeepalive);
04586       if (p->vrtp) {
04587          ast_rtp_settos(p->vrtp, global_tos_video);
04588          ast_rtp_setdtmf(p->vrtp, 0);
04589          ast_rtp_setdtmfcompensate(p->vrtp, 0);
04590          ast_rtp_set_rtptimeout(p->vrtp, global_rtptimeout);
04591          ast_rtp_set_rtpholdtimeout(p->vrtp, global_rtpholdtimeout);
04592          ast_rtp_set_rtpkeepalive(p->vrtp, global_rtpkeepalive);
04593       }
04594       if (p->udptl)
04595          ast_udptl_settos(p->udptl, global_tos_audio);
04596       p->maxcallbitrate = default_maxcallbitrate;
04597       p->autoframing = global_autoframing;
04598       ast_rtp_codec_setpref(p->rtp, &p->prefs);
04599    }
04600 
04601    if (useglobal_nat && sin) {
04602       /* Setup NAT structure according to global settings if we have an address */
04603       ast_copy_flags(&p->flags[0], &global_flags[0], SIP_NAT);
04604       p->recv = *sin;
04605       do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE);
04606    }
04607 
04608    if (p->method != SIP_REGISTER)
04609       ast_string_field_set(p, fromdomain, default_fromdomain);
04610    build_via(p);
04611    if (!callid)
04612       build_callid_pvt(p);
04613    else
04614       ast_string_field_set(p, callid, callid);
04615    /* Assign default music on hold class */
04616    ast_string_field_set(p, mohinterpret, default_mohinterpret);
04617    ast_string_field_set(p, mohsuggest, default_mohsuggest);
04618    p->capability = global_capability;
04619    p->allowtransfer = global_allowtransfer;
04620    if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) ||
04621        (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO))
04622       p->noncodeccapability |= AST_RTP_DTMF;
04623    if (p->udptl) {
04624       p->t38.capability = global_t38_capability;
04625       if (ast_udptl_get_error_correction_scheme(p->udptl) == UDPTL_ERROR_CORRECTION_REDUNDANCY)
04626          p->t38.capability |= T38FAX_UDP_EC_REDUNDANCY;
04627       else if (ast_udptl_get_error_correction_scheme(p->udptl) == UDPTL_ERROR_CORRECTION_FEC)
04628          p->t38.capability |= T38FAX_UDP_EC_FEC;
04629       else if (ast_udptl_get_error_correction_scheme(p->udptl) == UDPTL_ERROR_CORRECTION_NONE)
04630          p->t38.capability |= T38FAX_UDP_EC_NONE;
04631       p->t38.capability |= T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF;
04632       p->t38.jointcapability = p->t38.capability;
04633    }
04634    ast_string_field_set(p, context, default_context);
04635 
04636    /* Add to active dialog list */
04637    ast_mutex_lock(&iflock);
04638    p->next = iflist;
04639    iflist = p;
04640    ast_mutex_unlock(&iflock);
04641    if (option_debug)
04642       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");
04643    return p;
04644 }

static void sip_alreadygone ( struct sip_pvt dialog  )  [static]

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

01668 {
01669    if (option_debug > 2)
01670       ast_log(LOG_DEBUG, "Setting SIP_ALREADYGONE on dialog %s\n", dialog->callid);
01671    ast_set_flag(&dialog->flags[0], SIP_ALREADYGONE);
01672 }

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

References ast_channel::_state, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_setstate(), AST_STATE_UP, sip_pvt::lock, LOG_DEBUG, option_debug, SIP_PAGE2_DIALOG_ESTABLISHED, 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.

03709 {
03710    int res = 0;
03711    struct sip_pvt *p = ast->tech_pvt;
03712 
03713    ast_mutex_lock(&p->lock);
03714    if (ast->_state != AST_STATE_UP) {
03715       try_suggested_sip_codec(p);   
03716 
03717       ast_setstate(ast, AST_STATE_UP);
03718       if (option_debug)
03719          ast_log(LOG_DEBUG, "SIP answering channel: %s\n", ast->name);
03720       if (p->t38.state == T38_PEER_DIRECT) {
03721          p->t38.state = T38_ENABLED;
03722          if (option_debug > 1)
03723             ast_log(LOG_DEBUG,"T38State change to %d on channel %s\n", p->t38.state, ast->name);
03724          res = transmit_response_with_t38_sdp(p, "200 OK", &p->initreq, XMIT_CRITICAL);
03725          ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED);
03726       } else {
03727          res = transmit_response_with_sdp(p, "200 OK", &p->initreq, XMIT_CRITICAL);
03728          ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED);
03729       }
03730    }
03731    ast_mutex_unlock(&p->lock);
03732    return res;
03733 }

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 2986 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, sip_pvt::maxtime, sip_pvt::noncodeccapability, option_debug, sip_pvt::options, sip_pvt::prefcodec, sip_invite_param::replaces, sched, 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.

02987 {
02988    int res, xmitres = 0;
02989    struct sip_pvt *p;
02990    struct varshead *headp;
02991    struct ast_var_t *current;
02992    const char *referer = NULL;   /* SIP refererer */  
02993 
02994    p = ast->tech_pvt;
02995    if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) {
02996       ast_log(LOG_WARNING, "sip_call called on %s, neither down nor reserved\n", ast->name);
02997       return -1;
02998    }
02999 
03000    /* Check whether there is vxml_url, distinctive ring variables */
03001    headp=&ast->varshead;
03002    AST_LIST_TRAVERSE(headp,current,entries) {
03003       /* Check whether there is a VXML_URL variable */
03004       if (!p->options->vxml_url && !strcasecmp(ast_var_name(current), "VXML_URL")) {
03005          p->options->vxml_url = ast_var_value(current);
03006       } else if (!p->options->uri_options && !strcasecmp(ast_var_name(current), "SIP_URI_OPTIONS")) {
03007          p->options->uri_options = ast_var_value(current);
03008       } else if (!p->options->distinctive_ring && !strcasecmp(ast_var_name(current), "ALERT_INFO")) {
03009          /* Check whether there is a ALERT_INFO variable */
03010          p->options->distinctive_ring = ast_var_value(current);
03011       } else if (!p->options->addsipheaders && !strncasecmp(ast_var_name(current), "SIPADDHEADER", strlen("SIPADDHEADER"))) {
03012          /* Check whether there is a variable with a name starting with SIPADDHEADER */
03013          p->options->addsipheaders = 1;
03014       } else if (!strcasecmp(ast_var_name(current), "SIPTRANSFER")) {
03015          /* This is a transfered call */
03016          p->options->transfer = 1;
03017       } else if (!strcasecmp(ast_var_name(current), "SIPTRANSFER_REFERER")) {
03018          /* This is the referer */
03019          referer = ast_var_value(current);
03020       } else if (!strcasecmp(ast_var_name(current), "SIPTRANSFER_REPLACES")) {
03021          /* We're replacing a call. */
03022          p->options->replaces = ast_var_value(current);
03023       } else if (!strcasecmp(ast_var_name(current), "T38CALL")) {
03024          p->t38.state = T38_LOCAL_DIRECT;
03025          if (option_debug)
03026             ast_log(LOG_DEBUG,"T38State change to %d on channel %s\n", p->t38.state, ast->name);
03027       }
03028 
03029    }
03030    
03031    res = 0;
03032    ast_set_flag(&p->flags[0], SIP_OUTGOING);
03033 
03034    if (p->options->transfer) {
03035       char buf[SIPBUFSIZE/2];
03036 
03037       if (referer) {
03038          if (sipdebug && option_debug > 2)
03039             ast_log(LOG_DEBUG, "Call for %s transfered by %s\n", p->username, referer);
03040          snprintf(buf, sizeof(buf)-1, "-> %s (via %s)", p->cid_name, referer);
03041       } else 
03042          snprintf(buf, sizeof(buf)-1, "-> %s", p->cid_name);
03043       ast_string_field_set(p, cid_name, buf);
03044    } 
03045    if (option_debug)
03046       ast_log(LOG_DEBUG, "Outgoing Call for %s\n", p->username);
03047 
03048    res = update_call_counter(p, INC_CALL_RINGING);
03049    if ( res != -1 ) {
03050       p->callingpres = ast->cid.cid_pres;
03051       p->jointcapability = ast_translate_available_formats(p->capability, p->prefcodec);
03052       p->jointnoncodeccapability = p->noncodeccapability;
03053 
03054       /* If there are no audio formats left to offer, punt */
03055       if (!(p->jointcapability & AST_FORMAT_AUDIO_MASK)) {
03056          ast_log(LOG_WARNING, "No audio format found to offer. Cancelling call to %s\n", p->username);
03057          res = -1;
03058       } else {
03059          p->t38.jointcapability = p->t38.capability;
03060          if (option_debug > 1)
03061             ast_log(LOG_DEBUG,"Our T38 capability (%d), joint T38 capability (%d)\n", p->t38.capability, p->t38.jointcapability);
03062          xmitres = transmit_invite(p, SIP_INVITE, 1, 2);
03063          if (xmitres == XMIT_ERROR)
03064             return -1;  /* Transmission error */
03065 
03066          p->invitestate = INV_CALLING;
03067 
03068          /* Initialize auto-congest time */
03069          AST_SCHED_DEL(sched, p->initid);
03070          p->initid = ast_sched_add(sched, p->maxtime ? (p->maxtime * 4) : SIP_TRANS_TIMEOUT, auto_congest, p);
03071       }
03072    }
03073    return res;
03074 }

static int sip_cancel_destroy ( struct sip_pvt p  )  [static]

Cancel destruction of SIP dialog.

Definition at line 2155 of file chan_sip.c.

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

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

02156 {
02157    int res = 0;
02158    if (p->autokillid > -1) {
02159       if (!(res = ast_sched_del(sched, p->autokillid))) {
02160          append_history(p, "CancelDestroy", "");
02161          p->autokillid = -1;
02162       }
02163    }
02164    return res;
02165 }

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

See if we pass debug IP filter.

Definition at line 1749 of file chan_sip.c.

References sipdebug.

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

01750 {
01751    if (!sipdebug)
01752       return 0;
01753    if (debugaddr.sin_addr.s_addr) {
01754       if (((ntohs(debugaddr.sin_port) != 0)
01755          && (debugaddr.sin_port != addr->sin_port))
01756          || (debugaddr.sin_addr.s_addr != addr->sin_addr.s_addr))
01757          return 0;
01758    }
01759    return 1;
01760 }

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

Test PVT for debugging output.

Definition at line 1775 of file chan_sip.c.

References sip_debug_test_addr(), sip_real_dst(), and sipdebug.

Referenced by __sip_destroy(), add_sdp(), add_t38_sdp(), build_route(), check_via(), do_register_auth(), get_also_info(), get_destination(), get_rdnis(), get_refer_info(), handle_request(), process_sdp(), receive_message(), retrans_pkt(), send_request(), send_response(), set_destination(), sip_scheddestroy(), sip_sendtext(), and transmit_register().

01776 {
01777    if (!sipdebug)
01778       return 0;
01779    return sip_debug_test_addr(sip_real_dst(p));
01780 }

static void sip_destroy ( struct sip_pvt p  )  [static]

Destroy SIP call structure.

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

03351 {
03352    ast_mutex_lock(&iflock);
03353    if (option_debug > 2)
03354       ast_log(LOG_DEBUG, "Destroying SIP dialog %s\n", p->callid);
03355    __sip_destroy(p, 1);
03356    ast_mutex_unlock(&iflock);
03357 }

static void sip_destroy_peer ( struct sip_peer peer  )  [static]

Destroy peer object from memory.

Definition at line 2485 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(), expire_register(), function_sippeer(), handle_request_subscribe(), handle_response_peerpoke(), parse_register_contact(), reg_source_db(), register_verify(), 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().

02486 {
02487    if (option_debug > 2)
02488       ast_log(LOG_DEBUG, "Destroying SIP peer %s\n", peer->name);
02489 
02490    /* Delete it, it needs to disappear */
02491    if (peer->call)
02492       sip_destroy(peer->call);
02493 
02494    if (peer->mwipvt)    /* We have an active subscription, delete it */
02495       sip_destroy(peer->mwipvt);
02496 
02497    if (peer->chanvars) {
02498       ast_variables_destroy(peer->chanvars);
02499       peer->chanvars = NULL;
02500    }
02501 
02502    register_peer_exten(peer, FALSE);
02503    ast_free_ha(peer->ha);
02504    if (ast_test_flag(&peer->flags[1], SIP_PAGE2_SELFDESTRUCT))
02505       apeerobjs--;
02506    else if (ast_test_flag(&peer->flags[0], SIP_REALTIME))
02507       rpeerobjs--;
02508    else
02509       speerobjs--;
02510    clear_realm_authentication(peer->auth);
02511    peer->auth = NULL;
02512    free(peer);
02513 }

static void sip_destroy_user ( struct sip_user user  )  [static]

Remove user object from in-memory storage.

Definition at line 2703 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(), sip_show_user(), unload_module(), and update_call_counter().

02704 {
02705    if (option_debug > 2)
02706       ast_log(LOG_DEBUG, "Destroying user object from memory: %s\n", user->name);
02707    ast_free_ha(user->ha);
02708    if (user->chanvars) {
02709       ast_variables_destroy(user->chanvars);
02710       user->chanvars = NULL;
02711    }
02712    if (ast_test_flag(&user->flags[0], SIP_REALTIME))
02713       ruserobjs--;
02714    else
02715       suserobjs--;
02716    free(user);
02717 }

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:

For peers without call limit:

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

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

References sip_peer::addr, ahp, AST_DEVICE_BUSY, AST_DEVICE_INUSE, AST_DEVICE_INVALID, AST_DEVICE_NOT_INUSE, AST_DEVICE_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().

16481 {
16482    char *host;
16483    char *tmp;
16484 
16485    struct hostent *hp;
16486    struct ast_hostent ahp;
16487    struct sip_peer *p;
16488 
16489    int res = AST_DEVICE_INVALID;
16490 
16491    /* make sure data is not null. Maybe unnecessary, but better be safe */
16492    host = ast_strdupa(data ? data : "");
16493    if ((tmp = strchr(host, '@')))
16494       host = tmp + 1;
16495 
16496    if (option_debug > 2) 
16497       ast_log(LOG_DEBUG, "Checking device state for peer %s\n", host);
16498 
16499    /* If find_peer asks for a realtime peer, then this breaks rtautoclear.  This
16500     * is because when a peer tries to autoexpire, the last thing it does is to
16501     * queue up an event telling the system that the devicestate has changed
16502     * (presumably to unavailable).  If we ask for a realtime peer here, this would
16503     * load it BACK into memory, thus defeating the point of trying to trying to
16504     * clear dead hosts out of memory.
16505     */
16506    if ((p = find_peer(host, NULL, 0, 1))) {
16507       if (p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) {
16508          /* we have an address for the peer */
16509       
16510          /* Check status in this order
16511             - Hold
16512             - Ringing
16513             - Busy (enforced only by call limit)
16514             - Inuse (we have a call)
16515             - Unreachable (qualify)
16516             If we don't find any of these state, report AST_DEVICE_NOT_INUSE
16517             for registered devices */
16518 
16519          if (p->onHold)
16520             /* First check for hold or ring states */
16521             res = AST_DEVICE_ONHOLD;
16522          else if (p->inRinging) {
16523             if (p->inRinging == p->inUse)
16524                res = AST_DEVICE_RINGING;
16525             else
16526                res = AST_DEVICE_RINGINUSE;
16527          } else if (p->call_limit && (p->inUse == p->call_limit))
16528             /* check call limit */
16529             res = AST_DEVICE_BUSY;
16530          else if (p->call_limit && p->inUse)
16531             /* Not busy, but we do have a call */
16532             res = AST_DEVICE_INUSE;
16533          else if (p->maxms && ((p->lastms > p->maxms) || (p->lastms < 0))) 
16534             /* We don't have a call. Are we reachable at all? Requires qualify= */
16535             res = AST_DEVICE_UNAVAILABLE;
16536          else  /* Default reply if we're registered and have no other data */
16537             res = AST_DEVICE_NOT_INUSE;
16538       } else {
16539          /* there is no address, it's unavailable */
16540          res = AST_DEVICE_UNAVAILABLE;
16541       }
16542       ASTOBJ_UNREF(p,sip_destroy_peer);
16543    } else {
16544       char *port = strchr(host, ':');
16545       if (port)
16546          *port = '\0';
16547       hp = ast_gethostbyname(host, &ahp);
16548       if (hp)
16549          res = AST_DEVICE_UNKNOWN;
16550    }
16551 
16552    return res;
16553 }

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

Turn on SIP debugging (CLI command).

Definition at line 11476 of file chan_sip.c.

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

11477 {
11478    int oldsipdebug = sipdebug_console;
11479    if (argc != 3) {
11480       if (argc != 5) 
11481          return RESULT_SHOWUSAGE;
11482       else if (strcmp(argv[3], "ip") == 0)
11483          return sip_do_debug_ip(fd, argc, argv);
11484       else if (strcmp(argv[3], "peer") == 0)
11485          return sip_do_debug_peer(fd, argc, argv);
11486       else
11487          return RESULT_SHOWUSAGE;
11488    }
11489    ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE);
11490    memset(&debugaddr, 0, sizeof(debugaddr));
11491    ast_cli(fd, "SIP Debugging %senabled\n", oldsipdebug ? "re-" : "");
11492    return RESULT_SUCCESS;
11493 }

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

Definition at line 11495 of file chan_sip.c.

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

11496 {
11497    int oldsipdebug = sipdebug_console;
11498    char *newargv[6] = { "sip", "set", "debug", NULL };
11499    if (argc != 2) {
11500       if (argc != 4) 
11501          return RESULT_SHOWUSAGE;
11502       else if (strcmp(argv[2], "ip") == 0) {
11503          newargv[3] = argv[2];
11504          newargv[4] = argv[3];
11505          return sip_do_debug_ip(fd, argc + 1, newargv);
11506       } else if (strcmp(argv[2], "peer") == 0) {
11507          newargv[3] = argv[2];
11508          newargv[4] = argv[3];
11509          return sip_do_debug_peer(fd, argc + 1, newargv);
11510       } else
11511          return RESULT_SHOWUSAGE;
11512    }
11513    ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE);
11514    memset(&debugaddr, 0, sizeof(debugaddr));
11515    ast_cli(fd, "SIP Debugging %senabled\n", oldsipdebug ? "re-" : "");
11516    return RESULT_SUCCESS;
11517 }

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

Enable SIP Debugging in CLI.

Definition at line 11422 of file chan_sip.c.

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

Referenced by sip_do_debug(), and sip_do_debug_deprecated().

11423 {
11424    struct hostent *hp;
11425    struct ast_hostent ahp;
11426    int port = 0;
11427    char *p, *arg;
11428 
11429    /* sip set debug ip <ip> */
11430    if (argc != 5)
11431       return RESULT_SHOWUSAGE;
11432    p = arg = argv[4];
11433    strsep(&p, ":");
11434    if (p)
11435       port = atoi(p);
11436    hp = ast_gethostbyname(arg, &ahp);
11437    if (hp == NULL)
11438       return RESULT_SHOWUSAGE;
11439 
11440    debugaddr.sin_family = AF_INET;
11441    memcpy(&debugaddr.sin_addr, hp->h_addr, sizeof(debugaddr.sin_addr));
11442    debugaddr.sin_port = htons(port);
11443    if (port == 0)
11444       ast_cli(fd, "SIP Debugging Enabled for IP: %s\n", ast_inet_ntoa(debugaddr.sin_addr));
11445    else
11446       ast_cli(fd, "SIP Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(debugaddr.sin_addr), port);
11447 
11448    ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE);
11449 
11450    return RESULT_SUCCESS;
11451 }

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

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

Referenced by sip_do_debug(), and sip_do_debug_deprecated().

11455 {
11456    struct sip_peer *peer;
11457    if (argc != 5)
11458       return RESULT_SHOWUSAGE;
11459    peer = find_peer(argv[4], NULL, 1, 0);
11460    if (peer) {
11461       if (peer->addr.sin_addr.s_addr) {
11462          debugaddr.sin_family = AF_INET;
11463          debugaddr.sin_addr = peer->addr.sin_addr;
11464          debugaddr.sin_port = peer->addr.sin_port;
11465          ast_cli(fd, "SIP Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(debugaddr.sin_addr), ntohs(debugaddr.sin_port));
11466          ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE);
11467       } else
11468          ast_cli(fd, "Unable to get IP address of peer '%s'\n", argv[4]);
11469       ASTOBJ_UNREF(peer,sip_destroy_peer);
11470    } else
11471       ast_cli(fd, "No such peer '%s'\n", argv[4]);
11472    return RESULT_SUCCESS;
11473 }

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

Enable SIP History logging (CLI).

Definition at line 11595 of file chan_sip.c.

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

11596 {
11597    if (argc != 2) {
11598       return RESULT_SHOWUSAGE;
11599    }
11600    recordhistory = TRUE;
11601    ast_cli(fd, "SIP History Recording Enabled (use 'sip show history')\n");
11602    return RESULT_SUCCESS;
11603 }

static int sip_do_reload ( enum channelreloadreason  reason  )  [static]

Reload module.

Definition at line 18536 of file chan_sip.c.

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

Referenced by do_monitor().

18537 {
18538    reload_config(reason);
18539 
18540    /* Prune peers who still are supposed to be deleted */
18541    ASTOBJ_CONTAINER_PRUNE_MARKED(&peerl, sip_destroy_peer);
18542    if (option_debug > 3)
18543       ast_log(LOG_DEBUG, "--------------- Done destroying pruned peers\n");
18544 
18545    /* Send qualify (OPTIONS) to all peers */
18546    sip_poke_all_peers();
18547 
18548    /* Register with all services */
18549    sip_send_all_registers();
18550 
18551    if (option_debug > 3)
18552       ast_log(LOG_DEBUG, "--------------- SIP reload done\n");
18553 
18554    return 0;
18555 }

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

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

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

18336 {
18337    struct sip_pvt *p;
18338    char *mode;
18339    if (data)
18340       mode = (char *)data;
18341    else {
18342       ast_log(LOG_WARNING, "This application requires the argument: info, inband, rfc2833\n");
18343       return 0;
18344    }
18345    ast_channel_lock(chan);
18346    if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) {
18347       ast_log(LOG_WARNING, "Call this application only on SIP incoming calls\n");
18348       ast_channel_unlock(chan);
18349       return 0;
18350    }
18351    p = chan->tech_pvt;
18352    if (!p) {
18353       ast_channel_unlock(chan);
18354       return 0;
18355    }
18356    ast_mutex_lock(&p->lock);
18357    if (!strcasecmp(mode,"info")) {
18358       ast_clear_flag(&p->flags[0], SIP_DTMF);
18359       ast_set_flag(&p->flags[0], SIP_DTMF_INFO);
18360       p->jointnoncodeccapability &= ~AST_RTP_DTMF;
18361    } else if (!strcasecmp(mode,"rfc2833")) {
18362       ast_clear_flag(&p->flags[0], SIP_DTMF);
18363       ast_set_flag(&p->flags[0], SIP_DTMF_RFC2833);
18364       p->jointnoncodeccapability |= AST_RTP_DTMF;
18365    } else if (!strcasecmp(mode,"inband")) { 
18366       ast_clear_flag(&p->flags[0], SIP_DTMF);
18367       ast_set_flag(&p->flags[0], SIP_DTMF_INBAND);
18368       p->jointnoncodeccapability &= ~AST_RTP_DTMF;
18369    } else
18370       ast_log(LOG_WARNING, "I don't know about this dtmf mode: %s\n",mode);
18371    if (p->rtp)
18372       ast_rtp_setdtmf(p->rtp, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833);
18373    if (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) {
18374       if (!p->vad) {
18375          p->vad = ast_dsp_new();
18376          ast_dsp_set_features(p->vad, DSP_FEATURE_DTMF_DETECT);
18377       }
18378    } else {
18379       if (p->vad) {
18380          ast_dsp_free(p->vad);
18381          p->vad = NULL;
18382       }
18383    }
18384    ast_mutex_unlock(&p->lock);
18385    ast_channel_unlock(chan);
18386    return 0;
18387 }

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

11281 {
11282    int x = 0;
11283    struct sip_history *hist;
11284    static int errmsg = 0;
11285 
11286    if (!dialog)
11287       return;
11288 
11289    if (!option_debug && !sipdebug) {
11290       if (!errmsg) {
11291          ast_log(LOG_NOTICE, "You must have debugging enabled (SIP or Asterisk) in order to dump SIP history.\n");
11292          errmsg = 1;
11293       }
11294       return;
11295    }
11296 
11297    ast_log(LOG_DEBUG, "\n---------- SIP HISTORY for '%s' \n", dialog->callid);
11298    if (dialog->subscribed)
11299       ast_log(LOG_DEBUG, "  * Subscription\n");
11300    else
11301       ast_log(LOG_DEBUG, "  * SIP Call\n");
11302    if (dialog->history)
11303       AST_LIST_TRAVERSE(dialog->history, hist, list)
11304          ast_log(LOG_DEBUG, "  %-3.3d. %s\n", ++x, hist->event);
11305    if (!x)
11306       ast_log(LOG_DEBUG, "Call '%s' has no history\n", dialog->callid);
11307    ast_log(LOG_DEBUG, "\n---------- END SIP HISTORY for '%s' \n", dialog->callid);
11308 }

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 3814 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, option_debug, sip_pvt::owner, sip_set_rtp_peer(), and ast_channel::tech_pvt.

03815 {
03816    int ret = -1;
03817    struct sip_pvt *p;
03818 
03819    if (newchan && ast_test_flag(newchan, AST_FLAG_ZOMBIE) && option_debug)
03820       ast_log(LOG_DEBUG, "New channel is zombie\n");
03821    if (oldchan && ast_test_flag(oldchan, AST_FLAG_ZOMBIE) && option_debug)
03822       ast_log(LOG_DEBUG, "Old channel is zombie\n");
03823 
03824    if (!newchan || !newchan->tech_pvt) {
03825       if (!newchan)
03826          ast_log(LOG_WARNING, "No new channel! Fixup of %s failed.\n", oldchan->name);
03827       else
03828          ast_log(LOG_WARNING, "No SIP tech_pvt! Fixup of %s failed.\n", oldchan->name);
03829       return -1;
03830    }
03831    p = newchan->tech_pvt;
03832 
03833    if (!p) {
03834       ast_log(LOG_WARNING, "No pvt after masquerade. Strange things may happen\n");
03835       return -1;
03836    }
03837 
03838    ast_mutex_lock(&p->lock);
03839    append_history(p, "Masq", "Old channel: %s\n", oldchan->name);
03840    append_history(p, "Masq (cont)", "...new owner: %s\n", newchan->name);
03841    if (p->owner != oldchan)
03842       ast_log(LOG_WARNING, "old channel wasn't %p but was %p\n", oldchan, p->owner);
03843    else {
03844       p->owner = newchan;
03845       /* Re-invite RTP back to Asterisk. Needed if channel is masqueraded out of a native
03846          RTP bridge (i.e., RTP not going through Asterisk): RTP bridge code might not be
03847          able to do this if the masquerade happens before the bridge breaks (e.g., AMI
03848          redirect of both channels). Note that a channel can not be masqueraded *into*
03849          a native bridge. So there is no danger that this breaks a native bridge that
03850          should stay up. */
03851       sip_set_rtp_peer(newchan, NULL, NULL, 0, 0);
03852       ret = 0;
03853    }
03854    if (option_debug > 2)
03855       ast_log(LOG_DEBUG, "SIP Fixup: New owner for dialogue %s: %s (Old parent: %s)\n", p->callid, p->owner->name, oldchan->name);
03856 
03857    ast_mutex_unlock(&p->lock);
03858    return ret;
03859 }

static int sip_get_codec ( struct ast_channel chan  )  [static]

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

Definition at line 18480 of file chan_sip.c.

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

18481 {
18482    struct sip_pvt *p = chan->tech_pvt;
18483    return p->peercapability ? p->peercapability : p->capability;  
18484 }

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

18189 {
18190    struct sip_pvt *p = NULL;
18191    enum ast_rtp_get_result res = AST_RTP_TRY_PARTIAL;
18192 
18193    if (!(p = chan->tech_pvt))
18194       return AST_RTP_GET_FAILED;
18195 
18196    ast_mutex_lock(&p->lock);
18197    if (!(p->rtp)) {
18198       ast_mutex_unlock(&p->lock);
18199       return AST_RTP_GET_FAILED;
18200    }
18201 
18202    *rtp = p->rtp;
18203 
18204    if (ast_rtp_getnat(*rtp) && !ast_test_flag(&p->flags[0], SIP_CAN_REINVITE_NAT))
18205       res = AST_RTP_TRY_PARTIAL;
18206    else if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE))
18207       res = AST_RTP_TRY_NATIVE;
18208    else if (ast_test_flag(&global_jbconf, AST_JB_FORCED))
18209       res = AST_RTP_GET_FAILED;
18210 
18211    ast_mutex_unlock(&p->lock);
18212 
18213    return res;
18214 }

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

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

18054 {
18055    struct sip_pvt *p;
18056    struct ast_udptl *udptl = NULL;
18057    
18058    p = chan->tech_pvt;
18059    if (!p)
18060       return NULL;
18061    
18062    ast_mutex_lock(&p->lock);
18063    if (p->udptl && ast_test_flag(&p->flags[0], SIP_CAN_REINVITE))
18064       udptl = p->udptl;
18065    ast_mutex_unlock(&p->lock);
18066    return udptl;
18067 }

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 18217 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_pvt::rtp, SIP_CAN_REINVITE, ast_channel::tech_pvt, and sip_pvt::vrtp.

18218 {
18219    struct sip_pvt *p = NULL;
18220    enum ast_rtp_get_result res = AST_RTP_TRY_PARTIAL;
18221    
18222    if (!(p = chan->tech_pvt))
18223       return AST_RTP_GET_FAILED;
18224 
18225    ast_mutex_lock(&p->lock);
18226    if (!(p->vrtp)) {
18227       ast_mutex_unlock(&p->lock);
18228       return AST_RTP_GET_FAILED;
18229    }
18230 
18231    *rtp = p->vrtp;
18232 
18233    if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE))
18234       res = AST_RTP_TRY_NATIVE;
18235 
18236    ast_mutex_unlock(&p->lock);
18237 
18238    return res;
18239 }

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

Handle T38 reinvite.

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

18106 {
18107    struct sip_pvt *p;
18108    int flag = 0;
18109    
18110    p = chan->tech_pvt;
18111    if (!p || !pvt->udptl)
18112       return -1;
18113    
18114    /* Setup everything on the other side like offered/responded from first side */
18115    ast_mutex_lock(&p->lock);
18116 
18117    /*! \todo check if this is not set earlier when setting up the PVT. If not
18118       maybe it should move there. */
18119    p->t38.jointcapability = p->t38.peercapability = pvt->t38.jointcapability;
18120 
18121    ast_udptl_set_far_max_datagram(p->udptl, ast_udptl_get_local_max_datagram(pvt->udptl));
18122    ast_udptl_set_local_max_datagram(p->udptl, ast_udptl_get_local_max_datagram(pvt->udptl));
18123    ast_udptl_set_error_correction_scheme(p->udptl, ast_udptl_get_error_correction_scheme(pvt->udptl));
18124    
18125    if (reinvite) {      /* If we are handling sending re-invite to the other side of the bridge */
18126       /*! \note The SIP_CAN_REINVITE flag is for RTP media redirects,
18127          not really T38 re-invites which are different. In this
18128          case it's used properly, to see if we can reinvite over
18129          NAT 
18130       */
18131       if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE) && ast_test_flag(&pvt->flags[0], SIP_CAN_REINVITE)) {
18132          ast_udptl_get_peer(pvt->udptl, &p->udptlredirip);
18133          flag =1;
18134       } else {
18135          memset(&p->udptlredirip, 0, sizeof(p->udptlredirip));
18136       }
18137       if (!ast_test_flag(&p->flags[0], SIP_GOTREFER)) {
18138          if (!p->pendinginvite) {
18139             if (option_debug > 2) {
18140                if (flag)
18141                   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));
18142                else
18143                   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));
18144             }
18145             transmit_reinvite_with_t38_sdp(p);
18146          } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) {
18147             if (option_debug > 2) {
18148                if (flag)
18149                   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));
18150                else
18151                   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));
18152             }
18153             ast_set_flag(&p->flags[0], SIP_NEEDREINVITE);
18154          }
18155       }
18156       /* Reset lastrtprx timer */
18157       p->lastrtprx = p->lastrtptx = time(NULL);
18158       ast_mutex_unlock(&p->lock);
18159       return 0;
18160    } else { /* If we are handling sending 200 OK to the other side of the bridge */
18161       if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE) && ast_test_flag(&pvt->flags[0], SIP_CAN_REINVITE)) {
18162          ast_udptl_get_peer(pvt->udptl, &p->udptlredirip);
18163          flag = 1;
18164       } else {
18165          memset(&p->udptlredirip, 0, sizeof(p->udptlredirip));
18166       }
18167       if (option_debug > 2) {
18168          if (flag)
18169             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));
18170          else
18171             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));
18172       }
18173       pvt->t38.state = T38_ENABLED;
18174       p->t38.state = T38_ENABLED;
18175       if (option_debug > 1) {
18176          ast_log(LOG_DEBUG, "T38 changed state to %d on channel %s\n", pvt->t38.state, pvt->owner ? pvt->owner->name : "<none>");
18177          ast_log(LOG_DEBUG, "T38 changed state to %d on channel %s\n", p->t38.state, chan ? chan->name : "<none>");
18178       }
18179       transmit_response_with_t38_sdp(p, "200 OK", &p->initreq, XMIT_CRITICAL);
18180       p->lastrtprx = p->lastrtptx = time(NULL);
18181       ast_mutex_unlock(&p->lock);
18182       return 0;
18183    }
18184 }

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 3523 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, DEC_CALL_LIMIT, DEFAULT_TRANS_TIMEOUT, FALSE, sip_pvt::flags, hangup_cause2sip(), ast_channel::hangupcause, INC_CALL_LIMIT, INV_CALLING, INV_CANCELLED, INV_COMPLETED, INV_TERMINATED, sip_pvt::invitestate, sip_pvt::lock, LOG_DEBUG, option_debug, sip_pvt::owner, pbx_builtin_setvar_helper(), sip_pvt::refer, sched, 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, and XMIT_RELIABLE.

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

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

References ast_channel::_state, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_HOLD, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_RINGING, AST_CONTROL_SRCUPDATE, AST_CONTROL_UNHOLD, AST_CONTROL_VIDUPDATE, ast_log(), ast_moh_start(), ast_moh_stop(), ast_mutex_lock(), ast_mutex_unlock(), ast_rtp_new_source(), ast_set_flag, AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), AST_STATE_RING, AST_STATE_UP, ast_test_flag, sip_pvt::flags, sip_pvt::initreq, INV_COMPLETED, INV_EARLY_MEDIA, INV_PROCEEDING, sip_pvt::invitestate, sip_pvt::lock, 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_reliable(), transmit_response_with_sdp(), sip_pvt::vrtp, and XMIT_UNRELIABLE.

03931 {
03932    struct sip_pvt *p = ast->tech_pvt;
03933    int res = 0;
03934 
03935    ast_mutex_lock(&p->lock);
03936    switch(condition) {
03937    case AST_CONTROL_RINGING:
03938       if (ast->_state == AST_STATE_RING) {
03939          p->invitestate = INV_EARLY_MEDIA;
03940          if (!ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) ||
03941              (ast_test_flag(&p->flags[0], SIP_PROG_INBAND) == SIP_PROG_INBAND_NEVER)) {            
03942             /* Send 180 ringing if out-of-band seems reasonable */
03943             transmit_response(p, "180 Ringing", &p->initreq);
03944             ast_set_flag(&p->flags[0], SIP_RINGING);
03945             if (ast_test_flag(&p->flags[0], SIP_PROG_INBAND) != SIP_PROG_INBAND_YES)
03946                break;
03947          } else {
03948             /* Well, if it's not reasonable, just send in-band */
03949          }
03950       }
03951       res = -1;
03952       break;
03953    case AST_CONTROL_BUSY:
03954       if (ast->_state != AST_STATE_UP) {
03955          transmit_response_reliable(p, "486 Busy Here", &p->initreq);
03956          p->invitestate = INV_COMPLETED;
03957          sip_alreadygone(p);
03958          ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV);
03959          break;
03960       }
03961       res = -1;
03962       break;
03963    case AST_CONTROL_CONGESTION:
03964       if (ast->_state != AST_STATE_UP) {
03965          transmit_response_reliable(p, "503 Service Unavailable", &p->initreq);
03966          p->invitestate = INV_COMPLETED;
03967          sip_alreadygone(p);
03968          ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV);
03969          break;
03970       }
03971       res = -1;
03972       break;
03973    case AST_CONTROL_PROCEEDING:
03974       if ((ast->_state != AST_STATE_UP) &&
03975           !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) &&
03976           !ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
03977          transmit_response(p, "100 Trying", &p->initreq);
03978          p->invitestate = INV_PROCEEDING;  
03979          break;
03980       }
03981       res = -1;
03982       break;
03983    case AST_CONTROL_PROGRESS:
03984       if ((ast->_state != AST_STATE_UP) &&
03985           !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) &&
03986           !ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
03987          p->invitestate = INV_EARLY_MEDIA;
03988          transmit_response_with_sdp(p, "183 Session Progress", &p->initreq, XMIT_UNRELIABLE);
03989          ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT);  
03990          break;
03991       }
03992       res = -1;
03993       break;
03994    case AST_CONTROL_HOLD:
03995       ast_rtp_new_source(p->rtp);
03996       ast_moh_start(ast, data, p->mohinterpret);
03997       break;
03998    case AST_CONTROL_UNHOLD:
03999       ast_rtp_new_source(p->rtp);
04000       ast_moh_stop(ast);
04001       break;
04002    case AST_CONTROL_VIDUPDATE:   /* Request a video frame update */
04003       if (p->vrtp && !ast_test_flag(&p->flags[0], SIP_NOVIDEO)) {
04004          transmit_info_with_vidupdate(p);
04005          /* ast_rtcp_send_h261fur(p->vrtp); */
04006       } else
04007          res = -1;
04008       break;
04009    case AST_CONTROL_SRCUPDATE:
04010       ast_rtp_new_source(p->rtp);
04011       break;
04012    case -1:
04013       res = -1;
04014       break;
04015    default:
04016       ast_log(LOG_WARNING, "Don't know how to indicate condition %d\n", condition);
04017       res = -1;
04018       break;
04019    }
04020    ast_mutex_unlock(&p->lock);
04021    return res;
04022 }

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

Display SIP nat mode.

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

01770 {
01771    return ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE ? "NAT" : "no NAT";
01772 }

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

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 4030 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(), ast_verbose(), 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, f, ast_channel::fds, sip_pvt::flags, fmt, global_jbconf, sip_pvt::jointcapability, language, sip_pvt::lock, LOG_DEBUG, 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, VERBOSE_PREFIX_3, sip_pvt::vrtp, and ast_channel::writeformat.

Referenced by handle_request_invite(), and sip_request_call().

04031 {
04032    struct ast_channel *tmp;
04033    struct ast_variable *v = NULL;
04034    int fmt;
04035    int what;
04036    int needvideo = 0, video = 0;
04037    char *decoded_exten;
04038  
04039    if (option_debug != 0) {
04040      ast_verbose(VERBOSE_PREFIX_3 "NEW SIP CHANNEL, title: <%s>\n", title?title:"Null");
04041      ast_verbose(VERBOSE_PREFIX_3 "from: %s\n", i->from);
04042      ast_verbose(VERBOSE_PREFIX_3 "username: <%s>\n", i->username);
04043      ast_verbose(VERBOSE_PREFIX_3 "peername: <%s>\n", i->peername);
04044      ast_verbose(VERBOSE_PREFIX_3 "fromdomain: %s\n", i->fromdomain);
04045      ast_verbose(VERBOSE_PREFIX_3 "fromuser: %s\n", i->fromuser);
04046      ast_verbose(VERBOSE_PREFIX_3 "fromname: %s\n", i->fromname);
04047      ast_verbose(VERBOSE_PREFIX_3 "fullcontact: %s\n", i->fullcontact);
04048    }
04049 
04050    {
04051       char my_name[128];    /* pick a good name */
04052       const char *f, *fromdomain = NULL;
04053   
04054       if (!ast_strlen_zero(i->fromdomain) && strchr(i->fromdomain,':'))
04055          fromdomain = strchr(i->fromdomain,':') + 1; /* skip ':' */
04056       else
04057          fromdomain = i->fromdomain;
04058   
04059       if (!ast_strlen_zero(i->username)) {
04060          if (!ast_strlen_zero(title) && strcmp(i->username, title)) {
04061             /* title not empty and different from username */
04062             snprintf(my_name, sizeof(my_name), "%s@%s", i->username, title);
04063          } else {
04064             /* username not empty, title is empty or equal to username */
04065             snprintf(my_name, sizeof(my_name), "%s", i->username);
04066          }
04067       } else { /* username empty */ 
04068          if (!ast_strlen_zero(i->peername)) {
04069             /* call from unregisted peer */
04070             snprintf(my_name, sizeof(my_name), "%s", i->peername);
04071          } else { /* username and peername empty */
04072             if (!ast_strlen_zero(title)) { /* title not empty */
04073                snprintf(my_name, sizeof(my_name), "%s", title);
04074             } else if (!ast_strlen_zero(i->from)) { /* title empty, From: not empty */
04075                f = i->from;
04076                if (!strncmp(f, "sip:", 4))
04077                   f += 4;
04078                snprintf(my_name, sizeof(my_name), "%s", f);
04079             } else { /* fallback to fromdomain */
04080                snprintf(my_name, sizeof(my_name), "%s", fromdomain);
04081             }
04082          }
04083       }
04084       ast_mutex_unlock(&i->lock);
04085       /* Don't hold a sip pvt lock while we allocate a channel */
04086       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);
04087 
04088    }
04089    if (!tmp) {
04090       ast_log(LOG_WARNING, "Unable to allocate AST channel structure for SIP channel\n");
04091       ast_mutex_lock(&i->lock);
04092       return NULL;
04093    }
04094    ast_mutex_lock(&i->lock);
04095 
04096    if (ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_INFO)
04097       tmp->tech = &sip_tech_info;
04098    else
04099       tmp->tech = &sip_tech;
04100 
04101    /* Select our native format based on codec preference until we receive
04102       something from another device to the contrary. */
04103    if (i->jointcapability) {     /* The joint capabilities of us and peer */
04104       what = i->jointcapability;
04105       video = i->jointcapability & AST_FORMAT_VIDEO_MASK;
04106    } else if (i->capability)  {  /* Our configured capability for this peer */
04107       what = i->capability;
04108       video = i->capability & AST_FORMAT_VIDEO_MASK;
04109    } else {
04110       what = global_capability;  /* Global codec support */
04111       video = global_capability & AST_FORMAT_VIDEO_MASK;
04112    }
04113 
04114    /* Set the native formats for audio  and merge in video */
04115    tmp->nativeformats = ast_codec_choose(&i->prefs, what, 1) | video;
04116    if (option_debug > 2) {
04117       char buf[SIPBUFSIZE];
04118       ast_log(LOG_DEBUG, "*** Our native formats are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, tmp->nativeformats));
04119       ast_log(LOG_DEBUG, "*** Joint capabilities are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, i->jointcapability));
04120       ast_log(LOG_DEBUG, "*** Our capabilities are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, i->capability));
04121       ast_log(LOG_DEBUG, "*** AST_CODEC_CHOOSE formats are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, ast_codec_choose(&i->prefs, what, 1)));
04122       if (i->prefcodec)
04123          ast_log(LOG_DEBUG, "*** Our preferred formats from the incoming channel are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, i->prefcodec));
04124    }
04125 
04126    /* XXX Why are we choosing a codec from the native formats?? */
04127    fmt = ast_best_codec(tmp->nativeformats);
04128 
04129    /* If we have a prefcodec setting, we have an inbound channel that set a 
04130       preferred format for this call. Otherwise, we check the jointcapability
04131       We also check for vrtp. If it's not there, we are not allowed do any video anyway.
04132     */
04133    if (i->vrtp) {
04134       if (i->prefcodec)
04135          needvideo = i->prefcodec & AST_FORMAT_VIDEO_MASK;  /* Outbound call */
04136       else
04137          needvideo = i->jointcapability & AST_FORMAT_VIDEO_MASK;  /* Inbound call */
04138    }
04139 
04140    if (option_debug > 2) {
04141       if (needvideo) 
04142          ast_log(LOG_DEBUG, "This channel can handle video! HOLLYWOOD next!\n");
04143       else
04144          ast_log(LOG_DEBUG, "This channel will not be able to handle video.\n");
04145    }
04146 
04147 
04148 
04149    if (ast_test_flag(&i->flags[0], SIP_DTMF) ==  SIP_DTMF_INBAND) {
04150       i->vad = ast_dsp_new();
04151       ast_dsp_set_features(i->vad, DSP_FEATURE_DTMF_DETECT);
04152       if (global_relaxdtmf)
04153          ast_dsp_digitmode(i->vad, DSP_DIGITMODE_DTMF | DSP_DIGITMODE_RELAXDTMF);
04154    }
04155    if (i->rtp) {
04156       tmp->fds[0] = ast_rtp_fd(i->rtp);
04157       tmp->fds[1] = ast_rtcp_fd(i->rtp);
04158    }
04159    if (needvideo && i->vrtp) {
04160       tmp->fds[2] = ast_rtp_fd(i->vrtp);
04161       tmp->fds[3] = ast_rtcp_fd(i->vrtp);
04162    }
04163    if (i->udptl) {
04164       tmp->fds[5] = ast_udptl_fd(i->udptl);
04165    }
04166    if (state == AST_STATE_RING)
04167       tmp->rings = 1;
04168    tmp->adsicpe = AST_ADSI_UNAVAILABLE;
04169    tmp->writeformat = fmt;
04170    tmp->rawwriteformat = fmt;
04171    tmp->readformat = fmt;
04172    tmp->rawreadformat = fmt;
04173    tmp->tech_pvt = i;
04174 
04175    tmp->callgroup = i->callgroup;
04176    tmp->pickupgroup = i->pickupgroup;
04177    tmp->cid.cid_pres = i->callingpres;
04178    if (!ast_strlen_zero(i->accountcode))
04179       ast_string_field_set(tmp, accountcode, i->accountcode);
04180    if (i->amaflags)
04181       tmp->amaflags = i->amaflags;
04182    if (!ast_strlen_zero(i->language))
04183       ast_string_field_set(tmp, language, i->language);
04184    i->owner = tmp;
04185    ast_module_ref(ast_module_info->self);
04186    ast_copy_string(tmp->context, i->context, sizeof(tmp->context));
04187    /*Since it is valid to have extensions in the dialplan that have unescaped characters in them
04188     * we should decode the uri before storing it in the channel, but leave it encoded in the sip_pvt
04189     * structure so that there aren't issues when forming URI's
04190     */
04191    decoded_exten = ast_strdupa(i->exten);
04192    ast_uri_decode(decoded_exten);
04193    ast_copy_string(tmp->exten, decoded_exten, sizeof(tmp->exten));
04194 
04195    /* Don't use ast_set_callerid() here because it will
04196     * generate an unnecessary NewCallerID event  */
04197    tmp->cid.cid_ani = ast_strdup(i->cid_num);
04198    if (!ast_strlen_zero(i->rdnis))
04199       tmp->cid.cid_rdnis = ast_strdup(i->rdnis);
04200    
04201    if (!ast_strlen_zero(i->exten) && strcmp(i->exten, "s"))
04202       tmp->cid.cid_dnid = ast_strdup(i->exten);
04203 
04204    tmp->priority = 1;
04205    if (!ast_strlen_zero(i->uri))
04206       pbx_builtin_setvar_helper(tmp, "SIPURI", i->uri);
04207    if (!ast_strlen_zero(i->domain))
04208       pbx_builtin_setvar_helper(tmp, "SIPDOMAIN", i->domain);
04209    if (!ast_strlen_zero(i->useragent))
04210       pbx_builtin_setvar_helper(tmp, "SIPUSERAGENT", i->useragent);
04211    if (!ast_strlen_zero(i->callid))
04212       pbx_builtin_setvar_helper(tmp, "SIPCALLID", i->callid);
04213    if (i->rtp)
04214       ast_jb_configure(tmp, &global_jbconf);
04215 
04216    /* If the INVITE contains T.38 SDP information set the proper channel variable so a created outgoing call will also have T.38 */
04217    if (i->udptl && i->t38.state == T38_PEER_DIRECT)
04218       pbx_builtin_setvar_helper(tmp, "_T38CALL", "1");
04219 
04220    /* Set channel variables for this call from configuration */
04221    for (v = i->chanvars ; v ; v = v->next)
04222       pbx_builtin_setvar_helper(tmp, v->name, v->value);
04223 
04224    if (state != AST_STATE_DOWN && ast_pbx_start(tmp)) {
04225       ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
04226       tmp->hangupcause = AST_CAUSE_SWITCH_CONGESTION;
04227       ast_hangup(tmp);
04228       tmp = NULL;
04229    }
04230 
04231    if (!ast_test_flag(&i->flags[0], SIP_NO_HISTORY))
04232       append_history(i, "NewChan", "Channel %s - from %s", tmp->name, i->callid);
04233 
04234    return tmp;
04235 }

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

Disable SIP Debugging in CLI.

Definition at line 11576 of file chan_sip.c.

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

11577 {
11578    if (argc != 4)
11579       return RESULT_SHOWUSAGE;
11580    ast_clear_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE);
11581    ast_cli(fd, "SIP Debugging Disabled\n");
11582    return RESULT_SUCCESS;
11583 }

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

Definition at line 11585 of file chan_sip.c.

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

11586 {
11587    if (argc != 3)
11588       return RESULT_SHOWUSAGE;
11589    ast_clear_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE);
11590    ast_cli(fd, "SIP Debugging Disabled\n");
11591    return RESULT_SUCCESS;
11592 }

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

Disable SIP History logging (CLI).

Definition at line 11606 of file chan_sip.c.

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

11607 {
11608    if (argc != 3) {
11609       return RESULT_SHOWUSAGE;
11610    }
11611    recordhistory = FALSE;
11612    ast_cli(fd, "SIP History Recording Disabled\n");
11613    return RESULT_SUCCESS;
11614 }

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

Cli command to send SIP notify to peer.

Definition at line 11520 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(), notify_types, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, sip_alloc(), sip_destroy(), SIP_NOTIFY, sip_scheddestroy(), transmit_sip_request(), and var.

11521 {
11522    struct ast_variable *varlist;
11523    int i;
11524 
11525    if (argc < 4)
11526       return RESULT_SHOWUSAGE;
11527 
11528    if (!notify_types) {
11529       ast_cli(fd, "No %s file found, or no types listed there\n", notify_config);
11530       return RESULT_FAILURE;
11531    }
11532 
11533    varlist = ast_variable_browse(notify_types, argv[2]);
11534 
11535    if (!varlist) {
11536       ast_cli(fd, "Unable to find notify type '%s'\n", argv[2]);
11537       return RESULT_FAILURE;
11538    }
11539 
11540    for (i = 3; i < argc; i++) {
11541       struct sip_pvt *p;
11542       struct sip_request req;
11543       struct ast_variable *var;
11544 
11545       if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY))) {
11546          ast_log(LOG_WARNING, "Unable to build sip pvt data for notify (memory/socket error)\n");
11547          return RESULT_FAILURE;
11548       }
11549 
11550       if (create_addr(p, argv[i])) {
11551          /* Maybe they're not registered, etc. */
11552          sip_destroy(p);
11553          ast_cli(fd, "Could not create address for '%s'\n", argv[i]);
11554          continue;
11555       }
11556 
11557       initreqprep(&req, p, SIP_NOTIFY);
11558 
11559       for (var = varlist; var; var = var->next)
11560          add_header(&req, var->name, ast_unescape_semicolon(var->value));
11561 
11562       /* Recalculate our side, and recalculate Call ID */
11563       if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
11564          p->ourip = __ourip;
11565       build_via(p);
11566       build_callid_pvt(p);
11567       ast_cli(fd, "Sending NOTIFY of type '%s' to '%s'\n", argv[2], argv[i]);
11568       transmit_sip_request(p, &req);
11569       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
11570    }
11571 
11572    return RESULT_SUCCESS;
11573 }

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 13339 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, ast_channel::context, copy_request(), DEADLOCK_AVOIDANCE, ast_channel::exten, free, ast_channel::hangupcause, sip_pvt::lock, LOG_DEBUG, option_debug, ast_channel::priority, ast_channel::readformat, sip_park_thread(), ast_channel::tech_pvt, and ast_channel::writeformat.

Referenced by handle_request_refer().

13340 {
13341    struct sip_dual *d;
13342    struct ast_channel *transferee, *transferer;
13343       /* Chan2m: The transferer, chan1m: The transferee */
13344    pthread_t th;
13345 
13346    transferee = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan1->accountcode, chan1->exten, chan1->context, chan1->amaflags, "Parking/%s", chan1->name);
13347    transferer = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->amaflags, "SIPPeer/%s", chan2->name);
13348    if ((!transferer) || (!transferee)) {
13349       if (transferee) {
13350          transferee->hangupcause = AST_CAUSE_SWITCH_CONGESTION;
13351          ast_hangup(transferee);
13352       }
13353       if (transferer) {
13354          transferer->hangupcause = AST_CAUSE_SWITCH_CONGESTION;
13355          ast_hangup(transferer);
13356       }
13357       return -1;
13358    }
13359 
13360    /* Make formats okay */
13361    transferee->readformat = chan1->readformat;
13362    transferee->writeformat = chan1->writeformat;
13363 
13364    /* Prepare for taking over the channel */
13365    ast_channel_masquerade(transferee, chan1);
13366 
13367    /* Setup the extensions and such */
13368    ast_copy_string(transferee->context, chan1->context, sizeof(transferee->context));
13369    ast_copy_string(transferee->exten, chan1->exten, sizeof(transferee->exten));
13370    transferee->priority = chan1->priority;
13371       
13372    /* We make a clone of the peer channel too, so we can play
13373       back the announcement */
13374 
13375    /* Make formats okay */
13376    transferer->readformat = chan2->readformat;
13377    transferer->writeformat = chan2->writeformat;
13378 
13379    /* Prepare for taking over the channel.  Go ahead and grab this channel
13380     * lock here to avoid a deadlock with callbacks into the channel driver
13381     * that hold the channel lock and want the pvt lock.  */
13382    while (ast_channel_trylock(chan2)) {
13383       struct sip_pvt *pvt = chan2->tech_pvt;
13384       DEADLOCK_AVOIDANCE(&pvt->lock);
13385    }
13386    ast_channel_masquerade(transferer, chan2);
13387    ast_channel_unlock(chan2);
13388 
13389    /* Setup the extensions and such */
13390    ast_copy_string(transferer->context, chan2->context, sizeof(transferer->context));
13391    ast_copy_string(transferer->exten, chan2->exten, sizeof(transferer->exten));
13392    transferer->priority = chan2->priority;
13393 
13394    ast_channel_lock(transferer);
13395    if (ast_do_masquerade(transferer)) {
13396       ast_log(LOG_WARNING, "Masquerade failed :(\n");
13397       ast_channel_unlock(transferer);
13398       transferer->hangupcause = AST_CAUSE_SWITCH_CONGESTION;
13399       ast_hangup(transferer);
13400       return -1;
13401    }
13402    ast_channel_unlock(transferer);
13403    if (!transferer || !transferee) {
13404       if (!transferer) { 
13405          if (option_debug)
13406             ast_log(LOG_DEBUG, "No transferer channel, giving up parking\n");
13407       }
13408       if (!transferee) {
13409          if (option_debug)
13410             ast_log(LOG_DEBUG, "No transferee channel, giving up parking\n");
13411       }
13412       return -1;
13413    }
13414    if ((d = ast_calloc(1, sizeof(*d)))) {
13415       pthread_attr_t attr;
13416 
13417       pthread_attr_init(&attr);
13418       pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);   
13419 
13420       /* Save original request for followup */
13421       copy_request(&d->req, req);
13422       d->chan1 = transferee;  /* Transferee */
13423       d->chan2 = transferer;  /* Transferer */
13424       d->seqno = seqno;
13425       if (ast_pthread_create_background(&th, &attr, sip_park_thread, d) < 0) {
13426          /* Could not start thread */
13427          free(d); /* We don't need it anymore. If thread is created, d will be free'd
13428                   by sip_park_thread() */
13429          pthread_attr_destroy(&attr);
13430          return 0;
13431       }
13432       pthread_attr_destroy(&attr);
13433    } 
13434    return -1;
13435 }

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

13273 {
13274    struct ast_channel *transferee, *transferer; /* Chan1: The transferee, Chan2: The transferer */
13275    struct sip_dual *d;
13276    struct sip_request req;
13277    int ext;
13278    int res;
13279 
13280    d = stuff;
13281    transferee = d->chan1;
13282    transferer = d->chan2;
13283    copy_request(&req, &d->req);
13284    free(d);
13285 
13286    if (!transferee || !transferer) {
13287       ast_log(LOG_ERROR, "Missing channels for parking! Transferer %s Transferee %s\n", transferer ? "<available>" : "<missing>", transferee ? "<available>" : "<missing>" );
13288       return NULL;
13289    }
13290    if (option_debug > 3) 
13291       ast_log(LOG_DEBUG, "SIP Park: Transferer channel %s, Transferee %s\n", transferer->name, transferee->name);
13292 
13293    ast_channel_lock(transferee);
13294    if (ast_do_masquerade(transferee)) {
13295       ast_log(LOG_WARNING, "Masquerade failed.\n");
13296       transmit_response(transferer->tech_pvt, "503 Internal error", &req);
13297       ast_channel_unlock(transferee);
13298       return NULL;
13299    } 
13300    ast_channel_unlock(transferee);
13301 
13302    res = ast_park_call(transferee, transferer, 0, &ext);
13303    
13304 
13305 #ifdef WHEN_WE_KNOW_THAT_THE_CLIENT_SUPPORTS_MESSAGE
13306    if (!res) {
13307       transmit_message_with_text(transferer->tech_pvt, "Unable to park call.\n");
13308    } else {
13309       /* Then tell the transferer what happened */
13310       sprintf(buf, "Call parked on extension '%d'", ext);
13311       transmit_message_with_text(transferer->tech_pvt, buf);
13312    }
13313 #endif
13314 
13315    /* Any way back to the current call??? */
13316    /* Transmit response to the REFER request */
13317    transmit_response(transferer->tech_pvt, "202 Accepted", &req);
13318    if (!res)   {
13319       /* Transfer succeeded */
13320       append_history(transferer->tech_pvt, "SIPpark","Parked call on %d", ext);
13321       transmit_notify_with_sipfrag(transferer->tech_pvt, d->seqno, "200 OK", TRUE);
13322       transferer->hangupcause = AST_CAUSE_NORMAL_CLEARING;
13323       ast_hangup(transferer); /* This will cause a BYE */
13324       if (option_debug)
13325          ast_log(LOG_DEBUG, "SIP Call parked on extension '%d'\n", ext);
13326    } else {
13327       transmit_notify_with_sipfrag(transferer->tech_pvt, d->seqno, "503 Service Unavailable", TRUE);
13328       append_history(transferer->tech_pvt, "SIPpark","Parking failed\n");
13329       if (option_debug)
13330          ast_log(LOG_DEBUG, "SIP Call parked failed \n");
13331       /* Do not hangup call */
13332    }
13333    return NULL;
13334 }

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

08696 {
08697    struct sip_peer *peer = find_peer(p->peername, NULL, 1, 0);
08698 
08699    if (!peer)
08700       return;
08701 
08702    /* If they put someone on hold, increment the value... otherwise decrement it */
08703    if (hold)
08704       peer->onHold++;
08705    else
08706       peer->onHold--;
08707 
08708    /* Request device state update */
08709    ast_device_state_changed("SIP/%s", peer->name);
08710 
08711    return;
08712 }

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

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

Referenced by load_module(), and sip_do_reload().

18491 {
18492    int ms = 0;
18493    
18494    if (!speerobjs)   /* No peers, just give up */
18495       return;
18496 
18497    ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do {
18498       ASTOBJ_WRLOCK(iterator);
18499       if (!AST_SCHED_DEL(sched, iterator->pokeexpire)) {
18500          struct sip_peer *peer_ptr = iterator;
18501          ASTOBJ_UNREF(peer_ptr, sip_destroy_peer);
18502       }
18503       ms += 100;
18504       iterator->pokeexpire = ast_sched_add(sched, ms, sip_poke_peer_s, ASTOBJ_REF(iterator));
18505       if (iterator->pokeexpire == -1) {
18506          struct sip_peer *peer_ptr = iterator;
18507          ASTOBJ_UNREF(peer_ptr, sip_destroy_peer);
18508       }
18509       ASTOBJ_UNLOCK(iterator);
18510    } while (0)
18511    );
18512 }

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

React to lack of answer to Qualify poke.

Definition at line 16336 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, sched, sip_destroy(), sip_destroy_peer(), and sip_poke_peer_s().

Referenced by sip_poke_peer().

16337 {
16338    struct sip_peer *peer = (struct sip_peer *)data;
16339    
16340    peer->pokeexpire = -1;
16341    if (peer->lastms > -1) {
16342       ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE!  Last qualify: %d\n", peer->name, peer->lastms);
16343       manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, -1);
16344    }
16345    if (peer->call)
16346       sip_destroy(peer->call);
16347    peer->call = NULL;
16348    peer->lastms = -1;
16349    ast_device_state_changed("SIP/%s", peer->name);
16350 
16351    /* This function gets called one place outside of the scheduler ... */
16352    if (!AST_SCHED_DEL(sched, peer->pokeexpire)) {
16353       struct sip_peer *peer_ptr = peer;
16354       ASTOBJ_UNREF(peer_ptr, sip_destroy_peer);
16355    }
16356 
16357    /* There is no need to ASTOBJ_REF() here.  Just let the scheduled callback
16358     * inherit the reference that the current callback already has. */
16359    peer->pokeexpire = ast_sched_add(sched, DEFAULT_FREQ_NOTOK, sip_poke_peer_s, peer);
16360    if (peer->pokeexpire == -1) {
16361       ASTOBJ_UNREF(peer, sip_destroy_peer);
16362    }
16363 
16364    return 0;
16365 }

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 16370 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, sched, sip_alloc(), sip_destroy(), sip_destroy_peer(), SIP_FLAGS_TO_COPY, SIP_INVITE, SIP_OPTIONS, SIP_OUTGOING, SIP_PAGE2_FLAGS_TO_COPY, SIP_PAGE2_TCP, SIP_PAGE2_TCP_CONNECTED, sip_poke_noanswer(), sipdebug, sip_peer::sockfd, sip_pvt::sockfd, sip_peer::tohost, transmit_invite(), and XMIT_ERROR.

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

16371 {
16372    struct sip_pvt *p;
16373    int xmitres = 0;
16374 
16375    if (!peer->maxms || !peer->addr.sin_addr.s_addr) {
16376       /* IF we have no IP, or this isn't to be monitored, return
16377         imeediately after clearing things out */
16378       if (!AST_SCHED_DEL(sched, peer->pokeexpire)) {
16379          struct sip_peer *peer_ptr = peer;
16380          ASTOBJ_UNREF(peer_ptr, sip_destroy_peer);
16381       }
16382       peer->lastms = 0;
16383       peer->call = NULL;
16384       return 0;
16385    }
16386    if (peer->call) {
16387       if (sipdebug)
16388          ast_log(LOG_NOTICE, "Still have a QUALIFY dialog active, deleting\n");
16389       sip_destroy(peer->call);
16390    }
16391    if (!(p = peer->call = sip_alloc(NULL, NULL, 0, SIP_OPTIONS)))
16392       return -1;
16393    
16394    p->sa = peer->addr;
16395    p->recv = peer->addr;
16396    ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY);
16397    ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY);
16398    ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_TCP | SIP_PAGE2_TCP_CONNECTED);
16399    p->sockfd = peer->sockfd;
16400 
16401    /* Send OPTIONs to peer's fullcontact */
16402    if (!ast_strlen_zero(peer->fullcontact))
16403       ast_string_field_set(p, fullcontact, peer->fullcontact);
16404 
16405    if (!ast_strlen_zero(peer->tohost))
16406       ast_string_field_set(p, tohost, peer->tohost);
16407    else
16408       ast_string_field_set(p, tohost, ast_inet_ntoa(peer->addr.sin_addr));
16409 
16410    /* Recalculate our side, and recalculate Call ID */
16411    if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
16412       p->ourip = __ourip;
16413    build_via(p);
16414    build_callid_pvt(p);
16415 
16416    if (!AST_SCHED_DEL(sched, peer->pokeexpire)) {
16417       struct sip_peer *peer_ptr = peer;
16418       ASTOBJ_UNREF(peer_ptr, sip_destroy_peer);
16419    }
16420 
16421    p->relatedpeer = ASTOBJ_REF(peer);
16422    ast_set_flag(&p->flags[0], SIP_OUTGOING);
16423 #ifdef VOCAL_DATA_HACK
16424    ast_copy_string(p->username, "__VOCAL_DATA_SHOULD_READ_THE_SIP_SPEC__", sizeof(p->username));
16425    xmitres = transmit_invite(p, SIP_INVITE, 0, 2);
16426 #else
16427    xmitres = transmit_invite(p, SIP_OPTIONS, 0, 2);
16428 #endif
16429    gettimeofday(&peer->ps, NULL);
16430    if (xmitres == XMIT_ERROR) {
16431       sip_poke_noanswer(ASTOBJ_REF(peer));   /* Immediately unreachable, network problems */
16432    } else {
16433       if (!AST_SCHED_DEL(sched, peer->pokeexpire)) {
16434          struct sip_peer *peer_ptr = peer;
16435          ASTOBJ_UNREF(peer_ptr, sip_destroy_peer);
16436       }
16437       peer->pokeexpire = ast_sched_add(sched, peer->maxms * 2, sip_poke_noanswer, ASTOBJ_REF(peer));
16438       if (peer->pokeexpire == -1) {
16439          struct sip_peer *peer_ptr = peer;
16440          ASTOBJ_UNREF(peer_ptr, sip_destroy_peer);
16441       }
16442    }
16443 
16444    return 0;
16445 }

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

08049 {
08050    struct sip_peer *peer = (struct sip_peer *) data;
08051 
08052    peer->pokeexpire = -1;
08053 
08054    sip_poke_peer(peer);
08055 
08056    ASTOBJ_UNREF(peer, sip_destroy_peer);
08057 
08058    return 0;
08059 }

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

Remove temporary realtime objects from memory (CLI).

Definition at line 10299 of file chan_sip.c.

References ast_cli(), ast_test_flag, ASTOBJ_CONTAINER_PRUNE_MARKED, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_CONTAINER_UNLOCK, ASTOBJ_CONTAINER_WRLOCK, ASTOBJ_MARK, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, FALSE, name, peerl, RESULT_SHOWUSAGE, sip_destroy_peer(), SIP_PAGE2_RTCACHEFRIENDS, and TRUE.

10300 {
10301    struct sip_peer *peer;
10302    struct sip_user *user;
10303    int pruneuser = FALSE;
10304    int prunepeer = FALSE;
10305    int multi = FALSE;
10306    char *name = NULL;
10307    regex_t regexbuf;
10308 
10309    switch (argc) {
10310    case 4:
10311       if (!strcasecmp(argv[3], "user"))
10312          return RESULT_SHOWUSAGE;
10313       if (!strcasecmp(argv[3], "peer"))
10314          return RESULT_SHOWUSAGE;
10315       if (!strcasecmp(argv[3], "like"))
10316          return RESULT_SHOWUSAGE;
10317       if (!strcasecmp(argv[3], "all")) {
10318          multi = TRUE;
10319          pruneuser = prunepeer = TRUE;
10320       } else {
10321          pruneuser = prunepeer = TRUE;
10322          name = argv[3];
10323       }
10324       break;
10325    case 5:
10326       if (!strcasecmp(argv[4], "like"))
10327          return RESULT_SHOWUSAGE;
10328       if (!strcasecmp(argv[3], "all"))
10329          return RESULT_SHOWUSAGE;
10330       if (!strcasecmp(argv[3], "like")) {
10331          multi = TRUE;
10332          name = argv[4];
10333          pruneuser = prunepeer = TRUE;
10334       } else if (!strcasecmp(argv[3], "user")) {
10335          pruneuser = TRUE;
10336          if (!strcasecmp(argv[4], "all"))
10337             multi = TRUE;
10338          else
10339             name = argv[4];
10340       } else if (!strcasecmp(argv[3], "peer")) {
10341          prunepeer = TRUE;
10342          if (!strcasecmp(argv[4], "all"))
10343             multi = TRUE;
10344          else
10345             name = argv[4];
10346       } else
10347          return RESULT_SHOWUSAGE;
10348       break;
10349    case 6:
10350       if (strcasecmp(argv[4], "like"))
10351          return RESULT_SHOWUSAGE;
10352       if (!strcasecmp(argv[3], "user")) {
10353          pruneuser = TRUE;
10354          name = argv[5];
10355       } else if (!strcasecmp(argv[3], "peer")) {
10356          prunepeer = TRUE;
10357          name = argv[5];
10358       } else
10359          return RESULT_SHOWUSAGE;
10360       break;
10361    default:
10362       return RESULT_SHOWUSAGE;
10363    }
10364 
10365    if (multi && name) {
10366       if (regcomp(&regexbuf, name, REG_EXTENDED | REG_NOSUB))
10367          return RESULT_SHOWUSAGE;
10368    }
10369 
10370    if (multi) {
10371       if (prunepeer) {
10372          int pruned = 0;
10373 
10374          ASTOBJ_CONTAINER_WRLOCK(&peerl);
10375          ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do {
10376             ASTOBJ_RDLOCK(iterator);
10377             if (name && regexec(&regexbuf, iterator->name, 0, NULL, 0)) {
10378                ASTOBJ_UNLOCK(iterator);
10379                continue;
10380             };
10381             if (ast_test_flag(&iterator->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) {
10382                ASTOBJ_MARK(iterator);
10383                pruned++;
10384             }
10385             ASTOBJ_UNLOCK(iterator);
10386          } while (0) );
10387          if (pruned) {
10388             ASTOBJ_CONTAINER_PRUNE_MARKED(&peerl, sip_destroy_peer);
10389             ast_cli(fd, "%d peers pruned.\n", pruned);
10390          } else
10391             ast_cli(fd, "No peers found to prune.\n");
10392          ASTOBJ_CONTAINER_UNLOCK(&peerl);
10393       }
10394       if (pruneuser) {
10395          int pruned = 0;
10396 
10397          ASTOBJ_CONTAINER_WRLOCK(&userl);
10398          ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do {
10399             ASTOBJ_RDLOCK(iterator);
10400             if (name && regexec(&regexbuf, iterator->name, 0, NULL, 0)) {
10401                ASTOBJ_UNLOCK(iterator);
10402                continue;
10403             };
10404             if (ast_test_flag(&iterator->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) {
10405                ASTOBJ_MARK(iterator);
10406                pruned++;
10407             }
10408             ASTOBJ_UNLOCK(iterator);
10409          } while (0) );
10410          if (pruned) {
10411             ASTOBJ_CONTAINER_PRUNE_MARKED(&userl, sip_destroy_user);
10412             ast_cli(fd, "%d users pruned.\n", pruned);
10413          } else
10414             ast_cli(fd, "No users found to prune.\n");
10415          ASTOBJ_CONTAINER_UNLOCK(&userl);
10416       }
10417    } else {
10418       if (prunepeer) {
10419          if ((peer = ASTOBJ_CONTAINER_FIND_UNLINK(&peerl, name))) {
10420             if (!ast_test_flag(&peer->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) {
10421                ast_cli(fd, "Peer '%s' is not a Realtime peer, cannot be pruned.\n", name);
10422                ASTOBJ_CONTAINER_LINK(&peerl, peer);
10423             } else
10424                ast_cli(fd, "Peer '%s' pruned.\n", name);
10425             ASTOBJ_UNREF(peer, sip_destroy_peer);
10426          } else
10427             ast_cli(fd, "Peer '%s' not found.\n", name);
10428       }
10429       if (pruneuser) {
10430          if ((user = ASTOBJ_CONTAINER_FIND_UNLINK(&userl, name))) {
10431             if (!ast_test_flag(&user->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) {
10432                ast_cli(fd, "User '%s' is not a Realtime user, cannot be pruned.\n", name);
10433                ASTOBJ_CONTAINER_LINK(&userl, user);
10434             } else
10435                ast_cli(fd, "User '%s' pruned.\n", name);
10436             ASTOBJ_UNREF(user, sip_destroy_user);
10437          } else
10438             ast_cli(fd, "User '%s' not found.\n", name);
10439       }
10440    }
10441 
10442    return RESULT_SUCCESS;
10443 }

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

Read SIP RTP from channel.

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

04439 {
04440    struct ast_frame *fr;
04441    struct sip_pvt *p = ast->tech_pvt;
04442    int faxdetected = FALSE;
04443 
04444    ast_mutex_lock(&p->lock);
04445    fr = sip_rtp_read(ast, p, &faxdetected);
04446    p->lastrtprx = time(NULL);
04447 
04448    /* If we are NOT bridged to another channel, and we have detected fax tone we issue T38 re-invite to a peer */
04449    /* 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 */
04450    if (faxdetected && ast_test_flag(&p->t38.t38support, SIP_PAGE2_T38SUPPORT_UDPTL) && (p->t38.state == T38_DISABLED) && !(ast_bridged_channel(ast))) {
04451       if (!ast_test_flag(&p->flags[0], SIP_GOTREFER)) {
04452          if (!p->pendinginvite) {
04453             if (option_debug > 2)
04454                ast_log(LOG_DEBUG, "Sending reinvite on SIP (%s) for T.38 negotiation.\n",ast->name);
04455             p->t38.state = T38_LOCAL_REINVITE;
04456             transmit_reinvite_with_t38_sdp(p);
04457             if (option_debug > 1)
04458                ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, ast->name);
04459          }
04460       } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) {
04461          if (option_debug > 2)
04462             ast_log(LOG_DEBUG, "Deferring reinvite on SIP (%s) - it will be re-negotiated for T.38\n", ast->name);
04463          ast_set_flag(&p->flags[0], SIP_NEEDREINVITE);
04464       }
04465    }
04466 
04467    /* Only allow audio through if they sent progress with SDP, or if the channel is actually answered */
04468    if (fr && fr->frametype == AST_FRAME_VOICE && p->invitestate != INV_EARLY_MEDIA && ast->_state != AST_STATE_UP) {
04469       fr = &ast_null_frame;
04470    }
04471 
04472    ast_mutex_unlock(&p->lock);
04473    return fr;
04474 }

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

The real destination address for a write.

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

01764 {
01765    return ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE ? &p->recv : &p->sa;
01766 }

static int sip_refer_allocate ( struct sip_pvt p  )  [static]

Allocate SIP refer structure.

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

07850 {
07851    p->refer = ast_calloc(1, sizeof(struct sip_refer)); 
07852    return p->refer ? 1 : 0;
07853 }

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

Registration timeout, register again.

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

07597 {
07598 
07599    /* if we are here, our registration timed out, so we'll just do it over */
07600    struct sip_registry *r = ASTOBJ_REF((struct sip_registry *) data);
07601    struct sip_pvt *p;
07602    int res;
07603 
07604    /* if we couldn't get a reference to the registry object, punt */
07605    if (!r)
07606       return 0;
07607 
07608    ast_log(LOG_NOTICE, "   -- Registration for '%s@%s' timed out, trying again (Attempt #%d)\n", r->username, r->hostname, r->regattempts); 
07609    if (r->call) {
07610       /* Unlink us, destroy old call.  Locking is not relevant here because all this happens
07611          in the single SIP manager thread. */
07612       p = r->call;
07613       ast_mutex_lock(&p->lock);
07614       if (p->registry)
07615          ASTOBJ_UNREF(p->registry, sip_registry_destroy);
07616       r->call = NULL;
07617       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
07618       /* Pretend to ACK anything just in case */
07619       __sip_pretend_ack(p);
07620       ast_mutex_unlock(&p->lock);
07621    }
07622    /* If we have a limit, stop registration and give up */
07623    if (global_regattempts_max && (r->regattempts > global_regattempts_max)) {
07624       /* Ok, enough is enough. Don't try any more */
07625       /* We could add an external notification here... 
07626          steal it from app_voicemail :-) */
07627       ast_log(LOG_NOTICE, "   -- Giving up forever trying to register '%s@%s'\n", r->username, r->hostname);
07628       r->regstate = REG_STATE_FAILED;
07629    } else {
07630       r->regstate = REG_STATE_UNREGISTERED;
07631       r->timeout = -1;
07632       res=transmit_register(r, SIP_REGISTER, NULL, NULL);
07633    }
07634    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));
07635    ASTOBJ_UNREF(r, sip_registry_destroy);
07636    return 0;
07637 }

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

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

Definition at line 4767 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, FALSE, free, hostname, INITIAL_CSEQ, LOG_ERROR, regl, secret, sip_registry_destroy(), and username.

04768 {
04769    struct sip_registry *reg;
04770    int portnum = 0;
04771    char username[256] = "";
04772    char *hostname=NULL, *secret=NULL, *authuser=NULL;
04773    char *porta=NULL;
04774    char *contact=NULL;
04775 
04776    if (!value)
04777       return -1;
04778    ast_copy_string(username, value, sizeof(username));
04779    /* First split around the last '@' then parse the two components. */
04780    hostname = strrchr(username, '@'); /* allow @ in the first part */
04781    if (hostname)
04782       *hostname++ = '\0';
04783    if (ast_strlen_zero(username) || ast_strlen_zero(hostname)) {
04784       ast_log(LOG_WARNING, "Format for registration is user[:secret[:authuser]]@host[:port][/contact] at line %d\n", lineno);
04785       return -1;
04786    }
04787    /* split user[:secret[:authuser]] */
04788    secret = strchr(username, ':');
04789    if (secret) {
04790       *secret++ = '\0';
04791       authuser = strchr(secret, ':');
04792       if (authuser)
04793          *authuser++ = '\0';
04794    }
04795    /* split host[:port][/contact] */
04796    contact = strchr(hostname, '/');
04797    if (contact)
04798       *contact++ = '\0';
04799    if (ast_strlen_zero(contact))
04800       contact = "s";
04801    porta = strchr(hostname, ':');
04802    if (porta) {
04803       *porta++ = '\0';
04804       portnum = atoi(porta);
04805       if (portnum == 0) {
04806          ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno);
04807          return -1;
04808       }
04809    }
04810    if (!(reg = ast_calloc(1, sizeof(*reg)))) {
04811       ast_log(LOG_ERROR, "Out of memory. Can't allocate SIP registry entry\n");
04812       return -1;
04813    }
04814 
04815    if (ast_string_field_init(reg, 256)) {
04816       ast_log(LOG_ERROR, "Out of memory. Can't allocate SIP registry strings\n");
04817       free(reg);
04818       return -1;
04819    }
04820 
04821    regobjs++;
04822    ASTOBJ_INIT(reg);
04823    ast_string_field_set(reg, contact, contact);
04824    if (!ast_strlen_zero(username))
04825       ast_string_field_set(reg, username, username);
04826    if (hostname)
04827       ast_string_field_set(reg, hostname, hostname);
04828    if (authuser)
04829       ast_string_field_set(reg, authuser, authuser);
04830    if (secret)
04831       ast_string_field_set(reg, secret, secret);
04832    reg->expire = -1;
04833    reg->timeout =  -1;
04834    reg->refresh = default_expiry;
04835    reg->portno = portnum;
04836    reg->callid_valid = FALSE;
04837    reg->ocseq = INITIAL_CSEQ;
04838    ASTOBJ_CONTAINER_LINK(&regl, reg);  /* Add the new registry entry to the list */
04839    ASTOBJ_UNREF(reg,sip_registry_destroy);
04840    return 0;
04841 }

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

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

03079 {
03080    /* Really delete */
03081    if (option_debug > 2)
03082       ast_log(LOG_DEBUG, "Destroying registry entry for %s@%s\n", reg->username, reg->hostname);
03083 
03084    if (reg->call) {
03085       /* Clear registry before destroying to ensure
03086          we don't get reentered trying to grab the registry lock */
03087       reg->call->registry = NULL;
03088       if (option_debug > 2)
03089          ast_log(LOG_DEBUG, "Destroying active SIP dialog for registry %s@%s\n", reg->username, reg->hostname);
03090       sip_destroy(reg->call);
03091    }
03092    AST_SCHED_DEL(sched, reg->expire);
03093    AST_SCHED_DEL(sched, reg->timeout);
03094    ast_string_field_free_memory(reg);
03095    regobjs--;
03096    free(reg);
03097    
03098 }

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

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

Referenced by handle_response_invite().

12246 {
12247    struct sip_pvt *p = (struct sip_pvt *) data;
12248 
12249    ast_set_flag(&p->flags[0], SIP_NEEDREINVITE);   
12250    p->waitid = -1;
12251    return 0;
12252 }

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

Force reload of module from cli.

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

18559 {
18560    ast_mutex_lock(&sip_reload_lock);
18561    if (sip_reloading) 
18562       ast_verbose("Previous SIP reload not yet done\n");
18563    else {
18564       sip_reloading = TRUE;
18565       if (fd)
18566          sip_reloadreason = CHANNEL_CLI_RELOAD;
18567       else
18568          sip_reloadreason = CHANNEL_MODULE_RELOAD;
18569    }
18570    ast_mutex_unlock(&sip_reload_lock);
18571    restart_monitor();
18572 
18573    return 0;
18574 }

static struct ast_channel * sip_request_call ( const char *  type,
int  format,
void *  data,
int *  cause 
) [static]

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 16557 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, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, option_debug, sip_pvt::options, restart_monitor(), sip_alloc(), sip_destroy(), SIP_INVITE, sip_new(), SIP_PAGE2_OUTGOING_CALL, and username.

16558 {
16559    int oldformat;
16560    struct sip_pvt *p;
16561    struct ast_channel *tmpc = NULL;
16562    char *ext, *host;
16563    char tmp[256];
16564    char *dest = data;
16565 
16566    oldformat = format;
16567    if (!(format &= ((AST_FORMAT_MAX_AUDIO << 1) - 1))) {
16568       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));
16569       *cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;   /* Can't find codec to connect to host */
16570       return NULL;
16571    }
16572    if (option_debug)
16573       ast_log(LOG_DEBUG, "Asked to create a SIP channel with formats: %s\n", ast_getformatname_multiple(tmp, sizeof(tmp), oldformat));
16574 
16575    if (!(p = sip_alloc(NULL, NULL, 0, SIP_INVITE))) {
16576       ast_log(LOG_ERROR, "Unable to build sip pvt data for '%s' (Out of memory or socket error)\n", (char *)data);
16577       *cause = AST_CAUSE_SWITCH_CONGESTION;
16578       return NULL;
16579    }
16580 
16581    ast_set_flag(&p->flags[1], SIP_PAGE2_OUTGOING_CALL);
16582 
16583    if (!(p->options = ast_calloc(1, sizeof(*p->options)))) {
16584       sip_destroy(p);
16585       ast_log(LOG_ERROR, "Unable to build option SIP data structure - Out of memory\n");
16586       *cause = AST_CAUSE_SWITCH_CONGESTION;
16587       return NULL;
16588    }
16589 
16590    ast_copy_string(tmp, dest, sizeof(tmp));
16591    host = strchr(tmp, '@');
16592    if (host) {
16593       *host++ = '\0';
16594       ext = tmp;
16595    } else {
16596       ext = strchr(tmp, '/');
16597       if (ext) 
16598          *ext++ = '\0';
16599       host = tmp;
16600    }
16601 
16602    if (create_addr(p, host)) {
16603       *cause = AST_CAUSE_UNREGISTERED;
16604       if (option_debug > 2)
16605          ast_log(LOG_DEBUG, "Cant create SIP call - target device not registred\n");
16606       sip_destroy(p);
16607       return NULL;
16608    }
16609    if (ast_strlen_zero(p->peername) && ext)
16610       ast_string_field_set(p, peername, ext);
16611    /* Recalculate our side, and recalculate Call ID */
16612    if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
16613       p->ourip = __ourip;
16614    build_via(p);
16615    build_callid_pvt(p);
16616    
16617    /* We have an extension to call, don't use the full contact here */
16618    /* This to enable dialing registered peers with extension dialling,
16619       like SIP/peername/extension   
16620       SIP/peername will still use the full contact */
16621    if (ext) {
16622       ast_string_field_set(p, username, ext);
16623       ast_string_field_free(p, fullcontact);
16624    }
16625 #if 0
16626    printf("Setting up to call extension '%s' at '%s'\n", ext ? ext : "<none>", host);
16627 #endif
16628    p->prefcodec = oldformat;           /* Format for this call */
16629    ast_mutex_lock(&p->lock);
16630    tmpc = sip_new(p, AST_STATE_DOWN, host);  /* Place the call */
16631    ast_mutex_unlock(&p->lock);
16632    if (!tmpc)
16633       sip_destroy(p);
16634    ast_update_use_count();
16635    restart_monitor();
16636    return tmpc;
16637 }

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

Update registration with SIP Proxy.

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

07565 {
07566    /* if we are here, we know that we need to reregister. */
07567    struct sip_registry *r= ASTOBJ_REF((struct sip_registry *) data);
07568 
07569    /* if we couldn't get a reference to the registry object, punt */
07570    if (!r)
07571       return 0;
07572 
07573    if (r->call && !ast_test_flag(&r->call->flags[0], SIP_NO_HISTORY))
07574       append_history(r->call, "RegistryRenew", "Account: %s@%s", r->username, r->hostname);
07575    /* Since registry's are only added/removed by the the monitor thread, this
07576       may be overkill to reference/dereference at all here */
07577    if (sipdebug)
07578       ast_log(LOG_NOTICE, "   -- Re-registration for  %s@%s\n", r->username, r->hostname);
07579 
07580    r->expire = -1;
07581    __sip_do_register(r);
07582    ASTOBJ_UNREF(r, sip_registry_destroy);
07583    return 0;
07584 }

static struct ast_frame * sip_rtp_read ( struct ast_channel ast,
struct sip_pvt p,
int *  faxdetect 
) [static]

Read RTP from network.

Definition at line 4368 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, 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, sip_pvt::t38, t38properties::t38support, sip_pvt::udptl, sip_pvt::vad, sip_pvt::vrtp, and ast_channel::writeformat.

Referenced by sip_read().

04369 {
04370    /* Retrieve audio/etc from channel.  Assumes p->lock is already held. */
04371    struct ast_frame *f;
04372    
04373    if (!p->rtp) {
04374       /* We have no RTP allocated for this channel */
04375       return &ast_null_frame;
04376    }
04377 
04378    switch(ast->fdno) {
04379    case 0:
04380       f = ast_rtp_read(p->rtp);  /* RTP Audio */
04381       break;
04382    case 1:
04383       f = ast_rtcp_read(p->rtp); /* RTCP Control Channel */
04384       break;
04385    case 2:
04386       f = ast_rtp_read(p->vrtp); /* RTP Video */
04387       break;
04388    case 3:
04389       f = ast_rtcp_read(p->vrtp);   /* RTCP Control Channel for video */
04390       break;
04391    case 5:
04392       f = ast_udptl_read(p->udptl); /* UDPTL for T.38 */
04393       break;
04394    default:
04395       f = &ast_null_frame;
04396    }
04397    /* Don't forward RFC2833 if we're not supposed to */
04398    if (f && (f->frametype == AST_FRAME_DTMF) &&
04399        (ast_test_flag(&p->flags[0], SIP_DTMF) != SIP_DTMF_RFC2833))
04400       return &ast_null_frame;
04401 
04402       /* We already hold the channel lock */
04403    if (!p->owner || (f && f->frametype != AST_FRAME_VOICE))
04404       return f;
04405 
04406    if (f && f->subclass != (p->owner->nativeformats & AST_FORMAT_AUDIO_MASK)) {
04407       if (!(f->subclass & p->jointcapability)) {
04408          if (option_debug) {
04409             ast_log(LOG_DEBUG, "Bogus frame of format '%s' received from '%s'!\n",
04410                ast_getformatname(f->subclass), p->owner->name);
04411          }
04412          return &ast_null_frame;
04413       }
04414       if (option_debug)
04415          ast_log(LOG_DEBUG, "Oooh, format changed to %d\n", f->subclass);
04416       p->owner->nativeformats = (p->owner->nativeformats & AST_FORMAT_VIDEO_MASK) | f->subclass;
04417       ast_set_read_format(p->owner, p->owner->readformat);
04418       ast_set_write_format(p->owner, p->owner->writeformat);
04419    }
04420 
04421    if (f && (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) && p->vad) {
04422       f = ast_dsp_process(p->owner, p->vad, f);
04423       if (f && f->frametype == AST_FRAME_DTMF) {
04424          if (ast_test_flag(&p->t38.t38support, SIP_PAGE2_T38SUPPORT_UDPTL) && f->subclass == 'f') {
04425             if (option_debug)
04426                ast_log(LOG_DEBUG, "Fax CNG detected on %s\n", ast->name);
04427             *faxdetect = 1;
04428          } else if (option_debug) {
04429             ast_log(LOG_DEBUG, "* Detected inband DTMF '%c'\n", f->subclass);
04430          }
04431       }
04432    }
04433    
04434    return f;
04435 }

static void sip_scheddestroy ( struct sip_pvt p,
int  ms 
) [static]

Schedule destruction of SIP dialog.

Definition at line 2138 of file chan_sip.c.

References __sip_autodestruct(), append_history, ast_sched_add(), AST_SCHED_DEL, ast_test_flag, ast_verbose(), sip_pvt::flags, sip_pvt::method, sched, sip_debug_test_pvt(), sip_methods, SIP_NO_HISTORY, and sip_pvt::timer_t1.

Referenced by __sip_autodestruct(), cb_extensionstate(), check_auth(), check_pendings(), handle_invite_replaces(), handle_request(), handle_request_bye(), handle_request_cancel(), handle_request_info(), handle_request_invite(), handle_request_notify(), handle_request_options(), handle_request_register(), handle_request_subscribe(), handle_response_invite(), handle_response_register(), receive_message(), sip_hangup(), sip_notify(), sip_send_mwi_to_peer(), and sip_sipredirect().

02139 {
02140    if (ms < 0) {
02141       if (p->timer_t1 == 0)
02142          p->timer_t1 = 500;   /* Set timer T1 if not set (RFC 3261) */
02143       ms = p->timer_t1 * 64;
02144    }
02145    if (sip_debug_test_pvt(p))
02146       ast_verbose("Scheduling destruction of SIP dialog '%s' in %d ms (Method: %s)\n", p->callid, ms, sip_methods[p->method].text);
02147    if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY))
02148       append_history(p, "SchedDestroy", "%d ms", ms);
02149 
02150    AST_SCHED_DEL(sched, p->autokillid);
02151    p->autokillid = ast_sched_add(sched, ms, __sip_autodestruct, p);
02152 }

static void sip_send_all_registers ( void   )  [static]

Send all known registrations.

Definition at line 18515 of file chan_sip.c.

References ast_sched_add(), AST_SCHED_DEL, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_UNLOCK, ASTOBJ_WRLOCK, regl, sched, and sip_reregister().

Referenced by load_module(), and sip_do_reload().

18516 {
18517    int ms;
18518    int regspacing;
18519    if (!regobjs)
18520       return;
18521    regspacing = default_expiry * 1000/regobjs;
18522    if (regspacing > 100)
18523       regspacing = 100;
18524    ms = regspacing;
18525    ASTOBJ_CONTAINER_TRAVERSE(&regl, 1, do {
18526       ASTOBJ_WRLOCK(iterator);
18527       AST_SCHED_DEL(sched, iterator->expire);
18528       ms += regspacing;
18529       iterator->expire = ast_sched_add(sched, ms, sip_reregister, iterator);
18530       ASTOBJ_UNLOCK(iterator);
18531    } while (0)
18532    );
18533 }

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 16057 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 handle_request_subscribe().

16058 {
16059    /* Called with peerl lock, but releases it */
16060    struct sip_pvt *p;
16061    int newmsgs, oldmsgs;
16062 
16063    /* Do we have an IP address? If not, skip this peer */
16064    if (!peer->addr.sin_addr.s_addr && !peer->defaddr.sin_addr.s_addr) 
16065       return 0;
16066 
16067    /* Check for messages */
16068    ast_app_inboxcount(peer->mailbox, &newmsgs, &oldmsgs);
16069    
16070    peer->lastmsgcheck = time(NULL);
16071    
16072    /* Return now if it's the same thing we told them last time */
16073    if (((newmsgs > 0x7fff ? 0x7fff0000 : (newmsgs << 16)) | (oldmsgs > 0xffff ? 0xffff : oldmsgs)) == peer->lastmsgssent) {
16074       return 0;
16075    }
16076    
16077    
16078    peer->lastmsgssent = ((newmsgs > 0x7fff ? 0x7fff0000 : (newmsgs << 16)) | (oldmsgs > 0xffff ? 0xffff : oldmsgs));
16079 
16080    if (peer->mwipvt) {
16081       /* Base message on subscription */
16082       p = peer->mwipvt;
16083    } else {
16084       /* Build temporary dialog for this message */
16085       if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY))) 
16086          return -1;
16087       if (create_addr_from_peer(p, peer)) {
16088          /* Maybe they're not registered, etc. */
16089          sip_destroy(p);
16090          return 0;
16091       }
16092       /* Recalculate our side, and recalculate Call ID */
16093       if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
16094          p->ourip = __ourip;
16095       build_via(p);
16096       build_callid_pvt(p);
16097       /* Destroy this session after 32 secs */
16098       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
16099    }
16100    /* Send MWI */
16101    ast_set_flag(&p->flags[0], SIP_OUTGOING);
16102    transmit_notify_with_mwi(p, newmsgs, oldmsgs, peer->vmexten);
16103    return 0;
16104 }

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

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

03862 {
03863    struct sip_pvt *p = ast->tech_pvt;
03864    int res = 0;
03865 
03866    ast_mutex_lock(&p->lock);
03867    switch (ast_test_flag(&p->flags[0], SIP_DTMF)) {
03868    case SIP_DTMF_INBAND:
03869       res = -1; /* Tell Asterisk to generate inband indications */
03870       break;
03871    case SIP_DTMF_RFC2833:
03872       if (p->rtp)
03873          ast_rtp_senddigit_begin(p->rtp, digit);
03874       break;
03875    default:
03876       break;
03877    }
03878    ast_mutex_unlock(&p->lock);
03879 
03880    return res;
03881 }

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 3885 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_DTMF, SIP_DTMF_INBAND, SIP_DTMF_INFO, SIP_DTMF_RFC2833, ast_channel::tech_pvt, and transmit_info_with_digit().

03886 {
03887    struct sip_pvt *p = ast->tech_pvt;
03888    int res = 0;
03889 
03890    ast_mutex_lock(&p->lock);
03891    switch (ast_test_flag(&p->flags[0], SIP_DTMF)) {
03892    case SIP_DTMF_INFO:
03893       transmit_info_with_digit(p, digit, duration);
03894       break;
03895    case SIP_DTMF_RFC2833:
03896       if (p->rtp)
03897          ast_rtp_senddigit_end(p->rtp, digit);
03898       break;
03899    case SIP_DTMF_INBAND:
03900       res = -1; /* Tell Asterisk to stop inband indications */
03901       break;
03902    }
03903    ast_mutex_unlock(&p->lock);
03904 
03905    return res;
03906 }

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

02399 {
02400    struct sip_pvt *p = ast->tech_pvt;
02401    int debug = sip_debug_test_pvt(p);
02402 
02403    if (debug)
02404       ast_verbose("Sending text %s on %s\n", text, ast->name);
02405    if (!p)
02406       return -1;
02407    if (ast_strlen_zero(text))
02408       return 0;
02409    if (debug)
02410       ast_verbose("Really sending text %s on %s\n", text, ast->name);
02411    transmit_message_with_text(p, text);
02412    return 0;   
02413 }

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 18242 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, sip_pvt::ourip, sip_pvt::pendinginvite, sip_pvt::redircodecs, sip_pvt::redirip, sip_pvt::rtp, 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(), sip_pvt::vredirip, and sip_pvt::vrtp.

Referenced by sip_fixup().

18243 {
18244    struct sip_pvt *p;
18245    int changed = 0;
18246 
18247    p = chan->tech_pvt;
18248    if (!p) 
18249       return -1;
18250 
18251    /* Disable early RTP bridge  */
18252    if (chan->_state != AST_STATE_UP && !global_directrtpsetup)    /* We are in early state */
18253       return 0;
18254 
18255    ast_mutex_lock(&p->lock);
18256    if (ast_test_flag(&p->flags[0], SIP_ALREADYGONE)) {
18257       /* If we're destroyed, don't bother */
18258       ast_mutex_unlock(&p->lock);
18259       return 0;
18260    }
18261 
18262    /* if this peer cannot handle reinvites of the media stream to devices
18263       that are known to be behind a NAT, then stop the process now
18264    */
18265    if (nat_active && !ast_test_flag(&p->flags[0], SIP_CAN_REINVITE_NAT)) {
18266       ast_mutex_unlock(&p->lock);
18267       return 0;
18268    }
18269 
18270    if (rtp) {
18271       changed |= ast_rtp_get_peer(rtp, &p->redirip);
18272    } else if (p->redirip.sin_addr.s_addr || ntohs(p->redirip.sin_port) != 0) {
18273       memset(&p->redirip, 0, sizeof(p->redirip));
18274       changed = 1;
18275    }
18276    if (vrtp) {
18277       changed |= ast_rtp_get_peer(vrtp, &p->vredirip);
18278    } else if (p->vredirip.sin_addr.s_addr || ntohs(p->vredirip.sin_port) != 0) {
18279       memset(&p->vredirip, 0, sizeof(p->vredirip));
18280       changed = 1;
18281    }
18282    if (codecs) {
18283       if ((p->redircodecs != codecs)) {
18284          p->redircodecs = codecs;
18285          changed = 1;
18286       }
18287       if ((p->capability & codecs) != p->capability) {
18288          p->jointcapability &= codecs;
18289          p->capability &= codecs;
18290          changed = 1;
18291       }
18292    }
18293    if (changed && !ast_test_flag(&p->flags[0], SIP_GOTREFER) && !ast_test_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER)) {
18294       if (chan->_state != AST_STATE_UP) { /* We are in early state */
18295          if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY))
18296             append_history(p, "ExtInv", "Initial invite sent with remote bridge proposal.");
18297          if (option_debug)
18298             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));
18299       } else if (!p->pendinginvite) {     /* We are up, and have no outstanding invite */
18300          if (option_debug > 2) {
18301             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));
18302          }
18303          transmit_reinvite_with_sdp(p);
18304       } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) {
18305          if (option_debug > 2) {
18306             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));
18307          }
18308          /* We have a pending Invite. Send re-invite when we're done with the invite */
18309          ast_set_flag(&p->flags[0], SIP_NEEDREINVITE);   
18310       }
18311    }
18312    /* Reset lastrtprx timer */
18313    p->lastrtprx = p->lastrtptx = time(NULL);
18314    ast_mutex_unlock(&p->lock);
18315    return 0;
18316 }

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

Definition at line 18069 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, sip_pvt::ourip, sip_pvt::pendinginvite, SIP_GOTREFER, SIP_NEEDREINVITE, SIP_PENDINGBYE, ast_channel::tech_pvt, transmit_reinvite_with_t38_sdp(), sip_pvt::udptl, and sip_pvt::udptlredirip.

18070 {
18071    struct sip_pvt *p;
18072    
18073    p = chan->tech_pvt;
18074    if (!p)
18075       return -1;
18076    ast_mutex_lock(&p->lock);
18077    if (udptl)
18078       ast_udptl_get_peer(udptl, &p->udptlredirip);
18079    else
18080       memset(&p->udptlredirip, 0, sizeof(p->udptlredirip));
18081    if (!ast_test_flag(&p->flags[0], SIP_GOTREFER)) {
18082       if (!p->pendinginvite) {
18083          if (option_debug > 2) {
18084             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);
18085          }
18086          transmit_reinvite_with_t38_sdp(p);
18087       } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) {
18088          if (option_debug > 2) {
18089             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);
18090          }
18091          ast_set_flag(&p->flags[0], SIP_NEEDREINVITE);
18092       }
18093    }
18094    /* Reset lastrtprx timer */
18095    p->lastrtprx = p->lastrtptx = time(NULL);
18096    ast_mutex_unlock(&p->lock);
18097    return 0;
18098 }

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

Show details of one active dialog.

Definition at line 11175 of file chan_sip.c.

References sip_pvt::allowtransfer, ast_cli(), ast_getformatname_multiple(), ast_inet_ntoa(), ast_mutex_lock(), ast_strlen_zero(), ast_test_flag, sip_pvt::capability, dtmfmode2str(), sip_pvt::flags, sip_route::hop, 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, 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().

11176 {
11177    struct sip_pvt *cur;
11178    size_t len;
11179    int found = 0;
11180 
11181    if (argc != 4)
11182       return RESULT_SHOWUSAGE;
11183    len = strlen(argv[3]);
11184    ast_mutex_lock(&iflock);
11185    for (cur = iflist; cur; cur = cur->next) {
11186       if (!strncasecmp(cur->callid, argv[3], len)) {
11187          char formatbuf[SIPBUFSIZE/2];
11188          ast_cli(fd,"\n");
11189          if (cur->subscribed != NONE)
11190             ast_cli(fd, "  * Subscription (type: %s)\n", subscription_type2str(cur->subscribed));
11191          else
11192             ast_cli(fd, "  * SIP Call\n");
11193          ast_cli(fd, "  Curr. trans. direction:  %s\n", ast_test_flag(&cur->flags[0], SIP_OUTGOING) ? "Outgoing" : "Incoming");
11194          ast_cli(fd, "  Call-ID:                %s\n", cur->callid);
11195          ast_cli(fd, "  Owner channel ID:       %s\n", cur->owner ? cur->owner->name : "<none>");
11196          ast_cli(fd, "  Our Codec Capability:   %d\n", cur->capability);
11197          ast_cli(fd, "  Non-Codec Capability (DTMF):   %d\n", cur->noncodeccapability);
11198          ast_cli(fd, "  Their Codec Capability:   %d\n", cur->peercapability);
11199          ast_cli(fd, "  Joint Codec Capability:   %d\n", cur->jointcapability);
11200          ast_cli(fd, "  Format:                 %s\n", ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->owner ? cur->owner->nativeformats : 0) );
11201          ast_cli(fd, "  MaxCallBR:              %d kbps\n", cur->maxcallbitrate);
11202          ast_cli(fd, "  Theoretical Address:    %s:%d\n", ast_inet_ntoa(cur->sa.sin_addr), ntohs(cur->sa.sin_port));
11203          ast_cli(fd, "  Received Address:       %s:%d\n", ast_inet_ntoa(cur->recv.sin_addr), ntohs(cur->recv.sin_port));
11204          ast_cli(fd, "  SIP Transfer mode:      %s\n", transfermode2str(cur->allowtransfer));
11205          ast_cli(fd, "  NAT Support:            %s\n", nat2str(ast_test_flag(&cur->flags[0], SIP_NAT)));
11206          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)" );
11207          ast_cli(fd, "  Our Tag:                %s\n", cur->tag);
11208          ast_cli(fd, "  Their Tag:              %s\n", cur->theirtag);
11209          ast_cli(fd, "  SIP User agent:         %s\n", cur->useragent);
11210          if (!ast_strlen_zero(cur->username))
11211             ast_cli(fd, "  Username:               %s\n", cur->username);
11212          if (!ast_strlen_zero(cur->peername))
11213             ast_cli(fd, "  Peername:               %s\n", cur->peername);
11214          if (!ast_strlen_zero(cur->uri))
11215             ast_cli(fd, "  Original uri:           %s\n", cur->uri);
11216          if (!ast_strlen_zero(cur->cid_num))
11217             ast_cli(fd, "  Caller-ID:              %s\n", cur->cid_num);
11218          ast_cli(fd, "  Need Destroy:           %d\n", ast_test_flag(&cur->flags[0], SIP_NEEDDESTROY));
11219          ast_cli(fd, "  Last Message:           %s\n", cur->lastmsg);
11220          ast_cli(fd, "  Promiscuous Redir:      %s\n", ast_test_flag(&cur->flags[0], SIP_PROMISCREDIR) ? "Yes" : "No");
11221          ast_cli(fd, "  Route:                  %s\n", cur->route ? cur->route->hop : "N/A");
11222          ast_cli(fd, "  DTMF Mode:              %s\n", dtmfmode2str(ast_test_flag(&cur->flags[0], SIP_DTMF)));
11223          ast_cli(fd, "  SIP Options:            ");
11224          if (cur->sipoptions) {
11225             int x;
11226             for (x=0 ; (x < (sizeof(sip_options) / sizeof(sip_options[0]))); x++) {
11227                if (cur->sipoptions & sip_options[x].id)
11228                   ast_cli(fd, "%s ", sip_options[x].text);
11229             }
11230          } else
11231             ast_cli(fd, "(none)\n");
11232          ast_cli(fd, "\n\n");
11233          found++;
11234       }
11235    }
11236    ast_mutex_unlock(&iflock);
11237    if (!found) 
11238       ast_cli(fd, "No such SIP Call ID starting with '%s'\n", argv[3]);
11239    return RESULT_SUCCESS;
11240 }

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

Show active SIP channels.

Definition at line 10966 of file chan_sip.c.

References __sip_show_channels().

10967 {
10968         return __sip_show_channels(fd, argc, argv, 0);
10969 }

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

CLI command to list local domains.

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

10478 {
10479    struct domain *d;
10480 #define FORMAT "%-40.40s %-20.20s %-16.16s\n"
10481 
10482    if (AST_LIST_EMPTY(&domain_list)) {
10483       ast_cli(fd, "SIP Domain support not enabled.\n\n");
10484       return RESULT_SUCCESS;
10485    } else {
10486       ast_cli(fd, FORMAT, "Our local SIP domains:", "Context", "Set by");
10487       AST_LIST_LOCK(&domain_list);
10488       AST_LIST_TRAVERSE(&domain_list, d, list)
10489          ast_cli(fd, FORMAT, d->domain, S_OR(d->context, "(default)"),
10490             domain_mode_to_text(d->mode));
10491       AST_LIST_UNLOCK(&domain_list);
10492       ast_cli(fd, "\n");
10493       return RESULT_SUCCESS;
10494    }
10495 }

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

Show history details of one dialog.

Definition at line 11243 of file chan_sip.c.

References ast_cli(), AST_LIST_TRAVERSE, ast_mutex_lock(), sip_pvt::history, iflist, len, sip_pvt::next, NONE, RESULT_SHOWUSAGE, and sip_pvt::subscribed.

11244 {
11245    struct sip_pvt *cur;
11246    size_t len;
11247    int found = 0;
11248 
11249    if (argc != 4)
11250       return RESULT_SHOWUSAGE;
11251    if (!recordhistory)
11252       ast_cli(fd, "\n***Note: History recording is currently DISABLED.  Use 'sip history' to ENABLE.\n");
11253    len = strlen(argv[3]);
11254    ast_mutex_lock(&iflock);
11255    for (cur = iflist; cur; cur = cur->next) {
11256       if (!strncasecmp(cur->callid, argv[3], len)) {
11257          struct sip_history *hist;
11258          int x = 0;
11259 
11260          ast_cli(fd,"\n");
11261          if (cur->subscribed != NONE)
11262             ast_cli(fd, "  * Subscription\n");
11263          else
11264             ast_cli(fd, "  * SIP Call\n");
11265          if (cur->history)
11266             AST_LIST_TRAVERSE(cur->history, hist, list)
11267                ast_cli(fd, "%d. %s\n", ++x, hist->event);
11268          if (x == 0)
11269             ast_cli(fd, "Call '%s' has no history\n", cur->callid);
11270          found++;
11271       }
11272    }
11273    ast_mutex_unlock(&iflock);
11274    if (!found) 
11275       ast_cli(fd, "No such SIP Call ID starting with '%s'\n", argv[3]);
11276    return RESULT_SUCCESS;
11277 }

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

09903 {
09904 #define FORMAT  "%-25.25s %-15.15s %-15.15s \n"
09905 #define FORMAT2 "%-25.25s %-15.15s %-15.15s \n"
09906    char ilimits[40];
09907    char iused[40];
09908    int showall = FALSE;
09909 
09910    if (argc < 3) 
09911       return RESULT_SHOWUSAGE;
09912 
09913    if (argc == 4 && !strcmp(argv[3],"all")) 
09914          showall = TRUE;
09915    
09916    ast_cli(fd, FORMAT, "* User name", "In use", "Limit");
09917    ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do {
09918       ASTOBJ_RDLOCK(iterator);
09919       if (iterator->call_limit)
09920          snprintf(ilimits, sizeof(ilimits), "%d", iterator->call_limit);
09921       else 
09922          ast_copy_string(ilimits, "N/A", sizeof(ilimits));
09923       snprintf(iused, sizeof(iused), "%d", iterator->inUse);
09924       if (showall || iterator->call_limit)
09925          ast_cli(fd, FORMAT2, iterator->name, iused, ilimits);
09926       ASTOBJ_UNLOCK(iterator);
09927    } while (0) );
09928 
09929    ast_cli(fd, FORMAT, "* Peer name", "In use", "Limit");
09930 
09931    ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do {
09932       ASTOBJ_RDLOCK(iterator);
09933       if (iterator->call_limit)
09934          snprintf(ilimits, sizeof(ilimits), "%d", iterator->call_limit);
09935       else 
09936          ast_copy_string(ilimits, "N/A", sizeof(ilimits));
09937       snprintf(iused, sizeof(iused), "%d/%d", iterator->inUse, iterator->inRinging);
09938       if (showall || iterator->call_limit)
09939          ast_cli(fd, FORMAT2, iterator->name, iused, ilimits);
09940       ASTOBJ_UNLOCK(iterator);
09941    } while (0) );
09942 
09943    return RESULT_SUCCESS;
09944 #undef FORMAT
09945 #undef FORMAT2
09946 }

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

List all allocated SIP Objects (realtime or static).

Definition at line 10223 of file chan_sip.c.

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

10224 {
10225    char tmp[256];
10226    if (argc != 3)
10227       return RESULT_SHOWUSAGE;
10228    ast_cli(fd, "-= User objects: %d static, %d realtime =-\n\n", suserobjs, ruserobjs);
10229    ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), &userl);
10230    ast_cli(fd, "-= Peer objects: %d static, %d realtime, %d autocreate =-\n\n", speerobjs, rpeerobjs, apeerobjs);
10231    ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), &peerl);
10232    ast_cli(fd, "-= Registry objects: %d =-\n\n", regobjs);
10233    ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), &regl);
10234    return RESULT_SUCCESS;
10235 }

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

Show one peer in detail.

Definition at line 10529 of file chan_sip.c.

References _sip_show_peer().

10530 {
10531    return _sip_show_peer(0, fd, NULL, NULL, argc, (const char **) argv);
10532 }

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

CLI Show Peers command.

Definition at line 10079 of file chan_sip.c.

References _sip_show_peers().

10080 {
10081    return _sip_show_peers(fd, NULL, NULL, NULL, argc, (const char **) argv);
10082 }

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

Show SIP Registry (registrations with other SIP proxies.

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

10804 {
10805 #define FORMAT2 "%-30.30s  %-12.12s  %8.8s %-20.20s %-25.25s\n"
10806 #define FORMAT  "%-30.30s  %-12.12s  %8d %-20.20s %-25.25s\n"
10807    char host[80];
10808    char tmpdat[256];
10809    struct tm tm;
10810 
10811 
10812    if (argc != 3)
10813       return RESULT_SHOWUSAGE;
10814    ast_cli(fd, FORMAT2, "Host", "Username", "Refresh", "State", "Reg.Time");
10815    ASTOBJ_CONTAINER_TRAVERSE(&regl, 1, do {
10816       ASTOBJ_RDLOCK(iterator);
10817       snprintf(host, sizeof(host), "%s:%d", iterator->hostname, iterator->portno ? iterator->portno : STANDARD_SIP_PORT);
10818       if (iterator->regtime) {
10819          ast_localtime(&iterator->regtime, &tm, NULL);
10820          strftime(tmpdat, sizeof(tmpdat), "%a, %d %b %Y %T", &tm);
10821       } else {
10822          tmpdat[0] = 0;
10823       }
10824       ast_cli(fd, FORMAT, host, iterator->username, iterator->refresh, regstate2str(iterator->regstate), tmpdat);
10825       ASTOBJ_UNLOCK(iterator);
10826    } while(0));
10827    return RESULT_SUCCESS;
10828 #undef FORMAT
10829 #undef FORMAT2
10830 }

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

List global settings for the SIP channel.

Definition at line 10833 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(), global_flags, 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().

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

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

Show active SIP subscriptions.

Definition at line 10972 of file chan_sip.c.

References __sip_show_channels().

10973 {
10974         return __sip_show_channels(fd, argc, argv, 1);
10975 }

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

Show one user in detail.

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

10749 {
10750    char cbuf[256];
10751    struct sip_user *user;
10752    struct ast_variable *v;
10753    int load_realtime;
10754 
10755    if (argc < 4)
10756       return RESULT_SHOWUSAGE;
10757 
10758    /* Load from realtime storage? */
10759    load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? TRUE : FALSE;
10760 
10761    user = find_user(argv[3], load_realtime);
10762    if (user) {
10763       ast_cli(fd,"\n\n");
10764       ast_cli(fd, "  * Name       : %s\n", user->name);
10765       ast_cli(fd, "  Secret       : %s\n", ast_strlen_zero(user->secret)?"<Not set>":"<Set>");
10766       ast_cli(fd, "  MD5Secret    : %s\n", ast_strlen_zero(user->md5secret)?"<Not set>":"<Set>");
10767       ast_cli(fd, "  Context      : %s\n", user->context);
10768       ast_cli(fd, "  Language     : %s\n", user->language);
10769       if (!ast_strlen_zero(user->accountcode))
10770          ast_cli(fd, "  Accountcode  : %s\n", user->accountcode);
10771       ast_cli(fd, "  AMA flags    : %s\n", ast_cdr_flags2str(user->amaflags));
10772       ast_cli(fd, "  Transfer mode: %s\n", transfermode2str(user->allowtransfer));
10773       ast_cli(fd, "  MaxCallBR    : %d kbps\n", user->maxcallbitrate);
10774       ast_cli(fd, "  CallingPres  : %s\n", ast_describe_caller_presentation(user->callingpres));
10775       ast_cli(fd, "  Call limit   : %d\n", user->call_limit);
10776       ast_cli(fd, "  Callgroup    : ");
10777       print_group(fd, user->callgroup, 0);
10778       ast_cli(fd, "  Pickupgroup  : ");
10779       print_group(fd, user->pickupgroup, 0);
10780       ast_cli(fd, "  Callerid     : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), user->cid_name, user->cid_num, "<unspecified>"));
10781       ast_cli(fd, "  ACL          : %s\n", (user->ha?"Yes":"No"));
10782       ast_cli(fd, "  Codec Order  : (");
10783       print_codec_to_cli(fd, &user->prefs);
10784       ast_cli(fd, ")\n");
10785 
10786       ast_cli(fd, "  Auto-Framing:  %s \n", user->autoframing ? "Yes" : "No");
10787       if (user->chanvars) {
10788          ast_cli(fd, "  Variables    :\n");
10789          for (v = user->chanvars ; v ; v = v->next)
10790             ast_cli(fd, "                 %s = %s\n", v->name, v->value);
10791       }
10792       ast_cli(fd,"\n");
10793       ASTOBJ_UNREF(user,sip_destroy_user);
10794    } else {
10795       ast_cli(fd,"User %s not found.\n", argv[3]);
10796       ast_cli(fd,"\n");
10797    }
10798 
10799    return RESULT_SUCCESS;
10800 }

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

CLI Command 'SIP Show Users'.

Definition at line 10002 of file chan_sip.c.

References ast_cli(), ast_test_flag, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, FALSE, FORMAT, nat2str(), RESULT_SHOWUSAGE, SIP_NAT, TRUE, and userl.

10003 {
10004    regex_t regexbuf;
10005    int havepattern = FALSE;
10006 
10007 #define FORMAT  "%-25.25s  %-15.15s  %-15.15s  %-15.15s  %-5.5s%-10.10s\n"
10008 
10009    switch (argc) {
10010    case 5:
10011       if (!strcasecmp(argv[3], "like")) {
10012          if (regcomp(&regexbuf, argv[4], REG_EXTENDED | REG_NOSUB))
10013             return RESULT_SHOWUSAGE;
10014          havepattern = TRUE;
10015       } else
10016          return RESULT_SHOWUSAGE;
10017    case 3:
10018       break;
10019    default:
10020       return RESULT_SHOWUSAGE;
10021    }
10022 
10023    ast_cli(fd, FORMAT, "Username", "Secret", "Accountcode", "Def.Context", "ACL", "NAT");
10024    ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do {
10025       ASTOBJ_RDLOCK(iterator);
10026 
10027       if (havepattern && regexec(&regexbuf, iterator->name, 0, NULL, 0)) {
10028          ASTOBJ_UNLOCK(iterator);
10029          continue;
10030       }
10031 
10032       ast_cli(fd, FORMAT, iterator->name, 
10033          iterator->secret, 
10034          iterator->accountcode,
10035          iterator->context,
10036          iterator->ha ? "Yes" : "No",
10037          nat2str(ast_test_flag(&iterator->flags[0], SIP_NAT)));
10038       ASTOBJ_UNLOCK(iterator);
10039    } while (0)
10040    );
10041 
10042    if (havepattern)
10043       regfree(&regexbuf);
10044 
10045    return RESULT_SUCCESS;
10046 #undef FORMAT
10047 }

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

18430 {
18431    char *cdest;
18432    char *extension, *host, *port;
18433    char tmp[80];
18434    
18435    cdest = ast_strdupa(dest);
18436    
18437    extension = strsep(&cdest, "@");
18438    host = strsep(&cdest, ":");
18439    port = strsep(&cdest, ":");
18440    if (ast_strlen_zero(extension)) {
18441       ast_log(LOG_ERROR, "Missing mandatory argument: extension\n");
18442       return 0;
18443    }
18444 
18445    /* we'll issue the redirect message here */
18446    if (!host) {
18447       char *localtmp;
18448       ast_copy_string(tmp, get_header(&p->initreq, "To"), sizeof(tmp));
18449       if (ast_strlen_zero(tmp)) {
18450          ast_log(LOG_ERROR, "Cannot retrieve the 'To' header from the original SIP request!\n");
18451          return 0;
18452       }
18453       if ((localtmp = strcasestr(tmp, "sip:")) && (localtmp = strchr(localtmp, '@'))) {
18454          char lhost[80], lport[80];
18455          memset(lhost, 0, sizeof(lhost));
18456          memset(lport, 0, sizeof(lport));
18457          localtmp++;
18458          /* This is okey because lhost and lport are as big as tmp */
18459          sscanf(localtmp, "%[^<>:; ]:%[^<>:; ]", lhost, lport);
18460          if (ast_strlen_zero(lhost)) {
18461             ast_log(LOG_ERROR, "Can't find the host address\n");
18462             return 0;
18463          }
18464          host = ast_strdupa(lhost);
18465          if (!ast_strlen_zero(lport)) {
18466             port = ast_strdupa(lport);
18467          }
18468       }
18469    }
18470 
18471    ast_string_field_build(p, our_contact, "Transfer <sip:%s@%s%s%s>", extension, host, port ? ":" : "", port ? port : "");
18472    transmit_response_reliable(p, "302 Moved Temporarily", &p->initreq);
18473 
18474    sip_scheddestroy(p, SIP_TRANS_TIMEOUT);   /* Make sure we stop send this reply. */
18475    sip_alreadygone(p);
18476    return 0;
18477 }

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

Transfer SIP call.

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

03910 {
03911    struct sip_pvt *p = ast->tech_pvt;
03912    int res;
03913 
03914    if (dest == NULL) /* functions below do not take a NULL */
03915       dest = "";
03916    ast_mutex_lock(&p->lock);
03917    if (ast->_state == AST_STATE_RING)
03918       res = sip_sipredirect(p, dest);
03919    else
03920       res = transmit_refer(p, dest);
03921    ast_mutex_unlock(&p->lock);
03922    return res;
03923 }

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

Definition at line 14051 of file chan_sip.c.

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

Referenced by handle_request_invite().

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

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

helper routine for sip_uri_cmp

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

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

Definition at line 14017 of file chan_sip.c.

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

Referenced by sip_uri_cmp().

14018 {
14019    char *headers1 = ast_strdupa(input1);
14020    char *headers2 = ast_strdupa(input2);
14021    int zerolength1 = ast_strlen_zero(headers1);
14022    int zerolength2 = ast_strlen_zero(headers2);
14023    int different = 0;
14024    char *header1;
14025 
14026    if ((zerolength1 && !zerolength2) ||
14027          (zerolength2 && !zerolength1))
14028       return 1;
14029 
14030    if (zerolength1 && zerolength2)
14031       return 0;
14032 
14033    /* At this point, we can definitively state that both inputs are
14034     * not zero-length. First, one more optimization. If the length
14035     * of the headers is not equal, then we definitely have no match
14036     */
14037    if (strlen(headers1) != strlen(headers2)) {
14038       return 1;
14039    }
14040 
14041    for (header1 = strsep(&headers1, "&"); header1; header1 = strsep(&headers1, "&")) {
14042       if (!strcasestr(headers2, header1)) {
14043          different = 1;
14044          break;
14045       }
14046    }
14047 
14048    return different;
14049 }

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

helper routine for sip_uri_cmp

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

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

Definition at line 13890 of file chan_sip.c.

References ast_strdupa, and ast_strlen_zero().

Referenced by sip_uri_cmp().

13891 {
13892    char *params1 = ast_strdupa(input1);
13893    char *params2 = ast_strdupa(input2);
13894    char *pos1;
13895    char *pos2;
13896    int maddrmatch = 0;
13897    int ttlmatch = 0;
13898    int usermatch = 0;
13899    int methodmatch = 0;
13900 
13901    /*Quick optimization. If both params are zero-length, then
13902     * they match
13903     */
13904    if (ast_strlen_zero(params1) && ast_strlen_zero(params2)) {
13905       return 0;
13906    }
13907 
13908    pos1 = params1;
13909    while (!ast_strlen_zero(pos1)) {
13910       char *name1 = pos1;
13911       char *value1 = strchr(pos1, '=');
13912       char *semicolon1 = strchr(pos1, ';');
13913       int matched = 0;
13914       if (semicolon1) {
13915          *semicolon1++ = '\0';
13916       }
13917       if (!value1) {
13918          goto fail;
13919       }
13920       *value1++ = '\0';
13921       /* Checkpoint reached. We have the name and value parsed for param1 
13922        * We have to duplicate params2 each time through the second loop
13923        * or else we can't search and replace the semicolons with \0 each
13924        * time
13925        */
13926       pos2 = ast_strdupa(params2);
13927       while (!ast_strlen_zero(pos2)) {
13928          char *name2 = pos2;
13929          char *value2 = strchr(pos2, '=');
13930          char *semicolon2 = strchr(pos2, ';');
13931          if (semicolon2) {
13932             *semicolon2++ = '\0';
13933          }
13934          if (!value2) {
13935             goto fail;
13936          }
13937          *value2++ = '\0';
13938          if (!strcasecmp(name1, name2)) {
13939             if (strcasecmp(value1, value2)) {
13940                goto fail;
13941             } else {
13942                matched = 1;
13943                break;
13944             }
13945          }
13946          pos2 = semicolon2;
13947       }
13948       /* Need to see if the parameter we're looking at is one of the 'must-match' parameters */
13949       if (!strcasecmp(name1, "maddr")) {
13950          if (matched) {
13951             maddrmatch = 1;
13952          } else {
13953             goto fail;
13954          }
13955       } else if (!strcasecmp(name1, "ttl")) {
13956          if (matched) {
13957             ttlmatch = 1;
13958          } else {
13959             goto fail;
13960          }
13961       } else if (!strcasecmp(name1, "user")) {
13962          if (matched) {
13963             usermatch = 1;
13964          } else {
13965             goto fail;
13966          }
13967       } else if (!strcasecmp(name1, "method")) {
13968          if (matched) {
13969             methodmatch = 1;
13970          } else {
13971             goto fail;
13972          }
13973       }
13974       pos1 = semicolon1;
13975    }
13976 
13977    /* We've made it out of that horrible O(m*n) construct and there are no
13978     * failures yet. We're not done yet, though, because params2 could have
13979     * an maddr, ttl, user, or method header and params1 did not.
13980     */
13981    pos2 = params2;
13982    while (!ast_strlen_zero(pos2)) {
13983       char *name2 = pos2;
13984       char *value2 = strchr(pos2, '=');
13985       char *semicolon2 = strchr(pos2, ';');
13986       if (semicolon2) {
13987          *semicolon2++ = '\0';
13988       }
13989       if (!value2) {
13990          goto fail;
13991       }
13992       *value2++ = '\0';
13993       if ((!strcasecmp(name2, "maddr") && !maddrmatch) ||
13994             (!strcasecmp(name2, "ttl") && !ttlmatch) ||
13995             (!strcasecmp(name2, "user") && !usermatch) ||
13996             (!strcasecmp(name2, "method") && !methodmatch)) {
13997          goto fail;
13998       }
13999    }
14000    return 0;
14001 
14002 fail:
14003    return 1;
14004 }

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

Send frame to media channel (rtp).

Definition at line 3736 of file chan_sip.c.

References ast_channel::_state, AST_FORMAT_AUDIO_MASK, AST_FRAME_IMAGE, AST_FRAME_MODEM, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_getformatname_multiple(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_rtp_new_source(), ast_rtp_write(), ast_set_flag, AST_STATE_UP, ast_test_flag, ast_udptl_write(), sip_pvt::flags, ast_frame::frametype, sip_pvt::initreq, sip_pvt::lastrtptx, sip_pvt::lock, 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.

03737 {
03738    struct sip_pvt *p = ast->tech_pvt;
03739    int res = 0;
03740 
03741    switch (frame->frametype) {
03742    case AST_FRAME_VOICE:
03743       if (!(frame->subclass & ast->nativeformats)) {
03744          char s1[512], s2[512], s3[512];
03745          ast_log(LOG_WARNING, "Asked to transmit frame type %d, while native formats is %s(%d) read/write = %s(%d)/%s(%d)\n",
03746             frame->subclass, 
03747             ast_getformatname_multiple(s1, sizeof(s1) - 1, ast->nativeformats & AST_FORMAT_AUDIO_MASK),
03748             ast->nativeformats & AST_FORMAT_AUDIO_MASK,
03749             ast_getformatname_multiple(s2, sizeof(s2) - 1, ast->readformat),
03750             ast->readformat,
03751             ast_getformatname_multiple(s3, sizeof(s3) - 1, ast->writeformat),
03752             ast->writeformat);
03753          return 0;
03754       }
03755       if (p) {
03756          ast_mutex_lock(&p->lock);
03757          if (p->rtp) {
03758             /* If channel is not up, activate early media session */
03759             if ((ast->_state != AST_STATE_UP) &&
03760                 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) &&
03761                 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
03762                ast_rtp_new_source(p->rtp);
03763                transmit_response_with_sdp(p, "183 Session Progress", &p->initreq, XMIT_UNRELIABLE);
03764                ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT);  
03765             }
03766             p->lastrtptx = time(NULL);
03767             res = ast_rtp_write(p->rtp, frame);
03768          }
03769          ast_mutex_unlock(&p->lock);
03770       }
03771       break;
03772    case AST_FRAME_VIDEO:
03773       if (p) {
03774          ast_mutex_lock(&p->lock);
03775          if (p->vrtp) {
03776             /* Activate video early media */
03777             if ((ast->_state != AST_STATE_UP) &&
03778                 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) &&
03779                 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
03780                transmit_response_with_sdp(p, "183 Session Progress", &p->initreq, XMIT_UNRELIABLE);
03781                ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT);  
03782             }
03783             p->lastrtptx = time(NULL);
03784             res = ast_rtp_write(p->vrtp, frame);
03785          }
03786          ast_mutex_unlock(&p->lock);
03787       }
03788       break;
03789    case AST_FRAME_IMAGE:
03790       return 0;
03791       break;
03792    case AST_FRAME_MODEM:
03793       if (p) {
03794          ast_mutex_lock(&p->lock);
03795          /* UDPTL requires two-way communication, so early media is not needed here.
03796             we simply forget the frames if we get modem frames before the bridge is up.
03797             Fax will re-transmit.
03798          */
03799          if (p->udptl && ast->_state == AST_STATE_UP) 
03800             res = ast_udptl_write(p->udptl, frame);
03801          ast_mutex_unlock(&p->lock);
03802       }
03803       break;
03804    default: 
03805       ast_log(LOG_WARNING, "Can't send %d type frames with SIP write\n", frame->frametype);
03806       return 0;
03807    }
03808 
03809    return res;
03810 }

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 15913 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(), errno, find_call(), find_sip_method(), sip_pvt::flags, get_header(), handle_request(), len, sip_pvt::lock, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, lws2sws(), option_debug, sip_pvt::owner, parse_request(), sip_pvt::recv, S_OR, SIP_ACK, sip_debug_test_addr(), SIP_NO_HISTORY, SIP_PAGE2_TCP, SIP_PKT_DEBUG, sipsock, and transmit_response().

Referenced by do_monitor(), and siptcpsock_accept().

15914 {
15915    struct sip_request req;
15916    struct sockaddr_in sin = { 0, };
15917    struct sip_pvt *p;
15918    int res;
15919    socklen_t len = sizeof(sin);
15920    int nounlock;
15921    int recount = 0;
15922    int lockretry;
15923 
15924    memset(&req, 0, sizeof(req));
15925    if (fd == sipsock)
15926       res = recvfrom(fd, req.data, sizeof(req.data) - 1, 0, (struct sockaddr *)&sin, &len);
15927    else {
15928       if (getpeername(fd, (struct sockaddr *)&sin, &len) < 0) {
15929          close(fd);
15930          return 1;
15931       }
15932       if ((res = read(fd, req.data, sizeof(req.data) - 1)) == 0) {
15933          close(fd);
15934          return 1;
15935       }
15936    }
15937    if (res < 0) {
15938 #if !defined(__FreeBSD__)
15939       if (errno == EAGAIN)
15940          ast_log(LOG_NOTICE, "SIP: Received packet with bad UDP checksum\n");
15941       else 
15942 #endif
15943       if (errno != ECONNREFUSED)
15944          ast_log(LOG_WARNING, "Recv error: %s\n", strerror(errno));
15945       return 1;
15946    }
15947    if (option_debug && res == sizeof(req.data) - 1)
15948       ast_log(LOG_DEBUG, "Received packet exceeds buffer. Data is possibly lost\n");
15949 
15950    req.data[res] = '\0';
15951    req.len = res;
15952    if(sip_debug_test_addr(&sin)) /* Set the debug flag early on packet level */
15953       ast_set_flag(&req, SIP_PKT_DEBUG);
15954    if (pedanticsipchecking)
15955       req.len = lws2sws(req.data, req.len);  /* Fix multiline headers */
15956    if (ast_test_flag(&req, SIP_PKT_DEBUG))
15957       ast_verbose("\n<--- SIP read from %s:%d:%s --->\n%s\n<------------->\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port), 
15958          fd == sipsock ? "UDP" : "TCP",req.data);
15959 
15960    if(parse_request(&req) == -1) /* Bad packet, can't parse */
15961       return 1;
15962 
15963    req.method = find_sip_method(req.rlPart1);
15964 
15965    if (ast_test_flag(&req, SIP_PKT_DEBUG))
15966       ast_verbose("--- (%d headers %d lines)%s ---\n", req.headers, req.lines, (req.headers + req.lines == 0) ? " Nat keepalive" : "");
15967 
15968    if (req.headers < 2) /* Must have at least two headers */
15969       return 1;
15970 
15971    /* Process request, with netlock held, and with usual deadlock avoidance */
15972    for (lockretry = 100; lockretry > 0; lockretry--) {
15973       ast_mutex_lock(&netlock);
15974 
15975       /* Find the active SIP dialog or create a new one */
15976       p = find_call(&req, &sin, req.method); /* returns p locked */
15977       if (p == NULL) {
15978          if (option_debug)
15979             ast_log(LOG_DEBUG, "Invalid SIP message - rejected , no callid, len %d\n", req.len);
15980          ast_mutex_unlock(&netlock);
15981          return 1;
15982       }
15983       /* Go ahead and lock the owner if it has one -- we may need it */
15984       /* because this is deadlock-prone, we need to try and unlock if failed */
15985       if (!p->owner || !ast_channel_trylock(p->owner))
15986          break;   /* locking succeeded */
15987       if (lockretry == 1) {
15988          if (option_debug) {
15989             ast_log(LOG_DEBUG, "Failed to grab owner channel lock. (SIP call %s)\n", p->callid);
15990          }
15991       } else {
15992          if (option_debug) {
15993             ast_log(LOG_DEBUG, "Failed to grab owner channel lock, trying again. (SIP call %s)\n", p->callid);
15994          }
15995          ast_mutex_unlock(&p->lock);
15996          ast_mutex_unlock(&netlock);
15997          /* Sleep for a very short amount of time */
15998          usleep(1);
15999       }
16000    }
16001    p->recv = sin;
16002 
16003    if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) /* This is a request or response, note what it was for */
16004       append_history(p, "Rx", "%s / %s / %s", req.data, get_header(&req, "CSeq"), req.rlPart2);
16005 
16006    if (!lockretry) {
16007       /* XXX Wouldn't p->owner always exist here? */
16008       /* This is unsafe, since p->owner wouldn't be locked. */
16009       if (p->owner)
16010          ast_log(LOG_ERROR, "We could NOT get the channel lock for %s! \n", S_OR(p->owner->name, "- no channel name ??? - "));
16011       ast_log(LOG_ERROR, "SIP transaction failed: %s \n", p->callid);
16012       if (req.method != SIP_ACK)
16013          transmit_response(p, "503 Server error", &req); /* We must respond according to RFC 3261 sec 12.2 */
16014       /* XXX We could add retry-after to make sure they come back */
16015       append_history(p, "LockFail", "Owner lock failed, transaction failed.");
16016       ast_mutex_unlock(&p->lock);
16017       ast_mutex_unlock(&netlock);
16018       return 1;
16019    }
16020    nounlock = 0;
16021    /* Is this a TCP connection ?? if so set the socket accordingly*/
16022    if (fd != sipsock) {
16023       p->sockfd=fd;
16024       ast_set_flag(&p->flags[1], SIP_PAGE2_TCP);
16025    } else {
16026       p->sockfd=-1;
16027    }
16028    if (handle_request(p, &req, &sin, &recount, &nounlock) == -1) {
16029       /* Request failed */
16030       if (option_debug)
16031          ast_log(LOG_DEBUG, "SIP message could not be handled, bad request: %-70.70s\n", p->callid[0] ? p->callid : "<no callid>");
16032    }
16033       
16034    if (p->owner && !nounlock)
16035       ast_channel_unlock(p->owner);
16036    ast_mutex_unlock(&p->lock);
16037    ast_mutex_unlock(&netlock);
16038    if (recount)
16039       ast_update_use_count();
16040 
16041    return 1;
16042 }

static int siptcpsock_accept ( int *  id,
int  fd,
short  events,
void *  ignore 
) [static]

Accept incoming TCP connections.

Definition at line 16045 of file chan_sip.c.

References ast_io_add(), AST_IO_IN, io, sipsock_read(), and siptcpsock.

Referenced by do_monitor().

16046 {
16047    struct sockaddr_in sa;
16048    socklen_t sa_len=sizeof(sa);
16049    int newfd;
16050 
16051    if ((newfd=accept(siptcpsock, (struct sockaddr *)&sa, &sa_len)) >= 0)
16052       ast_io_add(io, newfd, sipsock_read, AST_IO_IN, NULL);
16053    return 1;
16054 }

static void stop_media_flows ( struct sip_pvt p  )  [static]

Immediately stop RTP, VRTP and UDPTL as applicable.

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

12829 {
12830    /* Immediately stop RTP, VRTP and UDPTL as applicable */
12831    if (p->rtp)
12832       ast_rtp_stop(p->rtp);
12833    if (p->vrtp)
12834       ast_rtp_stop(p->vrtp);
12835    if (p->udptl)
12836       ast_udptl_stop(p->udptl);
12837 }

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

Show subscription type in string format.

Definition at line 10940 of file chan_sip.c.

References subscription_types, and type.

Referenced by sip_show_channel().

10941 {
10942    int i;
10943 
10944    for (i = 1; (i < (sizeof(subscription_types) / sizeof(subscription_types[0]))); i++) {
10945       if (subscription_types[i].type == subtype) {
10946          return subscription_types[i].text;
10947       }
10948    }
10949    return subscription_types[0].text;
10950 }

static int t38_get_rate ( int  t38cap  )  [static]

Get Max T.38 Transmission rate from T38 capabilities.

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

06375 {
06376    int maxrate = (t38cap & (T38FAX_RATE_14400 | T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400));
06377    
06378    if (maxrate & T38FAX_RATE_14400) {
06379       if (option_debug > 1)
06380          ast_log(LOG_DEBUG, "T38MaxFaxRate 14400 found\n");
06381       return 14400;
06382    } else if (maxrate & T38FAX_RATE_12000) {
06383       if (option_debug > 1)
06384          ast_log(LOG_DEBUG, "T38MaxFaxRate 12000 found\n");
06385       return 12000;
06386    } else if (maxrate & T38FAX_RATE_9600) {
06387       if (option_debug > 1)
06388          ast_log(LOG_DEBUG, "T38MaxFaxRate 9600 found\n");
06389       return 9600;
06390    } else if (maxrate & T38FAX_RATE_7200) {
06391       if (option_debug > 1)
06392          ast_log(LOG_DEBUG, "T38MaxFaxRate 7200 found\n");
06393       return 7200;
06394    } else if (maxrate & T38FAX_RATE_4800) {
06395       if (option_debug > 1)
06396          ast_log(LOG_DEBUG, "T38MaxFaxRate 4800 found\n");
06397       return 4800;
06398    } else if (maxrate & T38FAX_RATE_2400) {
06399       if (option_debug > 1)
06400          ast_log(LOG_DEBUG, "T38MaxFaxRate 2400 found\n");
06401       return 2400;
06402    } else {
06403       if (option_debug > 1)
06404          ast_log(LOG_DEBUG, "Strange, T38MaxFaxRate NOT found in peers T38 SDP.\n");
06405       return 0;
06406    }
06407 }

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

Create temporary peer (used in autocreatepeer mode).

Definition at line 17118 of file chan_sip.c.

References ast_calloc, ast_set_flag, ASTOBJ_INIT, default_prefs, reg_source_db(), set_peer_defaults(), SIP_PAGE2_DYNAMIC, and SIP_PAGE2_SELFDESTRUCT.

Referenced by register_verify().

17119 {
17120    struct sip_peer *peer;
17121 
17122    if (!(peer = ast_calloc(1, sizeof(*peer))))
17123       return NULL;
17124 
17125    apeerobjs++;
17126    ASTOBJ_INIT(peer);
17127    set_peer_defaults(peer);
17128 
17129    ast_copy_string(peer->name, name, sizeof(peer->name));
17130 
17131    ast_set_flag(&peer->flags[1], SIP_PAGE2_SELFDESTRUCT);
17132    ast_set_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC);
17133    peer->prefs = default_prefs;
17134    reg_source_db(peer);
17135 
17136    return peer;
17137 }

static void temp_pvt_cleanup ( void *   )  [static]

Definition at line 6149 of file chan_sip.c.

References ast_string_field_free_memory, and free.

06150 {
06151    struct sip_pvt *p = data;
06152 
06153    ast_string_field_free_memory(p);
06154 
06155    free(data);
06156 }

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

Convert transfer mode to text string.

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

09950 {
09951    if (mode == TRANSFER_OPENFORALL)
09952       return "open";
09953    else if (mode == TRANSFER_CLOSED)
09954       return "closed";
09955    return "strict";
09956 }

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

08761 {
08762    ast_string_field_build(p, randdata, "%08lx", ast_random()); /* Create nonce for challenge */
08763    transmit_response_with_auth(p, "401 Unauthorized", req, p->randdata, reliable, "WWW-Authenticate", 0);
08764 }

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

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

Referenced by sip_senddigit_end().

07931 {
07932    struct sip_request req;
07933 
07934    reqprep(&req, p, SIP_INFO, 0, 1);
07935    add_digit(&req, digit, duration);
07936    return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
07937 }

static int transmit_info_with_vidupdate ( struct sip_pvt p  )  [static]

Send SIP INFO with video update request.

Definition at line 7940 of file chan_sip.c.

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

Referenced by sip_indicate().

07941 {
07942    struct sip_request req;
07943 
07944    reqprep(&req, p, SIP_INFO, 0, 1);
07945    add_vidupdate(&req);
07946    return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
07947 }

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 7181 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, sip_request::method, sip_pvt::ocseq, option_debug, sip_pvt::options, sip_pvt::owner, sip_pvt::refer, sip_refer::refer_to, sip_refer::referred_by, sip_refer::referred_by_name, sip_invite_param::replaces, reqprep(), sip_pvt::rtp, send_request(), SIP_REFER, SIPBUFSIZE, sipdebug, t38properties::state, SUPPORTED_EXTENSIONS, sip_pvt::t38, T38_LOCAL_DIRECT, T38_LOCAL_REINVITE, sip_pvt::udptl, ast_channel::varshead, XMIT_CRITICAL, and XMIT_RELIABLE.

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

07182 {
07183    struct sip_request req;
07184    
07185    req.method = sipmethod;
07186    if (init) {    /* Seems like init always is 2 */
07187       /* Bump branch even on initial requests */
07188       p->branch ^= ast_random();
07189       build_via(p);
07190       if (init > 1)
07191          initreqprep(&req, p, sipmethod);
07192       else
07193          reqprep(&req, p, sipmethod, 0, 1);
07194    } else
07195       reqprep(&req, p, sipmethod, 0, 1);
07196       
07197    if (p->options && p->options->auth)
07198       add_header(&req, p->options->authheader, p->options->auth);
07199    append_date(&req);
07200    if (sipmethod == SIP_REFER) { /* Call transfer */
07201       if (p->refer) {
07202          char buf[SIPBUFSIZE];
07203          if (!ast_strlen_zero(p->refer->refer_to))
07204             add_header(&req, "Refer-To", p->refer->refer_to);
07205          if (!ast_strlen_zero(p->refer->referred_by)) {
07206             snprintf(buf, sizeof(buf), "%s <%s>", p->refer->referred_by_name, p->refer->referred_by);
07207             add_header(&req, "Referred-By", buf);
07208          }
07209       }
07210    }
07211    /* This new INVITE is part of an attended transfer. Make sure that the
07212    other end knows and replace the current call with this new call */
07213    if (p->options && p->options->replaces && !ast_strlen_zero(p->options->replaces)) {
07214       add_header(&req, "Replaces", p->options->replaces);
07215       add_header(&req, "Require", "replaces");
07216    }
07217 
07218    add_header(&req, "Allow", ALLOWED_METHODS);
07219    add_header(&req, "Supported", SUPPORTED_EXTENSIONS);
07220    if (p->options && p->options->addsipheaders && p->owner) {
07221       struct ast_channel *chan = p->owner; /* The owner channel */
07222       struct varshead *headp;
07223    
07224       ast_channel_lock(chan);
07225 
07226       headp = &chan->varshead;
07227 
07228       if (!headp)
07229          ast_log(LOG_WARNING,"No Headp for the channel...ooops!\n");
07230       else {
07231          const struct ast_var_t *current;
07232          AST_LIST_TRAVERSE(headp, current, entries) {  
07233             /* SIPADDHEADER: Add SIP header to outgoing call */
07234             if (!strncasecmp(ast_var_name(current), "SIPADDHEADER", strlen("SIPADDHEADER"))) {
07235                char *content, *end;
07236                const char *header = ast_var_value(current);
07237                char *headdup = ast_strdupa(header);
07238 
07239                /* Strip of the starting " (if it's there) */
07240                if (*headdup == '"')
07241                   headdup++;
07242                if ((content = strchr(headdup, ':'))) {
07243                   *content++ = '\0';
07244                   content = ast_skip_blanks(content); /* Skip white space */
07245                   /* Strip the ending " (if it's there) */
07246                   end = content + strlen(content) -1; 
07247                   if (*end == '"')
07248                      *end = '\0';
07249                
07250                   add_header(&req, headdup, content);
07251                   if (sipdebug)
07252                      ast_log(LOG_DEBUG, "Adding SIP Header \"%s\" with content :%s: \n", headdup, content);
07253                }
07254             }
07255          }
07256       }
07257 
07258       ast_channel_unlock(chan);
07259    }
07260    if (sdp) {
07261       if (p->udptl && (p->t38.state == T38_LOCAL_DIRECT || p->t38.state == T38_LOCAL_REINVITE)) {
07262          ast_udptl_offered_from_local(p->udptl, 1);
07263          if (option_debug)
07264             ast_log(LOG_DEBUG, "T38 is in state %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>");
07265          add_t38_sdp(&req, p);
07266       } else if (p->rtp) 
07267          add_sdp(&req, p);
07268    } else {
07269       add_header_contentLength(&req, 0);
07270    }
07271 
07272    if (!p->initreq.headers || init > 2)
07273       initialize_initreq(p, &req);
07274    p->lastinvite = p->ocseq;
07275    return send_request(p, &req, init ? XMIT_CRITICAL : XMIT_RELIABLE, p->ocseq);
07276 }

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

Transmit text with SIP MESSAGE method.

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

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

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

07468 {
07469    struct sip_request req;
07470    char tmp[500];
07471    char *t = tmp;
07472    size_t maxbytes = sizeof(tmp);
07473 
07474    initreqprep(&req, p, SIP_NOTIFY);
07475    add_header(&req, "Event", "message-summary");
07476    add_header(&req, "Content-Type", default_notifymime);
07477 
07478    ast_build_string(&t, &maxbytes, "Messages-Waiting: %s\r\n", newmsgs ? "yes" : "no");
07479    ast_build_string(&t, &maxbytes, "Message-Account: sip:%s@%s\r\n",
07480       S_OR(vmexten, default_vmexten), S_OR(p->fromdomain, ast_inet_ntoa(p->ourip)));
07481    /* Cisco has a bug in the SIP stack where it can't accept the
07482       (0/0) notification. This can temporarily be disabled in
07483       sip.conf with the "buggymwi" option */
07484    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)"));
07485 
07486    if (p->subscribed) {
07487       if (p->expiry)
07488          add_header(&req, "Subscription-State", "active");
07489       else  /* Expired */
07490          add_header(&req, "Subscription-State", "terminated;reason=timeout");
07491    }
07492 
07493    if (t > tmp + sizeof(tmp))
07494       ast_log(LOG_WARNING, "Buffer overflow detected!!  (Please file a bug report)\n");
07495 
07496    add_header_contentLength(&req, strlen(tmp));
07497    add_line(&req, tmp);
07498 
07499    if (!p->initreq.headers) 
07500       initialize_initreq(p, &req);
07501    return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
07502 }

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

07514 {
07515    struct sip_request req;
07516    char tmp[SIPBUFSIZE/2];
07517 
07518    reqprep(&req, p, SIP_NOTIFY, 0, 1);
07519    snprintf(tmp, sizeof(tmp), "refer;id=%d", cseq);
07520    add_header(&req, "Event", tmp);
07521    add_header(&req, "Subscription-state", terminate ? "terminated;reason=noresource" : "active");
07522    add_header(&req, "Content-Type", "message/sipfrag;version=2.0");
07523    add_header(&req, "Allow", ALLOWED_METHODS);
07524    add_header(&req, "Supported", SUPPORTED_EXTENSIONS);
07525 
07526    snprintf(tmp, sizeof(tmp), "SIP/2.0 %s\r\n", message);
07527    add_header_contentLength(&req, strlen(tmp));
07528    add_line(&req, tmp);
07529 
07530    if (!p->initreq.headers)
07531       initialize_initreq(p, &req);
07532 
07533    p->lastnoninvite = p->ocseq;
07534 
07535    return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
07536 }

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

07861 {
07862    struct sip_request req = { 
07863       .headers = 0,  
07864    };
07865    char from[256];
07866    const char *of;
07867    char *c;
07868    char referto[256];
07869    char *ttag, *ftag;
07870    char *theirtag = ast_strdupa(p->theirtag);
07871 
07872    if (option_debug || sipdebug)
07873       ast_log(LOG_DEBUG, "SIP transfer of %s to %s\n", p->callid, dest);
07874 
07875    /* Are we transfering an inbound or outbound call ? */
07876    if (ast_test_flag(&p->flags[0], SIP_OUTGOING))  {
07877       of = get_header(&p->initreq, "To");
07878       ttag = theirtag;
07879       ftag = p->tag;
07880    } else {
07881       of = get_header(&p->initreq, "From");
07882       ftag = theirtag;
07883       ttag = p->tag;
07884    }
07885 
07886    ast_copy_string(from, of, sizeof(from));
07887    of = get_in_brackets(from);
07888    ast_string_field_set(p, from, of);
07889    if (strncasecmp(of, "sip:", 4))
07890       ast_log(LOG_NOTICE, "From address missing 'sip:', using it anyway\n");
07891    else
07892       of += 4;
07893    /* Get just the username part */
07894    if ((c = strchr(dest, '@')))
07895       c = NULL;
07896    else if ((c = strchr(of, '@')))
07897       *c++ = '\0';
07898    if (c) 
07899       snprintf(referto, sizeof(referto), "<sip:%s@%s>", dest, c);
07900    else
07901       snprintf(referto, sizeof(referto), "<sip:%s>", dest);
07902 
07903    /* save in case we get 407 challenge */
07904    sip_refer_allocate(p);
07905    ast_copy_string(p->refer->refer_to, referto, sizeof(p->refer->refer_to));
07906    ast_copy_string(p->refer->referred_by, p->our_contact, sizeof(p->refer->referred_by));
07907    p->refer->status = REFER_SENT;   /* Set refer status */
07908 
07909    reqprep(&req, p, SIP_REFER, 0, 1);
07910 
07911    add_header(&req, "Refer-To", referto);
07912    add_header(&req, "Allow", ALLOWED_METHODS);
07913    add_header(&req, "Supported", SUPPORTED_EXTENSIONS);
07914    if (!ast_strlen_zero(p->our_contact))
07915       add_header(&req, "Referred-By", p->our_contact);
07916 
07917    return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
07918    /* We should propably wait for a NOTIFY here until we ack the transfer */
07919    /* Maybe fork a new thread and wait for a STATUS of REFER_200OK on the refer status before returning to app_transfer */
07920 
07921    /*! \todo In theory, we should hang around and wait for a reply, before
07922    returning to the dial plan here. Don't know really how that would
07923    affect the transfer() app or the pbx, but, well, to make this
07924    useful we should have a STATUS code on transfer().
07925    */
07926 }

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 7640 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, make_our_tag(), sip_pvt::noncecount, sip_registry::noncecount, sip_pvt::ocseq, sip_registry::ocseq, option_debug, sip_registry::portno, REG_STATE_AUTHSENT, REG_STATE_REGSENT, sip_registry::regattempts, sip_pvt::registry, sip_registry::regstate, sched, 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().

07641 {
07642    struct sip_request req;
07643    char from[256];
07644    char to[256];
07645    char tmp[80];
07646    char addr[80];
07647    struct sip_pvt *p;
07648    char *fromdomain;
07649 
07650    /* exit if we are already in process with this registrar ?*/
07651    if ( r == NULL || ((auth==NULL) && (r->regstate==REG_STATE_REGSENT || r->regstate==REG_STATE_AUTHSENT))) {
07652       ast_log(LOG_NOTICE, "Strange, trying to register %s@%s when registration already pending\n", r->username, r->hostname);
07653       return 0;
07654    }
07655 
07656    if (r->call) { /* We have a registration */
07657       if (!auth) {
07658          ast_log(LOG_WARNING, "Already have a REGISTER going on to %s@%s?? \n", r->username, r->hostname);
07659          return 0;
07660       } else {
07661          p = r->call;
07662          make_our_tag(p->tag, sizeof(p->tag));  /* create a new local tag for every register attempt */
07663          ast_string_field_free(p, theirtag); /* forget their old tag, so we don't match tags when getting response */
07664       }
07665    } else {
07666       /* Build callid for registration if we haven't registered before */
07667       if (!r->callid_valid) {
07668          build_callid_registry(r, __ourip, default_fromdomain);
07669          r->callid_valid = TRUE;
07670       }
07671       /* Allocate SIP packet for registration */
07672       if (!(p = sip_alloc( r->callid, NULL, 0, SIP_REGISTER))) {
07673          ast_log(LOG_WARNING, "Unable to allocate registration transaction (memory or socket error)\n");
07674          return 0;
07675       }
07676       if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY))
07677          append_history(p, "RegistryInit", "Account: %s@%s", r->username, r->hostname);
07678       /* Find address to hostname */
07679       if (create_addr(p, r->hostname)) {
07680          /* we have what we hope is a temporary network error,
07681           * probably DNS.  We need to reschedule a registration try */
07682          sip_destroy(p);
07683 
07684          if (r->timeout > -1)
07685             ast_log(LOG_WARNING, "Still have a registration timeout for %s@%s (create_addr() error), %d\n", r->username, r->hostname, r->timeout);
07686          else
07687             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);
07688 
07689          AST_SCHED_DEL(sched, r->timeout);
07690          r->timeout = ast_sched_add(sched, global_reg_timeout * 1000, sip_reg_timeout, r);
07691          r->regattempts++;
07692          return 0;
07693       }
07694       /* Copy back Call-ID in case create_addr changed it */
07695       ast_string_field_set(r, callid, p->callid);
07696       if (r->portno) {
07697          p->sa.sin_port = htons(r->portno);
07698          p->recv.sin_port = htons(r->portno);
07699       } else   /* Set registry port to the port set from the peer definition/srv or default */
07700          r->portno = ntohs(p->sa.sin_port);
07701       ast_set_flag(&p->flags[0], SIP_OUTGOING); /* Registration is outgoing call */
07702       r->call=p;        /* Save pointer to SIP packet */
07703       p->registry = ASTOBJ_REF(r);  /* Add pointer to registry in packet */
07704       if (!ast_strlen_zero(r->secret)) /* Secret (password) */
07705          ast_string_field_set(p, peersecret, r->secret);
07706       if (!ast_strlen_zero(r->md5secret))
07707          ast_string_field_set(p, peermd5secret, r->md5secret);
07708       /* User name in this realm  
07709       - if authuser is set, use that, otherwise use username */
07710       if (!ast_strlen_zero(r->authuser)) {   
07711          ast_string_field_set(p, peername, r->authuser);
07712          ast_string_field_set(p, authname, r->authuser);
07713       } else if (!ast_strlen_zero(r->username)) {
07714          ast_string_field_set(p, peername, r->username);
07715          ast_string_field_set(p, authname, r->username);
07716          ast_string_field_set(p, fromuser, r->username);
07717       }
07718       if (!ast_strlen_zero(r->username))
07719          ast_string_field_set(p, username, r->username);
07720       /* Save extension in packet */
07721       ast_string_field_set(p, exten, r->contact);
07722 
07723       /*
07724         check which address we should use in our contact header 
07725         based on whether the remote host is on the external or
07726         internal network so we can register through nat
07727        */
07728       if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
07729          p->ourip = bindaddr.sin_addr;
07730       build_contact(p);
07731    }
07732 
07733    /* set up a timeout */
07734    if (auth == NULL)  {
07735       if (r->timeout > -1)
07736          ast_log(LOG_WARNING, "Still have a registration timeout, #%d - deleting it\n", r->timeout);
07737       AST_SCHED_DEL(sched, r->timeout);
07738       r->timeout = ast_sched_add(sched, global_reg_timeout * 1000, sip_reg_timeout, r);
07739       if (option_debug)
07740          ast_log(LOG_DEBUG, "Scheduled a registration timeout for %s id  #%d \n", r->hostname, r->timeout);
07741    }
07742 
07743    if ((fromdomain = strchr(r->username, '@'))) {
07744       /* We have a domain in the username for registration */
07745       snprintf(from, sizeof(from), "<sip:%s>;tag=%s", r->username, p->tag);
07746       if (!ast_strlen_zero(p->theirtag))
07747          snprintf(to, sizeof(to), "<sip:%s>;tag=%s", r->username, p->theirtag);
07748       else
07749          snprintf(to, sizeof(to), "<sip:%s>", r->username);
07750 
07751       /* If the registration username contains '@', then the domain should be used as
07752          the equivalent of "fromdomain" for the registration */
07753       if (ast_strlen_zero(p->fromdomain)) {
07754          ast_string_field_set(p, fromdomain, ++fromdomain);
07755       }
07756    } else {
07757       snprintf(from, sizeof(from), "<sip:%s@%s>;tag=%s", r->username, p->tohost, p->tag);
07758       if (!ast_strlen_zero(p->theirtag))
07759          snprintf(to, sizeof(to), "<sip:%s@%s>;tag=%s", r->username, p->tohost, p->theirtag);
07760       else
07761          snprintf(to, sizeof(to), "<sip:%s@%s>", r->username, p->tohost);
07762    }
07763    
07764    /* Fromdomain is what we are registering to, regardless of actual
07765       host name from SRV */
07766    if (!ast_strlen_zero(p->fromdomain)) {
07767       if (r->portno && r->portno != STANDARD_SIP_PORT)
07768          snprintf(addr, sizeof(addr), "sip:%s:%d", p->fromdomain, r->portno);
07769       else
07770          snprintf(addr, sizeof(addr), "sip:%s", p->fromdomain);
07771    } else {
07772       if (r->portno && r->portno != STANDARD_SIP_PORT)
07773          snprintf(addr, sizeof(addr), "sip:%s:%d", r->hostname, r->portno);
07774       else
07775          snprintf(addr, sizeof(addr), "sip:%s", r->hostname);
07776    }
07777    ast_string_field_set(p, uri, addr);
07778 
07779    p->branch ^= ast_random();
07780 
07781    init_req(&req, sipmethod, addr);
07782 
07783    /* Add to CSEQ */
07784    snprintf(tmp, sizeof(tmp), "%u %s", ++r->ocseq, sip_methods[sipmethod].text);
07785    p->ocseq = r->ocseq;
07786 
07787    build_via(p);
07788    add_header(&req, "Via", p->via);
07789    add_header(&req, "From", from);
07790    add_header(&req, "To", to);
07791    add_header(&req, "Call-ID", p->callid);
07792    add_header(&req, "CSeq", tmp);
07793    if (!ast_strlen_zero(global_useragent))
07794       add_header(&req, "User-Agent", global_useragent);
07795    add_header(&req, "Max-Forwards", DEFAULT_MAX_FORWARDS);
07796 
07797    
07798    if (auth)   /* Add auth header */
07799       add_header(&req, authheader, auth);
07800    else if (!ast_strlen_zero(r->nonce)) {
07801       char digest[1024];
07802 
07803       /* We have auth data to reuse, build a digest header! */
07804       if (sipdebug)
07805          ast_log(LOG_DEBUG, "   >>> Re-using Auth data for %s@%s\n", r->username, r->hostname);
07806       ast_string_field_set(p, realm, r->realm);
07807       ast_string_field_set(p, nonce, r->nonce);
07808       ast_string_field_set(p, domain, r->domain);
07809       ast_string_field_set(p, opaque, r->opaque);
07810       ast_string_field_set(p, qop, r->qop);
07811       r->noncecount++;
07812       p->noncecount = r->noncecount;
07813 
07814       memset(digest,0,sizeof(digest));
07815       if(!build_reply_digest(p, sipmethod, digest, sizeof(digest)))
07816          add_header(&req, "Authorization", digest);
07817       else
07818          ast_log(LOG_NOTICE, "No authorization available for authentication of registration to %s@%s\n", r->username, r->hostname);
07819    
07820    }
07821 
07822    snprintf(tmp, sizeof(tmp), "%d", default_expiry);
07823    add_header(&req, "Expires", tmp);
07824    add_header(&req, "Contact", p->our_contact);
07825    add_header(&req, "Event", "registration");
07826    add_header_contentLength(&req, 0);
07827 
07828    initialize_initreq(p, &req);
07829    if (sip_debug_test_pvt(p))
07830       ast_verbose("REGISTER %d headers, %d lines\n", p->initreq.headers, p->initreq.lines);
07831    r->regstate = auth ? REG_STATE_AUTHSENT : REG_STATE_REGSENT;
07832    r->regattempts++; /* Another attempt */
07833    if (option_debug > 3)
07834       ast_verbose("REGISTER attempt %d to %s@%s\n", r->regattempts, r->username, r->hostname);
07835    return send_request(p, &req, XMIT_CRITICAL, p->ocseq);
07836 }

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

06902 {
06903    struct sip_request req;
06904 
06905    reqprep(&req, p, ast_test_flag(&p->flags[0], SIP_REINVITE_UPDATE) ?  SIP_UPDATE : SIP_INVITE, 0, 1);
06906    
06907    add_header(&req, "Allow", ALLOWED_METHODS);
06908    add_header(&req, "Supported", SUPPORTED_EXTENSIONS);
06909    if (sipdebug)
06910       add_header(&req, "X-asterisk-Info", "SIP re-invite (External RTP bridge)");
06911    if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY))
06912       append_history(p, "ReInv", "Re-invite sent");
06913    add_sdp(&req, p);
06914    /* Use this as the basis */
06915    initialize_initreq(p, &req);
06916    p->lastinvite = p->ocseq;
06917    ast_set_flag(&p->flags[0], SIP_OUTGOING);    /* Change direction of this dialog */
06918    return send_request(p, &req, XMIT_CRITICAL, p->ocseq);
06919 }

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

06926 {
06927    struct sip_request req;
06928 
06929    reqprep(&req, p, ast_test_flag(&p->flags[0], SIP_REINVITE_UPDATE) ?  SIP_UPDATE : SIP_INVITE, 0, 1);
06930    
06931    add_header(&req, "Allow", ALLOWED_METHODS);
06932    add_header(&req, "Supported", SUPPORTED_EXTENSIONS);
06933    if (sipdebug)
06934       add_header(&req, "X-asterisk-info", "SIP re-invite (T38 switchover)");
06935    ast_udptl_offered_from_local(p->udptl, 1);
06936    add_t38_sdp(&req, p);
06937    /* Use this as the basis */
06938    initialize_initreq(p, &req);
06939    ast_set_flag(&p->flags[0], SIP_OUTGOING);    /* Change direction of this dialog */
06940    p->lastinvite = p->ocseq;
06941    return send_request(p, &req, XMIT_CRITICAL, p->ocseq);
06942 }

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

07953 {
07954    struct sip_request resp;
07955 
07956    if (sipmethod == SIP_ACK)
07957       p->invitestate = INV_CONFIRMED;
07958 
07959    reqprep(&resp, p, sipmethod, seqno, newbranch);
07960    add_header_contentLength(&resp, 0);
07961    return send_request(p, &resp, reliable, seqno ? seqno : p->ocseq);
07962 }

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

07966 {
07967    struct sip_request resp;
07968 
07969    reqprep(&resp, p, sipmethod, seqno, newbranch);
07970    if (!ast_strlen_zero(p->realm)) {
07971       char digest[1024];
07972 
07973       memset(digest, 0, sizeof(digest));
07974       if(!build_reply_digest(p, sipmethod, digest, sizeof(digest))) {
07975          if (p->options && p->options->auth_type == PROXY_AUTH)
07976             add_header(&resp, "Proxy-Authorization", digest);
07977          else if (p->options && p->options->auth_type == WWW_AUTH)
07978             add_header(&resp, "Authorization", digest);
07979          else  /* Default, to be backwards compatible (maybe being too careful, but leaving it for now) */
07980             add_header(&resp, "Proxy-Authorization", digest);
07981       } else
07982          ast_log(LOG_WARNING, "No authentication available for call %s\n", p->callid);
07983    }
07984    /* If we are hanging up and know a cause for that, send it in clear text to make
07985       debugging easier. */
07986    if (sipmethod == SIP_BYE && p->owner && p->owner->hangupcause) {
07987       char buf[10];
07988 
07989       add_header(&resp, "X-Asterisk-HangupCause", ast_cause2str(p->owner->hangupcause));
07990       snprintf(buf, sizeof(buf), "%d", p->owner->hangupcause);
07991       add_header(&resp, "X-Asterisk-HangupCauseCode", buf);
07992    }
07993 
07994    add_header_contentLength(&resp, 0);
07995    return send_request(p, &resp, reliable, seqno ? seqno : p->ocseq);   
07996 }

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

Transmit response, no retransmits.

Definition at line 6210 of file chan_sip.c.

References __transmit_response(), and XMIT_UNRELIABLE.

06211 {
06212    return __transmit_response(p, msg, req, XMIT_UNRELIABLE);
06213 }

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 6229 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(), sip_indicate(), and sip_sipredirect().

06230 {
06231    return __transmit_response(p, msg, req, XMIT_CRITICAL);
06232 }

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 6159 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, build_via(), check_via(), do_setnat(), global_flags, INITIAL_CSEQ, LOG_NOTICE, make_our_tag(), SIP_NAT, SIP_NAT_ROUTE, SIP_NO_HISTORY, and XMIT_UNRELIABLE.

06160 {
06161    struct sip_pvt *p = NULL;
06162 
06163    if (!(p = ast_threadstorage_get(&ts_temp_pvt, sizeof(*p)))) {
06164       ast_log(LOG_NOTICE, "Failed to get temporary pvt\n");
06165       return -1;
06166    }
06167 
06168    /* if the structure was just allocated, initialize it */
06169    if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) {
06170       ast_set_flag(&p->flags[0], SIP_NO_HISTORY);
06171       if (ast_string_field_init(p, 512))
06172          return -1;
06173    }
06174 
06175    /* Initialize the bare minimum */
06176    p->method = intended_method;
06177 
06178    if (sin) {
06179       p->sa = *sin;
06180       if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
06181          p->ourip = __ourip;
06182    } else
06183       p->ourip = __ourip;
06184 
06185    p->branch = ast_random();
06186    make_our_tag(p->tag, sizeof(p->tag));
06187    p->ocseq = INITIAL_CSEQ;
06188 
06189    if (useglobal_nat && sin) {
06190       ast_copy_flags(&p->flags[0], &global_flags[0], SIP_NAT);
06191       p->recv = *sin;
06192       do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE);
06193    }
06194    check_via(p, req);
06195 
06196    ast_string_field_set(p, fromdomain, default_fromdomain);
06197    build_via(p);
06198    ast_string_field_set(p, callid, callid);
06199 
06200    /* Use this temporary pvt structure to send the message */
06201    __transmit_response(p, msg, req, XMIT_UNRELIABLE);
06202 
06203    /* Free the string fields, but not the pool space */
06204    ast_string_field_reset_all(p);
06205 
06206    return 0;
06207 }

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

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

Referenced by handle_request(), and handle_request_options().

06258 {
06259    struct sip_request resp;
06260    respprep(&resp, p, msg, req);
06261    add_header(&resp, "Accept", "application/sdp");
06262    add_header_contentLength(&resp, 0);
06263    return send_response(p, &resp, reliable, 0);
06264 }

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

References add_header(), add_header_contentLength(), append_history, ast_log(), get_header(), sip_pvt::noncecount, respprep(), and send_response().

Referenced by check_auth(), and transmit_fake_auth_response().

06268 {
06269    struct sip_request resp;
06270    char tmp[512];
06271    int seqno = 0;
06272 
06273    if (reliable && (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1)) {
06274       ast_log(LOG_WARNING, "Unable to determine sequence number from '%s'\n", get_header(req, "CSeq"));
06275       return -1;
06276    }
06277    /* Stale means that they sent us correct authentication, but 
06278       based it on an old challenge (nonce) */
06279    snprintf(tmp, sizeof(tmp), "Digest algorithm=MD5, realm=\"%s\", nonce=\"%s\"%s", global_realm, randdata, stale ? ", stale=true" : "");
06280    respprep(&resp, p, msg, req);
06281    add_header(&resp, header, tmp);
06282    add_header_contentLength(&resp, 0);
06283    append_history(p, "AuthChal", "Auth challenge sent for %s - nc %d", p->username, p->noncecount);
06284    return send_response(p, &resp, reliable, seqno);
06285 }

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

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

Referenced by register_verify().

06248 {
06249    struct sip_request resp;
06250    respprep(&resp, p, msg, req);
06251    append_date(&resp);
06252    add_header_contentLength(&resp, 0);
06253    return send_response(p, &resp, XMIT_UNRELIABLE, 0);
06254 }

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

06831 {
06832    struct sip_request resp;
06833    int seqno;
06834    if (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1) {
06835       ast_log(LOG_WARNING, "Unable to get seqno from '%s'\n", get_header(req, "CSeq"));
06836       return -1;
06837    }
06838    respprep(&resp, p, msg, req);
06839    if (p->rtp) {
06840       if (!p->autoframing && !ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
06841          if (option_debug)
06842             ast_log(LOG_DEBUG, "Setting framing from config on incoming call\n");
06843          ast_rtp_codec_setpref(p->rtp, &p->prefs);
06844       }
06845       try_suggested_sip_codec(p);   
06846       add_sdp(&resp, p);
06847    } else 
06848       ast_log(LOG_ERROR, "Can't add SDP to response, since we have no RTP session allocated. Call-ID %s\n", p->callid);
06849    if (reliable && !p->pendinginvite)
06850       p->pendinginvite = seqno;     /* Buggy clients sends ACK on RINGING too */
06851    return send_response(p, &resp, reliable, seqno);
06852 }

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

References add_t38_sdp(), ast_log(), ast_udptl_offered_from_local(), get_header(), LOG_ERROR, sip_pvt::pendinginvite, respprep(), send_response(), and sip_pvt::udptl.

Referenced by handle_request_invite(), sip_answer(), and sip_handle_t38_reinvite().

06791 {
06792    struct sip_request resp;
06793    int seqno;
06794    
06795    if (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1) {
06796       ast_log(LOG_WARNING, "Unable to get seqno from '%s'\n", get_header(req, "CSeq"));
06797       return -1;
06798    }
06799    respprep(&resp, p, msg, req);
06800    if (p->udptl) {
06801       ast_udptl_offered_from_local(p->udptl, 0);
06802       add_t38_sdp(&resp, p);
06803    } else 
06804       ast_log(LOG_ERROR, "Can't add SDP to response, since we have no UDPTL session allocated. Call-ID %s\n", p->callid);
06805    if (retrans && !p->pendinginvite)
06806       p->pendinginvite = seqno;     /* Buggy clients sends ACK on RINGING too */
06807    return send_response(p, &resp, retrans, seqno);
06808 }

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

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

Referenced by handle_request_invite().

06217 {
06218    struct sip_request resp;
06219    respprep(&resp, p, msg, req);
06220    append_date(&resp);
06221    add_header(&resp, "Unsupported", unsupported);
06222    add_header_contentLength(&resp, 0);
06223    return send_response(p, &resp, XMIT_UNRELIABLE, 0);
06224 }

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

07506 {
07507    if (!p->initreq.headers)   /* Initialize first request before sending */
07508       initialize_initreq(p, req);
07509    return send_request(p, req, XMIT_UNRELIABLE, p->ocseq);
07510 }

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 7279 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, sip_pvt::expiry, find_subscription_type(), get_header(), get_in_brackets(), sip_pvt::initreq, 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().

07280 {
07281    char tmp[4000], from[256], to[256];
07282    char *t = tmp, *c, *mfrom, *mto;
07283    size_t maxbytes = sizeof(tmp);
07284    struct sip_request req;
07285    char hint[AST_MAX_EXTENSION];
07286    char *statestring = "terminated";
07287    const struct cfsubscription_types *subscriptiontype;
07288    enum state { NOTIFY_OPEN, NOTIFY_INUSE, NOTIFY_CLOSED } local_state = NOTIFY_OPEN;
07289    char *pidfstate = "--";
07290    char *pidfnote= "Ready";
07291 
07292    memset(from, 0, sizeof(from));
07293    memset(to, 0, sizeof(to));
07294    memset(tmp, 0, sizeof(tmp));
07295 
07296    switch (state) {
07297    case (AST_EXTENSION_RINGING | AST_EXTENSION_INUSE):
07298       statestring = (global_notifyringing) ? "early" : "confirmed";
07299       local_state = NOTIFY_INUSE;
07300       pidfstate = "busy";
07301       pidfnote = "Ringing";
07302       break;
07303    case AST_EXTENSION_RINGING:
07304       statestring = "early";
07305       local_state = NOTIFY_INUSE;
07306       pidfstate = "busy";
07307       pidfnote = "Ringing";
07308       break;
07309    case AST_EXTENSION_INUSE:
07310       statestring = "confirmed";
07311       local_state = NOTIFY_INUSE;
07312       pidfstate = "busy";
07313       pidfnote = "On the phone";
07314       break;
07315    case AST_EXTENSION_BUSY:
07316       statestring = "confirmed";
07317       local_state = NOTIFY_CLOSED;
07318       pidfstate = "busy";
07319       pidfnote = "On the phone";
07320       break;
07321    case AST_EXTENSION_UNAVAILABLE:
07322       statestring = "terminated";
07323       local_state = NOTIFY_CLOSED;
07324       pidfstate = "away";
07325       pidfnote = "Unavailable";
07326       break;
07327    case AST_EXTENSION_ONHOLD:
07328       statestring = "confirmed";
07329       local_state = NOTIFY_CLOSED;
07330       pidfstate = "busy";
07331       pidfnote = "On Hold";
07332       break;
07333    case AST_EXTENSION_NOT_INUSE:
07334    default:
07335       /* Default setting */
07336       break;
07337    }
07338 
07339    subscriptiontype = find_subscription_type(p->subscribed);
07340    
07341    /* Check which device/devices we are watching  and if they are registered */
07342    if (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, p->context, p->exten)) {
07343       char *hint2 = hint, *individual_hint = NULL;
07344       int hint_count = 0, unavailable_count = 0;
07345 
07346       while ((individual_hint = strsep(&hint2, "&"))) {
07347          hint_count++;
07348 
07349          if (ast_device_state(individual_hint) == AST_DEVICE_UNAVAILABLE)
07350             unavailable_count++;
07351       }
07352 
07353       /* If none of the hinted devices are registered, we will
07354        * override notification and show no availability.
07355        */
07356       if (hint_count > 0 && hint_count == unavailable_count) {
07357          local_state = NOTIFY_CLOSED;
07358          pidfstate = "away";
07359          pidfnote = "Not online";
07360       }
07361    }
07362 
07363    ast_copy_string(from, get_header(&p->initreq, "From"), sizeof(from));
07364    c = get_in_brackets(from);
07365    if (strncasecmp(c, "sip:", 4)) {
07366       ast_log(LOG_WARNING, "Huh?  Not a SIP header (%s)?\n", c);
07367       return -1;
07368    }
07369    mfrom = strsep(&c, ";");   /* trim ; and beyond */
07370 
07371    ast_copy_string(to, get_header(&p->initreq, "To"), sizeof(to));
07372    c = get_in_brackets(to);
07373    if (strncasecmp(c, "sip:", 4)) {
07374       ast_log(LOG_WARNING, "Huh?  Not a SIP header (%s)?\n", c);
07375       return -1;
07376    }
07377    mto = strsep(&c, ";");  /* trim ; and beyond */
07378 
07379    reqprep(&req, p, SIP_NOTIFY, 0, 1);
07380 
07381    
07382    add_header(&req, "Event", subscriptiontype->event);
07383    add_header(&req, "Content-Type", subscriptiontype->mediatype);
07384    switch(state) {
07385    case AST_EXTENSION_DEACTIVATED:
07386       if (timeout)
07387          add_header(&req, "Subscription-State", "terminated;reason=timeout");
07388       else {
07389          add_header(&req, "Subscription-State", "terminated;reason=probation");
07390          add_header(&req, "Retry-After", "60");
07391       }
07392       break;
07393    case AST_EXTENSION_REMOVED:
07394       add_header(&req, "Subscription-State", "terminated;reason=noresource");
07395       break;
07396    default:
07397       if (p->expiry)
07398          add_header(&req, "Subscription-State", "active");
07399       else  /* Expired */
07400          add_header(&req, "Subscription-State", "terminated;reason=timeout");
07401    }
07402    switch (p->subscribed) {
07403    case XPIDF_XML:
07404    case CPIM_PIDF_XML:
07405       ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\"?>\n");
07406       ast_build_string(&t, &maxbytes, "<!DOCTYPE presence PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n");
07407       ast_build_string(&t, &maxbytes, "<presence>\n");
07408       ast_build_string(&t, &maxbytes, "<presentity uri=\"%s;method=SUBSCRIBE\" />\n", mfrom);
07409       ast_build_string(&t, &maxbytes, "<atom id=\"%s\">\n", p->exten);
07410       ast_build_string(&t, &maxbytes, "<address uri=\"%s;user=ip\" priority=\"0.800000\">\n", mto);
07411       ast_build_string(&t, &maxbytes, "<status status=\"%s\" />\n", (local_state ==  NOTIFY_OPEN) ? "open" : (local_state == NOTIFY_INUSE) ? "inuse" : "closed");
07412       ast_build_string(&t, &maxbytes, "<msnsubstatus substatus=\"%s\" />\n", (local_state == NOTIFY_OPEN) ? "online" : (local_state == NOTIFY_INUSE) ? "onthephone" : "offline");
07413       ast_build_string(&t, &maxbytes, "</address>\n</atom>\n</presence>\n");
07414       break;
07415    case PIDF_XML: /* Eyebeam supports this format */
07416       ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n");
07417       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);
07418       ast_build_string(&t, &maxbytes, "<pp:person><status>\n");
07419       if (pidfstate[0] != '-')
07420          ast_build_string(&t, &maxbytes, "<ep:activities><ep:%s/></ep:activities>\n", pidfstate);
07421       ast_build_string(&t, &maxbytes, "</status></pp:person>\n");
07422       ast_build_string(&t, &maxbytes, "<note>%s</note>\n", pidfnote); /* Note */
07423       ast_build_string(&t, &maxbytes, "<tuple id=\"%s\">\n", p->exten); /* Tuple start */
07424       ast_build_string(&t, &maxbytes, "<contact priority=\"1\">%s</contact>\n", mto);
07425       if (pidfstate[0] == 'b') /* Busy? Still open ... */
07426          ast_build_string(&t, &maxbytes, "<status><basic>open</basic></status>\n");
07427       else
07428          ast_build_string(&t, &maxbytes, "<status><basic>%s</basic></status>\n", (local_state != NOTIFY_CLOSED) ? "open" : "closed");
07429       ast_build_string(&t, &maxbytes, "</tuple>\n</presence>\n");
07430       break;
07431    case DIALOG_INFO_XML: /* SNOM subscribes in this format */
07432       ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\"?>\n");
07433       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);
07434       if ((state & AST_EXTENSION_RINGING) && global_notifyringing)
07435          ast_build_string(&t, &maxbytes, "<dialog id=\"%s\" direction=\"recipient\">\n", p->exten);
07436       else
07437          ast_build_string(&t, &maxbytes, "<dialog id=\"%s\">\n", p->exten);
07438       ast_build_string(&t, &maxbytes, "<state>%s</state>\n", statestring);
07439       if (state == AST_EXTENSION_ONHOLD) {
07440          ast_build_string(&t, &maxbytes, "<local>\n<target uri=\"%s\">\n"
07441                                          "<param pname=\"+sip.rendering\" pvalue=\"no\"/>\n"
07442                                          "</target>\n</local>\n", mto);
07443       }
07444       ast_build_string(&t, &maxbytes, "</dialog>\n</dialog-info>\n");
07445       break;
07446    case NONE:
07447    default:
07448       break;
07449    }
07450 
07451    if (t > tmp + sizeof(tmp))
07452       ast_log(LOG_WARNING, "Buffer overflow detected!!  (Please file a bug report)\n");
07453 
07454    add_header_contentLength(&req, strlen(tmp));
07455    add_line(&req, tmp);
07456    p->pendinginvite = p->ocseq;  /* Remember that we have a pending NOTIFY in order not to confuse the NOTIFY subsystem */
07457 
07458    return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
07459 }

static void try_suggested_sip_codec ( struct sip_pvt p  )  [static]

Try setting codec suggested by the SIP_CODEC channel variable.

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

03685 {
03686    int fmt;
03687    const char *codec;
03688 
03689    codec = pbx_builtin_getvar_helper(p->owner, "SIP_CODEC");
03690    if (!codec) 
03691       return;
03692 
03693    fmt = ast_getformatbyname(codec);
03694    if (fmt) {
03695       ast_log(LOG_NOTICE, "Changing codec to '%s' for this call because of ${SIP_CODEC} variable\n", codec);
03696       if (p->jointcapability & fmt) {
03697          p->jointcapability &= fmt;
03698          p->capability &= fmt;
03699       } else
03700          ast_log(LOG_NOTICE, "Ignoring ${SIP_CODEC} variable because it is not shared by both ends.\n");
03701    } else
03702       ast_log(LOG_NOTICE, "Ignoring ${SIP_CODEC} variable because of unrecognized/not configured codec (check allow/disallow in sip.conf): %s\n", codec);
03703    return;  
03704 }

static int unload_module ( void   )  [static]

PBX unload module API.

Definition at line 18756 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, checksipdomain_function, clear_realm_authentication(), clear_sip_domains(), cli_sip, iflist, localaddr, sip_pvt::next, sip_pvt::owner, peerl, regl, sched, sched_context_destroy(), sip_destroy_peer(), sip_destroy_user(), sip_header_function, sip_registry_destroy(), sip_rtp, sip_tech, sip_udptl, sipchaninfo_function, sippeer_function, sipsock, siptcpsock, TRUE, and userl.

18757 {
18758    struct sip_pvt *p, *pl;
18759    
18760    /* First, take us out of the channel type list */
18761    ast_channel_unregister(&sip_tech);
18762 
18763    /* Unregister dial plan functions */
18764    ast_custom_function_unregister(&sipchaninfo_function);
18765    ast_custom_function_unregister(&sippeer_function);
18766    ast_custom_function_unregister(&sip_header_function);
18767    ast_custom_function_unregister(&checksipdomain_function);
18768 
18769    /* Unregister dial plan applications */
18770    ast_unregister_application(app_dtmfmode);
18771    ast_unregister_application(app_sipaddheader);
18772 
18773    /* Unregister CLI commands */
18774    ast_cli_unregister_multiple(cli_sip, sizeof(cli_sip) / sizeof(struct ast_cli_entry));
18775 
18776    /* Disconnect from the RTP subsystem */
18777    ast_rtp_proto_unregister(&sip_rtp);
18778 
18779    /* Disconnect from UDPTL */
18780    ast_udptl_proto_unregister(&sip_udptl);
18781 
18782    /* Unregister AMI actions */
18783    ast_manager_unregister("SIPpeers");
18784    ast_manager_unregister("SIPshowpeer");
18785 
18786    ast_mutex_lock(&iflock);
18787    /* Hangup all interfaces if they have an owner */
18788    for (p = iflist; p ; p = p->next) {
18789       if (p->owner)
18790          ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD);
18791    }
18792    ast_mutex_unlock(&iflock);
18793 
18794    ast_mutex_lock(&monlock);
18795    if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP) && (monitor_thread != AST_PTHREADT_NULL)) {
18796       pthread_cancel(monitor_thread);
18797       pthread_kill(monitor_thread, SIGURG);
18798       pthread_join(monitor_thread, NULL);
18799    }
18800    monitor_thread = AST_PTHREADT_STOP;
18801    ast_mutex_unlock(&monlock);
18802 
18803 restartdestroy:
18804    ast_mutex_lock(&iflock);
18805    /* Destroy all the interfaces and free their memory */
18806    p = iflist;
18807    while (p) {
18808       pl = p;
18809       p = p->next;
18810       if (__sip_destroy(pl, TRUE) < 0) {
18811          /* Something is still bridged, let it react to getting a hangup */
18812          iflist = p;
18813          ast_mutex_unlock(&iflock);
18814          usleep(1);
18815          goto restartdestroy;
18816       }
18817    }
18818    iflist = NULL;
18819    ast_mutex_unlock(&iflock);
18820 
18821    /* Free memory for local network address mask */
18822    ast_free_ha(localaddr);
18823 
18824    ASTOBJ_CONTAINER_DESTROYALL(&userl, sip_destroy_user);
18825    ASTOBJ_CONTAINER_DESTROY(&userl);
18826    ASTOBJ_CONTAINER_DESTROYALL(&peerl, sip_destroy_peer);
18827    ASTOBJ_CONTAINER_DESTROY(&peerl);
18828    ASTOBJ_CONTAINER_DESTROYALL(&regl, sip_registry_destroy);
18829    ASTOBJ_CONTAINER_DESTROY(&regl);
18830 
18831    clear_realm_authentication(authl);
18832    clear_sip_domains();
18833    close(sipsock);
18834    close(siptcpsock);
18835    sched_context_destroy(sched);
18836       
18837    return 0;
18838 }

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

03236 {
03237    char name[256];
03238    int *inuse = NULL, *call_limit = NULL, *inringing = NULL;
03239    int outgoing = ast_test_flag(&fup->flags[1], SIP_PAGE2_OUTGOING_CALL);
03240    struct sip_user *u = NULL;
03241    struct sip_peer *p = NULL;
03242 
03243    if (option_debug > 2)
03244       ast_log(LOG_DEBUG, "Updating call counter for %s call\n", outgoing ? "outgoing" : "incoming");
03245 
03246    /* Test if we need to check call limits, in order to avoid 
03247       realtime lookups if we do not need it */
03248    if (!ast_test_flag(&fup->flags[0], SIP_CALL_LIMIT) && !ast_test_flag(&fup->flags[1], SIP_PAGE2_CALL_ONHOLD))
03249       return 0;
03250 
03251    ast_copy_string(name, fup->username, sizeof(name));
03252 
03253    /* Check the list of users only for incoming calls */
03254    if (global_limitonpeers == FALSE && !outgoing && (u = find_user(name, 1)))  {
03255       inuse = &u->inUse;
03256       call_limit = &u->call_limit;
03257       inringing = NULL;
03258    } else if ( (p = find_peer(ast_strlen_zero(fup->peername) ? name : fup->peername, NULL, 1, 0) ) ) { /* Try to find peer */
03259       inuse = &p->inUse;
03260       call_limit = &p->call_limit;
03261       inringing = &p->inRinging;
03262       ast_copy_string(name, fup->peername, sizeof(name));
03263    } 
03264    if (!p && !u) {
03265       if (option_debug > 1)
03266          ast_log(LOG_DEBUG, "%s is not a local device, no call limit\n", name);
03267       return 0;
03268    }
03269 
03270    switch(event) {
03271    /* incoming and outgoing affects the inUse counter */
03272    case DEC_CALL_LIMIT:
03273       if ( *inuse > 0 ) {
03274          if (ast_test_flag(&fup->flags[0], SIP_INC_COUNT)) {
03275             (*inuse)--;
03276             ast_clear_flag(&fup->flags[0], SIP_INC_COUNT);
03277          }
03278       } else {
03279          *inuse = 0;
03280       }
03281       if (inringing) {
03282          if (ast_test_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING)) {
03283             if (*inringing > 0)
03284                (*inringing)--;
03285             else if (!ast_test_flag(&p->flags[0], SIP_REALTIME) || ast_test_flag(&p->flags[1], SIP_PAGE2_RTCACHEFRIENDS))
03286                ast_log(LOG_WARNING, "Inringing for peer '%s' < 0?\n", fup->peername);
03287             ast_clear_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING);
03288          }
03289       }
03290       if (ast_test_flag(&fup->flags[1], SIP_PAGE2_CALL_ONHOLD) && global_notifyhold) {
03291          ast_clear_flag(&fup->flags[1], SIP_PAGE2_CALL_ONHOLD);
03292          sip_peer_hold(fup, 0);
03293       }
03294       if (option_debug > 1 || sipdebug) {
03295          ast_log(LOG_DEBUG, "Call %s %s '%s' removed from call limit %d\n", outgoing ? "to" : "from", u ? "user":"peer", name, *call_limit);
03296       }
03297       break;
03298 
03299    case INC_CALL_RINGING:
03300    case INC_CALL_LIMIT:
03301       if (*call_limit > 0 ) {
03302          /* Let call limit affect only outgoing calls */
03303          if (outgoing && (*inuse >= *call_limit)) {
03304             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);
03305             if (u)
03306                ASTOBJ_UNREF(u, sip_destroy_user);
03307             else
03308                ASTOBJ_UNREF(p, sip_destroy_peer);
03309             return -1; 
03310          }
03311       }
03312       if (inringing && (event == INC_CALL_RINGING)) {
03313          if (!ast_test_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING)) {
03314             (*inringing)++;
03315             ast_set_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING);
03316          }
03317       }
03318       /* Continue */
03319       (*inuse)++;
03320       ast_set_flag(&fup->flags[0], SIP_INC_COUNT);
03321       if (option_debug > 1 || sipdebug) {
03322          ast_log(LOG_DEBUG, "Call %s %s '%s' is %d out of %d\n", outgoing ? "to" : "from", u ? "user":"peer", name, *inuse, *call_limit);
03323       }
03324       break;
03325 
03326    case DEC_CALL_RINGING:
03327       if (inringing) {
03328          if (ast_test_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING)) {
03329             if (*inringing > 0)
03330                (*inringing)--;
03331             else if (!ast_test_flag(&p->flags[0], SIP_REALTIME) || ast_test_flag(&p->flags[1], SIP_PAGE2_RTCACHEFRIENDS))
03332                ast_log(LOG_WARNING, "Inringing for peer '%s' < 0?\n", p->name);
03333             ast_clear_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING);
03334          }
03335       }
03336       break;
03337 
03338    default:
03339       ast_log(LOG_ERROR, "update_call_counter(%s, %d) called with no event!\n", name, event);
03340    }
03341    if (p) {
03342       ast_device_state_changed("SIP/%s", p->name);
03343       ASTOBJ_UNREF(p, sip_destroy_peer);
03344    } else /* u must be set */
03345       ASTOBJ_UNREF(u, sip_destroy_user);
03346    return 0;
03347 }

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

Update peer data in database (if used).

Definition at line 2516 of file chan_sip.c.

References sip_peer::addr, ast_test_flag, sip_peer::flags, sip_peer::fullcontact, global_flags, realtime_update_peer(), SIP_PAGE2_RTCACHEFRIENDS, SIP_PAGE2_RTUPDATE, SIP_REALTIME, and sip_peer::username.

Referenced by register_verify().

02517 {
02518    int rtcachefriends = ast_test_flag(&p->flags[1], SIP_PAGE2_RTCACHEFRIENDS);
02519    if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTUPDATE) &&
02520        (ast_test_flag(&p->flags[0], SIP_REALTIME) || rtcachefriends)) {
02521       realtime_update_peer(p->name, &p->addr, p->username, rtcachefriends ? p->fullcontact : NULL, expiry);
02522    }
02523 }


Variable Documentation

struct in_addr __ourip [static]

Definition at line 1222 of file chan_sip.c.

int allow_external_domains [static]

Accept calls to external SIP domains?

Definition at line 565 of file chan_sip.c.

int apeerobjs = 0 [static]

Autocreated peer objects

Definition at line 581 of file chan_sip.c.

char* app_dtmfmode = "SIPDtmfMode" [static]

Definition at line 18320 of file chan_sip.c.

char* app_sipaddheader = "SIPAddHeader" [static]

Definition at line 18322 of file chan_sip.c.

struct sip_auth* authl = NULL [static]

Definition at line 1210 of file chan_sip.c.

Referenced by build_reply_digest(), reload_config(), sip_show_settings(), and unload_module().

int autocreatepeer [static]

Auto creation of peers at registration? Default off.

Definition at line 545 of file chan_sip.c.

struct sockaddr_in bindaddr = { 0, } [static]

The address we bind to

Definition at line 1216 of file chan_sip.c.

struct ast_custom_function checksipdomain_function [static]

Definition at line 11986 of file chan_sip.c.

Referenced by load_module(), and unload_module().

struct ast_cli_entry cli_sip[] [static]

Definition at line 18592 of file chan_sip.c.

Referenced by load_module(), and unload_module().

struct ast_cli_entry cli_sip_debug_deprecated [static]

Initial value:

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

Definition at line 18582 of file chan_sip.c.

struct ast_cli_entry cli_sip_no_debug_deprecated [static]

Initial value:

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

Definition at line 18587 of file chan_sip.c.

int compactheaders [static]

send compact sip headers

Definition at line 559 of file chan_sip.c.

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

Definition at line 231 of file chan_sip.c.

char debug_usage[] [static]

Definition at line 11870 of file chan_sip.c.

struct sockaddr_in debugaddr [static]

Definition at line 1225 of file chan_sip.c.

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

char default_callerid[AST_MAX_EXTENSION] [static]

Definition at line 525 of file chan_sip.c.

char default_context[AST_MAX_CONTEXT] [static]

Definition at line 522 of file chan_sip.c.

int default_expiry = DEFAULT_DEFAULT_EXPIRY [static]

Definition at line 192 of file chan_sip.c.

char default_fromdomain[AST_MAX_EXTENSION] [static]

Definition at line 526 of file chan_sip.c.

struct ast_jb_conf default_jbconf [static]

Global jitterbuffer configuration - by default, jb is disabled.

Definition at line 222 of file chan_sip.c.

char default_language[MAX_LANGUAGE] [static]

Definition at line 524 of file chan_sip.c.

int default_maxcallbitrate [static]

Maximum bitrate for call

Definition at line 533 of file chan_sip.c.

char default_mohinterpret[MAX_MUSICCLASS] [static]

Global setting for moh class to use when put on hold

Definition at line 530 of file chan_sip.c.

char default_mohsuggest[MAX_MUSICCLASS] [static]

Global setting for moh class to suggest when putting a bridged channel on hold

Definition at line 531 of file chan_sip.c.

char default_notifymime[AST_MAX_EXTENSION] [static]

Definition at line 527 of file chan_sip.c.

struct ast_codec_pref default_prefs [static]

Default codec prefs

Definition at line 534 of file chan_sip.c.

Referenced by build_device(), build_user(), reload_config(), set_peer_defaults(), sip_alloc(), sip_show_settings(), and temp_peer().

int default_qualify [static]

Default Qualify= setting

Definition at line 528 of file chan_sip.c.

char default_subscribecontext[AST_MAX_CONTEXT] [static]

Definition at line 523 of file chan_sip.c.

char default_vmexten[AST_MAX_EXTENSION] [static]

Definition at line 529 of file chan_sip.c.

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

Definition at line 18319 of file chan_sip.c.

char* descrip_sipaddheader [static]

Definition at line 18325 of file chan_sip.c.

int dumphistory [static]

Dump history to verbose before destroying SIP dialog

Definition at line 561 of file chan_sip.c.

int expiry = DEFAULT_EXPIRY [static]

Definition at line 193 of file chan_sip.c.

Referenced by complete_dpreply().

time_t externexpire = 0 [static]

Expiration counter for re-resolving external host name in dynamic DNS

Definition at line 1219 of file chan_sip.c.

Referenced by ast_sip_ouraddrfor().

char externhost[MAXHOSTNAMELEN] [static]

External host name (possibly with dynamic DNS and DHCP

Definition at line 1218 of file chan_sip.c.

Referenced by ast_sip_ouraddrfor().

struct sockaddr_in externip [static]

External IP address if we are behind NAT

Definition at line 1217 of file chan_sip.c.

int externrefresh = 10 [static]

Definition at line 1220 of file chan_sip.c.

Referenced by ast_sip_ouraddrfor().

int global_allowguest [static]

allow unauthenticated users/peers to connect?

Definition at line 552 of file chan_sip.c.

int global_allowsubscribe [static]

Flag for disabling ALL subscriptions, this is FALSE only if all peers are FALSE the global setting is in globals_flags[1]

Definition at line 553 of file chan_sip.c.

enum transfermodes global_allowtransfer [static]

SIP Refer restriction scheme

Definition at line 569 of file chan_sip.c.

int global_alwaysauthreject [static]

Send 401 Unauthorized for all failing requests

Definition at line 542 of file chan_sip.c.

int global_autoframing [static]

Turn autoframing on or off.

Definition at line 568 of file chan_sip.c.

int global_callevents [static]

Whether we send manager events or not

Definition at line 566 of file chan_sip.c.

int global_capability = AST_FORMAT_ULAW | AST_FORMAT_ALAW | AST_FORMAT_GSM | AST_FORMAT_H263 [static]

Codecs that we support by default:.

Definition at line 574 of file chan_sip.c.

int global_directrtpsetup [static]

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

Definition at line 537 of file chan_sip.c.

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

global SIP_ flags

Definition at line 584 of file chan_sip.c.

Referenced by build_peer(), build_radius_record(), build_user(), destroy_association(), get_destination(), load_module(), realtime_update_peer(), set_peer_defaults(), sip_alloc(), sip_do_debug(), sip_do_debug_deprecated(), sip_do_debug_ip(), sip_do_debug_peer(), sip_no_debug(), sip_no_debug_deprecated(), sip_show_settings(), transmit_response_using_temp(), and update_peer().

struct ast_jb_conf global_jbconf [static]

Definition at line 229 of file chan_sip.c.

int global_limitonpeers [static]

Match call limit on peers only

Definition at line 538 of file chan_sip.c.

int global_matchexterniplocally [static]

Match externip/externhost setting against localnet setting

Definition at line 571 of file chan_sip.c.

int global_mwitime [static]

Time between MWI checks for peers

Definition at line 555 of file chan_sip.c.

int global_notifyhold [static]

Send notifications on hold

Definition at line 541 of file chan_sip.c.

int global_notifyringing [static]

Send notifications on ringing

Definition at line 540 of file chan_sip.c.

char global_realm[MAXHOSTNAMELEN] [static]

Default realm

Definition at line 562 of file chan_sip.c.

int global_reg_timeout [static]

Definition at line 550 of file chan_sip.c.

int global_regattempts_max [static]

Registration attempts before giving up

Definition at line 551 of file chan_sip.c.

char global_regcontext[AST_MAX_CONTEXT] [static]

Context for auto-extensions

Definition at line 563 of file chan_sip.c.

int global_relaxdtmf [static]

Relax DTMF

Definition at line 546 of file chan_sip.c.

int global_rtautoclear [static]

Definition at line 539 of file chan_sip.c.

int global_rtpholdtimeout [static]

Definition at line 548 of file chan_sip.c.

int global_rtpkeepalive [static]

Send RTP keepalives

Definition at line 549 of file chan_sip.c.

int global_rtptimeout [static]

Time out call if no RTP

Definition at line 547 of file chan_sip.c.

int global_t1min [static]

T1 roundtrip time minimum

Definition at line 567 of file chan_sip.c.

int global_t38_capability = T38FAX_VERSION_0 | T38FAX_RATE_2400 | T38FAX_RATE_4800 | T38FAX_RATE_7200 | T38FAX_RATE_9600 [static]

Definition at line 838 of file chan_sip.c.

Referenced by create_addr_from_peer(), and sip_alloc().

unsigned int global_tos_audio [static]

IP type of service for audio RTP packets

Definition at line 557 of file chan_sip.c.

unsigned int global_tos_sip [static]

IP type of service for SIP packets

Definition at line 556 of file chan_sip.c.

unsigned int global_tos_video [static]

IP type of service for video RTP packets

Definition at line 558 of file chan_sip.c.

char global_useragent[AST_MAX_EXTENSION] [static]

Useragent for the SIP channel

Definition at line 564 of file chan_sip.c.

char history_usage[] [static]

Initial value:

 
"Usage: sip history\n"
"       Enables recording of SIP dialog history for debugging purposes.\n"
"Use 'sip show history' to view the history of a call number.\n"

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

struct ast_ha* localaddr [static]

List of local networks, on the same side of NAT as this Asterisk

Definition at line 1221 of file chan_sip.c.

Referenced by ast_sip_ouraddrfor(), 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 10498 of file chan_sip.c.

char mandescr_show_peers[] [static]

Initial value:

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

Definition at line 10049 of file chan_sip.c.

int max_expiry = DEFAULT_MAX_EXPIRY [static]

Maximum accepted registration time

Definition at line 191 of file chan_sip.c.

int min_expiry = DEFAULT_MIN_EXPIRY [static]

Minimum accepted registration time

Definition at line 190 of file chan_sip.c.

pthread_t monitor_thread = AST_PTHREADT_NULL [static]

This is the thread for the monitor which checks for input on the channels which are not currently in use.

Definition at line 599 of file chan_sip.c.

char no_debug_usage[] [static]

Initial value:

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

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

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

Definition at line 232 of file chan_sip.c.

struct ast_config* notify_types [static]

The list of manual NOTIFY types we know how to send

Definition at line 1227 of file chan_sip.c.

Referenced by complete_sipnotify(), 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 11819 of file chan_sip.c.

int ourport [static]

Definition at line 1224 of file chan_sip.c.

struct sockaddr_in outboundproxyip [static]

Definition at line 1223 of file chan_sip.c.

int pedanticsipchecking [static]

Extra checking ? Default off

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

int recordhistory [static]

Record SIP history. Off by default

Definition at line 560 of file chan_sip.c.

struct c_referstatusstring referstatusstrings[] [static]

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

int rpeerobjs = 0 [static]

Realtime peers

Definition at line 580 of file chan_sip.c.

int ruserobjs = 0 [static]

Realtime users

Definition at line 578 of file chan_sip.c.

struct sched_context* sched [static]

The scheduling context

Definition at line 604 of file chan_sip.c.

char show_channel_usage[] [static]

Initial value:

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

Definition at line 11843 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 11839 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 11814 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 11847 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 11834 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 11900 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 11856 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 11851 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 11866 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 11904 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 11896 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 11829 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 11824 of file chan_sip.c.

struct ast_custom_function sip_header_function [static]

Definition at line 11962 of file chan_sip.c.

Referenced by load_module(), and unload_module().

struct cfsip_methods sip_methods[] [static]

XXX Note that sip_methods[i].id == i must hold or the code breaks

Referenced by __sip_ack(), __sip_autodestruct(), __sip_destroy(), __sip_pretend_ack(), __sip_semi_ack(), build_reply_digest(), check_auth(), do_proxy_auth(), find_sip_method(), get_destination(), handle_request(), handle_request_subscribe(), handle_response(), init_req(), initreqprep(), method_match(), reqprep(), retrans_pkt(), send_request(), send_response(), sip_alloc(), sip_scheddestroy(), and transmit_register().

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

int sip_reloading = FALSE [static]

Flag for avoiding multiple reloads at the same time

Definition at line 601 of file chan_sip.c.

enum channelreloadreason sip_reloadreason [static]

Reason for last reload/load of configuration

Definition at line 602 of file chan_sip.c.

struct ast_rtp_protocol sip_rtp [static]

Interface structure with callbacks used to connect to RTP module.

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

struct ast_channel_tech sip_tech_info [static]

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

Referenced by load_module(), and unload_module().

struct ast_custom_function sipchaninfo_function [static]

Structure to declare a dialplan function: SIPCHANINFO.

Definition at line 12141 of file chan_sip.c.

Referenced by load_module(), and unload_module().

struct ast_custom_function sippeer_function

Structure to declare a dialplan function: SIPPEER.

Definition at line 12061 of file chan_sip.c.

Referenced by load_module(), and unload_module().

int sipsock = -1 [static]

Main socket for SIP network communication UDP

Definition at line 1214 of file chan_sip.c.

Referenced by __sip_xmit(), do_monitor(), reg_source_db(), sipsock_read(), and unload_module().

int* sipsock_read_id [static]

ID of IO entry for sipsock FD

Definition at line 606 of file chan_sip.c.

int siptcpsock = -1 [static]

Main socket for SIP network communication TCP

Definition at line 1215 of file chan_sip.c.

Referenced by do_monitor(), reg_source_db(), siptcpsock_accept(), and unload_module().

int* siptcpsock_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 579 of file chan_sip.c.

int srvlookup [static]

SRV Lookup on or off. Default is on

Definition at line 543 of file chan_sip.c.

struct cfsubscription_types subscription_types[] [static]

Referenced by find_subscription_type(), and subscription_type2str().

int suserobjs = 0 [static]

Static users

Definition at line 577 of file chan_sip.c.

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

Definition at line 18318 of file chan_sip.c.

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

Definition at line 18323 of file chan_sip.c.

struct ast_user_list userl [static]

The user list: Users and friends.


Generated on Mon Nov 24 15:34:34 2008 for Asterisk - the Open Source PBX by  doxygen 1.4.7