Wed Aug 15 01:24:54 2007

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 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   FALSE
#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 %-4.4s %-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 %-4.4s %-7.7s %-15.15s\n"
#define FORMAT2   "%-30.30s %-12.12s %8.8s %-20.20s %-25.25s\n"
#define FORMAT2   "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8s %-10s %-10s\n"
#define FORMAT2   "%-25.25s %-15.15s %-15.15s \n"
#define FORMAT3   "%-15.15s %-10.10s %-11.11s %-15.15s %-13.13s %-15.15s %-10.10s\n"
#define INC_CALL_LIMIT   1
#define INC_CALL_RINGING   3
#define INITIAL_CSEQ   101
#define IPTOS_MINCOST   0x02
#define MAX(a, b)   ((a) > (b) ? (a) : (b))
#define MAX_AUTHTRIES   3
#define MAX_RETRANS   6
#define NO_RTP   0
#define NOT_SUPPORTED   0
#define RTP   1
#define SDP_SAMPLE_RATE(x)   (x == AST_FORMAT_G722) ? 16000 : 8000
#define SIP_ALREADYGONE   (1 << 0)
#define SIP_CALL_LIMIT   (1 << 28)
#define SIP_CAN_REINVITE   (1 << 20)
#define SIP_CAN_REINVITE_NAT   (2 << 20)
#define SIP_DEFER_BYE_ON_TRANSFER   (1 << 15)
#define SIP_DTMF   (3 << 16)
#define SIP_DTMF_AUTO   (3 << 16)
#define SIP_DTMF_INBAND   (1 << 16)
#define SIP_DTMF_INFO   (2 << 16)
#define SIP_DTMF_RFC2833   (0 << 16)
#define SIP_FLAGS_TO_COPY
#define SIP_FREE_BIT   (1 << 14)
#define SIP_G726_NONSTANDARD   (1 << 31)
#define SIP_GOTREFER   (1 << 7)
#define SIP_INC_COUNT   (1 << 30)
#define SIP_INSECURE_INVITE   (1 << 24)
#define SIP_INSECURE_PORT   (1 << 23)
#define SIP_MAX_HEADERS   64
#define SIP_MAX_LINES   64
#define SIP_MAX_PACKET   4096
#define SIP_NAT   (3 << 18)
#define SIP_NAT_ALWAYS   (3 << 18)
#define SIP_NAT_NEVER   (0 << 18)
#define SIP_NAT_RFC3581   (1 << 18)
#define SIP_NAT_ROUTE   (2 << 18)
#define SIP_NEEDDESTROY   (1 << 1)
#define SIP_NEEDREINVITE   (1 << 5)
#define SIP_NO_HISTORY   (1 << 27)
#define SIP_NOVIDEO   (1 << 2)
#define SIP_OPT_100REL   (1 << 1)
#define SIP_OPT_EARLY_SESSION   (1 << 3)
#define SIP_OPT_EVENTLIST   (1 << 11)
#define SIP_OPT_GRUU   (1 << 12)
#define SIP_OPT_HISTINFO   (1 << 15)
#define SIP_OPT_JOIN   (1 << 4)
#define SIP_OPT_NOREFERSUB   (1 << 14)
#define SIP_OPT_PATH   (1 << 5)
#define SIP_OPT_PRECONDITION   (1 << 7)
#define SIP_OPT_PREF   (1 << 6)
#define SIP_OPT_PRIVACY   (1 << 8)
#define SIP_OPT_REPLACES   (1 << 0)
#define SIP_OPT_RESPRIORITY   (1 << 16)
#define SIP_OPT_SDP_ANAT   (1 << 9)
#define SIP_OPT_SEC_AGREE   (1 << 10)
#define SIP_OPT_TARGET_DIALOG   (1 << 13)
#define SIP_OPT_TIMER   (1 << 2)
#define SIP_OUTGOING   (1 << 13)
#define SIP_PAGE2_ALLOWOVERLAP   (1 << 17)
#define SIP_PAGE2_ALLOWSUBSCRIBE   (1 << 16)
#define SIP_PAGE2_BUGGY_MWI   (1 << 26)
#define SIP_PAGE2_CALL_ONHOLD   (3 << 23)
#define SIP_PAGE2_CALL_ONHOLD_ACTIVE   (1 << 23)
#define SIP_PAGE2_CALL_ONHOLD_INACTIVE   (3 << 23)
#define SIP_PAGE2_CALL_ONHOLD_ONEDIR   (2 << 23)
#define SIP_PAGE2_DEBUG   (3 << 11)
#define SIP_PAGE2_DEBUG_CONFIG   (1 << 11)
#define SIP_PAGE2_DEBUG_CONSOLE   (1 << 12)
#define SIP_PAGE2_DYNAMIC   (1 << 13)
#define SIP_PAGE2_FLAGS_TO_COPY
#define SIP_PAGE2_IGNOREREGEXPIRE   (1 << 10)
#define SIP_PAGE2_INC_RINGING   (1 << 19)
#define SIP_PAGE2_OUTGOING_CALL   (1 << 27)
#define SIP_PAGE2_RFC2833_COMPENSATE   (1 << 25)
#define SIP_PAGE2_RT_FROMCONTACT   (1 << 4)
#define SIP_PAGE2_RTAUTOCLEAR   (1 << 2)
#define SIP_PAGE2_RTCACHEFRIENDS   (1 << 0)
#define SIP_PAGE2_RTSAVE_SYSNAME   (1 << 5)
#define SIP_PAGE2_RTUPDATE   (1 << 1)
#define SIP_PAGE2_SELFDESTRUCT   (1 << 14)
#define SIP_PAGE2_SUBSCRIBEMWIONLY   (1 << 18)
#define SIP_PAGE2_T38SUPPORT   (7 << 20)
#define SIP_PAGE2_T38SUPPORT_RTP   (2 << 20)
#define SIP_PAGE2_T38SUPPORT_TCP   (4 << 20)
#define SIP_PAGE2_T38SUPPORT_UDPTL   (1 << 20)
#define SIP_PAGE2_VIDEOSUPPORT   (1 << 15)
#define SIP_PENDINGBYE   (1 << 6)
#define SIP_PKT_DEBUG   (1 << 0)
#define SIP_PKT_IGNORE   (1 << 2)
#define SIP_PKT_IGNORE_REQ   (1 << 4)
#define SIP_PKT_IGNORE_RESP   (1 << 3)
#define SIP_PKT_WITH_TOTAG   (1 << 1)
#define SIP_PROG_INBAND   (3 << 25)
#define SIP_PROG_INBAND_NEVER   (0 << 25)
#define SIP_PROG_INBAND_NO   (1 << 25)
#define SIP_PROG_INBAND_YES   (2 << 25)
#define SIP_PROGRESS_SENT   (1 << 4)
#define SIP_PROMISCREDIR   (1 << 8)
#define SIP_REALTIME   (1 << 11)
#define SIP_REINVITE   (7 << 20)
#define SIP_REINVITE_UPDATE   (4 << 20)
#define SIP_RINGING   (1 << 3)
#define SIP_SENDRPID   (1 << 29)
#define SIP_TRANS_TIMEOUT   32000
#define SIP_TRUSTRPID   (1 << 9)
#define SIP_USECLIENTCODE   (1 << 12)
#define SIP_USEREQPHONE   (1 << 10)
#define sipdebug   ast_test_flag(&global_flags[1], SIP_PAGE2_DEBUG)
#define sipdebug_config   ast_test_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONFIG)
#define sipdebug_console   ast_test_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE)
#define STANDARD_SIP_PORT   5060
 Standard SIP port from RFC 3261. DO NOT CHANGE THIS.
#define SUPPORTED   1
#define SUPPORTED_EXTENSIONS   "replaces"
 SIP Extensions we support.
#define T38FAX_FILL_BIT_REMOVAL   (1 << 0)
#define T38FAX_RATE_12000   (1 << 12)
#define T38FAX_RATE_14400   (1 << 13)
#define T38FAX_RATE_2400   (1 << 8)
#define T38FAX_RATE_4800   (1 << 9)
#define T38FAX_RATE_7200   (1 << 10)
#define T38FAX_RATE_9600   (1 << 11)
#define T38FAX_RATE_MANAGEMENT_LOCAL_TCF   (1 << 3)
#define T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF   (0 << 3)
#define T38FAX_TRANSCODING_JBIG   (1 << 2)
#define T38FAX_TRANSCODING_MMR   (1 << 1)
#define T38FAX_UDP_EC_FEC   (1 << 4)
#define T38FAX_UDP_EC_NONE   (0 << 4)
#define T38FAX_UDP_EC_REDUNDANCY   (2 << 4)
#define T38FAX_VERSION   (3 << 6)
#define T38FAX_VERSION_0   (0 << 6)
#define T38FAX_VERSION_1   (1 << 6)
#define TRUE   1
#define UNLINK(element, head, prev)
#define VIDEO_CODEC_MASK   0x1fc0000
#define XMIT_ERROR   -2

Enumerations

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

Functions

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

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

static char * regstate2str (enum sipregistrystate regstate)
 Convert registration state status to string.
static int reload (void)
 Part of Asterisk module interface.
static int reload_config (enum channelreloadreason reason)
 Re-read SIP.conf config file.
static int reply_digest (struct sip_pvt *p, struct sip_request *req, char *header, int sipmethod, char *digest, int digest_len)
 reply to authentication for outbound registrations
static int reqprep (struct sip_request *req, struct sip_pvt *p, int sipmethod, int seqno, int newbranch)
 Initialize a SIP request message (not the initial one in a dialog).
static int respprep (struct sip_request *resp, struct sip_pvt *p, const char *msg, const struct sip_request *req)
 Prepare SIP response packet.
static int restart_monitor (void)
 Start the channel monitor thread.
static int retrans_pkt (void *data)
 Retransmit SIP message if no answer (Called from scheduler).
static int send_request (struct sip_pvt *p, struct sip_request *req, enum xmittype reliable, int seqno)
 Send SIP Request to the other part of the dialogue.
static int send_response (struct sip_pvt *p, struct sip_request *req, enum xmittype reliable, int seqno)
 Transmit response on SIP request.
static int set_address_from_contact (struct sip_pvt *pvt)
 Change the other partys IP address based on given contact.
static void set_destination (struct sip_pvt *p, char *uri)
 Set destination from SIP URI.
static void set_insecure_flags (struct ast_flags *flags, const char *value, int lineno)
 Parse the "insecure" setting from sip.conf or from realtime.
static void set_peer_defaults (struct sip_peer *peer)
 Set peer defaults before configuring specific configurations.
static int sip_addheader (struct ast_channel *chan, void *data)
 Add a SIP header to an outbound INVITE.
static int sip_addrcmp (char *name, struct sockaddr_in *sin)
 Support routine for find_peer.
static struct sip_pvtsip_alloc (ast_string_field callid, struct sockaddr_in *sin, int useglobal_nat, const int intended_method)
 Allocate SIP_PVT structure and set defaults.
static void sip_alreadygone (struct sip_pvt *dialog)
static int sip_answer (struct ast_channel *ast)
 sip_answer: Answer SIP call , send 200 OK on Invite Part of PBX interface
static int sip_call (struct ast_channel *ast, char *dest, int timeout)
 Initiate SIP call from PBX used from the dial() application.
static void sip_cancel_destroy (struct sip_pvt *p)
 Cancel destruction of SIP dialog.
static int sip_debug_test_addr (const struct sockaddr_in *addr)
 See if we pass debug IP filter.
static int sip_debug_test_pvt (struct sip_pvt *p)
 Test PVT for debugging output.
static void sip_destroy (struct sip_pvt *p)
 Destroy SIP call structure.
static void sip_destroy_peer (struct sip_peer *peer)
 Destroy peer object from memory.
static void sip_destroy_user (struct sip_user *user)
 Remove user object from in-memory storage.
static int sip_devicestate (void *data)
 Part of PBX channel interface.
static int sip_do_debug (int fd, int argc, char *argv[])
 Turn on SIP debugging (CLI command).
static int sip_do_debug_deprecated (int fd, int argc, char *argv[])
static int sip_do_debug_ip (int fd, int argc, char *argv[])
 Enable SIP Debugging in CLI.
static int sip_do_debug_peer (int fd, int argc, char *argv[])
 sip_do_debug_peer: Turn on SIP debugging with peer mask
static int sip_do_history (int fd, int argc, char *argv[])
 Enable SIP History logging (CLI).
static int sip_do_reload (enum channelreloadreason reason)
 Reload module.
static int sip_dtmfmode (struct ast_channel *chan, void *data)
 Set the DTMFmode for an outbound SIP call (application).
static void sip_dump_history (struct sip_pvt *dialog)
 Dump SIP history to debug log file at end of lifespan for SIP dialog.
static int sip_fixup (struct ast_channel *oldchan, struct ast_channel *newchan)
 sip_fixup: Fix up a channel: If a channel is consumed, this is called. Basically update any ->owner links
static int sip_get_codec (struct ast_channel *chan)
 Return SIP UA's codec (part of the RTP interface).
static enum
ast_rtp_get_result 
sip_get_rtp_peer (struct ast_channel *chan, struct ast_rtp **rtp)
 Returns null if we can't reinvite audio (part of RTP interface).
static struct ast_udptlsip_get_udptl_peer (struct ast_channel *chan)
static enum
ast_rtp_get_result 
sip_get_vrtp_peer (struct ast_channel *chan, struct ast_rtp **rtp)
 Returns null if we can't reinvite video (part of RTP interface).
static int sip_handle_t38_reinvite (struct ast_channel *chan, struct sip_pvt *pvt, int reinvite)
 Handle T38 reinvite.
static int sip_hangup (struct ast_channel *ast)
 sip_hangup: Hangup SIP call Part of PBX interface, called from ast_hangup
static int sip_indicate (struct ast_channel *ast, int condition, const void *data, size_t datalen)
 Play indication to user With SIP a lot of indications is sent as messages, letting the device play the indication - busy signal, congestion etc.
static const char * sip_nat_mode (const struct sip_pvt *p)
 Display SIP nat mode.
static struct
ast_channel
sip_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 (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 (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 (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_reload (int fd, int argc, char *argv[])
 Force reload of module from cli.
static struct
ast_channel
sip_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 (void *data)
 Update registration with SIP Proxy.
static struct ast_framesip_rtp_read (struct ast_channel *ast, struct sip_pvt *p, int *faxdetect)
 Read RTP from network.
static void sip_scheddestroy (struct sip_pvt *p, int ms)
 Schedule destruction of SIP dialog.
static void sip_send_all_registers (void)
 Send all known registrations.
static int sip_send_mwi_to_peer (struct sip_peer *peer)
 Send message waiting indication to alert peer that they've got voicemail.
static int sip_senddigit_begin (struct ast_channel *ast, char digit)
static int sip_senddigit_end (struct ast_channel *ast, char digit, unsigned int duration)
 Send DTMF character on SIP channel within one call, we're able to transmit in many methods simultaneously.
static int sip_sendtext (struct ast_channel *ast, const char *text)
 Send SIP MESSAGE text within a call Called from PBX core sendtext() application.
static int sip_set_rtp_peer (struct ast_channel *chan, struct ast_rtp *rtp, struct ast_rtp *vrtp, int codecs, int nat_active)
 Set the RTP peer for this call.
static int sip_set_udptl_peer (struct ast_channel *chan, struct ast_udptl *udptl)
static int sip_show_channel (int fd, int argc, char *argv[])
 Show details of one active dialog.
static int sip_show_channels (int fd, int argc, char *argv[])
 Show active SIP channels.
static int sip_show_domains (int fd, int argc, char *argv[])
 CLI command to list local domains.
static int sip_show_history (int fd, int argc, char *argv[])
 Show history details of one dialog.
static int sip_show_inuse (int fd, int argc, char *argv[])
 CLI Command to show calls within limits set by call_limit.
static int sip_show_objects (int fd, int argc, char *argv[])
 List all allocated SIP Objects (realtime or static).
static int sip_show_peer (int fd, int argc, char *argv[])
 Show one peer in detail.
static int sip_show_peers (int fd, int argc, char *argv[])
 CLI Show Peers command.
static int sip_show_registry (int fd, int argc, char *argv[])
 Show SIP Registry (registrations with other SIP proxies.
static int sip_show_settings (int fd, int argc, char *argv[])
 List global settings for the SIP channel.
static int sip_show_subscriptions (int fd, int argc, char *argv[])
 Show active SIP subscriptions.
static int sip_show_user (int fd, int argc, char *argv[])
 Show one user in detail.
static int sip_show_users (int fd, int argc, char *argv[])
 CLI Command 'SIP Show Users'.
static int sip_sipredirect (struct sip_pvt *p, const char *dest)
 Transfer call before connect with a 302 redirect.
static int sip_transfer (struct ast_channel *ast, const char *dest)
 Transfer SIP call.
static int sip_write (struct ast_channel *ast, struct ast_frame *frame)
 Send frame to media channel (rtp).
static int sipsock_read (int *id, int fd, short events, void *ignore)
 Read data from SIP socket.
static void stop_media_flows (struct sip_pvt *p)
 Immediately stop RTP, VRTP and UDPTL as applicable.
static const char * subscription_type2str (enum subscriptiontype subtype)
 Show subscription type in string format.
static int t38_get_rate (int t38cap)
 Get Max T.38 Transmission rate from T38 capabilities.
static struct sip_peertemp_peer (const char *name)
 Create temporary peer (used in autocreatepeer mode).
static void temp_pvt_cleanup (void *)
static char * transfermode2str (enum transfermodes mode)
 Convert transfer mode to text string.
static void transmit_fake_auth_response (struct sip_pvt *p, struct sip_request *req, int reliable)
 Send a fake 401 Unauthorized response when the administrator wants to hide the names of local users/peers from fishers.
static int transmit_info_with_digit (struct sip_pvt *p, const char digit, unsigned int duration)
 Send SIP INFO dtmf message, see Cisco documentation on cisco.com.
static int transmit_info_with_vidupdate (struct sip_pvt *p)
 Send SIP INFO with video update request.
static int transmit_invite (struct sip_pvt *p, int sipmethod, int sdp, int init)
 Build REFER/INVITE/OPTIONS message and transmit it.
static int transmit_message_with_text (struct sip_pvt *p, const char *text)
 Transmit text with SIP MESSAGE method.
static int transmit_notify_with_mwi (struct sip_pvt *p, int newmsgs, int oldmsgs, char *vmexten)
 Notify user of messages waiting in voicemail.
static int transmit_notify_with_sipfrag (struct sip_pvt *p, int cseq, char *message, int terminate)
 Notify a transferring party of the status of transfer.
static int transmit_refer (struct sip_pvt *p, const char *dest)
 Transmit SIP REFER message (initiated by the transfer() dialplan application.
static int transmit_register (struct sip_registry *r, int sipmethod, const char *auth, const char *authheader)
 Transmit register to SIP proxy or UA.
static int transmit_reinvite_with_sdp (struct sip_pvt *p)
 Transmit reinvite with SDP.
static int transmit_reinvite_with_t38_sdp (struct sip_pvt *p)
 Transmit reinvite with T38 SDP We reinvite so that the T38 processing can take place. SIP Signalling stays with * in the path.
static int transmit_request (struct sip_pvt *p, int sipmethod, int seqno, enum xmittype reliable, int newbranch)
 Transmit generic SIP request returns XMIT_ERROR if transmit failed with a critical error (don't retry).
static int transmit_request_with_auth (struct sip_pvt *p, int sipmethod, int seqno, enum xmittype reliable, int newbranch)
 Transmit SIP request, auth added.
static int transmit_response (struct sip_pvt *p, const char *msg, const struct sip_request *req)
 Transmit response, no retransmits.
static int transmit_response_reliable (struct sip_pvt *p, const char *msg, const struct sip_request *req)
 Transmit response, Make sure you get an ACK This is only used for responses to INVITEs, where we need to make sure we get an ACK.
static int transmit_response_using_temp (ast_string_field callid, struct sockaddr_in *sin, int useglobal_nat, const int intended_method, const struct sip_request *req, const char *msg)
 Transmit response, no retransmits, using a temporary pvt structure.
static int transmit_response_with_allow (struct sip_pvt *p, const char *msg, const struct sip_request *req, enum xmittype reliable)
 Append Accept header, content length before transmitting response.
static int transmit_response_with_auth (struct sip_pvt *p, const char *msg, const struct sip_request *req, const char *randdata, enum xmittype reliable, const char *header, int stale)
 Respond with authorization request.
static int transmit_response_with_date (struct sip_pvt *p, const char *msg, const struct sip_request *req)
 Append date and content length before transmitting response.
static int transmit_response_with_sdp (struct sip_pvt *p, const char *msg, const struct sip_request *req, enum xmittype reliable)
 Used for 200 OK and 183 early media.
static int transmit_response_with_t38_sdp (struct sip_pvt *p, char *msg, struct sip_request *req, int retrans)
 Used for 200 OK and 183 early media.
static int transmit_response_with_unsupported (struct sip_pvt *p, const char *msg, const struct sip_request *req, const char *unsupported)
 Transmit response, no retransmits.
static int transmit_sip_request (struct sip_pvt *p, struct sip_request *req)
 Transmit SIP request unreliably (only used in sip_notify subsystem).
static int transmit_state_notify (struct sip_pvt *p, int state, int full, int timeout)
 Used in the SUBSCRIBE notification subsystem.
static void try_suggested_sip_codec (struct sip_pvt *p)
 Try setting codec suggested by the SIP_CODEC channel variable.
static int unload_module (void)
 PBX unload module API.
static int update_call_counter (struct sip_pvt *fup, int event)
 update_call_counter: Handle call_limit for SIP users Setting a call-limit will cause calls above the limit not to be accepted.
static void update_peer (struct sip_peer *p, int expiry)
 Update peer data in database (if used).

Variables

static struct in_addr __ourip
static int allow_external_domains
static int apeerobjs = 0
static char * app_dtmfmode = "SIPDtmfMode"
static char * app_sipaddheader = "SIPAddHeader"
static struct sip_authauthl = NULL
static int autocreatepeer
static struct sockaddr_in bindaddr = { 0, }
static struct
ast_custom_function 
checksipdomain_function
static struct
ast_cli_entry 
cli_sip []
static struct
ast_cli_entry 
cli_sip_debug_deprecated
static struct
ast_cli_entry 
cli_sip_no_debug_deprecated
static int compactheaders
static const char config [] = "sip.conf"
static char debug_usage []
static struct sockaddr_in debugaddr
static char default_callerid [AST_MAX_EXTENSION]
static char default_context [AST_MAX_CONTEXT]
static int default_expiry = DEFAULT_DEFAULT_EXPIRY
static char default_fromdomain [AST_MAX_EXTENSION]
static struct ast_jb_conf default_jbconf
 Global jitterbuffer configuration - by default, jb is disabled.
static char default_language [MAX_LANGUAGE]
static int default_maxcallbitrate
static char default_mohinterpret [MAX_MUSICCLASS]
static char default_mohsuggest [MAX_MUSICCLASS]
static char default_notifymime [AST_MAX_EXTENSION]
static struct
ast_codec_pref 
default_prefs
static int default_qualify
static char default_subscribecontext [AST_MAX_CONTEXT]
static char default_vmexten [AST_MAX_EXTENSION]
static char * descrip_dtmfmode = "SIPDtmfMode(inband|info|rfc2833): Changes the dtmfmode for a SIP call\n"
static char * descrip_sipaddheader
static int dumphistory
static int expiry = DEFAULT_EXPIRY
static time_t externexpire = 0
static char externhost [MAXHOSTNAMELEN]
static struct sockaddr_in externip
static int externrefresh = 10
static int global_allowguest
static int global_allowsubscribe
static enum transfermodes global_allowtransfer
static int global_alwaysauthreject
static int global_autoframing
static int global_callevents
static int global_capability = AST_FORMAT_ULAW | AST_FORMAT_ALAW | AST_FORMAT_GSM | AST_FORMAT_H263
 Codecs that we support by default:.
static int global_directrtpsetup
static struct ast_flags global_flags [2] = {{0}}
static struct ast_jb_conf global_jbconf
static int global_limitonpeers
static int global_matchexterniplocally
static int global_mwitime
static int global_notifyhold
static int global_notifyringing
static char global_realm [MAXHOSTNAMELEN]
static int global_reg_timeout
static int global_regattempts_max
static char global_regcontext [AST_MAX_CONTEXT]
static int global_relaxdtmf
static int global_rtautoclear
static int global_rtpholdtimeout
static int global_rtpkeepalive
static int global_rtptimeout
static int global_t1min
static int global_t38_capability = T38FAX_VERSION_0 | T38FAX_RATE_2400 | T38FAX_RATE_4800 | T38FAX_RATE_7200 | T38FAX_RATE_9600
static unsigned int global_tos_audio
static unsigned int global_tos_sip
static unsigned int global_tos_video
static char global_useragent [AST_MAX_EXTENSION]
static char history_usage []
static struct sip_pvtiflist
 sip_pvt: PVT structures are used for each SIP dialog, ie. a call, a registration, a subscribe
static struct
io_context
io
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_config
notify_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_context
sched
static char show_channel_usage []
static char show_channels_usage []
static char show_domains_usage []
static char show_history_usage []
static char show_inuse_usage []
static char show_objects_usage []
static char show_peer_usage []
static char show_peers_usage []
static char show_reg_usage []
static char show_settings_usage []
static char show_subscriptions_usage []
static char show_user_usage []
static char show_users_usage []
static struct
ast_custom_function 
sip_header_function
static struct
cfsip_methods 
sip_methods []
static struct
cfsip_options 
sip_options []
 List of well-known SIP options. If we get this in a require, we should check the list and answer accordingly.
static char sip_reload_usage []
static int sip_reloading = FALSE
static enum
channelreloadreason 
sip_reloadreason
static struct
ast_rtp_protocol 
sip_rtp
 Interface structure with callbacks used to connect to RTP module.
static struct
ast_channel_tech 
sip_tech
 Definition of this channel for PBX channel registration.
static struct
ast_channel_tech 
sip_tech_info
 This version of the sip channel tech has no send_digit_begin callback. This is for use with channels using SIP INFO DTMF so that the core knows that the channel doesn't want DTMF BEGIN frames.
static struct
ast_udptl_protocol 
sip_udptl
 Interface structure with callbacks used to connect to UDPTL module.
static struct
ast_custom_function 
sipchaninfo_function
 Structure to declare a dialplan function: SIPCHANINFO.
struct
ast_custom_function 
sippeer_function
 Structure to declare a dialplan function: SIPPEER.
static int sipsock = -1
static int * sipsock_read_id
static int speerobjs = 0
static int srvlookup
static struct
cfsubscription_types 
subscription_types []
static int suserobjs = 0
static char * synopsis_dtmfmode = "Change the dtmfmode for a SIP call"
static char * synopsis_sipaddheader = "Add a SIP header to the outbound call"
static struct
ast_user_list 
userl
 The user list: Users and friends.


Detailed Description

Implementation of Session Initiation Protocol.

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

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

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

Referenced by initreqprep().

#define CAN_CREATE_DIALOG   1

Definition at line 361 of file chan_sip.c.

Referenced by find_call().

#define CAN_CREATE_DIALOG_UNSUPPORTED_METHOD   2

Definition at line 362 of file chan_sip.c.

Referenced by find_call().

#define CAN_NOT_CREATE_DIALOG   0

Definition at line 360 of file chan_sip.c.

#define DEC_CALL_LIMIT   0

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

Referenced by handle_response_invite(), and update_call_counter().

#define DEFAULT_ALLOW_EXT_DOM   TRUE

Definition at line 500 of file chan_sip.c.

Referenced by reload_config().

#define DEFAULT_ALLOWGUEST   TRUE

Definition at line 494 of file chan_sip.c.

Referenced by reload_config().

#define DEFAULT_AUTOCREATEPEER   FALSE

Definition at line 504 of file chan_sip.c.

Referenced by reload_config().

#define DEFAULT_CALLERID   "asterisk"

Definition at line 491 of file chan_sip.c.

Referenced by reload_config().

#define DEFAULT_COMPACTHEADERS   FALSE

Definition at line 496 of file chan_sip.c.

Referenced by reload_config().

#define DEFAULT_CONTEXT   "default"

Definition at line 487 of file chan_sip.c.

Referenced by reload_config().

#define DEFAULT_DEFAULT_EXPIRY   120

Definition at line 166 of file chan_sip.c.

Referenced by reload_config().

#define DEFAULT_EXPIRY   900

Expire slowly

Definition at line 183 of file chan_sip.c.

#define DEFAULT_FREQ_NOTOK   10 * 1000

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

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

#define DEFAULT_MAX_CALL_BITRATE   (384)

Max bitrate for video

Definition at line 507 of file chan_sip.c.

Referenced by reload_config().

#define DEFAULT_MAX_EXPIRY   3600

Definition at line 168 of file chan_sip.c.

Referenced by reload_config().

#define DEFAULT_MAX_FORWARDS   "70"

Definition at line 170 of file chan_sip.c.

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

#define DEFAULT_MAXMS   2000

Qualification: Must be faster than 2 seconds by default

Definition at line 196 of file chan_sip.c.

#define DEFAULT_MIN_EXPIRY   60

Definition at line 167 of file chan_sip.c.

Referenced by reload_config().

#define DEFAULT_MOHINTERPRET   "default"

Definition at line 488 of file chan_sip.c.

Referenced by reload_config().

#define DEFAULT_MOHSUGGEST   ""

Definition at line 489 of file chan_sip.c.

Referenced by reload_config().

#define DEFAULT_MWITIME   10

Definition at line 493 of file chan_sip.c.

Referenced by reload_config().

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

Definition at line 492 of file chan_sip.c.

Referenced by reload_config().

#define DEFAULT_NOTIFYRINGING   TRUE

Definition at line 502 of file chan_sip.c.

Referenced by reload_config().

#define DEFAULT_PEDANTIC   FALSE

Definition at line 503 of file chan_sip.c.

Referenced by reload_config().

#define DEFAULT_QUALIFY   FALSE

Definition at line 505 of file chan_sip.c.

Referenced by reload_config().

#define DEFAULT_REALM   "asterisk"

Definition at line 501 of file chan_sip.c.

Referenced by reload_config().

#define DEFAULT_REGISTRATION_TIMEOUT   20

Definition at line 169 of file chan_sip.c.

Referenced by reload_config().

#define DEFAULT_RETRANS   1000

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

Definition at line 200 of file chan_sip.c.

#define DEFAULT_SRVLOOKUP   FALSE

Recommended setting is ON

Definition at line 495 of file chan_sip.c.

Referenced by reload_config().

#define DEFAULT_T1MIN   100

100 MS for minimal roundtrip time

Definition at line 506 of file chan_sip.c.

Referenced by reload_config().

#define DEFAULT_TOS_AUDIO   0

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

Definition at line 498 of file chan_sip.c.

Referenced by reload_config().

#define DEFAULT_TOS_SIP   0

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

Definition at line 497 of file chan_sip.c.

Referenced by reload_config().

#define DEFAULT_TOS_VIDEO   0

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

Definition at line 499 of file chan_sip.c.

Referenced by reload_config().

#define DEFAULT_TRANS_TIMEOUT   -1

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

Referenced by reload_config().

#define DEFAULT_VMEXTEN   "asterisk"

Definition at line 490 of file chan_sip.c.

Referenced by reload_config().

#define EXPIRY_GUARD_LIMIT   30

Below here, we use EXPIRY_GUARD_PCT instead of EXPIRY_GUARD_SECS

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

Referenced by handle_response_register().

#define FALSE   0

Definition at line 150 of file chan_sip.c.

#define FLAG_FATAL   (1 << 1)

Definition at line 1012 of file chan_sip.c.

Referenced by __sip_reliable_xmit(), and retrans_pkt().

#define FLAG_RESPONSE   (1 << 0)

Definition at line 1011 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 %-4.4s %-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 %-4.4s %-7.7s %-15.15s\n"

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

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

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

#define FORMAT3   "%-15.15s %-10.10s %-11.11s %-15.15s %-13.13s %-15.15s %-10.10s\n"

Referenced by __sip_show_channels().

#define INC_CALL_LIMIT   1

Definition at line 602 of file chan_sip.c.

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

#define INC_CALL_RINGING   3

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

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

#define IPTOS_MINCOST   0x02

Definition at line 161 of file chan_sip.c.

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

Definition at line 191 of file chan_sip.c.

#define MAX_AUTHTRIES   3

Try authentication three times, then fail

Definition at line 206 of file chan_sip.c.

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

#define MAX_RETRANS   6

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

Definition at line 201 of file chan_sip.c.

#define NO_RTP   0

Definition at line 228 of file chan_sip.c.

#define NOT_SUPPORTED   0

Definition at line 401 of file chan_sip.c.

#define RTP   1

Definition at line 227 of file chan_sip.c.

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

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

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

#define SIP_CALL_LIMIT   (1 << 28)

Call limit enforced for this call

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

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

#define SIP_CAN_REINVITE_NAT   (2 << 20)

allow media reinvite when new peer is behind NAT

Definition at line 738 of file chan_sip.c.

Referenced by 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 723 of file chan_sip.c.

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

#define SIP_DTMF   (3 << 16)

DTMF Support: four settings, uses two bits

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

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

#define SIP_FLAGS_TO_COPY

Value:

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

#define SIP_G726_NONSTANDARD   (1 << 31)

Use non-standard packing for G726-32 data

Definition at line 752 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 715 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 751 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 742 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 741 of file chan_sip.c.

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

#define SIP_MAX_HEADERS   64

Max amount of SIP headers to read

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

#define SIP_NAT   (3 << 18)

four settings, uses two bits

Definition at line 730 of file chan_sip.c.

Referenced by _sip_show_peer(), build_via(), copy_via_headers(), create_addr_from_peer(), handle_common_options(), 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 734 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 731 of file chan_sip.c.

Referenced by handle_common_options(), and nat2str().

#define SIP_NAT_RFC3581   (1 << 18)

NAT RFC3581

Definition at line 732 of file chan_sip.c.

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

#define SIP_NAT_ROUTE   (2 << 18)

NAT Only ROUTE

Definition at line 733 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 709 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 713 of file chan_sip.c.

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

#define SIP_NO_HISTORY   (1 << 27)

Suppress recording request/response history

Definition at line 748 of file chan_sip.c.

Referenced by 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 710 of file chan_sip.c.

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

#define SIP_OPT_100REL   (1 << 1)

Definition at line 404 of file chan_sip.c.

#define SIP_OPT_EARLY_SESSION   (1 << 3)

Definition at line 406 of file chan_sip.c.

#define SIP_OPT_EVENTLIST   (1 << 11)

Definition at line 414 of file chan_sip.c.

#define SIP_OPT_GRUU   (1 << 12)

Definition at line 415 of file chan_sip.c.

#define SIP_OPT_HISTINFO   (1 << 15)

Definition at line 418 of file chan_sip.c.

#define SIP_OPT_JOIN   (1 << 4)

Definition at line 407 of file chan_sip.c.

#define SIP_OPT_NOREFERSUB   (1 << 14)

Definition at line 417 of file chan_sip.c.

#define SIP_OPT_PATH   (1 << 5)

Definition at line 408 of file chan_sip.c.

#define SIP_OPT_PRECONDITION   (1 << 7)

Definition at line 410 of file chan_sip.c.

#define SIP_OPT_PREF   (1 << 6)

Definition at line 409 of file chan_sip.c.

#define SIP_OPT_PRIVACY   (1 << 8)

Definition at line 411 of file chan_sip.c.

#define SIP_OPT_REPLACES   (1 << 0)

Definition at line 403 of file chan_sip.c.

Referenced by handle_request_invite().

#define SIP_OPT_RESPRIORITY   (1 << 16)

Definition at line 419 of file chan_sip.c.

#define SIP_OPT_SDP_ANAT   (1 << 9)

Definition at line 412 of file chan_sip.c.

#define SIP_OPT_SEC_AGREE   (1 << 10)

Definition at line 413 of file chan_sip.c.

#define SIP_OPT_TARGET_DIALOG   (1 << 13)

Definition at line 416 of file chan_sip.c.

#define SIP_OPT_TIMER   (1 << 2)

Definition at line 405 of file chan_sip.c.

#define SIP_OUTGOING   (1 << 13)

Direction of the last transaction in this dialog

Definition at line 721 of file chan_sip.c.

Referenced by get_sip_pvt_byid_locked(), 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 775 of file chan_sip.c.

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

#define SIP_PAGE2_ALLOWSUBSCRIBE   (1 << 16)

Allow subscriptions from this peer?

Definition at line 774 of file chan_sip.c.

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

#define SIP_PAGE2_BUGGY_MWI   (1 << 26)

26: Buggy CISCO MWI fix

Definition at line 787 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 782 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 783 of file chan_sip.c.

Referenced by change_hold_state().

#define SIP_PAGE2_CALL_ONHOLD_INACTIVE   (3 << 23)

23: Inactive hold

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

Referenced by add_sdp(), and change_hold_state().

#define SIP_PAGE2_DEBUG   (3 << 11)

Definition at line 768 of file chan_sip.c.

#define SIP_PAGE2_DEBUG_CONFIG   (1 << 11)

Definition at line 769 of file chan_sip.c.

Referenced by reload_config().

#define SIP_PAGE2_DEBUG_CONSOLE   (1 << 12)

Definition at line 770 of file chan_sip.c.

Referenced by reload_config(), 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_DYNAMIC   (1 << 13)

Dynamic Peers register with Asterisk

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

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

#define SIP_PAGE2_INC_RINGING   (1 << 19)

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

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

Referenced by sip_request_call(), and update_call_counter().

#define SIP_PAGE2_RFC2833_COMPENSATE   (1 << 25)

25: ????

Definition at line 786 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 764 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 763 of file chan_sip.c.

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

#define SIP_PAGE2_RTCACHEFRIENDS   (1 << 0)

Definition at line 761 of file chan_sip.c.

Referenced by complete_sip_prune_realtime_peer(), complete_sip_prune_realtime_user(), realtime_peer(), realtime_user(), reload_config(), sip_prune_realtime(), sip_show_settings(), update_call_counter(), and update_peer().

#define SIP_PAGE2_RTSAVE_SYSNAME   (1 << 5)

Definition at line 765 of file chan_sip.c.

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

#define SIP_PAGE2_RTUPDATE   (1 << 1)

Definition at line 762 of file chan_sip.c.

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

#define SIP_PAGE2_SELFDESTRUCT   (1 << 14)

Automatic peers need to destruct themselves

Definition at line 772 of file chan_sip.c.

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

#define SIP_PAGE2_SUBSCRIBEMWIONLY   (1 << 18)

Only issue MWI notification if subscribed to

Definition at line 776 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 778 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 780 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 781 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 779 of file chan_sip.c.

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

#define SIP_PAGE2_VIDEOSUPPORT   (1 << 15)

Definition at line 773 of file chan_sip.c.

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

#define SIP_PENDINGBYE   (1 << 6)

Need to send bye after we ack?

Definition at line 714 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 795 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 797 of file chan_sip.c.

Referenced by 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 799 of file chan_sip.c.

Referenced by handle_request().

#define SIP_PKT_IGNORE_RESP   (1 << 3)

Resp ignore - ???

Definition at line 798 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 796 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 744 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 745 of file chan_sip.c.

Referenced by sip_indicate(), and sip_show_settings().

#define SIP_PROG_INBAND_NO   (1 << 25)

Definition at line 746 of file chan_sip.c.

Referenced by handle_common_options(), and sip_show_settings().

#define SIP_PROG_INBAND_YES   (2 << 25)

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

Referenced by sip_indicate(), and sip_write().

#define SIP_PROMISCREDIR   (1 << 8)

Promiscuous redirection

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

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

#define SIP_REINVITE   (7 << 20)

three bits used

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

Referenced by transmit_reinvite_with_sdp(), and transmit_reinvite_with_t38_sdp().

#define SIP_RINGING   (1 << 3)

Have sent 180 ringing

Definition at line 711 of file chan_sip.c.

Referenced by sip_indicate().

#define SIP_SENDRPID   (1 << 29)

Remote Party-ID Support

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

Referenced by sip_call().

#define SIP_TRUSTRPID   (1 << 9)

Trust RPID headers?

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

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

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

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

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

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

Referenced by build_contact(), build_peer(), check_via(), create_addr(), initreqprep(), parse_register_contact(), reload_config(), set_address_from_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 400 of file chan_sip.c.

#define SUPPORTED_EXTENSIONS   "replaces"

SIP Extensions we support.

Definition at line 471 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 802 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 821 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 822 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 817 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 818 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 819 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 820 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 807 of file chan_sip.c.

Referenced by add_t38_sdp(), and process_sdp().

#define T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF   (0 << 3)

Definition at line 806 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 804 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 803 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 810 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 809 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 811 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 813 of file chan_sip.c.

Referenced by add_t38_sdp().

#define T38FAX_VERSION_0   (0 << 6)

Version 0

Definition at line 814 of file chan_sip.c.

Referenced by add_t38_sdp(), and process_sdp().

#define T38FAX_VERSION_1   (1 << 6)

Version 1

Definition at line 815 of file chan_sip.c.

Referenced by add_t38_sdp(), and process_sdp().

#define TRUE   1

Definition at line 154 of file chan_sip.c.

#define UNLINK ( element,
head,
prev   ) 

--- some list management macros.

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

#define XMIT_ERROR   -2

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

00336                        {
00337    AUTH_SUCCESSFUL = 0,
00338    AUTH_CHALLENGE_SENT = 1,
00339    AUTH_SECRET_FAILED = -1,
00340    AUTH_USERNAME_MISMATCH = -2,
00341    AUTH_NOT_FOUND = -3,
00342    AUTH_FAKE_AUTH = -4,
00343    AUTH_UNKNOWN_DOMAIN = -5,
00344    AUTH_PEER_NOT_DYNAMIC = -6,
00345    AUTH_ACL_FAILED = -7,
00346 };

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

00671                  {
00672    SIP_DOMAIN_AUTO,     /*!< This domain is auto-configured */
00673    SIP_DOMAIN_CONFIG,      /*!< This domain is from configuration */
00674 };

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

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

enum parse_register_result

Enumerator:
PARSE_REGISTER_FAILED 
PARSE_REGISTER_UPDATE 
PARSE_REGISTER_QUERY 

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

00851                  {
00852         REFER_IDLE,                    /*!< No REFER is in progress */
00853         REFER_SENT,                    /*!< Sent REFER to transferee */
00854         REFER_RECEIVED,                /*!< Received REFER from transferer */
00855         REFER_CONFIRMED,               /*!< Refer confirmed with a 100 TRYING */
00856         REFER_ACCEPTED,                /*!< Accepted by transferee */
00857         REFER_RINGING,                 /*!< Target Ringing */
00858         REFER_200OK,                   /*!< Answered by transfer target */
00859         REFER_FAILED,                  /*!< REFER declined - go on */
00860         REFER_NOAUTH                   /*!< We had no auth for REFER */
00861 };

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

00330                    {
00331    PROXY_AUTH,
00332    WWW_AUTH,
00333 };

enum sip_result

Enumerator:
AST_SUCCESS 
AST_FAILURE 

Definition at line 239 of file chan_sip.c.

00239                 {
00240    AST_SUCCESS = 0,
00241    AST_FAILURE = -1,
00242 };

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

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

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

00349                       {
00350    REG_STATE_UNREGISTERED = 0,   /*!< We are not registred */
00351    REG_STATE_REGSENT,   /*!< Registration request sent */
00352    REG_STATE_AUTHSENT,  /*!< We have tried to authenticate */
00353    REG_STATE_REGISTERED,   /*!< Registred and done */
00354    REG_STATE_REJECTED,  /*!< Registration rejected */
00355    REG_STATE_TIMEOUT,   /*!< Registration timed out */
00356    REG_STATE_NOAUTH, /*!< We have no accepted credentials */
00357    REG_STATE_FAILED, /*!< Registration failed after several tries */
00358 };

enum subscriptiontype

Enumerator:
NONE 
XPIDF_XML 
DIALOG_INFO_XML 
CPIM_PIDF_XML 
PIDF_XML 
MWI_NOTIFICATION 

Definition at line 280 of file chan_sip.c.

00280                       { 
00281    NONE = 0,
00282    XPIDF_XML,
00283    DIALOG_INFO_XML,
00284    CPIM_PIDF_XML,
00285    PIDF_XML,
00286    MWI_NOTIFICATION
00287 };

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

00832               {
00833         T38_DISABLED = 0,                /*!< Not enabled */
00834         T38_LOCAL_DIRECT,                /*!< Offered from local */
00835         T38_LOCAL_REINVITE,              /*!< Offered from local - REINVITE */
00836         T38_PEER_DIRECT,                 /*!< Offered from peer */
00837         T38_PEER_REINVITE,               /*!< Offered from peer - REINVITE */
00838         T38_ENABLED                      /*!< Negotiated (enabled) */
00839 };

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

00233                    {
00234    TRANSFER_OPENFORALL,            /*!< Allow all SIP transfers */
00235    TRANSFER_CLOSED,                /*!< Allow no SIP transfers */
00236 };

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

00267               {
00268    XMIT_CRITICAL = 2,              /*!< Transmit critical SIP message reliably, with re-transmits.
00269                                               If it fails, it's critical and will cause a teardown of the session */
00270    XMIT_RELIABLE = 1,              /*!< Transmit SIP message reliably, with re-transmits */
00271    XMIT_UNRELIABLE = 0,            /*!< Transmit SIP message without bothering with re-transmits */
00272 };


Function Documentation

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

Definition at line 4121 of file chan_sip.c.

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

04122 {
04123    int pass;
04124 
04125    /*
04126     * Technically you can place arbitrary whitespace both before and after the ':' in
04127     * a header, although RFC3261 clearly says you shouldn't before, and place just
04128     * one afterwards.  If you shouldn't do it, what absolute idiot decided it was 
04129     * a good idea to say you can do it, and if you can do it, why in the hell would.
04130     * you say you shouldn't.
04131     * Anyways, pedanticsipchecking controls whether we allow spaces before ':',
04132     * and we always allow spaces after that for compatibility.
04133     */
04134    for (pass = 0; name && pass < 2;pass++) {
04135       int x, len = strlen(name);
04136       for (x=*start; x<req->headers; x++) {
04137          if (!strncasecmp(req->header[x], name, len)) {
04138             char *r = req->header[x] + len;  /* skip name */
04139             if (pedanticsipchecking)
04140                r = ast_skip_blanks(r);
04141 
04142             if (*r == ':') {
04143                *start = x+1;
04144                return ast_skip_blanks(r+1);
04145             }
04146          }
04147       }
04148       if (pass == 0) /* Try aliases */
04149          name = find_alias(name, NULL);
04150    }
04151 
04152    /* Don't return NULL, so get_header is always a valid pointer */
04153    return "";
04154 }

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

Acknowledges receipt of a packet and stops retransmission.

Definition at line 2104 of file chan_sip.c.

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

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

02105 {
02106    struct sip_pkt *cur, *prev = NULL;
02107 
02108    /* Just in case... */
02109    char *msg;
02110    int res = FALSE;
02111 
02112    msg = sip_methods[sipmethod].text;
02113 
02114    ast_mutex_lock(&p->lock);
02115    for (cur = p->packets; cur; prev = cur, cur = cur->next) {
02116       if ((cur->seqno == seqno) && ((ast_test_flag(cur, FLAG_RESPONSE)) == resp) &&
02117          ((ast_test_flag(cur, FLAG_RESPONSE)) || 
02118           (!strncasecmp(msg, cur->data, strlen(msg)) && (cur->data[strlen(msg)] < 33)))) {
02119          if (!resp && (seqno == p->pendinginvite)) {
02120             if (option_debug)
02121                ast_log(LOG_DEBUG, "Acked pending invite %d\n", p->pendinginvite);
02122             p->pendinginvite = 0;
02123          }
02124          /* this is our baby */
02125          res = TRUE;
02126          UNLINK(cur, p->packets, prev);
02127          if (cur->retransid > -1) {
02128             if (sipdebug && option_debug > 3)
02129                ast_log(LOG_DEBUG, "** SIP TIMER: Cancelling retransmit of packet (reply received) Retransid #%d\n", cur->retransid);
02130             ast_sched_del(sched, cur->retransid);
02131             cur->retransid = -1;
02132          }
02133          free(cur);
02134          break;
02135       }
02136    }
02137    ast_mutex_unlock(&p->lock);
02138    if (option_debug)
02139       ast_log(LOG_DEBUG, "Stopping retransmission on '%s' of %s %d: Match %s\n", p->callid, resp ? "Response" : "Request", seqno, res ? "Not Found" : "Found");
02140 }

static int __sip_autodestruct ( void *  data  )  [static]

Kill a SIP dialog (called by scheduler).

Definition at line 2038 of file chan_sip.c.

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

Referenced by sip_scheddestroy().

02039 {
02040    struct sip_pvt *p = data;
02041 
02042    /* If this is a subscription, tell the phone that we got a timeout */
02043    if (p->subscribed) {
02044       transmit_state_notify(p, AST_EXTENSION_DEACTIVATED, 1, TRUE);  /* Send last notification */
02045       p->subscribed = NONE;
02046       append_history(p, "Subscribestatus", "timeout");
02047       if (option_debug > 2)
02048          ast_log(LOG_DEBUG, "Re-scheduled destruction of SIP subsription %s\n", p->callid ? p->callid : "<unknown>");
02049       return 10000;  /* Reschedule this destruction so that we know that it's gone */
02050    }
02051 
02052    /* If we're destroying a subscription, dereference peer object too */
02053    if (p->subscribed == MWI_NOTIFICATION && p->relatedpeer)
02054       ASTOBJ_UNREF(p->relatedpeer,sip_destroy_peer);
02055 
02056    /* Reset schedule ID */
02057    p->autokillid = -1;
02058 
02059    if (option_debug)
02060       ast_log(LOG_DEBUG, "Auto destroying SIP dialog '%s'\n", p->callid);
02061    append_history(p, "AutoDestroy", "%s", p->callid);
02062    if (p->owner) {
02063       ast_log(LOG_WARNING, "Autodestruct on dialog '%s' with owner in place (Method: %s)\n", p->callid, sip_methods[p->method].text);
02064       ast_queue_hangup(p->owner);
02065    } else if (p->refer) {
02066       if (option_debug > 2)
02067          ast_log(LOG_DEBUG, "Finally hanging up channel after transfer: %s\n", p->callid);
02068       transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, 1);
02069       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
02070    } else
02071       sip_destroy(p);
02072    return 0;
02073 }

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

Execute destruction of SIP dialog structure, release memory.

Definition at line 2990 of file chan_sip.c.

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

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

02991 {
02992    struct sip_pvt *cur, *prev = NULL;
02993    struct sip_pkt *cp;
02994 
02995    if (sip_debug_test_pvt(p) || option_debug > 2)
02996       ast_verbose("Really destroying SIP dialog '%s' Method: %s\n", p->callid, sip_methods[p->method].text);
02997 
02998    if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) {
02999       update_call_counter(p, DEC_CALL_LIMIT);
03000       if (option_debug > 1)
03001          ast_log(LOG_DEBUG, "This call did not properly clean up call limits. Call ID %s\n", p->callid);
03002    }
03003 
03004    /* Remove link from peer to subscription of MWI */
03005    if (p->relatedpeer && p->relatedpeer->mwipvt)
03006       p->relatedpeer->mwipvt = NULL;
03007 
03008    if (dumphistory)
03009       sip_dump_history(p);
03010 
03011    if (p->options)
03012       free(p->options);
03013 
03014    if (p->stateid > -1)
03015       ast_extension_state_del(p->stateid, NULL);
03016    if (p->initid > -1)
03017       ast_sched_del(sched, p->initid);
03018    if (p->autokillid > -1)
03019       ast_sched_del(sched, p->autokillid);
03020 
03021    if (p->rtp)
03022       ast_rtp_destroy(p->rtp);
03023    if (p->vrtp)
03024       ast_rtp_destroy(p->vrtp);
03025    if (p->udptl)
03026       ast_udptl_destroy(p->udptl);
03027    if (p->refer)
03028       free(p->refer);
03029    if (p->route) {
03030       free_old_route(p->route);
03031       p->route = NULL;
03032    }
03033    if (p->registry) {
03034       if (p->registry->call == p)
03035          p->registry->call = NULL;
03036       ASTOBJ_UNREF(p->registry, sip_registry_destroy);
03037    }
03038 
03039    /* Unlink us from the owner if we have one */
03040    if (p->owner) {
03041       if (lockowner)
03042          ast_channel_lock(p->owner);
03043       if (option_debug)
03044          ast_log(LOG_DEBUG, "Detaching from %s\n", p->owner->name);
03045       p->owner->tech_pvt = NULL;
03046       if (lockowner)
03047          ast_channel_unlock(p->owner);
03048    }
03049    /* Clear history */
03050    if (p->history) {
03051       struct sip_history *hist;
03052       while( (hist = AST_LIST_REMOVE_HEAD(p->history, list)) )
03053          free(hist);
03054       free(p->history);
03055       p->history = NULL;
03056    }
03057 
03058    for (prev = NULL, cur = iflist; cur; prev = cur, cur = cur->next) {
03059       if (cur == p) {
03060          UNLINK(cur, iflist, prev);
03061          break;
03062       }
03063    }
03064    if (!cur) {
03065       ast_log(LOG_WARNING, "Trying to destroy \"%s\", not found in dialog list?!?! \n", p->callid);
03066       return;
03067    } 
03068 
03069    /* remove all current packets in this dialog */
03070    while((cp = p->packets)) {
03071       p->packets = p->packets->next;
03072       if (cp->retransid > -1)
03073          ast_sched_del(sched, cp->retransid);
03074       free(cp);
03075    }
03076    if (p->chanvars) {
03077       ast_variables_destroy(p->chanvars);
03078       p->chanvars = NULL;
03079    }
03080    ast_mutex_destroy(&p->lock);
03081 
03082    ast_string_field_free_pools(p);
03083 
03084    free(p);
03085 }

static int __sip_do_register ( struct sip_registry r  )  [static]

Register with SIP proxy.

Definition at line 7280 of file chan_sip.c.

References SIP_REGISTER, and transmit_register().

Referenced by sip_reregister().

07281 {
07282    int res;
07283 
07284    res = transmit_register(r, SIP_REGISTER, NULL, NULL);
07285    return res;
07286 }

static void __sip_pretend_ack ( struct sip_pvt p  )  [static]

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

Definition at line 2144 of file chan_sip.c.

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

Referenced by sip_hangup(), and sip_reg_timeout().

02145 {
02146    struct sip_pkt *cur = NULL;
02147 
02148    while (p->packets) {
02149       int method;
02150       if (cur == p->packets) {
02151          ast_log(LOG_WARNING, "Have a packet that doesn't want to give up! %s\n", sip_methods[cur->method].text);
02152          return;
02153       }
02154       cur = p->packets;
02155       method = (cur->method) ? cur->method : find_sip_method(cur->data);
02156       __sip_ack(p, cur->seqno, ast_test_flag(cur, FLAG_RESPONSE), method);
02157    }
02158 }

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

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

Referenced by send_request(), and send_response().

01993 {
01994    struct sip_pkt *pkt;
01995    int siptimer_a = DEFAULT_RETRANS;
01996    int xmitres = 0;
01997 
01998    if (!(pkt = ast_calloc(1, sizeof(*pkt) + len + 1)))
01999       return AST_FAILURE;
02000    memcpy(pkt->data, data, len);
02001    pkt->method = sipmethod;
02002    pkt->packetlen = len;
02003    pkt->next = p->packets;
02004    pkt->owner = p;
02005    pkt->seqno = seqno;
02006    if (resp)
02007       ast_set_flag(pkt, FLAG_RESPONSE);
02008    pkt->data[len] = '\0';
02009    pkt->timer_t1 = p->timer_t1;  /* Set SIP timer T1 */
02010    if (fatal)
02011       ast_set_flag(pkt, FLAG_FATAL);
02012    if (pkt->timer_t1)
02013       siptimer_a = pkt->timer_t1 * 2;
02014 
02015    /* Schedule retransmission */
02016    pkt->retransid = ast_sched_add_variable(sched, siptimer_a, retrans_pkt, pkt, 1);
02017    if (option_debug > 3 && sipdebug)
02018       ast_log(LOG_DEBUG, "*** SIP TIMER: Initalizing retransmit timer on packet: Id  #%d\n", pkt->retransid);
02019    pkt->next = p->packets;
02020    p->packets = pkt;
02021    if (sipmethod == SIP_INVITE) {
02022       /* Note this is a pending invite */
02023       p->pendinginvite = seqno;
02024    }
02025 
02026    xmitres = __sip_xmit(pkt->owner, pkt->data, pkt->packetlen);   /* Send packet */
02027 
02028    if (xmitres == XMIT_ERROR) {  /* Serious network trouble, no need to try again */
02029       append_history(pkt->owner, "XmitErr", "%s", (ast_test_flag(pkt, FLAG_FATAL)) ? "(Critical)" : "(Non-critical)");
02030       ast_sched_del(sched, pkt->retransid);  /* No more retransmission */
02031       pkt->retransid = -1;
02032       return AST_FAILURE;
02033    } else
02034       return AST_SUCCESS;
02035 }

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

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

Referenced by handle_response().

02162 {
02163    struct sip_pkt *cur;
02164    int res = -1;
02165 
02166    for (cur = p->packets; cur; cur = cur->next) {
02167       if (cur->seqno == seqno && ast_test_flag(cur, FLAG_RESPONSE) == resp &&
02168          (ast_test_flag(cur, FLAG_RESPONSE) || method_match(sipmethod, cur->data))) {
02169          /* this is our baby */
02170          if (cur->retransid > -1) {
02171             if (option_debug > 3 && sipdebug)
02172                ast_log(LOG_DEBUG, "*** SIP TIMER: Cancelling retransmission #%d - %s (got response)\n", cur->retransid, sip_methods[sipmethod].text);
02173             ast_sched_del(sched, cur->retransid);
02174             cur->retransid = -1;
02175          }
02176          res = 0;
02177          break;
02178       }
02179    }
02180    if (option_debug)
02181       ast_log(LOG_DEBUG, "(Provisional) Stopping retransmission (but retaining packet) on '%s' %s %d: %s\n", p->callid, resp ? "Response" : "Request", seqno, res ? "Not Found" : "Found");
02182    return res;
02183 }

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

SIP show channels CLI (main function).

Definition at line 10558 of file chan_sip.c.

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

Referenced by sip_show_channels(), and sip_show_subscriptions().

10559 {
10560 #define FORMAT3 "%-15.15s  %-10.10s  %-11.11s  %-15.15s  %-13.13s  %-15.15s %-10.10s\n"
10561 #define FORMAT2 "%-15.15s  %-10.10s  %-11.11s  %-11.11s  %-4.4s  %-7.7s  %-15.15s\n"
10562 #define FORMAT  "%-15.15s  %-10.10s  %-11.11s  %5.5d/%5.5d  %-4.4s  %-3.3s %-3.3s  %-15.15s %-10.10s\n"
10563    struct sip_pvt *cur;
10564    int numchans = 0;
10565    char *referstatus = NULL;
10566 
10567    if (argc != 3)
10568       return RESULT_SHOWUSAGE;
10569    ast_mutex_lock(&iflock);
10570    cur = iflist;
10571    if (!subscriptions)
10572       ast_cli(fd, FORMAT2, "Peer", "User/ANR", "Call ID", "Seq (Tx/Rx)", "Format", "Hold", "Last Message");
10573    else 
10574       ast_cli(fd, FORMAT3, "Peer", "User", "Call ID", "Extension", "Last state", "Type", "Mailbox");
10575    for (; cur; cur = cur->next) {
10576       referstatus = "";
10577       if (cur->refer) { /* SIP transfer in progress */
10578          referstatus = referstatus2str(cur->refer->status);
10579       }
10580       if (cur->subscribed == NONE && !subscriptions) {
10581          ast_cli(fd, FORMAT, ast_inet_ntoa(cur->sa.sin_addr), 
10582             S_OR(cur->username, S_OR(cur->cid_num, "(None)")),
10583             cur->callid, 
10584             cur->ocseq, cur->icseq, 
10585             ast_getformatname(cur->owner ? cur->owner->nativeformats : 0), 
10586             ast_test_flag(&cur->flags[1], SIP_PAGE2_CALL_ONHOLD) ? "Yes" : "No",
10587             ast_test_flag(&cur->flags[0], SIP_NEEDDESTROY) ? "(d)" : "",
10588             cur->lastmsg ,
10589             referstatus
10590          );
10591          numchans++;
10592       }
10593       if (cur->subscribed != NONE && subscriptions) {
10594          ast_cli(fd, FORMAT3, ast_inet_ntoa(cur->sa.sin_addr),
10595             S_OR(cur->username, S_OR(cur->cid_num, "(None)")), 
10596                cur->callid,
10597             /* the 'complete' exten/context is hidden in the refer_to field for subscriptions */
10598             cur->subscribed == MWI_NOTIFICATION ? "--" : cur->subscribeuri,
10599             cur->subscribed == MWI_NOTIFICATION ? "<none>" : ast_extension_state2str(cur->laststate), 
10600             subscription_type2str(cur->subscribed),
10601             cur->subscribed == MWI_NOTIFICATION ? (cur->relatedpeer ? cur->relatedpeer->mailbox : "<none>") : "<none>"
10602 );
10603          numchans++;
10604       }
10605    }
10606    ast_mutex_unlock(&iflock);
10607    if (!subscriptions)
10608       ast_cli(fd, "%d active SIP channel%s\n", numchans, (numchans != 1) ? "s" : "");
10609    else
10610       ast_cli(fd, "%d active SIP subscription%s\n", numchans, (numchans != 1) ? "s" : "");
10611    return RESULT_SUCCESS;
10612 #undef FORMAT
10613 #undef FORMAT2
10614 #undef FORMAT3
10615 }

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

Transmit SIP message.

Definition at line 1755 of file chan_sip.c.

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

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

01756 {
01757    int res;
01758    const struct sockaddr_in *dst = sip_real_dst(p);
01759    res = sendto(sipsock, data, len, 0, (const struct sockaddr *)dst, sizeof(struct sockaddr_in));
01760 
01761    if (res == -1) {
01762       switch (errno) {
01763          case EBADF:       /* Bad file descriptor - seems like this is generated when the host exist, but doesn't accept the UDP packet */
01764          case EHOSTUNREACH:   /* Host can't be reached */
01765          case ENETDOWN:       /* Inteface down */
01766          case ENETUNREACH: /* Network failure */
01767             res = XMIT_ERROR; /* Don't bother with trying to transmit again */
01768       }
01769    }
01770    if (res != len)
01771       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));
01772    return res;
01773 }

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

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

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

05844 {
05845    struct sip_request resp;
05846    int seqno = 0;
05847 
05848    if (reliable && (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1)) {
05849       ast_log(LOG_WARNING, "Unable to determine sequence number from '%s'\n", get_header(req, "CSeq"));
05850       return -1;
05851    }
05852    respprep(&resp, p, msg, req);
05853    add_header_contentLength(&resp, 0);
05854    /* If we are cancelling an incoming invite for some reason, add information
05855       about the reason why we are doing this in clear text */
05856    if (p->method == SIP_INVITE && msg[0] != '1' && p->owner && p->owner->hangupcause) {
05857       char buf[10];
05858 
05859       add_header(&resp, "X-Asterisk-HangupCause", ast_cause2str(p->owner->hangupcause));
05860       snprintf(buf, sizeof(buf), "%d", p->owner->hangupcause);
05861       add_header(&resp, "X-Asterisk-HangupCauseCode", buf);
05862    }
05863    return send_response(p, &resp, reliable, seqno);
05864 }

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

References sip_peer::accountcode, sip_peer::addr, sip_peer::allowtransfer, sip_peer::amaflags, ast_callerid_merge(), ast_cdr_flags2str(), ast_check_realtime(), ast_cli(), ast_codec_pref_index(), ast_describe_caller_presentation(), ast_getformatname(), ast_getformatname_multiple(), ast_inet_ntoa(), ast_print_group(), ast_sched_when(), ast_strlen_zero(), ast_test_flag, astman_append(), astman_get_header(), astman_send_error(), ASTOBJ_UNREF, sip_peer::auth, sip_peer::autoframing, sip_peer::call_limit, sip_peer::callgroup, sip_peer::callingpres, sip_peer::capability, sip_peer::chanvars, sip_peer::cid_name, sip_peer::cid_num, sip_peer::context, sip_peer::defaddr, dtmfmode2str(), sip_peer::expire, FALSE, find_peer(), sip_peer::flags, sip_peer::fromdomain, sip_peer::fromuser, sip_peer::fullcontact, sip_peer::ha, cfsip_options::id, insecure2str(), sip_peer::language, sip_peer::lastmsg, sip_peer::lastmsgssent, sip_peer::mailbox, sip_peer::maxcallbitrate, sip_auth::md5secret, sip_peer::md5secret, ast_variable::name, nat2str(), ast_variable::next, sip_auth::next, peer_status(), sip_peer::pickupgroup, sip_peer::prefs, print_codec_to_cli(), print_group(), sip_auth::realm, sip_peer::regexten, RESULT_SHOWUSAGE, RESULT_SUCCESS, S_OR, sip_auth::secret, sip_peer::secret, SIP_CAN_REINVITE, sip_destroy_peer(), SIP_DTMF, SIP_INSECURE_INVITE, SIP_INSECURE_PORT, SIP_NAT, sip_options, SIP_PAGE2_ALLOWOVERLAP, SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PAGE2_DYNAMIC, SIP_PAGE2_T38SUPPORT_RTP, SIP_PAGE2_T38SUPPORT_TCP, SIP_PAGE2_T38SUPPORT_UDPTL, SIP_PAGE2_VIDEOSUPPORT, SIP_PROMISCREDIR, SIP_REALTIME, SIP_SENDRPID, SIP_TRUSTRPID, SIP_USEREQPHONE, sip_peer::sipoptions, sip_peer::subscribecontext, text, sip_peer::tohost, transfermode2str(), TRUE, sip_peer::useragent, sip_peer::username, sip_auth::username, ast_variable::value, and sip_peer::vmexten.

Referenced by manager_sip_show_peer(), and sip_show_peer().

10117 {
10118    char status[30] = "";
10119    char cbuf[256];
10120    struct sip_peer *peer;
10121    char codec_buf[512];
10122    struct ast_codec_pref *pref;
10123    struct ast_variable *v;
10124    struct sip_auth *auth;
10125    int x = 0, codec = 0, load_realtime;
10126    int realtimepeers;
10127 
10128    realtimepeers = ast_check_realtime("sippeers");
10129 
10130    if (argc < 4)
10131       return RESULT_SHOWUSAGE;
10132 
10133    load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? TRUE : FALSE;
10134    peer = find_peer(argv[3], NULL, load_realtime);
10135    if (s) {    /* Manager */
10136       if (peer) {
10137          const char *id = astman_get_header(m,"ActionID");
10138 
10139          astman_append(s, "Response: Success\r\n");
10140          if (!ast_strlen_zero(id))
10141             astman_append(s, "ActionID: %s\r\n",id);
10142       } else {
10143          snprintf (cbuf, sizeof(cbuf), "Peer %s not found.\n", argv[3]);
10144          astman_send_error(s, m, cbuf);
10145          return 0;
10146       }
10147    }
10148    if (peer && type==0 ) { /* Normal listing */
10149       ast_cli(fd,"\n\n");
10150       ast_cli(fd, "  * Name       : %s\n", peer->name);
10151       if (realtimepeers) { /* Realtime is enabled */
10152          ast_cli(fd, "  Realtime peer: %s\n", ast_test_flag(&peer->flags[0], SIP_REALTIME) ? "Yes, cached" : "No");
10153       }
10154       ast_cli(fd, "  Secret       : %s\n", ast_strlen_zero(peer->secret)?"<Not set>":"<Set>");
10155       ast_cli(fd, "  MD5Secret    : %s\n", ast_strlen_zero(peer->md5secret)?"<Not set>":"<Set>");
10156       for (auth = peer->auth; auth; auth = auth->next) {
10157          ast_cli(fd, "  Realm-auth   : Realm %-15.15s User %-10.20s ", auth->realm, auth->username);
10158          ast_cli(fd, "%s\n", !ast_strlen_zero(auth->secret)?"<Secret set>":(!ast_strlen_zero(auth->md5secret)?"<MD5secret set>" : "<Not set>"));
10159       }
10160       ast_cli(fd, "  Context      : %s\n", peer->context);
10161       ast_cli(fd, "  Subscr.Cont. : %s\n", S_OR(peer->subscribecontext, "<Not set>") );
10162       ast_cli(fd, "  Language     : %s\n", peer->language);
10163       if (!ast_strlen_zero(peer->accountcode))
10164          ast_cli(fd, "  Accountcode  : %s\n", peer->accountcode);
10165       ast_cli(fd, "  AMA flags    : %s\n", ast_cdr_flags2str(peer->amaflags));
10166       ast_cli(fd, "  Transfer mode: %s\n", transfermode2str(peer->allowtransfer));
10167       ast_cli(fd, "  CallingPres  : %s\n", ast_describe_caller_presentation(peer->callingpres));
10168       if (!ast_strlen_zero(peer->fromuser))
10169          ast_cli(fd, "  FromUser     : %s\n", peer->fromuser);
10170       if (!ast_strlen_zero(peer->fromdomain))
10171          ast_cli(fd, "  FromDomain   : %s\n", peer->fromdomain);
10172       ast_cli(fd, "  Callgroup    : ");
10173       print_group(fd, peer->callgroup, 0);
10174       ast_cli(fd, "  Pickupgroup  : ");
10175       print_group(fd, peer->pickupgroup, 0);
10176       ast_cli(fd, "  Mailbox      : %s\n", peer->mailbox);
10177       ast_cli(fd, "  VM Extension : %s\n", peer->vmexten);
10178       ast_cli(fd, "  LastMsgsSent : %d/%d\n", (peer->lastmsgssent & 0x7fff0000) >> 16, peer->lastmsgssent & 0xffff);
10179       ast_cli(fd, "  Call limit   : %d\n", peer->call_limit);
10180       ast_cli(fd, "  Dynamic      : %s\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)?"Yes":"No"));
10181       ast_cli(fd, "  Callerid     : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>"));
10182       ast_cli(fd, "  MaxCallBR    : %d kbps\n", peer->maxcallbitrate);
10183       ast_cli(fd, "  Expire       : %ld\n", ast_sched_when(sched, peer->expire));
10184       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)));
10185       ast_cli(fd, "  Nat          : %s\n", nat2str(ast_test_flag(&peer->flags[0], SIP_NAT)));
10186       ast_cli(fd, "  ACL          : %s\n", (peer->ha?"Yes":"No"));
10187       ast_cli(fd, "  T38 pt UDPTL : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT_UDPTL)?"Yes":"No");
10188 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS
10189       ast_cli(fd, "  T38 pt RTP   : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT_RTP)?"Yes":"No");
10190       ast_cli(fd, "  T38 pt TCP   : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT_TCP)?"Yes":"No");
10191 #endif
10192       ast_cli(fd, "  CanReinvite  : %s\n", ast_test_flag(&peer->flags[0], SIP_CAN_REINVITE)?"Yes":"No");
10193       ast_cli(fd, "  PromiscRedir : %s\n", ast_test_flag(&peer->flags[0], SIP_PROMISCREDIR)?"Yes":"No");
10194       ast_cli(fd, "  User=Phone   : %s\n", ast_test_flag(&peer->flags[0], SIP_USEREQPHONE)?"Yes":"No");
10195       ast_cli(fd, "  Video Support: %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_VIDEOSUPPORT)?"Yes":"No");
10196       ast_cli(fd, "  Trust RPID   : %s\n", ast_test_flag(&peer->flags[0], SIP_TRUSTRPID) ? "Yes" : "No");
10197       ast_cli(fd, "  Send RPID    : %s\n", ast_test_flag(&peer->flags[0], SIP_SENDRPID) ? "Yes" : "No");
10198       ast_cli(fd, "  Subscriptions: %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE) ? "Yes" : "No");
10199       ast_cli(fd, "  Overlap dial : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWOVERLAP) ? "Yes" : "No");
10200 
10201       /* - is enumerated */
10202       ast_cli(fd, "  DTMFmode     : %s\n", dtmfmode2str(ast_test_flag(&peer->flags[0], SIP_DTMF)));
10203       ast_cli(fd, "  LastMsg      : %d\n", peer->lastmsg);
10204       ast_cli(fd, "  ToHost       : %s\n", peer->tohost);
10205       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));
10206       ast_cli(fd, "  Defaddr->IP  : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port));
10207       if (!ast_strlen_zero(global_regcontext))
10208          ast_cli(fd, "  Reg. exten   : %s\n", peer->regexten);
10209       ast_cli(fd, "  Def. Username: %s\n", peer->username);
10210       ast_cli(fd, "  SIP Options  : ");
10211       if (peer->sipoptions) {
10212          int lastoption = -1;
10213          for (x=0 ; (x < (sizeof(sip_options) / sizeof(sip_options[0]))); x++) {
10214             if (sip_options[x].id != lastoption) {
10215                if (peer->sipoptions & sip_options[x].id)
10216                   ast_cli(fd, "%s ", sip_options[x].text);
10217                lastoption = x;
10218             }
10219          }
10220       } else
10221          ast_cli(fd, "(none)");
10222 
10223       ast_cli(fd, "\n");
10224       ast_cli(fd, "  Codecs       : ");
10225       ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability);
10226       ast_cli(fd, "%s\n", codec_buf);
10227       ast_cli(fd, "  Codec Order  : (");
10228       print_codec_to_cli(fd, &peer->prefs);
10229       ast_cli(fd, ")\n");
10230 
10231       ast_cli(fd, "  Auto-Framing:  %s \n", peer->autoframing ? "Yes" : "No");
10232       ast_cli(fd, "  Status       : ");
10233       peer_status(peer, status, sizeof(status));
10234       ast_cli(fd, "%s\n",status);
10235       ast_cli(fd, "  Useragent    : %s\n", peer->useragent);
10236       ast_cli(fd, "  Reg. Contact : %s\n", peer->fullcontact);
10237       if (peer->chanvars) {
10238          ast_cli(fd, "  Variables    :\n");
10239          for (v = peer->chanvars ; v ; v = v->next)
10240             ast_cli(fd, "                 %s = %s\n", v->name, v->value);
10241       }
10242       ast_cli(fd,"\n");
10243       ASTOBJ_UNREF(peer,sip_destroy_peer);
10244    } else  if (peer && type == 1) { /* manager listing */
10245       char buf[256];
10246       astman_append(s, "Channeltype: SIP\r\n");
10247       astman_append(s, "ObjectName: %s\r\n", peer->name);
10248       astman_append(s, "ChanObjectType: peer\r\n");
10249       astman_append(s, "SecretExist: %s\r\n", ast_strlen_zero(peer->secret)?"N":"Y");
10250       astman_append(s, "MD5SecretExist: %s\r\n", ast_strlen_zero(peer->md5secret)?"N":"Y");
10251       astman_append(s, "Context: %s\r\n", peer->context);
10252       astman_append(s, "Language: %s\r\n", peer->language);
10253       if (!ast_strlen_zero(peer->accountcode))
10254          astman_append(s, "Accountcode: %s\r\n", peer->accountcode);
10255       astman_append(s, "AMAflags: %s\r\n", ast_cdr_flags2str(peer->amaflags));
10256       astman_append(s, "CID-CallingPres: %s\r\n", ast_describe_caller_presentation(peer->callingpres));
10257       if (!ast_strlen_zero(peer->fromuser))
10258          astman_append(s, "SIP-FromUser: %s\r\n", peer->fromuser);
10259       if (!ast_strlen_zero(peer->fromdomain))
10260          astman_append(s, "SIP-FromDomain: %s\r\n", peer->fromdomain);
10261       astman_append(s, "Callgroup: ");
10262       astman_append(s, "%s\r\n", ast_print_group(buf, sizeof(buf), peer->callgroup));
10263       astman_append(s, "Pickupgroup: ");
10264       astman_append(s, "%s\r\n", ast_print_group(buf, sizeof(buf), peer->pickupgroup));
10265       astman_append(s, "VoiceMailbox: %s\r\n", peer->mailbox);
10266       astman_append(s, "TransferMode: %s\r\n", transfermode2str(peer->allowtransfer));
10267       astman_append(s, "LastMsgsSent: %d\r\n", peer->lastmsgssent);
10268       astman_append(s, "Call-limit: %d\r\n", peer->call_limit);
10269       astman_append(s, "MaxCallBR: %d kbps\r\n", peer->maxcallbitrate);
10270       astman_append(s, "Dynamic: %s\r\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)?"Y":"N"));
10271       astman_append(s, "Callerid: %s\r\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, ""));
10272       astman_append(s, "RegExpire: %ld seconds\r\n", ast_sched_when(sched,peer->expire));
10273       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)));
10274       astman_append(s, "SIP-NatSupport: %s\r\n", nat2str(ast_test_flag(&peer->flags[0], SIP_NAT)));
10275       astman_append(s, "ACL: %s\r\n", (peer->ha?"Y":"N"));
10276       astman_append(s, "SIP-CanReinvite: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_CAN_REINVITE)?"Y":"N"));
10277       astman_append(s, "SIP-PromiscRedir: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_PROMISCREDIR)?"Y":"N"));
10278       astman_append(s, "SIP-UserPhone: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_USEREQPHONE)?"Y":"N"));
10279       astman_append(s, "SIP-VideoSupport: %s\r\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_VIDEOSUPPORT)?"Y":"N"));
10280 
10281       /* - is enumerated */
10282       astman_append(s, "SIP-DTMFmode: %s\r\n", dtmfmode2str(ast_test_flag(&peer->flags[0], SIP_DTMF)));
10283       astman_append(s, "SIPLastMsg: %d\r\n", peer->lastmsg);
10284       astman_append(s, "ToHost: %s\r\n", peer->tohost);
10285       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));
10286       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));
10287       astman_append(s, "Default-Username: %s\r\n", peer->username);
10288       if (!ast_strlen_zero(global_regcontext))
10289          astman_append(s, "RegExtension: %s\r\n", peer->regexten);
10290       astman_append(s, "Codecs: ");
10291       ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability);
10292       astman_append(s, "%s\r\n", codec_buf);
10293       astman_append(s, "CodecOrder: ");
10294       pref = &peer->prefs;
10295       for(x = 0; x < 32 ; x++) {
10296          codec = ast_codec_pref_index(pref,x);
10297          if (!codec)
10298             break;
10299          astman_append(s, "%s", ast_getformatname(codec));
10300          if (x < 31 && ast_codec_pref_index(pref,x+1))
10301             astman_append(s, ",");
10302       }
10303 
10304       astman_append(s, "\r\n");
10305       astman_append(s, "Status: ");
10306       peer_status(peer, status, sizeof(status));
10307       astman_append(s, "%s\r\n", status);
10308       astman_append(s, "SIP-Useragent: %s\r\n", peer->useragent);
10309       astman_append(s, "Reg-Contact : %s\r\n", peer->fullcontact);
10310       if (peer->chanvars) {
10311          for (v = peer->chanvars ; v ; v = v->next) {
10312             astman_append(s, "ChanVariable:\n");
10313             astman_append(s, " %s,%s\r\n", v->name, v->value);
10314          }
10315       }
10316 
10317       ASTOBJ_UNREF(peer,sip_destroy_peer);
10318 
10319    } else {
10320       ast_cli(fd,"Peer %s not found.\n", argv[3]);
10321       ast_cli(fd,"\n");
10322    }
10323 
10324    return RESULT_SUCCESS;
10325 }

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

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

Referenced by manager_sip_show_peers(), and sip_show_peers().

09667 {
09668    regex_t regexbuf;
09669    int havepattern = FALSE;
09670 
09671 #define FORMAT2 "%-25.25s  %-15.15s %-3.3s %-3.3s %-3.3s %-8s %-10s %-10s\n"
09672 #define FORMAT  "%-25.25s  %-15.15s %-3.3s %-3.3s %-3.3s %-8d %-10s %-10s\n"
09673 
09674    char name[256];
09675    int total_peers = 0;
09676    int peers_mon_online = 0;
09677    int peers_mon_offline = 0;
09678    int peers_unmon_offline = 0;
09679    int peers_unmon_online = 0;
09680    const char *id;
09681    char idtext[256] = "";
09682    int realtimepeers;
09683 
09684    realtimepeers = ast_check_realtime("sippeers");
09685 
09686    if (s) { /* Manager - get ActionID */
09687       id = astman_get_header(m,"ActionID");
09688       if (!ast_strlen_zero(id))
09689          snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
09690    }
09691 
09692    switch (argc) {
09693    case 5:
09694       if (!strcasecmp(argv[3], "like")) {
09695          if (regcomp(&regexbuf, argv[4], REG_EXTENDED | REG_NOSUB))
09696             return RESULT_SHOWUSAGE;
09697          havepattern = TRUE;
09698       } else
09699          return RESULT_SHOWUSAGE;
09700    case 3:
09701       break;
09702    default:
09703       return RESULT_SHOWUSAGE;
09704    }
09705 
09706    if (!s) /* Normal list */
09707       ast_cli(fd, FORMAT2, "Name/username", "Host", "Dyn", "Nat", "ACL", "Port", "Status", (realtimepeers ? "Realtime" : ""));
09708    
09709    ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do {
09710       char status[20] = "";
09711       char srch[2000];
09712       char pstatus;
09713       
09714       ASTOBJ_RDLOCK(iterator);
09715 
09716       if (havepattern && regexec(&regexbuf, iterator->name, 0, NULL, 0)) {
09717          ASTOBJ_UNLOCK(iterator);
09718          continue;
09719       }
09720 
09721       if (!ast_strlen_zero(iterator->username) && !s)
09722          snprintf(name, sizeof(name), "%s/%s", iterator->name, iterator->username);
09723       else
09724          ast_copy_string(name, iterator->name, sizeof(name));
09725       
09726       pstatus = peer_status(iterator, status, sizeof(status));
09727       if (pstatus == 1)
09728          peers_mon_online++;
09729       else if (pstatus == 0)
09730          peers_mon_offline++;
09731       else {
09732          if (iterator->addr.sin_port == 0)
09733             peers_unmon_offline++;
09734          else
09735             peers_unmon_online++;
09736       }
09737 
09738       snprintf(srch, sizeof(srch), FORMAT, name,
09739          iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iterator->addr.sin_addr) : "(Unspecified)",
09740          ast_test_flag(&iterator->flags[1], SIP_PAGE2_DYNAMIC) ? " D " : "   ",  /* Dynamic or not? */
09741          ast_test_flag(&iterator->flags[0], SIP_NAT_ROUTE) ? " N " : "   ",   /* NAT=yes? */
09742          iterator->ha ? " A " : "   ",    /* permit/deny */
09743          ntohs(iterator->addr.sin_port), status,
09744          realtimepeers ? (ast_test_flag(&iterator->flags[0], SIP_REALTIME) ? "Cached RT":"") : "");
09745 
09746       if (!s)  {/* Normal CLI list */
09747          ast_cli(fd, FORMAT, name, 
09748          iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iterator->addr.sin_addr) : "(Unspecified)",
09749          ast_test_flag(&iterator->flags[1], SIP_PAGE2_DYNAMIC) ? " D " : "   ",  /* Dynamic or not? */
09750          ast_test_flag(&iterator->flags[0], SIP_NAT_ROUTE) ? " N " : "   ",   /* NAT=yes? */
09751          iterator->ha ? " A " : "   ",       /* permit/deny */
09752          
09753          ntohs(iterator->addr.sin_port), status,
09754          realtimepeers ? (ast_test_flag(&iterator->flags[0], SIP_REALTIME) ? "Cached RT":"") : "");
09755       } else { /* Manager format */
09756          /* The names here need to be the same as other channels */
09757          astman_append(s, 
09758          "Event: PeerEntry\r\n%s"
09759          "Channeltype: SIP\r\n"
09760          "ObjectName: %s\r\n"
09761          "ChanObjectType: peer\r\n" /* "peer" or "user" */
09762          "IPaddress: %s\r\n"
09763          "IPport: %d\r\n"
09764          "Dynamic: %s\r\n"
09765          "Natsupport: %s\r\n"
09766          "VideoSupport: %s\r\n"
09767          "ACL: %s\r\n"
09768          "Status: %s\r\n"
09769          "RealtimeDevice: %s\r\n\r\n", 
09770          idtext,
09771          iterator->name, 
09772          iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iterator->addr.sin_addr) : "-none-",
09773          ntohs(iterator->addr.sin_port), 
09774          ast_test_flag(&iterator->flags[1], SIP_PAGE2_DYNAMIC) ? "yes" : "no",   /* Dynamic or not? */
09775          ast_test_flag(&iterator->flags[0], SIP_NAT_ROUTE) ? "yes" : "no", /* NAT=yes? */
09776          ast_test_flag(&iterator->flags[1], SIP_PAGE2_VIDEOSUPPORT) ? "yes" : "no", /* VIDEOSUPPORT=yes? */
09777          iterator->ha ? "yes" : "no",       /* permit/deny */
09778          status,
09779          realtimepeers ? (ast_test_flag(&iterator->flags[0], SIP_REALTIME) ? "yes":"no") : "no");
09780       }
09781 
09782       ASTOBJ_UNLOCK(iterator);
09783 
09784       total_peers++;
09785    } while(0) );
09786    
09787    if (!s)
09788       ast_cli(fd, "%d sip peers [Monitored: %d online, %d offline Unmonitored: %d online, %d offline]\n",
09789               total_peers, peers_mon_online, peers_mon_offline, peers_unmon_online, peers_unmon_offline);
09790 
09791    if (havepattern)
09792       regfree(&regexbuf);
09793 
09794    if (total)
09795       *total = total_peers;
09796    
09797 
09798    return RESULT_SUCCESS;
09799 #undef FORMAT
09800 #undef FORMAT2
09801 }

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

Definition at line 14337 of file chan_sip.c.

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

14338 {
14339    struct ast_rtp_quality qos;
14340    struct sip_pvt *p = chan->tech_pvt;
14341    char *all = "", *parse = ast_strdupa(preparse);
14342    AST_DECLARE_APP_ARGS(args,
14343       AST_APP_ARG(param);
14344       AST_APP_ARG(type);
14345       AST_APP_ARG(field);
14346    );
14347    AST_STANDARD_APP_ARGS(args, parse);
14348 
14349    /* Sanity check */
14350    if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) {
14351       ast_log(LOG_ERROR, "Cannot call %s on a non-SIP channel\n", funcname);
14352       return 0;
14353    }
14354 
14355    if (strcasecmp(args.param, "rtpqos"))
14356       return 0;
14357 
14358    /* Default arguments of audio,all */
14359    if (ast_strlen_zero(args.type))
14360       args.type = "audio";
14361    if (ast_strlen_zero(args.field))
14362       args.field = "all";
14363 
14364    memset(buf, 0, buflen);
14365    memset(&qos, 0, sizeof(qos));
14366 
14367    if (strcasecmp(args.type, "AUDIO") == 0) {
14368       all = ast_rtp_get_quality(p->rtp, &qos);
14369    } else if (strcasecmp(args.type, "VIDEO") == 0) {
14370       all = ast_rtp_get_quality(p->vrtp, &qos);
14371    }
14372 
14373    if (strcasecmp(args.field, "local_ssrc") == 0)
14374       snprintf(buf, buflen, "%u", qos.local_ssrc);
14375    else if (strcasecmp(args.field, "local_lostpackets") == 0)
14376       snprintf(buf, buflen, "%u", qos.local_lostpackets);
14377    else if (strcasecmp(args.field, "local_jitter") == 0)
14378       snprintf(buf, buflen, "%.0lf", qos.local_jitter * 1000.0);
14379    else if (strcasecmp(args.field, "local_count") == 0)
14380       snprintf(buf, buflen, "%u", qos.local_count);
14381    else if (strcasecmp(args.field, "remote_ssrc") == 0)
14382       snprintf(buf, buflen, "%u", qos.remote_ssrc);
14383    else if (strcasecmp(args.field, "remote_lostpackets") == 0)
14384       snprintf(buf, buflen, "%u", qos.remote_lostpackets);
14385    else if (strcasecmp(args.field, "remote_jitter") == 0)
14386       snprintf(buf, buflen, "%.0lf", qos.remote_jitter * 1000.0);
14387    else if (strcasecmp(args.field, "remote_count") == 0)
14388       snprintf(buf, buflen, "%u", qos.remote_count);
14389    else if (strcasecmp(args.field, "rtt") == 0)
14390       snprintf(buf, buflen, "%.0lf", qos.rtt * 1000.0);
14391    else if (strcasecmp(args.field, "all") == 0)
14392       ast_copy_string(buf, all, buflen);
14393    else {
14394       ast_log(LOG_WARNING, "Unrecognized argument '%s' to %s\n", preparse, funcname);
14395       return -1;
14396    }
14397    return 0;
14398 }

static void add_blank ( struct sip_request req  )  [static]

add a blank line if no body

Definition at line 2196 of file chan_sip.c.

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

Referenced by send_request(), and send_response().

02197 {
02198    if (!req->lines) {
02199       /* Add extra empty return. add_header() reserves 4 bytes so cannot be truncated */
02200       snprintf(req->data + req->len, sizeof(req->data) - req->len, "\r\n");
02201       req->len += strlen(req->data + req->len);
02202    }
02203 }

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

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

Referenced by add_sdp().

06050 {
06051    int rtp_code;
06052    struct ast_format_list fmt;
06053 
06054 
06055    if (debug)
06056       ast_verbose("Adding codec 0x%x (%s) to SDP\n", codec, ast_getformatname(codec));
06057    if ((rtp_code = ast_rtp_lookup_code(p->rtp, 1, codec)) == -1)
06058       return;
06059 
06060    if (p->rtp) {
06061       struct ast_codec_pref *pref = ast_rtp_codec_getpref(p->rtp);
06062       fmt = ast_codec_pref_getsize(pref, codec);
06063    } 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 */
06064       return;
06065    ast_build_string(m_buf, m_size, " %d", rtp_code);
06066    ast_build_string(a_buf, a_size, "a=rtpmap:%d %s/%d\r\n", rtp_code,
06067           ast_rtp_lookup_mime_subtype(1, codec,
06068                        ast_test_flag(&p->flags[0], SIP_G726_NONSTANDARD) ? AST_RTP_OPT_G726_NONSTANDARD : 0),
06069           sample_rate);
06070    if (codec == AST_FORMAT_G729A) {
06071       /* Indicate that we don't support VAD (G.729 annex B) */
06072       ast_build_string(a_buf, a_size, "a=fmtp:%d annexb=no\r\n", rtp_code);
06073    } else if (codec == AST_FORMAT_G723_1) {
06074       /* Indicate that we don't support VAD (G.723.1 annex A) */
06075       ast_build_string(a_buf, a_size, "a=fmtp:%d annexa=no\r\n", rtp_code);
06076    } else if (codec == AST_FORMAT_ILBC) {
06077       /* Add information about us using only 20/30 ms packetization */
06078       ast_build_string(a_buf, a_size, "a=fmtp:%d mode=%d\r\n", rtp_code, fmt.cur_ms);
06079    }
06080 
06081    if (fmt.cur_ms && (fmt.cur_ms < *min_packet_size))
06082       *min_packet_size = fmt.cur_ms;
06083 
06084    /* Our first codec packetization processed cannot be less than zero */
06085    if ((*min_packet_size) == 0  && fmt.cur_ms)
06086       *min_packet_size = fmt.cur_ms;
06087 }

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

Add DTMF INFO tone to sip message.

Definition at line 6015 of file chan_sip.c.

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

Referenced by transmit_info_with_digit().

06016 {
06017    char tmp[256];
06018 
06019    snprintf(tmp, sizeof(tmp), "Signal=%c\r\nDuration=%u\r\n", digit, duration);
06020    add_header(req, "Content-Type", "application/dtmf-relay");
06021    add_header_contentLength(req, strlen(tmp));
06022    add_line(req, tmp);
06023    return 0;
06024 }

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

Add header to SIP message.

Definition at line 5406 of file chan_sip.c.

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

05407 {
05408    int maxlen = sizeof(req->data) - 4 - req->len; /* 4 bytes are for two \r\n ? */
05409 
05410    if (req->headers == SIP_MAX_HEADERS) {
05411       ast_log(LOG_WARNING, "Out of SIP header space\n");
05412       return -1;
05413    }
05414 
05415    if (req->lines) {
05416       ast_log(LOG_WARNING, "Can't add more headers when lines have been added\n");
05417       return -1;
05418    }
05419 
05420    if (maxlen <= 0) {
05421       ast_log(LOG_WARNING, "Out of space, can't add anymore (%s:%s)\n", var, value);
05422       return -1;
05423    }
05424 
05425    req->header[req->headers] = req->data + req->len;
05426 
05427    if (compactheaders)
05428       var = find_alias(var, var);
05429 
05430    snprintf(req->header[req->headers], maxlen, "%s: %s\r\n", var, value);
05431    req->len += strlen(req->header[req->headers]);
05432    req->headers++;
05433    if (req->headers < SIP_MAX_HEADERS)
05434       req->headers++;
05435    else
05436       ast_log(LOG_WARNING, "Out of SIP header space... Will generate broken SIP message\n");
05437 
05438    return 0;   
05439 }

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

Add 'Content-Length' header to SIP message.

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

05443 {
05444    char clen[10];
05445 
05446    snprintf(clen, sizeof(clen), "%d", len);
05447    return add_header(req, "Content-Length", clen);
05448 }

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

Add content (not header) to SIP message.

Definition at line 5451 of file chan_sip.c.

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

05452 {
05453    if (req->lines == SIP_MAX_LINES)  {
05454       ast_log(LOG_WARNING, "Out of SIP line space\n");
05455       return -1;
05456    }
05457    if (!req->lines) {
05458       /* Add extra empty return */
05459       snprintf(req->data + req->len, sizeof(req->data) - req->len, "\r\n");
05460       req->len += strlen(req->data + req->len);
05461    }
05462    if (req->len >= sizeof(req->data) - 4) {
05463       ast_log(LOG_WARNING, "Out of space, can't add anymore\n");
05464       return -1;
05465    }
05466    req->line[req->lines] = req->data + req->len;
05467    snprintf(req->line[req->lines], sizeof(req->data) - req->len, "%s", line);
05468    req->len += strlen(req->line[req->lines]);
05469    req->lines++;
05470    return 0;   
05471 }

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

06226 {
06227    int rtp_code;
06228 
06229    if (debug)
06230       ast_verbose("Adding non-codec 0x%x (%s) to SDP\n", format, ast_rtp_lookup_mime_subtype(0, format, 0));
06231    if ((rtp_code = ast_rtp_lookup_code(p->rtp, 0, format)) == -1)
06232       return;
06233 
06234    ast_build_string(m_buf, m_size, " %d", rtp_code);
06235    ast_build_string(a_buf, a_size, "a=rtpmap:%d %s/%d\r\n", rtp_code,
06236           ast_rtp_lookup_mime_subtype(0, format, 0),
06237           sample_rate);
06238    if (format == AST_RTP_DTMF)
06239       /* Indicate we support DTMF and FLASH... */
06240       ast_build_string(a_buf, a_size, "a=fmtp:%d 0-16\r\n", rtp_code);
06241 }

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

Add realm authentication in list.

Definition at line 15900 of file chan_sip.c.

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

Referenced by build_peer(), and reload_config().

15901 {
15902    char authcopy[256];
15903    char *username=NULL, *realm=NULL, *secret=NULL, *md5secret=NULL;
15904    char *stringp;
15905    struct sip_auth *a, *b, *auth;
15906 
15907    if (ast_strlen_zero(configuration))
15908       return authlist;
15909 
15910    if (option_debug)
15911       ast_log(LOG_DEBUG, "Auth config ::  %s\n", configuration);
15912 
15913    ast_copy_string(authcopy, configuration, sizeof(authcopy));
15914    stringp = authcopy;
15915 
15916    username = stringp;
15917    realm = strrchr(stringp, '@');
15918    if (realm)
15919       *realm++ = '\0';
15920    if (ast_strlen_zero(username) || ast_strlen_zero(realm)) {
15921       ast_log(LOG_WARNING, "Format for authentication entry is user[:secret]@realm at line %d\n", lineno);
15922       return authlist;
15923    }
15924    stringp = username;
15925    username = strsep(&stringp, ":");
15926    if (username) {
15927       secret = strsep(&stringp, ":");
15928       if (!secret) {
15929          stringp = username;
15930          md5secret = strsep(&stringp,"#");
15931       }
15932    }
15933    if (!(auth = ast_calloc(1, sizeof(*auth))))
15934       return authlist;
15935 
15936    ast_copy_string(auth->realm, realm, sizeof(auth->realm));
15937    ast_copy_string(auth->username, username, sizeof(auth->username));
15938    if (secret)
15939       ast_copy_string(auth->secret, secret, sizeof(auth->secret));
15940    if (md5secret)
15941       ast_copy_string(auth->md5secret, md5secret, sizeof(auth->md5secret));
15942 
15943    /* find the end of the list */
15944    for (b = NULL, a = authlist; a ; b = a, a = a->next)
15945       ;
15946    if (b)
15947       b->next = auth;   /* Add structure add end of list */
15948    else
15949       authlist = auth;
15950 
15951    if (option_verbose > 2)
15952       ast_verbose("Added authentication for realm %s\n", realm);
15953 
15954    return authlist;
15955 
15956 }

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

Add route header into request per learned route.

Definition at line 5572 of file chan_sip.c.

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

Referenced by reqprep().

05573 {
05574    char r[BUFSIZ*2], *p;
05575    int n, rem = sizeof(r);
05576 
05577    if (!route)
05578       return;
05579 
05580    p = r;
05581    for (;route ; route = route->next) {
05582       n = strlen(route->hop);
05583       if (rem < n+3) /* we need room for ",<route>" */
05584          break;
05585       if (p != r) {  /* add a separator after fist route */
05586          *p++ = ',';
05587          --rem;
05588       }
05589       *p++ = '<';
05590       ast_copy_string(p, route->hop, rem); /* cannot fail */
05591       p += n;
05592       *p++ = '>';
05593       rem -= (n+2);
05594    }
05595    *p = '\0';
05596    add_header(req, "Route", r);
05597 }

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

Add Session Description Protocol message.

Definition at line 6246 of file chan_sip.c.

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

06247 {
06248    int len = 0;
06249    int alreadysent = 0;
06250 
06251    struct sockaddr_in sin;
06252    struct sockaddr_in vsin;
06253    struct sockaddr_in dest;
06254    struct sockaddr_in vdest = { 0, };
06255 
06256    /* SDP fields */
06257    char *version =   "v=0\r\n";     /* Protocol version */
06258    char *subject =   "s=session\r\n";  /* Subject of the session */
06259    char owner[256];           /* Session owner/creator */
06260    char connection[256];            /* Connection data */
06261    char *stime = "t=0 0\r\n";          /* Time the session is active */
06262    char bandwidth[256] = "";        /* Max bitrate */
06263    char *hold;
06264    char m_audio[256];            /* Media declaration line for audio */
06265    char m_video[256];            /* Media declaration line for video */
06266    char a_audio[1024];           /* Attributes for audio */
06267    char a_video[1024];           /* Attributes for video */
06268    char *m_audio_next = m_audio;
06269    char *m_video_next = m_video;
06270    size_t m_audio_left = sizeof(m_audio);
06271    size_t m_video_left = sizeof(m_video);
06272    char *a_audio_next = a_audio;
06273    char *a_video_next = a_video;
06274    size_t a_audio_left = sizeof(a_audio);
06275    size_t a_video_left = sizeof(a_video);
06276 
06277    int x;
06278    int capability;
06279    int needvideo = FALSE;
06280    int debug = sip_debug_test_pvt(p);
06281    int min_audio_packet_size = 0;
06282    int min_video_packet_size = 0;
06283 
06284    m_video[0] = '\0';   /* Reset the video media string if it's not needed */
06285 
06286    if (!p->rtp) {
06287       ast_log(LOG_WARNING, "No way to add SDP without an RTP structure\n");
06288       return AST_FAILURE;
06289    }
06290 
06291    /* Set RTP Session ID and version */
06292    if (!p->sessionid) {
06293       p->sessionid = getpid();
06294       p->sessionversion = p->sessionid;
06295    } else
06296       p->sessionversion++;
06297 
06298    /* Get our addresses */
06299    ast_rtp_get_us(p->rtp, &sin);
06300    if (p->vrtp)
06301       ast_rtp_get_us(p->vrtp, &vsin);
06302 
06303    /* Is this a re-invite to move the media out, then use the original offer from caller  */
06304    if (p->redirip.sin_addr.s_addr) {
06305       dest.sin_port = p->redirip.sin_port;
06306       dest.sin_addr = p->redirip.sin_addr;
06307    } else {
06308       dest.sin_addr = p->ourip;
06309       dest.sin_port = sin.sin_port;
06310    }
06311 
06312    capability = p->jointcapability;
06313 
06314 
06315    if (option_debug > 1) {
06316       char codecbuf[BUFSIZ];
06317       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");
06318       ast_log(LOG_DEBUG, "** Our prefcodec: %s \n", ast_getformatname_multiple(codecbuf, sizeof(codecbuf), p->prefcodec));
06319    }
06320    
06321 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS
06322    if (ast_test_flag(&p->t38.t38support, SIP_PAGE2_T38SUPPORT_RTP)) {
06323       ast_build_string(&m_audio_next, &m_audio_left, " %d", 191);
06324       ast_build_string(&a_audio_next, &a_audio_left, "a=rtpmap:%d %s/%d\r\n", 191, "t38", 8000);
06325    }
06326 #endif
06327 
06328    /* Check if we need video in this call */
06329    if ((capability & AST_FORMAT_VIDEO_MASK) && !ast_test_flag(&p->flags[0], SIP_NOVIDEO)) {
06330       if (p->vrtp) {
06331          needvideo = TRUE;
06332          if (option_debug > 1)
06333             ast_log(LOG_DEBUG, "This call needs video offers!\n");
06334       } else if (option_debug > 1)
06335          ast_log(LOG_DEBUG, "This call needs video offers, but there's no video support enabled!\n");
06336    }
06337       
06338 
06339    /* Ok, we need video. Let's add what we need for video and set codecs.
06340       Video is handled differently than audio since we can not transcode. */
06341    if (needvideo) {
06342       /* Determine video destination */
06343       if (p->vredirip.sin_addr.s_addr) {
06344          vdest.sin_addr = p->vredirip.sin_addr;
06345          vdest.sin_port = p->vredirip.sin_port;
06346       } else {
06347          vdest.sin_addr = p->ourip;
06348          vdest.sin_port = vsin.sin_port;
06349       }
06350       ast_build_string(&m_video_next, &m_video_left, "m=video %d RTP/AVP", ntohs(vdest.sin_port));
06351 
06352       /* Build max bitrate string */
06353       if (p->maxcallbitrate)
06354          snprintf(bandwidth, sizeof(bandwidth), "b=CT:%d\r\n", p->maxcallbitrate);
06355       if (debug) 
06356          ast_verbose("Video is at %s port %d\n", ast_inet_ntoa(p->ourip), ntohs(vsin.sin_port));   
06357    }
06358 
06359    if (debug) 
06360       ast_verbose("Audio is at %s port %d\n", ast_inet_ntoa(p->ourip), ntohs(sin.sin_port)); 
06361 
06362    /* Start building generic SDP headers */
06363 
06364    /* We break with the "recommendation" and send our IP, in order that our
06365       peer doesn't have to ast_gethostbyname() us */
06366 
06367    snprintf(owner, sizeof(owner), "o=root %d %d IN IP4 %s\r\n", p->sessionid, p->sessionversion, ast_inet_ntoa(dest.sin_addr));
06368    snprintf(connection, sizeof(connection), "c=IN IP4 %s\r\n", ast_inet_ntoa(dest.sin_addr));
06369    ast_build_string(&m_audio_next, &m_audio_left, "m=audio %d RTP/AVP", ntohs(dest.sin_port));
06370 
06371    if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) == SIP_PAGE2_CALL_ONHOLD_ONEDIR)
06372       hold = "a=recvonly\r\n";
06373    else if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) == SIP_PAGE2_CALL_ONHOLD_INACTIVE)
06374       hold = "a=inactive\r\n";
06375    else
06376       hold = "a=sendrecv\r\n";
06377 
06378    /* Now, start adding audio codecs. These are added in this order:
06379       - First what was requested by the calling channel
06380       - Then preferences in order from sip.conf device config for this peer/user
06381       - Then other codecs in capabilities, including video
06382    */
06383 
06384    /* Prefer the audio codec we were requested to use, first, no matter what 
06385       Note that p->prefcodec can include video codecs, so mask them out
06386     */
06387    if (capability & p->prefcodec) {
06388       int codec = p->prefcodec & AST_FORMAT_AUDIO_MASK;
06389 
06390       add_codec_to_sdp(p, codec, SDP_SAMPLE_RATE(codec),
06391              &m_audio_next, &m_audio_left,
06392              &a_audio_next, &a_audio_left,
06393              debug, &min_audio_packet_size);
06394       alreadysent |= codec;
06395    }
06396 
06397    /* Start by sending our preferred audio codecs */
06398    for (x = 0; x < 32; x++) {
06399       int codec;
06400 
06401       if (!(codec = ast_codec_pref_index(&p->prefs, x)))
06402          break; 
06403 
06404       if (!(capability & codec))
06405          continue;
06406 
06407       if (alreadysent & codec)
06408          continue;
06409 
06410       add_codec_to_sdp(p, codec, SDP_SAMPLE_RATE(codec),
06411              &m_audio_next, &m_audio_left,
06412              &a_audio_next, &a_audio_left,
06413              debug, &min_audio_packet_size);
06414       alreadysent |= codec;
06415    }
06416 
06417    /* Now send any other common audio and video codecs, and non-codec formats: */
06418    for (x = 1; x <= (needvideo ? AST_FORMAT_MAX_VIDEO : AST_FORMAT_MAX_AUDIO); x <<= 1) {
06419       if (!(capability & x))  /* Codec not requested */
06420          continue;
06421 
06422       if (alreadysent & x) /* Already added to SDP */
06423          continue;
06424 
06425       if (x <= AST_FORMAT_MAX_AUDIO)
06426          add_codec_to_sdp(p, x, SDP_SAMPLE_RATE(x),
06427                 &m_audio_next, &m_audio_left,
06428                 &a_audio_next, &a_audio_left,
06429                 debug, &min_audio_packet_size);
06430       else 
06431          add_codec_to_sdp(p, x, 90000,
06432                 &m_video_next, &m_video_left,
06433                 &a_video_next, &a_video_left,
06434                 debug, &min_video_packet_size);
06435    }
06436 
06437    /* Now add DTMF RFC2833 telephony-event as a codec */
06438    for (x = 1; x <= AST_RTP_MAX; x <<= 1) {
06439       if (!(p->jointnoncodeccapability & x))
06440          continue;
06441 
06442       add_noncodec_to_sdp(p, x, 8000,
06443                 &m_audio_next, &m_audio_left,
06444                 &a_audio_next, &a_audio_left,
06445                 debug);
06446    }
06447 
06448    if (option_debug > 2)
06449       ast_log(LOG_DEBUG, "-- Done with adding codecs to SDP\n");
06450 
06451    if (!p->owner || !ast_internal_timing_enabled(p->owner))
06452       ast_build_string(&a_audio_next, &a_audio_left, "a=silenceSupp:off - - - -\r\n");
06453 
06454    if (min_audio_packet_size)
06455       ast_build_string(&a_audio_next, &a_audio_left, "a=ptime:%d\r\n", min_audio_packet_size);
06456 
06457    if (min_video_packet_size)
06458       ast_build_string(&a_video_next, &a_video_left, "a=ptime:%d\r\n", min_video_packet_size);
06459 
06460    if ((m_audio_left < 2) || (m_video_left < 2) || (a_audio_left == 0) || (a_video_left == 0))
06461       ast_log(LOG_WARNING, "SIP SDP may be truncated due to undersized buffer!!\n");
06462 
06463    ast_build_string(&m_audio_next, &m_audio_left, "\r\n");
06464    if (needvideo)
06465       ast_build_string(&m_video_next, &m_video_left, "\r\n");
06466 
06467    len = strlen(version) + strlen(subject) + strlen(owner) + strlen(connection) + strlen(stime) + strlen(m_audio) + strlen(a_audio) + strlen(hold);
06468    if (needvideo) /* only if video response is appropriate */
06469       len += strlen(m_video) + strlen(a_video) + strlen(bandwidth) + strlen(hold);
06470 
06471    add_header(resp, "Content-Type", "application/sdp");
06472    add_header_contentLength(resp, len);
06473    add_line(resp, version);
06474    add_line(resp, owner);
06475    add_line(resp, subject);
06476    add_line(resp, connection);
06477    if (needvideo)    /* only if video response is appropriate */
06478       add_line(resp, bandwidth);
06479    add_line(resp, stime);
06480    add_line(resp, m_audio);
06481    add_line(resp, a_audio);
06482    add_line(resp, hold);
06483    if (needvideo) { /* only if video response is appropriate */
06484       add_line(resp, m_video);
06485       add_line(resp, a_video);
06486       add_line(resp, hold);   /* Repeat hold for the video stream */
06487    }
06488 
06489    /* Update lastrtprx when we send our SDP */
06490    p->lastrtprx = p->lastrtptx = time(NULL); /* XXX why both ? */
06491 
06492    if (option_debug > 2) {
06493       char buf[BUFSIZ];
06494       ast_log(LOG_DEBUG, "Done building SDP. Settling with this capability: %s\n", ast_getformatname_multiple(buf, BUFSIZ, capability));
06495    }
06496 
06497    return AST_SUCCESS;
06498 }

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

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

Referenced by reload_config().

15837 {
15838    struct domain *d;
15839 
15840    if (ast_strlen_zero(domain)) {
15841       ast_log(LOG_WARNING, "Zero length domain.\n");
15842       return 1;
15843    }
15844 
15845    if (!(d = ast_calloc(1, sizeof(*d))))
15846       return 0;
15847 
15848    ast_copy_string(d->domain, domain, sizeof(d->domain));
15849 
15850    if (!ast_strlen_zero(context))
15851       ast_copy_string(d->context, context, sizeof(d->context));
15852 
15853    d->mode = mode;
15854 
15855    AST_LIST_LOCK(&domain_list);
15856    AST_LIST_INSERT_TAIL(&domain_list, d, list);
15857    AST_LIST_UNLOCK(&domain_list);
15858 
15859    if (sipdebug)  
15860       ast_log(LOG_DEBUG, "Added local SIP domain '%s'\n", domain);
15861 
15862    return 1;
15863 }

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

Add T.38 Session Description Protocol message.

Definition at line 6126 of file chan_sip.c.

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

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

06127 {
06128    int len = 0;
06129    int x = 0;
06130    struct sockaddr_in udptlsin;
06131    char v[256] = "";
06132    char s[256] = "";
06133    char o[256] = "";
06134    char c[256] = "";
06135    char t[256] = "";
06136    char m_modem[256];
06137    char a_modem[1024];
06138    char *m_modem_next = m_modem;
06139    size_t m_modem_left = sizeof(m_modem);
06140    char *a_modem_next = a_modem;
06141    size_t a_modem_left = sizeof(a_modem);
06142    struct sockaddr_in udptldest = { 0, };
06143    int debug;
06144    
06145    debug = sip_debug_test_pvt(p);
06146    len = 0;
06147    if (!p->udptl) {
06148       ast_log(LOG_WARNING, "No way to add SDP without an UDPTL structure\n");
06149       return -1;
06150    }
06151    
06152    if (!p->sessionid) {
06153       p->sessionid = getpid();
06154       p->sessionversion = p->sessionid;
06155    } else
06156       p->sessionversion++;
06157    
06158    /* Our T.38 end is */
06159    ast_udptl_get_us(p->udptl, &udptlsin);
06160    
06161    /* Determine T.38 UDPTL destination */
06162    if (p->udptlredirip.sin_addr.s_addr) {
06163       udptldest.sin_port = p->udptlredirip.sin_port;
06164       udptldest.sin_addr = p->udptlredirip.sin_addr;
06165    } else {
06166       udptldest.sin_addr = p->ourip;
06167       udptldest.sin_port = udptlsin.sin_port;
06168    }
06169    
06170    if (debug) 
06171       ast_log(LOG_DEBUG, "T.38 UDPTL is at %s port %d\n", ast_inet_ntoa(p->ourip), ntohs(udptlsin.sin_port));
06172    
06173    /* We break with the "recommendation" and send our IP, in order that our
06174       peer doesn't have to ast_gethostbyname() us */
06175    
06176    if (debug) {
06177       ast_log(LOG_DEBUG, "Our T38 capability (%d), peer T38 capability (%d), joint capability (%d)\n",
06178          p->t38.capability,
06179          p->t38.peercapability,
06180          p->t38.jointcapability);
06181    }
06182    snprintf(v, sizeof(v), "v=0\r\n");
06183    snprintf(o, sizeof(o), "o=root %d %d IN IP4 %s\r\n", p->sessionid, p->sessionversion, ast_inet_ntoa(udptldest.sin_addr));
06184    snprintf(s, sizeof(s), "s=session\r\n");
06185    snprintf(c, sizeof(c), "c=IN IP4 %s\r\n", ast_inet_ntoa(udptldest.sin_addr));
06186    snprintf(t, sizeof(t), "t=0 0\r\n");
06187    ast_build_string(&m_modem_next, &m_modem_left, "m=image %d udptl t38\r\n", ntohs(udptldest.sin_port));
06188    
06189    if ((p->t38.jointcapability & T38FAX_VERSION) == T38FAX_VERSION_0)
06190       ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxVersion:0\r\n");
06191    if ((p->t38.jointcapability & T38FAX_VERSION) == T38FAX_VERSION_1)
06192       ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxVersion:1\r\n");
06193    if ((x = t38_get_rate(p->t38.jointcapability)))
06194       ast_build_string(&a_modem_next, &a_modem_left, "a=T38MaxBitRate:%d\r\n",x);
06195    ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxFillBitRemoval:%d\r\n", (p->t38.jointcapability & T38FAX_FILL_BIT_REMOVAL) ? 1 : 0);
06196    ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxTranscodingMMR:%d\r\n", (p->t38.jointcapability & T38FAX_TRANSCODING_MMR) ? 1 : 0);
06197    ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxTranscodingJBIG:%d\r\n", (p->t38.jointcapability & T38FAX_TRANSCODING_JBIG) ? 1 : 0);
06198    ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxRateManagement:%s\r\n", (p->t38.jointcapability & T38FAX_RATE_MANAGEMENT_LOCAL_TCF) ? "localTCF" : "transferredTCF");
06199    x = ast_udptl_get_local_max_datagram(p->udptl);
06200    ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxMaxBuffer:%d\r\n",x);
06201    ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxMaxDatagram:%d\r\n",x);
06202    if (p->t38.jointcapability != T38FAX_UDP_EC_NONE)
06203       ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxUdpEC:%s\r\n", (p->t38.jointcapability & T38FAX_UDP_EC_REDUNDANCY) ? "t38UDPRedundancy" : "t38UDPFEC");
06204    len = strlen(v) + strlen(s) + strlen(o) + strlen(c) + strlen(t) + strlen(m_modem) + strlen(a_modem);
06205    add_header(resp, "Content-Type", "application/sdp");
06206    add_header_contentLength(resp, len);
06207    add_line(resp, v);
06208    add_line(resp, o);
06209    add_line(resp, s);
06210    add_line(resp, c);
06211    add_line(resp, t);
06212    add_line(resp, m_modem);
06213    add_line(resp, a_modem);
06214    
06215    /* Update lastrtprx when we send our SDP */
06216    p->lastrtprx = p->lastrtptx = time(NULL);
06217    
06218    return 0;
06219 }

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

Add text body to SIP message.

Definition at line 6004 of file chan_sip.c.

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

Referenced by transmit_message_with_text().

06005 {
06006    /* XXX Convert \n's to \r\n's XXX */
06007    add_header(req, "Content-Type", "text/plain");
06008    add_header_contentLength(req, strlen(text));
06009    add_line(req, text);
06010    return 0;
06011 }

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

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

Referenced by transmit_info_with_vidupdate().

06029 {
06030    const char *xml_is_a_huge_waste_of_space =
06031       "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\r\n"
06032       " <media_control>\r\n"
06033       "  <vc_primitive>\r\n"
06034       "   <to_encoder>\r\n"
06035       "    <picture_fast_update>\r\n"
06036       "    </picture_fast_update>\r\n"
06037       "   </to_encoder>\r\n"
06038       "  </vc_primitive>\r\n"
06039       " </media_control>\r\n";
06040    add_header(req, "Content-Type", "application/media_control+xml");
06041    add_header_contentLength(req, strlen(xml_is_a_huge_waste_of_space));
06042    add_line(req, xml_is_a_huge_waste_of_space);
06043    return 0;
06044 }

static void append_date ( struct sip_request req  )  [static]

Append date to SIP message.

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

05952 {
05953    char tmpdat[256];
05954    struct tm tm;
05955    time_t t = time(NULL);
05956 
05957    gmtime_r(&t, &tm);
05958    strftime(tmpdat, sizeof(tmpdat), "%a, %d %b %Y %T GMT", &tm);
05959    add_header(req, "Date", tmpdat);
05960 }

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

Append to SIP dialog history with arg list.

Definition at line 1853 of file chan_sip.c.

References append_history_va().

01854 {
01855    va_list ap;
01856 
01857    if (!p)
01858       return;
01859    va_start(ap, fmt);
01860    append_history_va(p, fmt, ap);
01861    va_end(ap);
01862 
01863    return;
01864 }

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

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

Referenced by append_history_full().

01834 {
01835    char buf[80], *c = buf; /* max history length */
01836    struct sip_history *hist;
01837    int l;
01838 
01839    vsnprintf(buf, sizeof(buf), fmt, ap);
01840    strsep(&c, "\r\n"); /* Trim up everything after \r or \n */
01841    l = strlen(buf) + 1;
01842    if (!(hist = ast_calloc(1, sizeof(*hist) + l)))
01843       return;
01844    if (!p->history && !(p->history = ast_calloc(1, sizeof(*p->history)))) {
01845       free(hist);
01846       return;
01847    }
01848    memcpy(hist->event, buf, l);
01849    AST_LIST_INSERT_TAIL(p->history, hist, list);
01850 }

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

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

Referenced by attempt_transfer(), and handle_invite_replaces().

12908 {
12909    if (chan && chan->_state == AST_STATE_UP) {
12910       if (chan->generatordata)
12911          ast_deactivate_generator(chan);
12912    }
12913 }

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

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

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

01794 {
01795    struct sockaddr_in theirs, ours;
01796 
01797    /* Get our local information */
01798    ast_ouraddrfor(them, us);
01799    theirs.sin_addr = *them;
01800    ours.sin_addr = *us;
01801 
01802    if (localaddr && externip.sin_addr.s_addr &&
01803        (ast_apply_ha(localaddr, &theirs)) &&
01804        (!global_matchexterniplocally || !ast_apply_ha(localaddr, &ours))) {
01805       if (externexpire && time(NULL) >= externexpire) {
01806          struct ast_hostent ahp;
01807          struct hostent *hp;
01808 
01809          externexpire = time(NULL) + externrefresh;
01810          if ((hp = ast_gethostbyname(externhost, &ahp))) {
01811             memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr));
01812          } else
01813             ast_log(LOG_NOTICE, "Warning: Re-lookup of '%s' failed!\n", externhost);
01814       }
01815       *us = externip.sin_addr;
01816       if (option_debug) {
01817          ast_log(LOG_DEBUG, "Target address %s is not local, substituting externip\n", 
01818             ast_inet_ntoa(*(struct in_addr *)&them->s_addr));
01819       }
01820    } else if (bindaddr.sin_addr.s_addr)
01821       *us = bindaddr.sin_addr;
01822    return AST_SUCCESS;
01823 }

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

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

12918 {
12919    int res = 0;
12920    struct ast_channel *peera = NULL,   
12921       *peerb = NULL,
12922       *peerc = NULL,
12923       *peerd = NULL;
12924 
12925 
12926    /* We will try to connect the transferee with the target and hangup
12927       all channels to the transferer */   
12928    if (option_debug > 3) {
12929       ast_log(LOG_DEBUG, "Sip transfer:--------------------\n");
12930       if (transferer->chan1)
12931          ast_log(LOG_DEBUG, "-- Transferer to PBX channel: %s State %s\n", transferer->chan1->name, ast_state2str(transferer->chan1->_state));
12932       else
12933          ast_log(LOG_DEBUG, "-- No transferer first channel - odd??? \n");
12934       if (target->chan1)
12935          ast_log(LOG_DEBUG, "-- Transferer to PBX second channel (target): %s State %s\n", target->chan1->name, ast_state2str(target->chan1->_state));
12936       else
12937          ast_log(LOG_DEBUG, "-- No target first channel ---\n");
12938       if (transferer->chan2)
12939          ast_log(LOG_DEBUG, "-- Bridged call to transferee: %s State %s\n", transferer->chan2->name, ast_state2str(transferer->chan2->_state));
12940       else
12941          ast_log(LOG_DEBUG, "-- No bridged call to transferee\n");
12942       if (target->chan2)
12943          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)");
12944       else
12945          ast_log(LOG_DEBUG, "-- No target second channel ---\n");
12946       ast_log(LOG_DEBUG, "-- END Sip transfer:--------------------\n");
12947    }
12948    if (transferer->chan2) { /* We have a bridge on the transferer's channel */
12949       peera = transferer->chan1; /* Transferer - PBX -> transferee channel * the one we hangup */
12950       peerb = target->chan1;     /* Transferer - PBX -> target channel - This will get lost in masq */
12951       peerc = transferer->chan2; /* Asterisk to Transferee */
12952       peerd = target->chan2;     /* Asterisk to Target */
12953       if (option_debug > 2)
12954          ast_log(LOG_DEBUG, "SIP transfer: Four channels to handle\n");
12955    } else if (target->chan2) {   /* Transferer has no bridge (IVR), but transferee */
12956       peera = target->chan1;     /* Transferer to PBX -> target channel */
12957       peerb = transferer->chan1; /* Transferer to IVR*/
12958       peerc = target->chan2;     /* Asterisk to Target */
12959       peerd = transferer->chan2; /* Nothing */
12960       if (option_debug > 2)
12961          ast_log(LOG_DEBUG, "SIP transfer: Three channels to handle\n");
12962    }
12963 
12964    if (peera && peerb && peerc && (peerb != peerc)) {
12965       ast_quiet_chan(peera);     /* Stop generators */
12966       ast_quiet_chan(peerb);  
12967       ast_quiet_chan(peerc);
12968       if (peerd)
12969          ast_quiet_chan(peerd);
12970 
12971       /* Fix CDRs so they're attached to the remaining channel */
12972       if (peera->cdr && peerb->cdr)
12973          peerb->cdr = ast_cdr_append(peerb->cdr, peera->cdr);
12974       else if (peera->cdr) 
12975          peerb->cdr = peera->cdr;
12976       peera->cdr = NULL;
12977 
12978       if (peerb->cdr && peerc->cdr) 
12979          peerb->cdr = ast_cdr_append(peerb->cdr, peerc->cdr);
12980       else if (peerc->cdr)
12981          peerb->cdr = peerc->cdr;
12982       peerc->cdr = NULL;
12983    
12984       if (option_debug > 3)
12985          ast_log(LOG_DEBUG, "SIP transfer: trying to masquerade %s into %s\n", peerc->name, peerb->name);
12986       if (ast_channel_masquerade(peerb, peerc)) {
12987          ast_log(LOG_WARNING, "Failed to masquerade %s into %s\n", peerb->name, peerc->name);
12988          res = -1;
12989       } else
12990          ast_log(LOG_DEBUG, "SIP transfer: Succeeded to masquerade channels.\n");
12991       return res;
12992    } else {
12993       ast_log(LOG_NOTICE, "SIP Transfer attempted with no appropriate bridged calls to transfer\n");
12994       if (transferer->chan1)
12995          ast_softhangup_nolock(transferer->chan1, AST_SOFTHANGUP_DEV);
12996       if (target->chan1)
12997          ast_softhangup_nolock(target->chan1, AST_SOFTHANGUP_DEV);
12998       return -2;
12999    }
13000    return 0;
13001 }

static int auto_congest ( void *  nothing  )  [static]

Scheduled congestion on a call.

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

02853 {
02854    struct sip_pvt *p = nothing;
02855 
02856    ast_mutex_lock(&p->lock);
02857    p->initid = -1;
02858    if (p->owner) {
02859       /* XXX fails on possible deadlock */
02860       if (!ast_channel_trylock(p->owner)) {
02861          ast_log(LOG_NOTICE, "Auto-congesting %s\n", p->owner->name);
02862          append_history(p, "Cong", "Auto-congesting (timer)");
02863          ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
02864          ast_channel_unlock(p->owner);
02865       }
02866    }
02867    ast_mutex_unlock(&p->lock);
02868    return 0;
02869 }

static void build_callid_pvt ( struct sip_pvt pvt  )  [static]

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

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

04283 {
04284    char buf[33];
04285 
04286    const char *host = S_OR(pvt->fromdomain, ast_inet_ntoa(pvt->ourip));
04287    
04288    ast_string_field_build(pvt, callid, "%s@%s", generate_random_string(buf, sizeof(buf)), host);
04289 
04290 }

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

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

Referenced by transmit_register().

04294 {
04295    char buf[33];
04296 
04297    const char *host = S_OR(fromdomain, ast_inet_ntoa(ourip));
04298 
04299    ast_string_field_build(reg, callid, "%s@%s", generate_random_string(buf, sizeof(buf)), host);
04300 }

static void build_contact ( struct sip_pvt p  )  [static]

Build contact header - the contact header we send out.

Definition at line 6669 of file chan_sip.c.

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

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

06670 {
06671    /* Construct Contact: header */
06672    if (ourport != STANDARD_SIP_PORT)
06673       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);
06674    else
06675       ast_string_field_build(p, our_contact, "<sip:%s%s%s>", p->exten, ast_strlen_zero(p->exten) ? "" : "@", ast_inet_ntoa(p->ourip));
06676 }

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

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

Definition at line 16166 of file chan_sip.c.

References sip_peer::accountcode, add_realm_authentication(), sip_peer::addr, sip_peer::allowtransfer, sip_peer::amaflags, ast_append_ha(), ast_callerid_split(), ast_calloc, ast_cdr_amaflags2int(), ast_clear_flag, ast_copy_flags, ast_free_ha(), ast_get_group(), ast_get_ip(), ast_get_ip_or_srv(), ast_get_time_t(), ast_log(), ast_parse_allow_disallow(), ast_parse_caller_presentation(), ast_sched_del(), ast_set2_flag, ast_set_flag, ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_true(), ast_variable_new(), ast_variables_destroy(), ASTOBJ_CONTAINER_FIND_UNLINK_FULL, ASTOBJ_FLAG_MARKED, ASTOBJ_INIT, ASTOBJ_UNMARK, ASTOBJ_UNREF, sip_peer::auth, sip_peer::autoframing, sip_peer::call_limit, sip_peer::callgroup, sip_peer::callingpres, sip_peer::capability, sip_peer::chanvars, sip_peer::cid_name, sip_peer::cid_num, clear_realm_authentication(), sip_peer::context, sip_peer::defaddr, DEFAULT_MAXMS, destroy_association(), sip_peer::expire, ast_flags::flags, sip_peer::flags, sip_peer::fromdomain, sip_peer::fromuser, sip_peer::fullcontact, sip_peer::ha, handle_common_options(), sip_peer::language, sip_peer::lastmsgssent, ast_variable::lineno, LOG_DEBUG, LOG_WARNING, sip_peer::mailbox, sip_peer::maxcallbitrate, sip_peer::maxms, sip_peer::md5secret, sip_peer::mohinterpret, sip_peer::mohsuggest, ast_variable::name, ast_variable::next, option_debug, peerl, sip_peer::pickupgroup, sip_peer::prefs, reg_source_db(), sip_peer::regexten, sip_peer::rtpholdtimeout, sip_peer::rtpkeepalive, sip_peer::rtptimeout, sip_peer::secret, set_peer_defaults(), sip_destroy_peer(), SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PAGE2_DYNAMIC, SIP_PAGE2_IGNOREREGEXPIRE, SIP_PAGE2_RT_FROMCONTACT, SIP_PAGE2_SUBSCRIBEMWIONLY, SIP_REALTIME, SIP_USEREQPHONE, STANDARD_SIP_PORT, sip_peer::subscribecontext, sip_peer::tohost, TRANSFER_CLOSED, TRANSFER_OPENFORALL, TRUE, sip_peer::username, ast_variable::value, and sip_peer::vmexten.

16167 {
16168    struct sip_peer *peer = NULL;
16169    struct ast_ha *oldha = NULL;
16170    int obproxyfound=0;
16171    int found=0;
16172    int firstpass=1;
16173    int format=0;     /* Ama flags */
16174    time_t regseconds = 0;
16175    char *varname = NULL, *varval = NULL;
16176    struct ast_variable *tmpvar = NULL;
16177    struct ast_flags peerflags[2] = {{(0)}};
16178    struct ast_flags mask[2] = {{(0)}};
16179 
16180 
16181    if (!realtime)
16182       /* Note we do NOT use find_peer here, to avoid realtime recursion */
16183       /* We also use a case-sensitive comparison (unlike find_peer) so
16184          that case changes made to the peer name will be properly handled
16185          during reload
16186       */
16187       peer = ASTOBJ_CONTAINER_FIND_UNLINK_FULL(&peerl, name, name, 0, 0, strcmp);
16188 
16189    if (peer) {
16190       /* Already in the list, remove it and it will be added back (or FREE'd)  */
16191       found = 1;
16192       if (!(peer->objflags & ASTOBJ_FLAG_MARKED))
16193          firstpass = 0;
16194    } else {
16195       if (!(peer = ast_calloc(1, sizeof(*peer))))
16196          return NULL;
16197 
16198       if (realtime)
16199          rpeerobjs++;
16200       else
16201          speerobjs++;
16202       ASTOBJ_INIT(peer);
16203    }
16204    /* Note that our peer HAS had its reference count incrased */
16205    if (firstpass) {
16206       peer->lastmsgssent = -1;
16207       oldha = peer->ha;
16208       peer->ha = NULL;
16209       set_peer_defaults(peer);   /* Set peer defaults */
16210    }
16211    if (!found && name)
16212          ast_copy_string(peer->name, name, sizeof(peer->name));
16213 
16214    /* If we have channel variables, remove them (reload) */
16215    if (peer->chanvars) {
16216       ast_variables_destroy(peer->chanvars);
16217       peer->chanvars = NULL;
16218       /* XXX should unregister ? */
16219    }
16220 
16221    /* If we have realm authentication information, remove them (reload) */
16222    clear_realm_authentication(peer->auth);
16223    peer->auth = NULL;
16224 
16225    for (; v || ((v = alt) && !(alt=NULL)); v = v->next) {
16226       if (handle_common_options(&peerflags[0], &mask[0], v))
16227          continue;
16228       if (realtime && !strcasecmp(v->name, "regseconds")) {
16229          ast_get_time_t(v->value, &regseconds, 0, NULL);
16230       } else if (realtime && !strcasecmp(v->name, "ipaddr") && !ast_strlen_zero(v->value) ) {
16231          inet_aton(v->value, &(peer->addr.sin_addr));
16232       } else if (realtime && !strcasecmp(v->name, "name"))
16233          ast_copy_string(peer->name, v->value, sizeof(peer->name));
16234       else if (realtime && !strcasecmp(v->name, "fullcontact")) {
16235          ast_copy_string(peer->fullcontact, v->value, sizeof(peer->fullcontact));
16236          ast_set_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT);
16237       } else if (!strcasecmp(v->name, "secret")) 
16238          ast_copy_string(peer->secret, v->value, sizeof(peer->secret));
16239       else if (!strcasecmp(v->name, "md5secret")) 
16240          ast_copy_string(peer->md5secret, v->value, sizeof(peer->md5secret));
16241       else if (!strcasecmp(v->name, "auth"))
16242          peer->auth = add_realm_authentication(peer->auth, v->value, v->lineno);
16243       else if (!strcasecmp(v->name, "callerid")) {
16244          ast_callerid_split(v->value, peer->cid_name, sizeof(peer->cid_name), peer->cid_num, sizeof(peer->cid_num));
16245       } else if (!strcasecmp(v->name, "fullname")) {
16246          ast_copy_string(peer->cid_name, v->value, sizeof(peer->cid_name));
16247       } else if (!strcasecmp(v->name, "cid_number")) {
16248          ast_copy_string(peer->cid_num, v->value, sizeof(peer->cid_num));
16249       } else if (!strcasecmp(v->name, "context")) {
16250          ast_copy_string(peer->context, v->value, sizeof(peer->context));
16251       } else if (!strcasecmp(v->name, "subscribecontext")) {
16252          ast_copy_string(peer->subscribecontext, v->value, sizeof(peer->subscribecontext));
16253       } else if (!strcasecmp(v->name, "fromdomain")) {
16254          ast_copy_string(peer->fromdomain, v->value, sizeof(peer->fromdomain));
16255       } else if (!strcasecmp(v->name, "usereqphone")) {
16256          ast_set2_flag(&peer->flags[0], ast_true(v->value), SIP_USEREQPHONE);
16257       } else if (!strcasecmp(v->name, "fromuser")) {
16258          ast_copy_string(peer->fromuser, v->value, sizeof(peer->fromuser));
16259       } else if (!strcasecmp(v->name, "host") || !strcasecmp(v->name, "outboundproxy")) {
16260          if (!strcasecmp(v->value, "dynamic")) {
16261             if (!strcasecmp(v->name, "outboundproxy") || obproxyfound) {
16262                ast_log(LOG_WARNING, "You can't have a dynamic outbound proxy, you big silly head at line %d.\n", v->lineno);
16263             } else {
16264                /* They'll register with us */
16265                if (!found || !ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)) {
16266                   /* Initialize stuff if this is a new peer, or if it used to be
16267                    * non-dynamic before the reload. */
16268                   memset(&peer->addr.sin_addr, 0, 4);
16269                   if (peer->addr.sin_port) {
16270                      /* If we've already got a port, make it the default rather than absolute */
16271                      peer->defaddr.sin_port = peer->addr.sin_port;
16272                      peer->addr.sin_port = 0;
16273                   }
16274                }
16275                ast_set_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC);
16276             }
16277          } else {
16278             /* Non-dynamic.  Make sure we become that way if we're not */
16279             if (peer->expire > -1)
16280                ast_sched_del(sched, peer->expire);
16281             peer->expire = -1;
16282             ast_clear_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC);
16283             if (!obproxyfound || !strcasecmp(v->name, "outboundproxy")) {
16284                if (ast_get_ip_or_srv(&peer->addr, v->value, srvlookup ? "_sip._udp" : NULL)) {
16285                   ASTOBJ_UNREF(peer, sip_destroy_peer);
16286                   return NULL;
16287                }
16288             }
16289             if (!strcasecmp(v->name, "outboundproxy"))
16290                obproxyfound=1;
16291             else {
16292                ast_copy_string(peer->tohost, v->value, sizeof(peer->tohost));
16293                if (!peer->addr.sin_port)
16294                   peer->addr.sin_port = htons(STANDARD_SIP_PORT);
16295             }
16296          }
16297       } else if (!strcasecmp(v->name, "defaultip")) {
16298          if (ast_get_ip(&peer->defaddr, v->value)) {
16299             ASTOBJ_UNREF(peer, sip_destroy_peer);
16300             return NULL;
16301          }
16302       } else if (!strcasecmp(v->name, "permit") || !strcasecmp(v->name, "deny")) {
16303          peer->ha = ast_append_ha(v->name, v->value, peer->ha);
16304       } else if (!strcasecmp(v->name, "port")) {
16305          if (!realtime && ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC))
16306             peer->defaddr.sin_port = htons(atoi(v->value));
16307          else
16308             peer->addr.sin_port = htons(atoi(v->value));
16309       } else if (!strcasecmp(v->name, "callingpres")) {
16310          peer->callingpres = ast_parse_caller_presentation(v->value);
16311          if (peer->callingpres == -1)
16312             peer->callingpres = atoi(v->value);
16313       } else if (!strcasecmp(v->name, "username")) {
16314          ast_copy_string(peer->username, v->value, sizeof(peer->username));
16315       } else if (!strcasecmp(v->name, "language")) {
16316          ast_copy_string(peer->language, v->value, sizeof(peer->language));
16317       } else if (!strcasecmp(v->name, "regexten")) {
16318          ast_copy_string(peer->regexten, v->value, sizeof(peer->regexten));
16319       } else if (!strcasecmp(v->name, "call-limit") || !strcasecmp(v->name, "incominglimit")) {
16320          peer->call_limit = atoi(v->value);
16321          if (peer->call_limit < 0)
16322             peer->call_limit = 0;
16323       } else if (!strcasecmp(v->name, "amaflags")) {
16324          format = ast_cdr_amaflags2int(v->value);
16325          if (format < 0) {
16326             ast_log(LOG_WARNING, "Invalid AMA Flags for peer: %s at line %d\n", v->value, v->lineno);
16327          } else {
16328             peer->amaflags = format;
16329          }
16330       } else if (!strcasecmp(v->name, "accountcode")) {
16331          ast_copy_string(peer->accountcode, v->value, sizeof(peer->accountcode));
16332       } else if (!strcasecmp(v->name, "mohinterpret")
16333          || !strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) {
16334          ast_copy_string(peer->mohinterpret, v->value, sizeof(peer->mohinterpret));
16335       } else if (!strcasecmp(v->name, "mohsuggest")) {
16336          ast_copy_string(peer->mohsuggest, v->value, sizeof(peer->mohsuggest));
16337       } else if (!strcasecmp(v->name, "mailbox")) {
16338          ast_copy_string(peer->mailbox, v->value, sizeof(peer->mailbox));
16339       } else if (!strcasecmp(v->name, "subscribemwi")) {
16340          ast_set2_flag(&peer->flags[1], ast_true(v->value), SIP_PAGE2_SUBSCRIBEMWIONLY);
16341       } else if (!strcasecmp(v->name, "vmexten")) {
16342          ast_copy_string(peer->vmexten, v->value, sizeof(peer->vmexten));
16343       } else if (!strcasecmp(v->name, "callgroup")) {
16344          peer->callgroup = ast_get_group(v->value);
16345       } else if (!strcasecmp(v->name, "allowtransfer")) {
16346          peer->allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED;
16347       } else if (!strcasecmp(v->name, "pickupgroup")) {
16348          peer->pickupgroup = ast_get_group(v->value);
16349       } else if (!strcasecmp(v->name, "allow")) {
16350          ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1);
16351       } else if (!strcasecmp(v->name, "disallow")) {
16352          ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0);
16353       } else if (!strcasecmp(v->name, "autoframing")) {
16354          peer->autoframing = ast_true(v->value);
16355       } else if (!strcasecmp(v->name, "rtptimeout")) {
16356          if ((sscanf(v->value, "%d", &peer->rtptimeout) != 1) || (peer->rtptimeout < 0)) {
16357             ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d.  Using default.\n", v->value, v->lineno);
16358             peer->rtptimeout = global_rtptimeout;
16359          }
16360       } else if (!strcasecmp(v->name, "rtpholdtimeout")) {
16361          if ((sscanf(v->value, "%d", &peer->rtpholdtimeout) != 1) || (peer->rtpholdtimeout < 0)) {
16362             ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d.  Using default.\n", v->value, v->lineno);
16363             peer->rtpholdtimeout = global_rtpholdtimeout;
16364          }
16365       } else if (!strcasecmp(v->name, "rtpkeepalive")) {
16366          if ((sscanf(v->value, "%d", &peer->rtpkeepalive) != 1) || (peer->rtpkeepalive < 0)) {
16367             ast_log(LOG_WARNING, "'%s' is not a valid RTP keepalive time at line %d.  Using default.\n", v->value, v->lineno);
16368             peer->rtpkeepalive = global_rtpkeepalive;
16369          }
16370       } else if (!strcasecmp(v->name, "setvar")) {
16371          /* Set peer channel variable */
16372          varname = ast_strdupa(v->value);
16373          if ((varval = strchr(varname, '='))) {
16374             *varval++ = '\0';
16375             if ((tmpvar = ast_variable_new(varname, varval))) {
16376                tmpvar->next = peer->chanvars;
16377                peer->chanvars = tmpvar;
16378             }
16379          }
16380       } else if (!strcasecmp(v->name, "qualify")) {
16381          if (!strcasecmp(v->value, "no")) {
16382             peer->maxms = 0;
16383          } else if (!strcasecmp(v->value, "yes")) {
16384             peer->maxms = DEFAULT_MAXMS;
16385          } else if (sscanf(v->value, "%d", &peer->maxms) != 1) {
16386             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);
16387             peer->maxms = 0;
16388          }
16389       } else if (!strcasecmp(v->name, "maxcallbitrate")) {
16390          peer->maxcallbitrate = atoi(v->value);
16391          if (peer->maxcallbitrate < 0)
16392             peer->maxcallbitrate = default_maxcallbitrate;
16393       }
16394    }
16395    if (!ast_test_flag(&global_flags[1], SIP_PAGE2_IGNOREREGEXPIRE) && ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC) && realtime) {
16396       time_t nowtime = time(NULL);
16397 
16398       if ((nowtime - regseconds) > 0) {
16399          destroy_association(peer);
16400          memset(&peer->addr, 0, sizeof(peer->addr));
16401          if (option_debug)
16402             ast_log(LOG_DEBUG, "Bah, we're expired (%d/%d/%d)!\n", (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
16403       }
16404    }
16405    ast_copy_flags(&peer->flags[0], &peerflags[0], mask[0].flags);
16406    ast_copy_flags(&peer->flags[1], &peerflags[1], mask[1].flags);
16407    if (ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE))
16408       global_allowsubscribe = TRUE; /* No global ban any more */
16409    if (!found && ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC) && !ast_test_flag(&peer->flags[0], SIP_REALTIME))
16410       reg_source_db(peer);
16411    ASTOBJ_UNMARK(peer);
16412    ast_free_ha(oldha);
16413    return peer;
16414 }

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

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

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

11299 {
11300    char a1[256];
11301    char a2[256];
11302    char a1_hash[256];
11303    char a2_hash[256];
11304    char resp[256];
11305    char resp_hash[256];
11306    char uri[256];
11307    char cnonce[80];
11308    const char *username;
11309    const char *secret;
11310    const char *md5secret;
11311    struct sip_auth *auth = NULL; /* Realm authentication */
11312 
11313    if (!ast_strlen_zero(p->domain))
11314       ast_copy_string(uri, p->domain, sizeof(uri));
11315    else if (!ast_strlen_zero(p->uri))
11316       ast_copy_string(uri, p->uri, sizeof(uri));
11317    else
11318       snprintf(uri, sizeof(uri), "sip:%s@%s",p->username, ast_inet_ntoa(p->sa.sin_addr));
11319 
11320    snprintf(cnonce, sizeof(cnonce), "%08lx", ast_random());
11321 
11322    /* Check if we have separate auth credentials */
11323    if ((auth = find_realm_authentication(authl, p->realm))) {
11324       ast_log(LOG_WARNING, "use realm [%s] from peer [%s][%s]\n",
11325          auth->username, p->peername, p->username);
11326       username = auth->username;
11327       secret = auth->secret;
11328       md5secret = auth->md5secret;
11329       if (sipdebug)
11330          ast_log(LOG_DEBUG,"Using realm %s authentication for call %s\n", p->realm, p->callid);
11331    } else {
11332       /* No authentication, use peer or register= config */
11333       username = p->authname;
11334       secret =  p->peersecret;
11335       md5secret = p->peermd5secret;
11336    }
11337    if (ast_strlen_zero(username))   /* We have no authentication */
11338       return -1;
11339 
11340    /* Calculate SIP digest response */
11341    snprintf(a1,sizeof(a1),"%s:%s:%s", username, p->realm, secret);
11342    snprintf(a2,sizeof(a2),"%s:%s", sip_methods[method].text, uri);
11343    if (!ast_strlen_zero(md5secret))
11344       ast_copy_string(a1_hash, md5secret, sizeof(a1_hash));
11345    else
11346       ast_md5_hash(a1_hash,a1);
11347    ast_md5_hash(a2_hash,a2);
11348 
11349    p->noncecount++;
11350    if (!ast_strlen_zero(p->qop))
11351       snprintf(resp,sizeof(resp),"%s:%s:%08x:%s:%s:%s", a1_hash, p->nonce, p->noncecount, cnonce, "auth", a2_hash);
11352    else
11353       snprintf(resp,sizeof(resp),"%s:%s:%s", a1_hash, p->nonce, a2_hash);
11354    ast_md5_hash(resp_hash, resp);
11355    /* XXX We hard code our qop to "auth" for now.  XXX */
11356    if (!ast_strlen_zero(p->qop))
11357       snprintf(digest, digest_len, "Digest username=\"%s\", realm=\"%s\", algorithm=MD5, uri=\"%s\", nonce=\"%s\", response=\"%s\", opaque=\"%s\", qop=auth, cnonce=\"%s\", nc=%08x", username, p->realm, uri, p->nonce, resp_hash, p->opaque, cnonce, p->noncecount);
11358    else
11359       snprintf(digest, digest_len, "Digest username=\"%s\", realm=\"%s\", algorithm=MD5, uri=\"%s\", nonce=\"%s\", response=\"%s\", opaque=\"%s\"", username, p->realm, uri, p->nonce, resp_hash, p->opaque);
11360 
11361    append_history(p, "AuthResp", "Auth response sent for %s in realm %s - nc %d", username, p->realm, p->noncecount);
11362 
11363    return 0;
11364 }

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

08049 {
08050    struct sip_route *thishop, *head, *tail;
08051    int start = 0;
08052    int len;
08053    const char *rr, *contact, *c;
08054 
08055    /* Once a persistant route is set, don't fool with it */
08056    if (p->route && p->route_persistant) {
08057       if (option_debug)
08058          ast_log(LOG_DEBUG, "build_route: Retaining previous route: <%s>\n", p->route->hop);
08059       return;
08060    }
08061 
08062    if (p->route) {
08063       free_old_route(p->route);
08064       p->route = NULL;
08065    }
08066    
08067    p->route_persistant = backwards;
08068    
08069    /* Build a tailq, then assign it to p->route when done.
08070     * If backwards, we add entries from the head so they end up
08071     * in reverse order. However, we do need to maintain a correct
08072     * tail pointer because the contact is always at the end.
08073     */
08074    head = NULL;
08075    tail = head;
08076    /* 1st we pass through all the hops in any Record-Route headers */
08077    for (;;) {
08078       /* Each Record-Route header */
08079       rr = __get_header(req, "Record-Route", &start);
08080       if (*rr == '\0')
08081          break;
08082       for (; (rr = strchr(rr, '<')) ; rr += len) { /* Each route entry */
08083          ++rr;
08084          len = strcspn(rr, ">") + 1;
08085          /* Make a struct route */
08086          if ((thishop = ast_malloc(sizeof(*thishop) + len))) {
08087             /* ast_calloc is not needed because all fields are initialized in this block */
08088             ast_copy_string(thishop->hop, rr, len);
08089             if (option_debug > 1)
08090                ast_log(LOG_DEBUG, "build_route: Record-Route hop: <%s>\n", thishop->hop);
08091             /* Link in */
08092             if (backwards) {
08093                /* Link in at head so they end up in reverse order */
08094                thishop->next = head;
08095                head = thishop;
08096                /* If this was the first then it'll be the tail */
08097                if (!tail)
08098                   tail = thishop;
08099             } else {
08100                thishop->next = NULL;
08101                /* Link in at the end */
08102                if (tail)
08103                   tail->next = thishop;
08104                else
08105                   head = thishop;
08106                tail = thishop;
08107             }
08108          }
08109       }
08110    }
08111 
08112    /* Only append the contact if we are dealing with a strict router */
08113    if (!head || (!ast_strlen_zero(head->hop) && strstr(head->hop,";lr") == NULL) ) {
08114       /* 2nd append the Contact: if there is one */
08115       /* Can be multiple Contact headers, comma separated values - we just take the first */
08116       contact = get_header(req, "Contact");
08117       if (!ast_strlen_zero(contact)) {
08118          if (option_debug > 1)
08119             ast_log(LOG_DEBUG, "build_route: Contact hop: %s\n", contact);
08120          /* Look for <: delimited address */
08121          c = strchr(contact, '<');
08122          if (c) {
08123             /* Take to > */
08124             ++c;
08125             len = strcspn(c, ">") + 1;
08126          } else {
08127             /* No <> - just take the lot */
08128             c = contact;
08129             len = strlen(contact) + 1;
08130          }
08131          if ((thishop = ast_malloc(sizeof(*thishop) + len))) {
08132             /* ast_calloc is not needed because all fields are initialized in this block */
08133             ast_copy_string(thishop->hop, c, len);
08134             thishop->next = NULL;
08135             /* Goes at the end */
08136             if (tail)
08137                tail->next = thishop;
08138             else
08139                head = thishop;
08140          }
08141       }
08142    }
08143 
08144    /* Store as new route */
08145    p->route = head;
08146 
08147    /* For debugging dump what we ended up with */
08148    if (sip_debug_test_pvt(p))
08149       list_route(p->route);
08150 }

static void build_rpid ( struct sip_pvt p  )  [static]

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

Definition at line 6679 of file chan_sip.c.

References ast_inet_ntoa(), ast_log(), AST_PRES_ALLOWED, AST_PRES_ALLOWED_NETWORK_NUMBER, AST_PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN, AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED, AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN, AST_PRES_NUMBER_NOT_AVAILABLE, AST_PRES_PROHIB_NETWORK_NUMBER, AST_PRES_PROHIB_USER_NUMBER_FAILED_SCREEN, AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED, AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN, AST_PRES_RESTRICTION, ast_string_field_build, ast_string_field_set, ast_strlen_zero(), sip_pvt::callingpres, ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, FALSE, LOG_WARNING, sip_pvt::ourip, sip_pvt::owner, S_OR, sip_pvt::tag, and TRUE.

Referenced by initreqprep().

06680 {
06681    int send_pres_tags = TRUE;
06682    const char *privacy=NULL;
06683    const char *screen=NULL;
06684    char buf[256];
06685    const char *clid = default_callerid;
06686    const char *clin = NULL;
06687    const char *fromdomain;
06688 
06689    if (!ast_strlen_zero(p->rpid) || !ast_strlen_zero(p->rpid_from))  
06690       return;
06691 
06692    if (p->owner && p->owner->cid.cid_num)
06693       clid = p->owner->cid.cid_num;
06694    if (p->owner && p->owner->cid.cid_name)
06695       clin = p->owner->cid.cid_name;
06696    if (ast_strlen_zero(clin))
06697       clin = clid;
06698 
06699    switch (p->callingpres) {
06700    case AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED:
06701       privacy = "off";
06702       screen = "no";
06703       break;
06704    case AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN:
06705       privacy = "off";
06706       screen = "yes";
06707       break;
06708    case AST_PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN:
06709       privacy = "off";
06710       screen = "no";
06711       break;
06712    case AST_PRES_ALLOWED_NETWORK_NUMBER:
06713       privacy = "off";
06714       screen = "yes";
06715       break;
06716    case AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED:
06717       privacy = "full";
06718       screen = "no";
06719       break;
06720    case AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN:
06721       privacy = "full";
06722       screen = "yes";
06723       break;
06724    case AST_PRES_PROHIB_USER_NUMBER_FAILED_SCREEN:
06725       privacy = "full";
06726       screen = "no";
06727       break;
06728    case AST_PRES_PROHIB_NETWORK_NUMBER:
06729       privacy = "full";
06730       screen = "yes";
06731       break;
06732    case AST_PRES_NUMBER_NOT_AVAILABLE:
06733       send_pres_tags = FALSE;
06734       break;
06735    default:
06736       ast_log(LOG_WARNING, "Unsupported callingpres (%d)\n", p->callingpres);
06737       if ((p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED)
06738          privacy = "full";
06739       else
06740          privacy = "off";
06741       screen = "no";
06742       break;
06743    }
06744    
06745    fromdomain = S_OR(p->fromdomain, ast_inet_ntoa(p->ourip));
06746 
06747    snprintf(buf, sizeof(buf), "\"%s\" <sip:%s@%s>", clin, clid, fromdomain);
06748    if (send_pres_tags)
06749       snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), ";privacy=%s;screen=%s", privacy, screen);
06750    ast_string_field_set(p, rpid, buf);
06751 
06752    ast_string_field_build(p, rpid_from, "\"%s\" <sip:%s@%s>;tag=%s", clin,
06753                 S_OR(p->fromuser, clid),
06754                 fromdomain, p->tag);
06755 }

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

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

Definition at line 15987 of file chan_sip.c.

References sip_user::accountcode, sip_user::allowtransfer, sip_user::amaflags, ast_append_ha(), ast_callerid_split(), ast_calloc, ast_cdr_amaflags2int(), ast_copy_flags, ast_free_ha(), ast_get_group(), ast_log(), ast_parse_allow_disallow(), ast_parse_caller_presentation(), ast_strdupa, ast_test_flag, ast_true(), ast_variable_new(), ASTOBJ_INIT, sip_user::autoframing, sip_user::call_limit, sip_user::callgroup, sip_user::callingpres, sip_user::capability, sip_user::chanvars, sip_user::cid_name, sip_user::cid_num, sip_user::context, default_prefs, ast_flags::flags, sip_user::flags, format, sip_user::ha, handle_common_options(), sip_user::language, ast_variable::lineno, LOG_WARNING, sip_user::maxcallbitrate, sip_user::md5secret, sip_user::mohinterpret, sip_user::mohsuggest, ast_variable::name, ast_variable::next, sip_user::pickupgroup, sip_user::prefs, sip_user::secret, SIP_FLAGS_TO_COPY, SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PAGE2_FLAGS_TO_COPY, sip_user::subscribecontext, TRANSFER_CLOSED, TRANSFER_OPENFORALL, TRUE, and ast_variable::value.

15988 {
15989    struct sip_user *user;
15990    int format;
15991    struct ast_ha *oldha = NULL;
15992    char *varname = NULL, *varval = NULL;
15993    struct ast_variable *tmpvar = NULL;
15994    struct ast_flags userflags[2] = {{(0)}};
15995    struct ast_flags mask[2] = {{(0)}};
15996 
15997 
15998    if (!(user = ast_calloc(1, sizeof(*user))))
15999       return NULL;
16000       
16001    suserobjs++;
16002    ASTOBJ_INIT(user);
16003    ast_copy_string(user->name, name, sizeof(user->name));
16004    oldha = user->ha;
16005    user->ha = NULL;
16006    ast_copy_flags(&user->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY);
16007    ast_copy_flags(&user->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY);
16008    user->capability = global_capability;
16009    user->allowtransfer = global_allowtransfer;
16010    user->maxcallbitrate = default_maxcallbitrate;
16011    user->autoframing = global_autoframing;
16012    user->prefs = default_prefs;
16013    /* set default context */
16014    strcpy(user->context, default_context);
16015    strcpy(user->language, default_language);
16016    strcpy(user->mohinterpret, default_mohinterpret);
16017    strcpy(user->mohsuggest, default_mohsuggest);
16018    for (; v; v = v->next) {
16019       if (handle_common_options(&userflags[0], &mask[0], v))
16020          continue;
16021 
16022       if (!strcasecmp(v->name, "context")) {
16023          ast_copy_string(user->context, v->value, sizeof(user->context));
16024       } else if (!strcasecmp(v->name, "subscribecontext")) {
16025          ast_copy_string(user->subscribecontext, v->value, sizeof(user->subscribecontext));
16026       } else if (!strcasecmp(v->name, "setvar")) {
16027          varname = ast_strdupa(v->value);
16028          if ((varval = strchr(varname,'='))) {
16029             *varval++ = '\0';
16030             if ((tmpvar = ast_variable_new(varname, varval))) {
16031                tmpvar->next = user->chanvars;
16032                user->chanvars = tmpvar;
16033             }
16034          }
16035       } else if (!strcasecmp(v->name, "permit") ||
16036                !strcasecmp(v->name, "deny")) {
16037          user->ha = ast_append_ha(v->name, v->value, user->ha);
16038       } else if (!strcasecmp(v->name, "allowtransfer")) {
16039          user->allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED;
16040       } else if (!strcasecmp(v->name, "secret")) {
16041          ast_copy_string(user->secret, v->value, sizeof(user->secret)); 
16042       } else if (!strcasecmp(v->name, "md5secret")) {
16043          ast_copy_string(user->md5secret, v->value, sizeof(user->md5secret));
16044       } else if (!strcasecmp(v->name, "callerid")) {
16045          ast_callerid_split(v->value, user->cid_name, sizeof(user->cid_name), user->cid_num, sizeof(user->cid_num));
16046       } else if (!strcasecmp(v->name, "fullname")) {
16047          ast_copy_string(user->cid_name, v->value, sizeof(user->cid_name));
16048       } else if (!strcasecmp(v->name, "cid_number")) {
16049          ast_copy_string(user->cid_num, v->value, sizeof(user->cid_num));
16050       } else if (!strcasecmp(v->name, "callgroup")) {
16051          user->callgroup = ast_get_group(v->value);
16052       } else if (!strcasecmp(v->name, "pickupgroup")) {
16053          user->pickupgroup = ast_get_group(v->value);
16054       } else if (!strcasecmp(v->name, "language")) {
16055          ast_copy_string(user->language, v->value, sizeof(user->language));
16056       } else if (!strcasecmp(v->name, "mohinterpret") 
16057          || !strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) {
16058          ast_copy_string(user->mohinterpret, v->value, sizeof(user->mohinterpret));
16059       } else if (!strcasecmp(v->name, "mohsuggest")) {
16060          ast_copy_string(user->mohsuggest, v->value, sizeof(user->mohsuggest));
16061       } else if (!strcasecmp(v->name, "accountcode")) {
16062          ast_copy_string(user->accountcode, v->value, sizeof(user->accountcode));
16063       } else if (!strcasecmp(v->name, "call-limit")) {
16064          user->call_limit = atoi(v->value);
16065          if (user->call_limit < 0)
16066             user->call_limit = 0;
16067       } else if (!strcasecmp(v->name, "amaflags")) {
16068          format = ast_cdr_amaflags2int(v->value);
16069          if (format < 0) {
16070             ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
16071          } else {
16072             user->amaflags = format;
16073          }
16074       } else if (!strcasecmp(v->name, "allow")) {
16075          ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1);
16076       } else if (!strcasecmp(v->name, "disallow")) {
16077          ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 0);
16078       } else if (!strcasecmp(v->name, "autoframing")) {
16079          user->autoframing = ast_true(v->value);
16080       } else if (!strcasecmp(v->name, "callingpres")) {
16081          user->callingpres = ast_parse_caller_presentation(v->value);
16082          if (user->callingpres == -1)
16083             user->callingpres = atoi(v->value);
16084       } else if (!strcasecmp(v->name, "maxcallbitrate")) {
16085          user->maxcallbitrate = atoi(v->value);
16086          if (user->maxcallbitrate < 0)
16087             user->maxcallbitrate = default_maxcallbitrate;
16088       }
16089       /* We can't just report unknown options here because this may be a
16090        * type=friend entry.  All user options are valid for a peer, but not
16091        * the other way around.  */
16092    }
16093    ast_copy_flags(&user->flags[0], &userflags[0], mask[0].flags);
16094    ast_copy_flags(&user->flags[1], &userflags[1], mask[1].flags);
16095    if (ast_test_flag(&user->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE))
16096       global_allowsubscribe = TRUE; /* No global ban any more */
16097    ast_free_ha(oldha);
16098    return user;
16099 }

static void build_via ( struct sip_pvt p  )  [static]

Build a Via header for a request.

Definition at line 1777 of file chan_sip.c.

References ast_inet_ntoa(), ast_string_field_build, ast_test_flag, sip_pvt::branch, sip_pvt::flags, sip_pvt::ourip, ourport, SIP_NAT, and SIP_NAT_RFC3581.

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

01778 {
01779    /* Work around buggy UNIDEN UIP200 firmware */
01780    const char *rport = ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_RFC3581 ? ";rport" : "";
01781 
01782    /* z9hG4bK is a magic cookie.  See RFC 3261 section 8.1.1.7 */
01783    ast_string_field_build(p, via, "SIP/2.0/UDP %s:%d;branch=z9hG4bK%08x%s",
01784           ast_inet_ntoa(p->ourip), ourport, p->branch, rport);
01785 }

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

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

Referenced by handle_request_subscribe().

08341 {
08342    struct sip_pvt *p = data;
08343 
08344    ast_mutex_lock(&p->lock);
08345 
08346    switch(state) {
08347    case AST_EXTENSION_DEACTIVATED:  /* Retry after a while */
08348    case AST_EXTENSION_REMOVED:   /* Extension is gone */
08349       if (p->autokillid > -1)
08350          sip_cancel_destroy(p);  /* Remove subscription expiry for renewals */
08351       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);  /* Delete subscription in 32 secs */
08352       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);
08353       p->stateid = -1;
08354       p->subscribed = NONE;
08355       append_history(p, "Subscribestatus", "%s", state == AST_EXTENSION_REMOVED ? "HintRemoved" : "Deactivated");
08356       break;
08357    default: /* Tell user */
08358       p->laststate = state;
08359       break;
08360    }
08361    if (p->subscribed != NONE) /* Only send state NOTIFY if we know the format */
08362       transmit_state_notify(p, state, 1, FALSE);
08363 
08364    if (option_verbose > 1)
08365       ast_verbose(VERBOSE_PREFIX_1 "Extension Changed %s new state %s for Notify User %s\n", exten, ast_extension_state2str(state), p->username);
08366    
08367    ast_mutex_unlock(&p->lock);
08368 
08369    return 0;
08370 }

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

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

Referenced by handle_request_invite(), and process_sdp().

04824 {
04825    if (global_notifyhold)
04826       sip_peer_hold(dialog, holdstate);
04827    if (global_callevents)
04828       manager_event(EVENT_FLAG_CALL, holdstate ? "Hold" : "Unhold",
04829                "Channel: %s\r\n"
04830                "Uniqueid: %s\r\n",
04831                dialog->owner->name, 
04832                dialog->owner->uniqueid);
04833    append_history(dialog, holdstate ? "Hold" : "Unhold", "%s", req->data);
04834    if (!holdstate) {    /* Put off remote hold */
04835       ast_clear_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD);   /* Clear both flags */
04836       return;
04837    }
04838    /* No address for RTP, we're on hold */
04839 
04840    if (sendonly == 1)   /* One directional hold (sendonly/recvonly) */
04841       ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_ONEDIR);
04842    else if (sendonly == 2) /* Inactive stream */
04843       ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_INACTIVE);
04844    else
04845       ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_ACTIVE);
04846    return;
04847 }

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

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

Returns:
0 on success, non-zero on error

Definition at line 8158 of file chan_sip.c.

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

Referenced by check_user_full(), and register_verify().

08161 {
08162    const char *response = "407 Proxy Authentication Required";
08163    const char *reqheader = "Proxy-Authorization";
08164    const char *respheader = "Proxy-Authenticate";
08165    const char *authtoken;
08166    char a1_hash[256];
08167    char resp_hash[256]="";
08168    char tmp[BUFSIZ * 2];                /* Make a large enough buffer */
08169    char *c;
08170    int  wrongnonce = FALSE;
08171    int  good_response;
08172    const char *usednonce = p->randdata;
08173 
08174    /* table of recognised keywords, and their value in the digest */
08175    enum keys { K_RESP, K_URI, K_USER, K_NONCE, K_LAST };
08176    struct x {
08177       const char *key;
08178       const char *s;
08179    } *i, keys[] = {
08180       [K_RESP] = { "response=", "" },
08181       [K_URI] = { "uri=", "" },
08182       [K_USER] = { "username=", "" },
08183       [K_NONCE] = { "nonce=", "" },
08184       [K_LAST] = { NULL, NULL}
08185    };
08186 
08187    /* Always OK if no secret */
08188    if (ast_strlen_zero(secret) && ast_strlen_zero(md5secret))
08189       return AUTH_SUCCESSFUL;
08190    if (sipmethod == SIP_REGISTER || sipmethod == SIP_SUBSCRIBE) {
08191       /* On a REGISTER, we have to use 401 and its family of headers instead of 407 and its family
08192          of headers -- GO SIP!  Whoo hoo!  Two things that do the same thing but are used in
08193          different circumstances! What a surprise. */
08194       response = "401 Unauthorized";
08195       reqheader = "Authorization";
08196       respheader = "WWW-Authenticate";
08197    }
08198    authtoken =  get_header(req, reqheader);  
08199    if (ignore && !ast_strlen_zero(p->randdata) && ast_strlen_zero(authtoken)) {
08200       /* This is a retransmitted invite/register/etc, don't reconstruct authentication
08201          information */
08202       if (!reliable) {
08203          /* Resend message if this was NOT a reliable delivery.   Otherwise the
08204             retransmission should get it */
08205          transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0);
08206          /* Schedule auto destroy in 32 seconds (according to RFC 3261) */
08207          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
08208       }
08209       return AUTH_CHALLENGE_SENT;
08210    } else if (ast_strlen_zero(p->randdata) || ast_strlen_zero(authtoken)) {
08211       /* We have no auth, so issue challenge and request authentication */
08212       ast_string_field_build(p, randdata, "%08lx", ast_random()); /* Create nonce for challenge */
08213       transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0);
08214       /* Schedule auto destroy in 32 seconds */
08215       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
08216       return AUTH_CHALLENGE_SENT;
08217    } 
08218 
08219    /* --- We have auth, so check it */
08220 
08221    /* Whoever came up with the authentication section of SIP can suck my %&#$&* for not putting
08222          an example in the spec of just what it is you're doing a hash on. */
08223 
08224 
08225    /* Make a copy of the response and parse it */
08226    ast_copy_string(tmp, authtoken, sizeof(tmp));
08227    c = tmp;
08228 
08229    while(c && *(c = ast_skip_blanks(c)) ) { /* lookup for keys */
08230       for (i = keys; i->key != NULL; i++) {
08231          const char *separator = ",";  /* default */
08232 
08233          if (strncasecmp(c, i->key, strlen(i->key)) != 0)
08234             continue;
08235          /* Found. Skip keyword, take text in quotes or up to the separator. */
08236          c += strlen(i->key);
08237          if (*c == '"') { /* in quotes. Skip first and look for last */
08238             c++;
08239             separator = "\"";
08240          }
08241          i->s = c;
08242          strsep(&c, separator);
08243          break;
08244       }
08245       if (i->key == NULL) /* not found, jump after space or comma */
08246          strsep(&c, " ,");
08247    }
08248 
08249    /* Verify that digest username matches  the username we auth as */
08250    if (strcmp(username, keys[K_USER].s)) {
08251       ast_log(LOG_WARNING, "username mismatch, have <%s>, digest has <%s>\n",
08252          username, keys[K_USER].s);
08253       /* Oops, we're trying something here */
08254       return AUTH_USERNAME_MISMATCH;
08255    }
08256 
08257    /* Verify nonce from request matches our nonce.  If not, send 401 with new nonce */
08258    if (strcasecmp(p->randdata, keys[K_NONCE].s)) { /* XXX it was 'n'casecmp ? */
08259       wrongnonce = TRUE;
08260       usednonce = keys[K_NONCE].s;
08261    }
08262 
08263    if (!ast_strlen_zero(md5secret))
08264       ast_copy_string(a1_hash, md5secret, sizeof(a1_hash));
08265    else {
08266       char a1[256];
08267       snprintf(a1, sizeof(a1), "%s:%s:%s", username, global_realm, secret);
08268       ast_md5_hash(a1_hash, a1);
08269    }
08270 
08271    /* compute the expected response to compare with what we received */
08272    {
08273       char a2[256];
08274       char a2_hash[256];
08275       char resp[256];
08276 
08277       snprintf(a2, sizeof(a2), "%s:%s", sip_methods[sipmethod].text,
08278             S_OR(keys[K_URI].s, uri));
08279       ast_md5_hash(a2_hash, a2);
08280       snprintf(resp, sizeof(resp), "%s:%s:%s", a1_hash, usednonce, a2_hash);
08281       ast_md5_hash(resp_hash, resp);
08282    }
08283 
08284    good_response = keys[K_RESP].s &&
08285          !strncasecmp(keys[K_RESP].s, resp_hash, strlen(resp_hash));
08286    if (wrongnonce) {
08287       ast_string_field_build(p, randdata, "%08lx", ast_random());
08288       if (good_response) {
08289          if (sipdebug)
08290             ast_log(LOG_NOTICE, "Correct auth, but based on stale nonce received from '%s'\n", get_header(req, "To"));
08291          /* We got working auth token, based on stale nonce . */
08292          transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, TRUE);
08293       } else {
08294          /* Everything was wrong, so give the device one more try with a new challenge */
08295          if (sipdebug)
08296             ast_log(LOG_NOTICE, "Bad authentication received from '%s'\n", get_header(req, "To"));
08297          transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, FALSE);
08298       }
08299 
08300       /* Schedule auto destroy in 32 seconds */
08301       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
08302       return AUTH_CHALLENGE_SENT;
08303    } 
08304    if (good_response) {
08305       append_history(p, "AuthOK", "Auth challenge succesful for %s", username);
08306       return AUTH_SUCCESSFUL;
08307    }
08308 
08309    /* Ok, we have a bad username/secret pair */
08310    /* Challenge again, and again, and again */
08311    transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0);
08312    sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
08313 
08314    return AUTH_CHALLENGE_SENT;
08315 }

static void check_pendings ( struct sip_pvt p  )  [static]

Check pending actions on SIP call.

Definition at line 11759 of file chan_sip.c.

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

Referenced by handle_request(), and handle_response_invite().

11760 {
11761    if (ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) {
11762       /* if we can't BYE, then this is really a pending CANCEL */
11763       if (p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA)
11764          transmit_request(p, SIP_CANCEL, p->ocseq, XMIT_RELIABLE, FALSE);
11765          /* Actually don't destroy us yet, wait for the 487 on our original 
11766             INVITE, but do set an autodestruct just in case we never get it. */
11767       else 
11768          transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, TRUE);
11769       ast_clear_flag(&p->flags[0], SIP_PENDINGBYE);   
11770       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
11771    } else if (ast_test_flag(&p->flags[0], SIP_NEEDREINVITE)) {
11772       if (option_debug)
11773          ast_log(LOG_DEBUG, "Sending pending reinvite on '%s'\n", p->callid);
11774       /* Didn't get to reinvite yet, so do it now */
11775       transmit_reinvite_with_sdp(p);
11776       ast_clear_flag(&p->flags[0], SIP_NEEDREINVITE); 
11777    }
11778 }

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

15867 {
15868    struct domain *d;
15869    int result = 0;
15870 
15871    AST_LIST_LOCK(&domain_list);
15872    AST_LIST_TRAVERSE(&domain_list, d, list) {
15873       if (strcasecmp(d->domain, domain))
15874          continue;
15875 
15876       if (len && !ast_strlen_zero(d->context))
15877          ast_copy_string(context, d->context, len);
15878       
15879       result = 1;
15880       break;
15881    }
15882    AST_LIST_UNLOCK(&domain_list);
15883 
15884    return result;
15885 }

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

References check_user_full().

Referenced by handle_request_invite().

09415 {
09416    return check_user_full(p, req, sipmethod, uri, reliable, sin, NULL);
09417 }

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

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

Referenced by check_user(), and handle_request_subscribe().

09096 {
09097    struct sip_user *user = NULL;
09098    struct sip_peer *peer;
09099    char from[256], *c;
09100    char *of;
09101    char rpid_num[50];
09102    const char *rpid;
09103    enum check_auth_result res = AUTH_SUCCESSFUL;
09104    char *t;
09105    char calleridname[50];
09106    int debug=sip_debug_test_addr(sin);
09107    struct ast_variable *tmpvar = NULL, *v = NULL;
09108    char *uri2 = ast_strdupa(uri);
09109 
09110    /* Terminate URI */
09111    t = uri2;
09112    while (*t && *t > 32 && *t != ';')
09113       t++;
09114    *t = '\0';
09115    ast_copy_string(from, get_header(req, "From"), sizeof(from));  /* XXX bug in original code, overwrote string */
09116    if (pedanticsipchecking)
09117       ast_uri_decode(from);
09118    /* XXX here tries to map the username for invite things */
09119    memset(calleridname, 0, sizeof(calleridname));
09120    get_calleridname(from, calleridname, sizeof(calleridname));
09121    if (calleridname[0])
09122       ast_string_field_set(p, cid_name, calleridname);
09123 
09124    rpid = get_header(req, "Remote-Party-ID");
09125    memset(rpid_num, 0, sizeof(rpid_num));
09126    if (!ast_strlen_zero(rpid)) 
09127       p->callingpres = get_rpid_num(rpid, rpid_num, sizeof(rpid_num));
09128 
09129    of = get_in_brackets(from);
09130    if (ast_strlen_zero(p->exten)) {
09131       t = uri2;
09132       if (!strncasecmp(t, "sip:", 4))
09133          t+= 4;
09134       ast_string_field_set(p, exten, t);
09135       t = strchr(p->exten, '@');
09136       if (t)
09137          *t = '\0';
09138       if (ast_strlen_zero(p->our_contact))
09139          build_contact(p);
09140    }
09141    /* save the URI part of the From header */
09142    ast_string_field_set(p, from, of);
09143    if (strncasecmp(of, "sip:", 4)) {
09144       ast_log(LOG_NOTICE, "From address missing 'sip:', using it anyway\n");
09145    } else
09146       of += 4;
09147    /* Get just the username part */
09148    if ((c = strchr(of, '@'))) {
09149       char *tmp;
09150       *c = '\0';
09151       if ((c = strchr(of, ':')))
09152          *c = '\0';
09153       tmp = ast_strdupa(of);
09154       /* We need to be able to handle auth-headers looking like
09155          <sip:8164444422;phone-context=+1@1.2.3.4:5060;user=phone;tag=SDadkoa01-gK0c3bdb43>
09156       */
09157       tmp = strsep(&tmp, ";");
09158       if (ast_is_shrinkable_phonenumber(tmp))
09159          ast_shrink_phone_number(tmp);
09160       ast_string_field_set(p, cid_num, tmp);
09161    }
09162    if (ast_strlen_zero(of))
09163       return AUTH_SUCCESSFUL;
09164 
09165    if (!authpeer) /* If we are looking for a peer, don't check the user objects (or realtime) */
09166       user = find_user(of, 1);
09167 
09168    /* Find user based on user name in the from header */
09169    if (user && ast_apply_ha(user->ha, sin)) {
09170       ast_copy_flags(&p->flags[0], &user->flags[0], SIP_FLAGS_TO_COPY);
09171       ast_copy_flags(&p->flags[1], &user->flags[1], SIP_PAGE2_FLAGS_TO_COPY);
09172       /* copy channel vars */
09173       for (v = user->chanvars ; v ; v = v->next) {
09174          if ((tmpvar = ast_variable_new(v->name, v->value))) {
09175             tmpvar->next = p->chanvars; 
09176             p->chanvars = tmpvar;
09177          }
09178       }
09179       p->prefs = user->prefs;
09180       /* Set Frame packetization */
09181       if (p->rtp) {
09182          ast_rtp_codec_setpref(p->rtp, &p->prefs);
09183          p->autoframing = user->autoframing;
09184       }
09185       /* replace callerid if rpid found, and not restricted */
09186       if (!ast_strlen_zero(rpid_num) && ast_test_flag(&p->flags[0], SIP_TRUSTRPID)) {
09187          char *tmp;
09188          if (*calleridname)
09189             ast_string_field_set(p, cid_name, calleridname);
09190          tmp = ast_strdupa(rpid_num);
09191          if (ast_is_shrinkable_phonenumber(tmp))
09192             ast_shrink_phone_number(tmp);
09193          ast_string_field_set(p, cid_num, tmp);
09194       }
09195       
09196       do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT_ROUTE) );
09197 
09198       if (!(res = check_auth(p, req, user->name, user->secret, user->md5secret, sipmethod, uri2, reliable, ast_test_flag(req, SIP_PKT_IGNORE)))) {
09199          sip_cancel_destroy(p);
09200          ast_copy_flags(&p->flags[0], &user->flags[0], SIP_FLAGS_TO_COPY);
09201          ast_copy_flags(&p->flags[1], &user->flags[1], SIP_PAGE2_FLAGS_TO_COPY);
09202          /* Copy SIP extensions profile from INVITE */
09203          if (p->sipoptions)
09204             user->sipoptions = p->sipoptions;
09205 
09206          /* If we have a call limit, set flag */
09207          if (user->call_limit)
09208             ast_set_flag(&p->flags[0], SIP_CALL_LIMIT);
09209          if (!ast_strlen_zero(user->context))
09210             ast_string_field_set(p, context, user->context);
09211          if (!ast_strlen_zero(user->cid_num) && !ast_strlen_zero(p->cid_num)) {
09212             char *tmp = ast_strdupa(user->cid_num);
09213             if (ast_is_shrinkable_phonenumber(tmp))
09214                ast_shrink_phone_number(tmp);
09215             ast_string_field_set(p, cid_num, tmp);
09216          }
09217          if (!ast_strlen_zero(user->cid_name) && !ast_strlen_zero(p->cid_num))
09218             ast_string_field_set(p, cid_name, user->cid_name);
09219          ast_string_field_set(p, username, user->name);
09220          ast_string_field_set(p, peername, user->name);
09221          ast_string_field_set(p, peersecret, user->secret);
09222          ast_string_field_set(p, peermd5secret, user->md5secret);
09223          ast_string_field_set(p, subscribecontext, user->subscribecontext);
09224          ast_string_field_set(p, accountcode, user->accountcode);
09225          ast_string_field_set(p, language, user->language);
09226          ast_string_field_set(p, mohsuggest, user->mohsuggest);
09227          ast_string_field_set(p, mohinterpret, user->mohinterpret);
09228          p->allowtransfer = user->allowtransfer;
09229          p->amaflags = user->amaflags;
09230          p->callgroup = user->callgroup;
09231          p->pickupgroup = user->pickupgroup;
09232          if (user->callingpres)  /* User callingpres setting will override RPID header */
09233             p->callingpres = user->callingpres;
09234          
09235          /* Set default codec settings for this call */
09236          p->capability = user->capability;      /* User codec choice */
09237          p->jointcapability = user->capability;    /* Our codecs */
09238          if (p->peercapability)           /* AND with peer's codecs */
09239             p->jointcapability &= p->peercapability;
09240          if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) ||
09241              (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO))
09242             p->noncodeccapability |= AST_RTP_DTMF;
09243          else
09244             p->noncodeccapability &= ~AST_RTP_DTMF;
09245          p->jointnoncodeccapability = p->noncodeccapability;
09246          if (p->t38.peercapability)
09247             p->t38.jointcapability &= p->t38.peercapability;
09248          p->maxcallbitrate = user->maxcallbitrate;
09249          /* If we do not support video, remove video from call structure */
09250          if ((!ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) || !(p->capability & AST_FORMAT_VIDEO_MASK)) && p->vrtp) {
09251             ast_rtp_destroy(p->vrtp);
09252             p->vrtp = NULL;
09253          }
09254       }
09255       if (user && debug)
09256          ast_verbose("Found user '%s'\n", user->name);
09257    } else {
09258       if (user) {
09259          if (!authpeer && debug)
09260             ast_verbose("Found user '%s', but fails host access\n", user->name);
09261          ASTOBJ_UNREF(user,sip_destroy_user);
09262       }
09263       user = NULL;
09264    }
09265 
09266    if (!user) {
09267       /* If we didn't find a user match, check for peers */
09268       if (sipmethod == SIP_SUBSCRIBE)
09269          /* For subscribes, match on peer name only */
09270          peer = find_peer(of, NULL, 1);
09271       else
09272          /* Look for peer based on the IP address we received data from */
09273          /* If peer is registered from this IP address or have this as a default
09274             IP address, this call is from the peer 
09275          */
09276          peer = find_peer(NULL, &p->recv, 1);
09277 
09278       if (peer) {
09279          /* Set Frame packetization */
09280          if (p->rtp) {
09281             ast_rtp_codec_setpref(p->rtp, &peer->prefs);
09282             p->autoframing = peer->autoframing;
09283          }
09284          if (debug)
09285             ast_verbose("Found peer '%s'\n", peer->name);
09286 
09287          /* Take the peer */
09288          ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY);
09289          ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY);
09290 
09291          /* Copy SIP extensions profile to peer */
09292          if (p->sipoptions)
09293             peer->sipoptions = p->sipoptions;
09294 
09295          /* replace callerid if rpid found, and not restricted */
09296          if (!ast_strlen_zero(rpid_num) && ast_test_flag(&p->flags[0], SIP_TRUSTRPID)) {
09297             char *tmp = ast_strdupa(rpid_num);
09298             if (*calleridname)
09299                ast_string_field_set(p, cid_name, calleridname);
09300             if (ast_is_shrinkable_phonenumber(tmp))
09301                ast_shrink_phone_number(tmp);
09302             ast_string_field_set(p, cid_num, tmp);
09303          }
09304          do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT_ROUTE));
09305 
09306          ast_string_field_set(p, peersecret, peer->secret);
09307          ast_string_field_set(p, peermd5secret, peer->md5secret);
09308          ast_string_field_set(p, subscribecontext, peer->subscribecontext);
09309          ast_string_field_set(p, mohinterpret, peer->mohinterpret);
09310          ast_string_field_set(p, mohsuggest, peer->mohsuggest);
09311          if (peer->callingpres)  /* Peer calling pres setting will override RPID */
09312             p->callingpres = peer->callingpres;
09313          if (peer->maxms && peer->lastms)
09314             p->timer_t1 = peer->lastms;
09315          if (ast_test_flag(&peer->flags[0], SIP_INSECURE_INVITE)) {
09316             /* Pretend there is no required authentication */
09317             ast_string_field_free(p, peersecret);
09318             ast_string_field_free(p, peermd5secret);
09319          }
09320          if (!(res = check_auth(p, req, peer->name, p->peersecret, p->peermd5secret, sipmethod, uri2, reliable, ast_test_flag(req, SIP_PKT_IGNORE)))) {
09321             ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY);
09322             ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY);
09323             /* If we have a call limit, set flag */
09324             if (peer->call_limit)
09325                ast_set_flag(&p->flags[0], SIP_CALL_LIMIT);
09326             ast_string_field_set(p, peername, peer->name);
09327             ast_string_field_set(p, authname, peer->name);
09328 
09329             /* copy channel vars */
09330             for (v = peer->chanvars ; v ; v = v->next) {
09331                if ((tmpvar = ast_variable_new(v->name, v->value))) {
09332                   tmpvar->next = p->chanvars; 
09333                   p->chanvars = tmpvar;
09334                }
09335             }
09336             if (authpeer) {
09337                (*authpeer) = ASTOBJ_REF(peer);  /* Add a ref to the object here, to keep it in memory a bit longer if it is realtime */
09338             }
09339 
09340             if (!ast_strlen_zero(peer->username)) {
09341                ast_string_field_set(p, username, peer->username);
09342                /* Use the default username for authentication on outbound calls */
09343                /* XXX this takes the name from the caller... can we override ? */
09344                ast_string_field_set(p, authname, peer->username);
09345             }
09346             if (!ast_strlen_zero(peer->cid_num) && !ast_strlen_zero(p->cid_num)) {
09347                char *tmp = ast_strdupa(peer->cid_num);
09348                if (ast_is_shrinkable_phonenumber(tmp))
09349                   ast_shrink_phone_number(tmp);
09350                ast_string_field_set(p, cid_num, tmp);
09351             }
09352             if (!ast_strlen_zero(peer->cid_name) && !ast_strlen_zero(p->cid_name)) 
09353                ast_string_field_set(p, cid_name, peer->cid_name);
09354             ast_string_field_set(p, fullcontact, peer->fullcontact);
09355             if (!ast_strlen_zero(peer->context))
09356                ast_string_field_set(p, context, peer->context);
09357             ast_string_field_set(p, peersecret, peer->secret);
09358             ast_string_field_set(p, peermd5secret, peer->md5secret);
09359             ast_string_field_set(p, language, peer->language);
09360             ast_string_field_set(p, accountcode, peer->accountcode);
09361             p->amaflags = peer->amaflags;
09362             p->callgroup = peer->callgroup;
09363             p->pickupgroup = peer->pickupgroup;
09364             p->capability = peer->capability;
09365             p->prefs = peer->prefs;
09366             p->jointcapability = peer->capability;
09367             if (p->peercapability)
09368                p->jointcapability &= p->peercapability;
09369             p->maxcallbitrate = peer->maxcallbitrate;
09370             if ((!ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) || !(p->capability & AST_FORMAT_VIDEO_MASK)) && p->vrtp) {
09371                ast_rtp_destroy(p->vrtp);
09372                p->vrtp = NULL;
09373             }
09374             if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) ||
09375                 (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO))
09376                p->noncodeccapability |= AST_RTP_DTMF;
09377             else
09378                p->noncodeccapability &= ~AST_RTP_DTMF;
09379             p->jointnoncodeccapability = p->noncodeccapability;
09380             if (p->t38.peercapability)
09381                p->t38.jointcapability &= p->t38.peercapability;
09382          }
09383          ASTOBJ_UNREF(peer, sip_destroy_peer);
09384       } else { 
09385          if (debug)
09386             ast_verbose("Found no matching peer or user for '%s:%d'\n", ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port));
09387 
09388          /* do we allow guests? */
09389          if (!global_allowguest) {
09390             if (global_alwaysauthreject)
09391                res = AUTH_FAKE_AUTH; /* reject with fake authorization request */
09392             else
09393                res = AUTH_SECRET_FAILED; /* we don't want any guests, authentication will fail */
09394          } else if (!ast_strlen_zero(rpid_num) && ast_test_flag(&p->flags[0], SIP_TRUSTRPID)) {
09395             char *tmp = ast_strdupa(rpid_num);
09396             if (*calleridname)
09397                ast_string_field_set(p, cid_name, calleridname);
09398             if (ast_is_shrinkable_phonenumber(tmp))
09399                ast_shrink_phone_number(tmp);
09400             ast_string_field_set(p, cid_num, tmp);
09401                         }
09402       }
09403 
09404    }
09405 
09406    if (user)
09407       ASTOBJ_UNREF(user, sip_destroy_user);
09408    return res;
09409 }

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

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

Definition at line 8961 of file chan_sip.c.

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

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

08962 {
08963    char via[256];
08964    char *c, *pt;
08965    struct hostent *hp;
08966    struct ast_hostent ahp;
08967 
08968    ast_copy_string(via, get_header(req, "Via"), sizeof(via));
08969 
08970    /* Work on the leftmost value of the topmost Via header */
08971    c = strchr(via, ',');
08972    if (c)
08973       *c = '\0';
08974 
08975    /* Check for rport */
08976    c = strstr(via, ";rport");
08977    if (c && (c[6] != '=')) /* rport query, not answer */
08978       ast_set_flag(&p->flags[0], SIP_NAT_ROUTE);
08979 
08980    c = strchr(via, ';');
08981    if (c) 
08982       *c = '\0';
08983 
08984    c = strchr(via, ' ');
08985    if (c) {
08986       *c = '\0';
08987       c = ast_skip_blanks(c+1);
08988       if (strcasecmp(via, "SIP/2.0/UDP")) {
08989          ast_log(LOG_WARNING, "Don't know how to respond via '%s'\n", via);
08990          return;
08991       }
08992       pt = strchr(c, ':');
08993       if (pt)
08994          *pt++ = '\0';  /* remember port pointer */
08995       hp = ast_gethostbyname(c, &ahp);
08996       if (!hp) {
08997          ast_log(LOG_WARNING, "'%s' is not a valid host\n", c);
08998          return;
08999       }
09000       memset(&p->sa, 0, sizeof(p->sa));
09001       p->sa.sin_family = AF_INET;
09002       memcpy(&p->sa.sin_addr, hp->h_addr, sizeof(p->sa.sin_addr));
09003       p->sa.sin_port = htons(pt ? atoi(pt) : STANDARD_SIP_PORT);
09004 
09005       if (sip_debug_test_pvt(p)) {
09006          const struct sockaddr_in *dst = sip_real_dst(p);
09007          ast_verbose("Sending to %s : %d (%s)\n", ast_inet_ntoa(dst->sin_addr), ntohs(dst->sin_port), sip_nat_mode(p));
09008       }
09009    }
09010 }

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

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

Referenced by reload_config().

09857 {
09858    char *oldcontext, *newcontext, *stalecontext, *stringp, newlist[AST_MAX_CONTEXT];
09859 
09860    while ((oldcontext = strsep(&old, "&"))) {
09861       stalecontext = '\0';
09862       ast_copy_string(newlist, new, sizeof(newlist));
09863       stringp = newlist;
09864       while ((newcontext = strsep(&stringp, "&"))) {
09865          if (strcmp(newcontext, oldcontext) == 0) {
09866             /* This is not the context you're looking for */
09867             stalecontext = '\0';
09868             break;
09869          } else if (strcmp(newcontext, oldcontext)) {
09870             stalecontext = oldcontext;
09871          }
09872          
09873       }
09874       if (stalecontext)
09875          ast_context_destroy(ast_context_find(stalecontext), "SIP");
09876    }
09877 }

static int clear_realm_authentication ( struct sip_auth authlist  )  [static]

Clear realm authentication list (at reload).

Definition at line 15959 of file chan_sip.c.

References free, and sip_auth::next.

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

15960 {
15961    struct sip_auth *a = authlist;
15962    struct sip_auth *b;
15963 
15964    while (a) {
15965       b = a;
15966       a = a->next;
15967       free(b);
15968    }
15969 
15970    return 1;
15971 }

static void clear_sip_domains ( void   )  [static]

Clear our domain list (at reload).

Definition at line 15888 of file chan_sip.c.

References AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, and free.

Referenced by sip_do_reload(), and unload_module().

15889 {
15890    struct domain *d;
15891 
15892    AST_LIST_LOCK(&domain_list);
15893    while ((d = AST_LIST_REMOVE_HEAD(&domain_list, list)))
15894       free(d);
15895    AST_LIST_UNLOCK(&domain_list);
15896 }

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

References complete_sip_peer().

10664 {
10665    if (pos == 3)
10666       return complete_sip_peer(word, state, 0);
10667 
10668    return NULL;
10669 }

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

Do completion on peer name.

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

10638 {
10639    char *result = NULL;
10640    int wordlen = strlen(word);
10641    int which = 0;
10642 
10643    ASTOBJ_CONTAINER_TRAVERSE(&peerl, !result, do {
10644       /* locking of the object is not required because only the name and flags are being compared */
10645       if (!strncasecmp(word, iterator->name, wordlen) &&
10646             (!flags2 || ast_test_flag(&iterator->flags[1], flags2)) &&
10647             ++which > state)
10648          result = ast_strdup(iterator->name);
10649    } while(0) );
10650    return result;
10651 }

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

References complete_sip_peer(), and SIP_PAGE2_RTCACHEFRIENDS.

10732 {
10733    if (pos == 4)
10734       return complete_sip_peer(word, state, SIP_PAGE2_RTCACHEFRIENDS);
10735    return NULL;
10736 }

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

References complete_sip_user(), and SIP_PAGE2_RTCACHEFRIENDS.

10740 {
10741    if (pos == 4)
10742       return complete_sip_user(word, state, SIP_PAGE2_RTCACHEFRIENDS);
10743 
10744    return NULL;
10745 }

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

References complete_sip_peer().

10655 {
10656    if (pos == 3)
10657       return complete_sip_peer(word, state, 0);
10658 
10659    return NULL;
10660 }

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

References complete_sip_user().

10693 {
10694    if (pos == 3)
10695       return complete_sip_user(word, state, 0);
10696 
10697    return NULL;
10698 }

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

Do completion on user name.

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

10673 {
10674    char *result = NULL;
10675    int wordlen = strlen(word);
10676    int which = 0;
10677 
10678    ASTOBJ_CONTAINER_TRAVERSE(&userl, !result, do {
10679       /* locking of the object is not required because only the name and flags are being compared */
10680       if (!strncasecmp(word, iterator->name, wordlen)) {
10681          if (flags2 && !ast_test_flag(&iterator->flags[1], flags2))
10682             continue;
10683          if (++which > state) {
10684             result = ast_strdup(iterator->name);
10685          }
10686       }
10687    } while(0) );
10688    return result;
10689 }

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

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

10619 {
10620    int which=0;
10621    struct sip_pvt *cur;
10622    char *c = NULL;
10623    int wordlen = strlen(word);
10624 
10625    ast_mutex_lock(&iflock);
10626    for (cur = iflist; cur; cur = cur->next) {
10627       if (!strncasecmp(word, cur->callid, wordlen) && ++which > state) {
10628          c = ast_strdup(cur->callid);
10629          break;
10630       }
10631    }
10632    ast_mutex_unlock(&iflock);
10633    return c;
10634 }

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

Support routine for 'sip notify' CLI.

Definition at line 10701 of file chan_sip.c.

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

10702 {
10703    char *c = NULL;
10704 
10705    if (pos == 2) {
10706       int which = 0;
10707       char *cat = NULL;
10708       int wordlen = strlen(word);
10709 
10710       /* do completion for notify type */
10711 
10712       if (!notify_types)
10713          return NULL;
10714       
10715       while ( (cat = ast_category_browse(notify_types, cat)) ) {
10716          if (!strncasecmp(word, cat, wordlen) && ++which > state) {
10717             c = ast_strdup(cat);
10718             break;
10719          }
10720       }
10721       return c;
10722    }
10723 
10724    if (pos > 2)
10725       return complete_sip_peer(word, state, 0);
10726 
10727    return NULL;
10728 }

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

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

Referenced by respprep().

05486 {
05487    int start = 0;
05488    int copied = 0;
05489    for (;;) {
05490       const char *tmp = __get_header(orig, field, &start);
05491 
05492       if (ast_strlen_zero(tmp))
05493          break;
05494       /* Add what we're responding to */
05495       add_header(req, field, tmp);
05496       copied++;
05497    }
05498    return copied ? 0 : -1;
05499 }

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

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

Referenced by reqprep(), and respprep().

05475 {
05476    const char *tmp = get_header(orig, field);
05477 
05478    if (!ast_strlen_zero(tmp)) /* Add what we're responding to */
05479       return add_header(req, field, tmp);
05480    ast_log(LOG_NOTICE, "No field '%s' present to copy\n", field);
05481    return -1;
05482 }

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

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

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

06523 {
06524    long offset;
06525    int x;
06526    offset = ((void *)dst) - ((void *)src);
06527    /* First copy stuff */
06528    memcpy(dst, src, sizeof(*dst));
06529    /* Now fix pointer arithmetic */
06530    for (x=0; x < src->headers; x++)
06531       dst->header[x] += offset;
06532    for (x=0; x < src->lines; x++)
06533       dst->line[x] += offset;
06534    dst->rlPart1 += offset;
06535    dst->rlPart2 += offset;
06536 }

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

05508 {
05509    int copied = 0;
05510    int start = 0;
05511 
05512    for (;;) {
05513       char new[256];
05514       const char *oh = __get_header(orig, field, &start);
05515 
05516       if (ast_strlen_zero(oh))
05517          break;
05518 
05519       if (!copied) { /* Only check for empty rport in topmost via header */
05520          char leftmost[256], *others, *rport;
05521 
05522          /* Only work on leftmost value */
05523          ast_copy_string(leftmost, oh, sizeof(leftmost));
05524          others = strchr(leftmost, ',');
05525          if (others)
05526              *others++ = '\0';
05527 
05528          /* Find ;rport;  (empty request) */
05529          rport = strstr(leftmost, ";rport");
05530          if (rport && *(rport+6) == '=') 
05531             rport = NULL;     /* We already have a parameter to rport */
05532 
05533          /* Check rport if NAT=yes or NAT=rfc3581 (which is the default setting)  */
05534          if (rport && ((ast_test_flag(&p->flags[0], SIP_NAT) == SIP_NAT_ALWAYS) || (ast_test_flag(&p->flags[0], SIP_NAT) == SIP_NAT_RFC3581))) {
05535             /* We need to add received port - rport */
05536             char *end;
05537 
05538             rport = strstr(leftmost, ";rport");
05539 
05540             if (rport) {
05541                end = strchr(rport + 1, ';');
05542                if (end)
05543                   memmove(rport, end, strlen(end) + 1);
05544                else
05545                   *rport = '\0';
05546             }
05547 
05548             /* Add rport to first VIA header if requested */
05549             snprintf(new, sizeof(new), "%s;received=%s;rport=%d%s%s",
05550                leftmost, ast_inet_ntoa(p->recv.sin_addr),
05551                ntohs(p->recv.sin_port),
05552                others ? "," : "", others ? others : "");
05553          } else {
05554             /* We should *always* add a received to the topmost via */
05555             snprintf(new, sizeof(new), "%s;received=%s%s%s",
05556                leftmost, ast_inet_ntoa(p->recv.sin_addr),
05557                others ? "," : "", others ? others : "");
05558          }
05559          oh = new;   /* the header to copy */
05560       }  /* else add the following via headers untouched */
05561       add_header(req, field, oh);
05562       copied++;
05563    }
05564    if (!copied) {
05565       ast_log(LOG_NOTICE, "No header field '%s' present to copy\n", field);
05566       return -1;
05567    }
05568    return 0;
05569 }

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

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

02803 {
02804    struct hostent *hp;
02805    struct ast_hostent ahp;
02806    struct sip_peer *p;
02807    char *port;
02808    int portno;
02809    char host[MAXHOSTNAMELEN], *hostn;
02810    char peer[256];
02811 
02812    ast_copy_string(peer, opeer, sizeof(peer));
02813    port = strchr(peer, ':');
02814    if (port)
02815       *port++ = '\0';
02816    dialog->sa.sin_family = AF_INET;
02817    dialog->timer_t1 = 500; /* Default SIP retransmission timer T1 (RFC 3261) */
02818    p = find_peer(peer, NULL, 1);
02819 
02820    if (p) {
02821       int res = create_addr_from_peer(dialog, p);
02822       ASTOBJ_UNREF(p, sip_destroy_peer);
02823       return res;
02824    }
02825    hostn = peer;
02826    portno = port ? atoi(port) : STANDARD_SIP_PORT;
02827    if (srvlookup) {
02828       char service[MAXHOSTNAMELEN];
02829       int tportno;
02830       int ret;
02831 
02832       snprintf(service, sizeof(service), "_sip._udp.%s", peer);
02833       ret = ast_get_srv(NULL, host, sizeof(host), &tportno, service);
02834       if (ret > 0) {
02835          hostn = host;
02836          portno = tportno;
02837       }
02838    }
02839    hp = ast_gethostbyname(hostn, &ahp);
02840    if (!hp) {
02841       ast_log(LOG_WARNING, "No such host: %s\n", peer);
02842       return -1;
02843    }
02844    ast_string_field_set(dialog, tohost, peer);
02845    memcpy(&dialog->sa.sin_addr, hp->h_addr, sizeof(dialog->sa.sin_addr));
02846    dialog->sa.sin_port = htons(portno);
02847    dialog->recv = dialog->sa;
02848    return 0;
02849 }

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

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

Referenced by create_addr(), and sip_send_mwi_to_peer().

02695 {
02696    if ((peer->addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr) &&
02697        (!peer->maxms || ((peer->lastms >= 0)  && (peer->lastms <= peer->maxms)))) {
02698       dialog->sa = (peer->addr.sin_addr.s_addr) ? peer->addr : peer->defaddr;
02699       dialog->recv = dialog->sa;
02700    } else 
02701       return -1;
02702 
02703    ast_copy_flags(&dialog->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY);
02704    ast_copy_flags(&dialog->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY);
02705    dialog->capability = peer->capability;
02706    if ((!ast_test_flag(&dialog->flags[1], SIP_PAGE2_VIDEOSUPPORT) || !(dialog->capability & AST_FORMAT_VIDEO_MASK)) && dialog->vrtp) {
02707       ast_rtp_destroy(dialog->vrtp);
02708       dialog->vrtp = NULL;
02709    }
02710    dialog->prefs = peer->prefs;
02711    if (ast_test_flag(&dialog->flags[1], SIP_PAGE2_T38SUPPORT)) {
02712       dialog->t38.capability = global_t38_capability;
02713       if (dialog->udptl) {
02714          if (ast_udptl_get_error_correction_scheme(dialog->udptl) == UDPTL_ERROR_CORRECTION_FEC )
02715             dialog->t38.capability |= T38FAX_UDP_EC_FEC;
02716          else if (ast_udptl_get_error_correction_scheme(dialog->udptl) == UDPTL_ERROR_CORRECTION_REDUNDANCY )
02717             dialog->t38.capability |= T38FAX_UDP_EC_REDUNDANCY;
02718          else if (ast_udptl_get_error_correction_scheme(dialog->udptl) == UDPTL_ERROR_CORRECTION_NONE )
02719             dialog->t38.capability |= T38FAX_UDP_EC_NONE;
02720          dialog->t38.capability |= T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF;
02721          if (option_debug > 1)
02722             ast_log(LOG_DEBUG,"Our T38 capability (%d)\n", dialog->t38.capability);
02723       }
02724       dialog->t38.jointcapability = dialog->t38.capability;
02725    } else if (dialog->udptl) {
02726       ast_udptl_destroy(dialog->udptl);
02727       dialog->udptl = NULL;
02728    }
02729    do_setnat(dialog, ast_test_flag(&dialog->flags[0], SIP_NAT) & SIP_NAT_ROUTE );
02730 
02731    if (dialog->rtp) {
02732       ast_rtp_setdtmf(dialog->rtp, ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833);
02733       ast_rtp_setdtmfcompensate(dialog->rtp, ast_test_flag(&dialog->flags[1], SIP_PAGE2_RFC2833_COMPENSATE));
02734       ast_rtp_set_rtptimeout(dialog->rtp, peer->rtptimeout);
02735       ast_rtp_set_rtpholdtimeout(dialog->rtp, peer->rtpholdtimeout);
02736       ast_rtp_set_rtpkeepalive(dialog->rtp, peer->rtpkeepalive);
02737       /* Set Frame packetization */
02738       ast_rtp_codec_setpref(dialog->rtp, &dialog->prefs);
02739       dialog->autoframing = peer->autoframing;
02740    }
02741    if (dialog->vrtp) {
02742       ast_rtp_setdtmf(dialog->vrtp, 0);
02743       ast_rtp_setdtmfcompensate(dialog->vrtp, 0);
02744       ast_rtp_set_rtptimeout(dialog->vrtp, peer->rtptimeout);
02745       ast_rtp_set_rtpholdtimeout(dialog->vrtp, peer->rtpholdtimeout);
02746       ast_rtp_set_rtpkeepalive(dialog->vrtp, peer->rtpkeepalive);
02747    }
02748 
02749    ast_string_field_set(dialog, peername, peer->name);
02750    ast_string_field_set(dialog, authname, peer->username);
02751    ast_string_field_set(dialog, username, peer->username);
02752    ast_string_field_set(dialog, peersecret, peer->secret);
02753    ast_string_field_set(dialog, peermd5secret, peer->md5secret);
02754    ast_string_field_set(dialog, mohsuggest, peer->mohsuggest);
02755    ast_string_field_set(dialog, mohinterpret, peer->mohinterpret);
02756    ast_string_field_set(dialog, tohost, peer->tohost);
02757    ast_string_field_set(dialog, fullcontact, peer->fullcontact);
02758    if (!dialog->initreq.headers && !ast_strlen_zero(peer->fromdomain)) {
02759       char *tmpcall;
02760       char *c;
02761       tmpcall = ast_strdupa(dialog->callid);
02762       c = strchr(tmpcall, '@');
02763       if (c) {
02764          *c = '\0';
02765          ast_string_field_build(dialog, callid, "%s@%s", tmpcall, peer->fromdomain);
02766       }
02767    }
02768    if (ast_strlen_zero(dialog->tohost))
02769       ast_string_field_set(dialog, tohost, ast_inet_ntoa(dialog->sa.sin_addr));
02770    if (!ast_strlen_zero(peer->fromdomain))
02771       ast_string_field_set(dialog, fromdomain, peer->fromdomain);
02772    if (!ast_strlen_zero(peer->fromuser))
02773       ast_string_field_set(dialog, fromuser, peer->fromuser);
02774    if (!ast_strlen_zero(peer->language))
02775       ast_string_field_set(dialog, language, peer->language);
02776    dialog->maxtime = peer->maxms;
02777    dialog->callgroup = peer->callgroup;
02778    dialog->pickupgroup = peer->pickupgroup;
02779    dialog->allowtransfer = peer->allowtransfer;
02780    /* Set timer T1 to RTT for this peer (if known by qualify=) */
02781    /* Minimum is settable or default to 100 ms */
02782    if (peer->maxms && peer->lastms)
02783       dialog->timer_t1 = peer->lastms < global_t1min ? global_t1min : peer->lastms;
02784    if ((ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) ||
02785        (ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_AUTO))
02786       dialog->noncodeccapability |= AST_RTP_DTMF;
02787    else
02788       dialog->noncodeccapability &= ~AST_RTP_DTMF;
02789    dialog->jointnoncodeccapability = dialog->noncodeccapability;
02790    ast_string_field_set(dialog, context, peer->context);
02791    dialog->rtptimeout = peer->rtptimeout;
02792    if (peer->call_limit)
02793       ast_set_flag(&dialog->flags[0], SIP_CALL_LIMIT);
02794    dialog->maxcallbitrate = peer->maxcallbitrate;
02795    
02796    return 0;
02797 }

static void destroy_association ( struct sip_peer peer  )  [static]

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

Definition at line 7683 of file chan_sip.c.

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

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

07684 {
07685    if (!ast_test_flag(&global_flags[1], SIP_PAGE2_IGNOREREGEXPIRE)) {
07686       if (ast_test_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT))
07687          ast_update_realtime("sippeers", "name", peer->name, "fullcontact", "", "ipaddr", "", "port", "", "regseconds", "0", "username", "", "regserver", "", NULL);
07688       else 
07689          ast_db_del("SIP/Registry", peer->name);
07690    }
07691 }

static int determine_firstline_parts ( struct sip_request req  )  [static]

Parse first line of incoming SIP request.

Definition at line 6566 of file chan_sip.c.

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

Referenced by parse_request().

06567 {
06568    char *e = ast_skip_blanks(req->header[0]);   /* there shouldn't be any */
06569 
06570    if (!*e)
06571       return -1;
06572    req->rlPart1 = e; /* method or protocol */
06573    e = ast_skip_nonblanks(e);
06574    if (*e)
06575       *e++ = '\0';
06576    /* Get URI or status code */
06577    e = ast_skip_blanks(e);
06578    if ( !*e )
06579       return -1;
06580    ast_trim_blanks(e);
06581 
06582    if (!strcasecmp(req->rlPart1, "SIP/2.0") ) { /* We have a response */
06583       if (strlen(e) < 3)   /* status code is 3 digits */
06584          return -1;
06585       req->rlPart2 = e;
06586    } else { /* We have a request */
06587       if ( *e == '<' ) { /* XXX the spec says it must not be in <> ! */
06588          ast_log(LOG_WARNING, "bogus uri in <> %s\n", e);
06589          e++;
06590          if (!*e)
06591             return -1; 
06592       }
06593       req->rlPart2 = e; /* URI */
06594       e = ast_skip_nonblanks(e);
06595       if (*e)
06596          *e++ = '\0';
06597       e = ast_skip_blanks(e);
06598       if (strcasecmp(e, "SIP/2.0") ) {
06599          ast_log(LOG_WARNING, "Bad request protocol %s\n", e);
06600          return -1;
06601       }
06602    }
06603    return 1;
06604 }

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

Definition at line 15224 of file chan_sip.c.

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

15225 {
15226    int res;
15227    struct sip_pvt *sip;
15228    struct sip_peer *peer = NULL;
15229    time_t t;
15230    int fastrestart = FALSE;
15231    int lastpeernum = -1;
15232    int curpeernum;
15233    int reloading;
15234 
15235    /* Add an I/O event to our SIP UDP socket */
15236    if (sipsock > -1) 
15237       sipsock_read_id = ast_io_add(io, sipsock, sipsock_read, AST_IO_IN, NULL);
15238    
15239    /* From here on out, we die whenever asked */
15240    for(;;) {
15241       /* Check for a reload request */
15242       ast_mutex_lock(&sip_reload_lock);
15243       reloading = sip_reloading;
15244       sip_reloading = FALSE;
15245       ast_mutex_unlock(&sip_reload_lock);
15246       if (reloading) {
15247          if (option_verbose > 0)
15248             ast_verbose(VERBOSE_PREFIX_1 "Reloading SIP\n");
15249          sip_do_reload(sip_reloadreason);
15250 
15251          /* Change the I/O fd of our UDP socket */
15252          if (sipsock > -1) {
15253             if (sipsock_read_id)
15254                sipsock_read_id = ast_io_change(io, sipsock_read_id, sipsock, NULL, 0, NULL);
15255             else
15256                sipsock_read_id = ast_io_add(io, sipsock, sipsock_read, AST_IO_IN, NULL);
15257          }
15258       }
15259       /* Check for interfaces needing to be killed */
15260       ast_mutex_lock(&iflock);
15261 restartsearch:    
15262       t = time(NULL);
15263       /* don't scan the interface list if it hasn't been a reasonable period
15264          of time since the last time we did it (when MWI is being sent, we can
15265          get back to this point every millisecond or less)
15266       */
15267       for (sip = iflist; !fastrestart && sip; sip = sip->next) {
15268          ast_mutex_lock(&sip->lock);
15269          /* Check RTP timeouts and kill calls if we have a timeout set and do not get RTP */
15270          if (sip->rtp && sip->owner &&
15271              (sip->owner->_state == AST_STATE_UP) &&
15272              !sip->redirip.sin_addr.s_addr &&
15273              sip->t38.state != T38_ENABLED) {
15274             if (sip->lastrtptx &&
15275                 ast_rtp_get_rtpkeepalive(sip->rtp) &&
15276                 (t > sip->lastrtptx + ast_rtp_get_rtpkeepalive(sip->rtp))) {
15277                /* Need to send an empty RTP packet */
15278                sip->lastrtptx = time(NULL);
15279                ast_rtp_sendcng(sip->rtp, 0);
15280             }
15281             if (sip->lastrtprx &&
15282                (ast_rtp_get_rtptimeout(sip->rtp) || ast_rtp_get_rtpholdtimeout(sip->rtp)) &&
15283                 (t > sip->lastrtprx + ast_rtp_get_rtptimeout(sip->rtp))) {
15284                /* Might be a timeout now -- see if we're on hold */
15285                struct sockaddr_in sin;
15286                ast_rtp_get_peer(sip->rtp, &sin);
15287                if (sin.sin_addr.s_addr || 
15288                    (ast_rtp_get_rtpholdtimeout(sip->rtp) &&
15289                     (t > sip->lastrtprx + ast_rtp_get_rtpholdtimeout(sip->rtp)))) {
15290                   /* Needs a hangup */
15291                   if (ast_rtp_get_rtptimeout(sip->rtp)) {
15292                      while (sip->owner && ast_channel_trylock(sip->owner)) {
15293                         ast_mutex_unlock(&sip->lock);
15294                         usleep(1);
15295                         ast_mutex_lock(&sip->lock);
15296                      }
15297                      if (sip->owner) {
15298                         if (!(ast_rtp_get_bridged(sip->rtp))) {
15299                            ast_log(LOG_NOTICE,
15300                               "Disconnecting call '%s' for lack of RTP activity in %ld seconds\n",
15301                               sip->owner->name,
15302                               (long) (t - sip->lastrtprx));
15303                            /* Issue a softhangup */
15304                            ast_softhangup_nolock(sip->owner, AST_SOFTHANGUP_DEV);
15305                         } else
15306                            ast_log(LOG_NOTICE, "'%s' will not be disconnected in %ld seconds because it is directly bridged to another RTP stream\n", sip->owner->name, (long) (t - sip->lastrtprx));
15307                         ast_channel_unlock(sip->owner);
15308                         /* forget the timeouts for this call, since a hangup
15309                            has already been requested and we don't want to
15310                            repeatedly request hangups
15311                         */
15312                         ast_rtp_set_rtptimeout(sip->rtp, 0);
15313                         ast_rtp_set_rtpholdtimeout(sip->rtp, 0);
15314                         if (sip->vrtp) {
15315                            ast_rtp_set_rtptimeout(sip->vrtp, 0);
15316                            ast_rtp_set_rtpholdtimeout(sip->vrtp, 0);
15317                         }
15318                      }
15319                   }
15320                }
15321             }
15322          }
15323          /* If we have sessions that needs to be destroyed, do it now */
15324          if (ast_test_flag(&sip->flags[0], SIP_NEEDDESTROY) && !sip->packets &&
15325              !sip->owner) {
15326             ast_mutex_unlock(&sip->lock);
15327             __sip_destroy(sip, 1);
15328             goto restartsearch;
15329          }
15330          ast_mutex_unlock(&sip->lock);
15331       }
15332       ast_mutex_unlock(&iflock);
15333 
15334       pthread_testcancel();
15335       /* Wait for sched or io */
15336       res = ast_sched_wait(sched);
15337       if ((res < 0) || (res > 1000))
15338          res = 1000;
15339       /* If we might need to send more mailboxes, don't wait long at all.*/
15340       if (fastrestart)
15341          res = 1;
15342       res = ast_io_wait(io, res);
15343       if (option_debug && res > 20)
15344          ast_log(LOG_DEBUG, "chan_sip: ast_io_wait ran %d all at once\n", res);
15345       ast_mutex_lock(&monlock);
15346       if (res >= 0)  {
15347          res = ast_sched_runq(sched);
15348          if (option_debug && res >= 20)
15349             ast_log(LOG_DEBUG, "chan_sip: ast_sched_runq ran %d all at once\n", res);
15350       }
15351 
15352       /* Send MWI notifications to peers - static and cached realtime peers */
15353       t = time(NULL);
15354       fastrestart = FALSE;
15355       curpeernum = 0;
15356       peer = NULL;
15357       /* Find next peer that needs mwi */
15358       ASTOBJ_CONTAINER_TRAVERSE(&peerl, !peer, do {
15359          if ((curpeernum > lastpeernum) && does_peer_need_mwi(iterator)) {
15360             fastrestart = TRUE;
15361             lastpeernum = curpeernum;
15362             peer = ASTOBJ_REF(iterator);
15363          };
15364          curpeernum++;
15365       } while (0)
15366       );
15367       /* Send MWI to the peer */
15368       if (peer) {
15369          ASTOBJ_WRLOCK(peer);
15370          sip_send_mwi_to_peer(peer);
15371          ASTOBJ_UNLOCK(peer);
15372          ASTOBJ_UNREF(peer,sip_destroy_peer);
15373       } else {
15374          /* Reset where we come from */
15375          lastpeernum = -1;
15376       }
15377       ast_mutex_unlock(&monlock);
15378    }
15379    /* Never reached */
15380    return NULL;
15381    
15382 }

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

11200 {
11201    char digest[1024];
11202 
11203    if (!p->options && !(p->options = ast_calloc(1, sizeof(*p->options))))
11204       return -2;
11205 
11206    p->authtries++;
11207    if (option_debug > 1)
11208       ast_log(LOG_DEBUG, "Auth attempt %d on %s\n", p->authtries, sip_methods[sipmethod].text);
11209    memset(digest, 0, sizeof(digest));
11210    if (reply_digest(p, req, header, sipmethod, digest, sizeof(digest) )) {
11211       /* No way to authenticate */
11212       return -1;
11213    }
11214    /* Now we have a reply digest */
11215    p->options->auth = digest;
11216    p->options->authheader = respheader;
11217    return transmit_invite(p, sipmethod, sipmethod == SIP_INVITE, init); 
11218 }

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

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

Referenced by handle_response_register().

11179 {
11180    char digest[1024];
11181    p->authtries++;
11182    memset(digest,0,sizeof(digest));
11183    if (reply_digest(p, req, header, SIP_REGISTER, digest, sizeof(digest))) {
11184       /* There's nothing to use for authentication */
11185       /* No digest challenge in request */
11186       if (sip_debug_test_pvt(p) && p->registry)
11187          ast_verbose("No authentication challenge, sending blank registration to domain/host name %s\n", p->registry->hostname);
11188          /* No old challenge */
11189       return -1;
11190    }
11191    if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY))
11192       append_history(p, "RegistryAuth", "Try: %d", p->authtries);
11193    if (sip_debug_test_pvt(p) && p->registry)
11194       ast_verbose("Responding to challenge, registration to domain/host name %s\n", p->registry->hostname);
11195    return transmit_register(p->registry, SIP_REGISTER, digest, respheader); 
11196 }

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

Set nat mode on the various data sockets.

Definition at line 2670 of file chan_sip.c.

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

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

02671 {
02672    const char *mode = natflags ? "On" : "Off";
02673 
02674    if (p->rtp) {
02675       if (option_debug)
02676          ast_log(LOG_DEBUG, "Setting NAT on RTP to %s\n", mode);
02677       ast_rtp_setnat(p->rtp, natflags);
02678    }
02679    if (p->vrtp) {
02680       if (option_debug)
02681          ast_log(LOG_DEBUG, "Setting NAT on VRTP to %s\n", mode);
02682       ast_rtp_setnat(p->vrtp, natflags);
02683    }
02684    if (p->udptl) {
02685       if (option_debug)
02686          ast_log(LOG_DEBUG, "Setting NAT on UDPTL to %s\n", mode);
02687       ast_udptl_setnat(p->udptl, natflags);
02688    }
02689 }

static int does_peer_need_mwi ( struct sip_peer peer  )  [static]

Check whether peer needs a new MWI notification check.

Definition at line 15203 of file chan_sip.c.

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

Referenced by do_monitor().

15204 {
15205    time_t t = time(NULL);
15206 
15207    if (ast_test_flag(&peer->flags[1], SIP_PAGE2_SUBSCRIBEMWIONLY) &&
15208        !peer->mwipvt) { /* We don't have a subscription */
15209       peer->lastmsgcheck = t; /* Reset timer */
15210       return FALSE;
15211    }
15212 
15213    if (!ast_strlen_zero(peer->mailbox) && (t - peer->lastmsgcheck) > global_mwitime)
15214       return TRUE;
15215 
15216    return FALSE;
15217 }

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

Print domain mode to cli.

Definition at line 10045 of file chan_sip.c.

References SIP_DOMAIN_AUTO, and SIP_DOMAIN_CONFIG.

Referenced by sip_show_domains().

10046 {
10047    switch (mode) {
10048    case SIP_DOMAIN_AUTO:
10049       return "[Automatic]";
10050    case SIP_DOMAIN_CONFIG:
10051       return "[Configured]";
10052    }
10053 
10054    return "";
10055 }

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

Convert DTMF mode to printable string.

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

09826 {
09827    switch (mode) {
09828    case SIP_DTMF_RFC2833:
09829       return "rfc2833";
09830    case SIP_DTMF_INFO:
09831       return "info";
09832    case SIP_DTMF_INBAND:
09833       return "inband";
09834    case SIP_DTMF_AUTO:
09835       return "auto";
09836    }
09837    return "<error>";
09838 }

static int expire_register ( void *  data  )  [static]

Expire registration of SIP peer.

Definition at line 7694 of file chan_sip.c.

References sip_peer::addr, ast_device_state_changed(), ast_test_flag, ASTOBJ_CONTAINER_UNLINK, ASTOBJ_UNREF, destroy_association(), EVENT_FLAG_SYSTEM, sip_peer::expire, FALSE, sip_peer::flags, manager_event(), peerl, register_peer_exten(), sip_destroy_peer(), SIP_PAGE2_RTAUTOCLEAR, and SIP_PAGE2_SELFDESTRUCT.

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

07695 {
07696    struct sip_peer *peer = data;
07697    
07698    if (!peer)     /* Hmmm. We have no peer. Weird. */
07699       return 0;
07700 
07701    memset(&peer->addr, 0, sizeof(peer->addr));
07702 
07703    destroy_association(peer); /* remove registration data from storage */
07704    
07705    manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name);
07706    register_peer_exten(peer, FALSE);   /* Remove regexten */
07707    peer->expire = -1;
07708    ast_device_state_changed("SIP/%s", peer->name);
07709 
07710    /* Do we need to release this peer from memory? 
07711       Only for realtime peers and autocreated peers
07712    */
07713    if (ast_test_flag(&peer->flags[1], SIP_PAGE2_SELFDESTRUCT) ||
07714        ast_test_flag(&peer->flags[1], SIP_PAGE2_RTAUTOCLEAR)) {
07715       peer = ASTOBJ_CONTAINER_UNLINK(&peerl, peer);   /* Remove from peer list */
07716       ASTOBJ_UNREF(peer, sip_destroy_peer);     /* Remove from memory */
07717    }
07718 
07719    return 0;
07720 }

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

Check Contact: URI of SIP message.

Definition at line 6656 of file chan_sip.c.

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

Referenced by handle_request(), and handle_request_invite().

06657 {
06658    char stripped[BUFSIZ];
06659    char *c;
06660 
06661    ast_copy_string(stripped, get_header(req, "Contact"), sizeof(stripped));
06662    c = get_in_brackets(stripped);
06663    c = strsep(&c, ";"); /* trim ; and beyond */
06664    if (!ast_strlen_zero(c))
06665       ast_string_field_set(p, uri, c);
06666 }

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

References aliases.

04085 {
04086    /*! \brief Structure for conversion between compressed SIP and "normal" SIP */
04087    static const struct cfalias {
04088       char * const fullname;
04089       char * const shortname;
04090    } aliases[] = {
04091       { "Content-Type",  "c" },
04092       { "Content-Encoding",    "e" },
04093       { "From",       "f" },
04094       { "Call-ID",       "i" },
04095       { "Contact",       "m" },
04096       { "Content-Length",   "l" },
04097       { "Subject",       "s" },
04098       { "To",         "t" },
04099       { "Supported",     "k" },
04100       { "Refer-To",      "r" },
04101       { "Referred-By",   "b" },
04102       { "Allow-Events",  "u" },
04103       { "Event",      "o" },
04104       { "Via",     "v" },
04105       { "Accept-Contact",      "a" },
04106       { "Reject-Contact",      "j" },
04107       { "Request-Disposition", "d" },
04108       { "Session-Expires",     "x" },
04109       { "Identity",            "y" },
04110       { "Identity-Info",       "n" },
04111    };
04112    int x;
04113 
04114    for (x=0; x<sizeof(aliases) / sizeof(aliases[0]); x++) 
04115       if (!strcasecmp(aliases[x].fullname, name))
04116          return aliases[x].shortname;
04117 
04118    return _default;
04119 }

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

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

Definition at line 4435 of file chan_sip.c.

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

Referenced by sipsock_read().

04436 {
04437    struct sip_pvt *p = NULL;
04438    char *tag = "";   /* note, tag is never NULL */
04439    char totag[128];
04440    char fromtag[128];
04441    const char *callid = get_header(req, "Call-ID");
04442    const char *from = get_header(req, "From");
04443    const char *to = get_header(req, "To");
04444    const char *cseq = get_header(req, "Cseq");
04445 
04446    /* Call-ID, to, from and Cseq are required by RFC 3261. (Max-forwards and via too - ignored now) */
04447    /* get_header always returns non-NULL so we must use ast_strlen_zero() */
04448    if (ast_strlen_zero(callid) || ast_strlen_zero(to) ||
04449          ast_strlen_zero(from) || ast_strlen_zero(cseq))
04450       return NULL;   /* Invalid packet */
04451 
04452    if (pedanticsipchecking) {
04453       /* In principle Call-ID's uniquely identify a call, but with a forking SIP proxy
04454          we need more to identify a branch - so we have to check branch, from
04455          and to tags to identify a call leg.
04456          For Asterisk to behave correctly, you need to turn on pedanticsipchecking
04457          in sip.conf
04458          */
04459       if (gettag(req, "To", totag, sizeof(totag)))
04460          ast_set_flag(req, SIP_PKT_WITH_TOTAG); /* Used in handle_request/response */
04461       gettag(req, "From", fromtag, sizeof(fromtag));
04462 
04463       tag = (req->method == SIP_RESPONSE) ? totag : fromtag;
04464 
04465       if (option_debug > 4 )
04466          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);
04467    }
04468 
04469    ast_mutex_lock(&iflock);
04470    for (p = iflist; p; p = p->next) {
04471       /* In pedantic, we do not want packets with bad syntax to be connected to a PVT */
04472       int found = FALSE;
04473       if (ast_strlen_zero(p->callid))
04474          continue;
04475       if (req->method == SIP_REGISTER)
04476          found = (!strcmp(p->callid, callid));
04477       else 
04478          found = (!strcmp(p->callid, callid) && 
04479          (!pedanticsipchecking || !tag || ast_strlen_zero(p->theirtag) || !strcmp(p->theirtag, tag))) ;
04480 
04481       if (option_debug > 4)
04482          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);
04483 
04484       /* If we get a new request within an existing to-tag - check the to tag as well */
04485       if (pedanticsipchecking && found  && req->method != SIP_RESPONSE) {  /* SIP Request */
04486          if (p->tag[0] == '\0' && totag[0]) {
04487             /* We have no to tag, but they have. Wrong dialog */
04488             found = FALSE;
04489          } else if (totag[0]) {        /* Both have tags, compare them */
04490             if (strcmp(totag, p->tag)) {
04491                found = FALSE;    /* This is not our packet */
04492             }
04493          }
04494          if (!found && option_debug > 4)
04495             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);
04496       }
04497 
04498 
04499       if (found) {
04500          /* Found the call */
04501          ast_mutex_lock(&p->lock);
04502          ast_mutex_unlock(&iflock);
04503          return p;
04504       }
04505    }
04506    ast_mutex_unlock(&iflock);
04507 
04508    /* See if the method is capable of creating a dialog */
04509    if (sip_methods[intended_method].can_create == CAN_CREATE_DIALOG) {
04510       if (intended_method == SIP_REFER) {
04511          /* We do support REFER, but not outside of a dialog yet */
04512          transmit_response_using_temp(callid, sin, 1, intended_method, req, "603 Declined (no dialog)");
04513       } else if (intended_method == SIP_NOTIFY) {
04514          /* We do not support out-of-dialog NOTIFY either,
04515             like voicemail notification, so cancel that early */
04516          transmit_response_using_temp(callid, sin, 1, intended_method, req, "489 Bad event");
04517       } else {
04518          /* Ok, time to create a new SIP dialog object, a pvt */
04519          if ((p = sip_alloc(callid, sin, 1, intended_method)))  {
04520             /* Ok, we've created a dialog, let's go and process it */
04521             ast_mutex_lock(&p->lock);
04522          } else {
04523             /* We have a memory or file/socket error (can't allocate RTP sockets or something) so we're not
04524                getting a dialog from sip_alloc. 
04525    
04526                Without a dialog we can't retransmit and handle ACKs and all that, but at least
04527                send an error message.
04528    
04529                Sorry, we apologize for the inconvienience
04530             */
04531             transmit_response_using_temp(callid, sin, 1, intended_method, req, "500 Server internal error");
04532             if (option_debug > 3)
04533                ast_log(LOG_DEBUG, "Failed allocating SIP dialog, sending 500 Server internal error and giving up\n");
04534          }
04535       }
04536       return p;
04537    } else if( sip_methods[intended_method].can_create == CAN_CREATE_DIALOG_UNSUPPORTED_METHOD) {
04538       /* A method we do not support, let's take it on the volley */
04539       transmit_response_using_temp(callid, sin, 1, intended_method, req, "501 Method Not Implemented");
04540    } else if (intended_method != SIP_RESPONSE && intended_method != SIP_ACK) {
04541       /* This is a request outside of a dialog that we don't know about 
04542          ...never reply to an ACK!
04543       */
04544       transmit_response_using_temp(callid, sin, 1, intended_method, req, "481 Call leg/transaction does not exist");
04545    }
04546    /* We do not respond to responses for dialogs that we don't know about, we just drop
04547       the session quickly */
04548 
04549    return p;
04550 }

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

References s.

Referenced by get_in_brackets().

02261 {
02262         char last_char = '\0';
02263         const char *s;
02264         for (s = start; *s && s != lim; last_char = *s++) {
02265                 if (*s == '"' && last_char != '\\')
02266                         break;
02267         }
02268         return s;
02269 }

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

Locate peer by name or ip address This is used on incoming SIP message to find matching peer on ip or outgoing message to find matching peer on name.

Definition at line 2582 of file chan_sip.c.

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

02583 {
02584    struct sip_peer *p = NULL;
02585 
02586    if (peer)
02587       p = ASTOBJ_CONTAINER_FIND(&peerl, peer);
02588    else
02589       p = ASTOBJ_CONTAINER_FIND_FULL(&peerl, sin, name, sip_addr_hashfunc, 1, sip_addrcmp);
02590 
02591    if (!p && realtime)
02592       p = realtime_peer(peer, sin);
02593 
02594    return p;
02595 }

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

Find authentication for a specific realm.

Definition at line 15974 of file chan_sip.c.

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

Referenced by build_reply_digest().

15975 {
15976    struct sip_auth *a;
15977 
15978    for (a = authlist; a; a = a->next) {
15979       if (!strcasecmp(a->realm, realm))
15980          break;
15981    }
15982 
15983    return a;
15984 }

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

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

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

04757 {
04758    const char *content_type;
04759    const char *search;
04760    char *boundary;
04761    unsigned int x;
04762    int boundaryisquoted = FALSE;
04763 
04764    content_type = get_header(req, "Content-Type");
04765 
04766    /* if the body contains only SDP, this is easy */
04767    if (!strcasecmp(content_type, "application/sdp")) {
04768       req->sdp_start = 0;
04769       req->sdp_end = req->lines;
04770       return req->lines ? 1 : 0;
04771    }
04772 
04773    /* if it's not multipart/mixed, there cannot be an SDP */
04774    if (strncasecmp(content_type, "multipart/mixed", 15))
04775       return 0;
04776 
04777    /* if there is no boundary marker, it's invalid */
04778    if (!(search = strcasestr(content_type, ";boundary=")))
04779       return 0;
04780 
04781    search += 10;
04782    if (ast_strlen_zero(search))
04783       return 0;
04784 
04785    /* If the boundary is quoted with ", remove quote */
04786    if (*search == '\"')  {
04787       search++;
04788       boundaryisquoted = TRUE;
04789    }
04790 
04791    /* make a duplicate of the string, with two extra characters
04792       at the beginning */
04793    boundary = ast_strdupa(search - 2);
04794    boundary[0] = boundary[1] = '-';
04795 
04796    /* Remove final quote */
04797    if (boundaryisquoted)
04798       boundary[strlen(boundary) - 1] = '\0';
04799 
04800    /* search for the boundary marker, but stop when there are not enough
04801       lines left for it, the Content-Type header and at least one line of
04802       body */
04803    for (x = 0; x < (req->lines - 2); x++) {
04804       if (!strncasecmp(req->line[x], boundary, strlen(boundary)) &&
04805           !strcasecmp(req->line[x + 1], "Content-Type: application/sdp")) {
04806          x += 2;
04807          req->sdp_start = x;
04808 
04809          /* search for the end of the body part */
04810          for ( ; x < req->lines; x++) {
04811             if (!strncasecmp(req->line[x], boundary, strlen(boundary)))
04812                break;
04813          }
04814          req->sdp_end = x;
04815          return 1;
04816       }
04817    }
04818 
04819    return 0;
04820 }

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

find_sip_method: Find SIP method from header

Definition at line 1663 of file chan_sip.c.

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

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

01664 {
01665    int i, res = 0;
01666    
01667    if (ast_strlen_zero(msg))
01668       return 0;
01669    for (i = 1; i < (sizeof(sip_methods) / sizeof(sip_methods[0])) && !res; i++) {
01670       if (method_match(i, msg))
01671          res = sip_methods[i].id;
01672    }
01673    return res;
01674 }

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

Find subscription type in array.

Definition at line 10533 of file chan_sip.c.

References subscription_types, and type.

Referenced by transmit_state_notify().

10534 {
10535    int i;
10536 
10537    for (i = 1; (i < (sizeof(subscription_types) / sizeof(subscription_types[0]))); i++) {
10538       if (subscription_types[i].type == subtype) {
10539          return &subscription_types[i];
10540       }
10541    }
10542    return &subscription_types[0];
10543 }

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

Locate user by name Locates user by name (From: sip uri user name part) first from in-memory list (static configuration) then from realtime storage (defined in extconfig.conf).

Definition at line 2661 of file chan_sip.c.

References ASTOBJ_CONTAINER_FIND, realtime_user(), and userl.

02662 {
02663    struct sip_user *u = ASTOBJ_CONTAINER_FIND(&userl, name);
02664    if (!u && realtime)
02665       u = realtime_user(name);
02666    return u;
02667 }

static void free_old_route ( struct sip_route route  )  [static]

Remove route from route list.

Definition at line 8025 of file chan_sip.c.

References free, and sip_route::next.

Referenced by __sip_destroy(), and build_route().

08026 {
08027    struct sip_route *next;
08028 
08029    while (route) {
08030       next = route->next;
08031       free(route);
08032       route = next;
08033    }
08034 }

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

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

11526 {
11527    if (ast_strlen_zero(data)) {
11528       ast_log(LOG_WARNING, "CHECKSIPDOMAIN requires an argument - A domain name\n");
11529       return -1;
11530    }
11531    if (check_sip_domain(data, NULL, 0))
11532       ast_copy_string(buf, data, len);
11533    else
11534       buf[0] = '\0';
11535    return 0;
11536 }

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

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

11462 {
11463    struct sip_pvt *p;
11464    const char *content = NULL;
11465    AST_DECLARE_APP_ARGS(args,
11466       AST_APP_ARG(header);
11467       AST_APP_ARG(number);
11468    );
11469    int i, number, start = 0;
11470 
11471    if (ast_strlen_zero(data)) {
11472       ast_log(LOG_WARNING, "This function requires a header name.\n");
11473       return -1;
11474    }
11475 
11476    ast_channel_lock(chan);
11477    if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) {
11478       ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n");
11479       ast_channel_unlock(chan);
11480       return -1;
11481    }
11482 
11483    AST_STANDARD_APP_ARGS(args, data);
11484    if (!args.number) {
11485       number = 1;
11486    } else {
11487       sscanf(args.number, "%d", &number);
11488       if (number < 1)
11489          number = 1;
11490    }
11491 
11492    p = chan->tech_pvt;
11493 
11494    /* If there is no private structure, this channel is no longer alive */
11495    if (!p) {
11496       ast_channel_unlock(chan);
11497       return -1;
11498    }
11499 
11500    for (i = 0; i < number; i++)
11501       content = __get_header(&p->initreq, args.header, &start);
11502 
11503    if (ast_strlen_zero(content)) {
11504       ast_channel_unlock(chan);
11505       return -1;
11506    }
11507 
11508    ast_copy_string(buf, content, len);
11509    ast_channel_unlock(chan);
11510 
11511    return 0;
11512 }

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

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

11641 {
11642    struct sip_pvt *p;
11643 
11644    *buf = 0;
11645    
11646    if (!data) {
11647       ast_log(LOG_WARNING, "This function requires a parameter name.\n");
11648       return -1;
11649    }
11650 
11651    ast_channel_lock(chan);
11652    if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) {
11653       ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n");
11654       ast_channel_unlock(chan);
11655       return -1;
11656    }
11657 
11658    p = chan->tech_pvt;
11659 
11660    /* If there is no private structure, this channel is no longer alive */
11661    if (!p) {
11662       ast_channel_unlock(chan);
11663       return -1;
11664    }
11665 
11666    if (!strcasecmp(data, "peerip")) {
11667       ast_copy_string(buf, p->sa.sin_addr.s_addr ? ast_inet_ntoa(p->sa.sin_addr) : "", len);
11668    } else  if (!strcasecmp(data, "recvip")) {
11669       ast_copy_string(buf, p->recv.sin_addr.s_addr ? ast_inet_ntoa(p->recv.sin_addr) : "", len);
11670    } else  if (!strcasecmp(data, "from")) {
11671       ast_copy_string(buf, p->from, len);
11672    } else  if (!strcasecmp(data, "uri")) {
11673       ast_copy_string(buf, p->uri, len);
11674    } else  if (!strcasecmp(data, "useragent")) {
11675       ast_copy_string(buf, p->useragent, len);
11676    } else  if (!strcasecmp(data, "peername")) {
11677       ast_copy_string(buf, p->peername, len);
11678    } else if (!strcasecmp(data, "t38passthrough")) {
11679       if (p->t38.state == T38_DISABLED)
11680          ast_copy_string(buf, "0", sizeof("0"));
11681       else    /* T38 is offered or enabled in this call */
11682          ast_copy_string(buf, "1", sizeof("1"));
11683    } else {
11684       ast_channel_unlock(chan);
11685       return -1;
11686    }
11687    ast_channel_unlock(chan);
11688 
11689    return 0;
11690 }

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

11551 {
11552    struct sip_peer *peer;
11553    char *colname;
11554 
11555    if ((colname = strchr(data, ':')))  /*! \todo Will be deprecated after 1.4 */
11556       *colname++ = '\0';
11557    else if ((colname = strchr(data, '|')))
11558       *colname++ = '\0';
11559    else
11560       colname = "ip";
11561 
11562    if (!(peer = find_peer(data, NULL, 1)))
11563       return -1;
11564 
11565    if (!strcasecmp(colname, "ip")) {
11566       ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "", len);
11567    } else  if (!strcasecmp(colname, "status")) {
11568       peer_status(peer, buf, len);
11569    } else  if (!strcasecmp(colname, "language")) {
11570       ast_copy_string(buf, peer->language, len);
11571    } else  if (!strcasecmp(colname, "regexten")) {
11572       ast_copy_string(buf, peer->regexten, len);
11573    } else  if (!strcasecmp(colname, "limit")) {
11574       snprintf(buf, len, "%d", peer->call_limit);
11575    } else  if (!strcasecmp(colname, "curcalls")) {
11576       snprintf(buf, len, "%d", peer->inUse);
11577    } else  if (!strcasecmp(colname, "accountcode")) {
11578       ast_copy_string(buf, peer->accountcode, len);
11579    } else  if (!strcasecmp(colname, "useragent")) {
11580       ast_copy_string(buf, peer->useragent, len);
11581    } else  if (!strcasecmp(colname, "mailbox")) {
11582       ast_copy_string(buf, peer->mailbox, len);
11583    } else  if (!strcasecmp(colname, "context")) {
11584       ast_copy_string(buf, peer->context, len);
11585    } else  if (!strcasecmp(colname, "expire")) {
11586       snprintf(buf, len, "%d", peer->expire);
11587    } else  if (!strcasecmp(colname, "dynamic")) {
11588       ast_copy_string(buf, (ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC) ? "yes" : "no"), len);
11589    } else  if (!strcasecmp(colname, "callerid_name")) {
11590       ast_copy_string(buf, peer->cid_name, len);
11591    } else  if (!strcasecmp(colname, "callerid_num")) {
11592       ast_copy_string(buf, peer->cid_num, len);
11593    } else  if (!strcasecmp(colname, "codecs")) {
11594       ast_getformatname_multiple(buf, len -1, peer->capability);
11595    } else  if (!strncasecmp(colname, "codec[", 6)) {
11596       char *codecnum;
11597       int index = 0, codec = 0;
11598       
11599       codecnum = colname + 6; /* move past the '[' */
11600       codecnum = strsep(&codecnum, "]"); /* trim trailing ']' if any */
11601       index = atoi(codecnum);
11602       if((codec = ast_codec_pref_index(&peer->prefs, index))) {
11603          ast_copy_string(buf, ast_getformatname(codec), len);
11604       }
11605    }
11606 
11607    ASTOBJ_UNREF(peer, sip_destroy_peer);
11608 
11609    return 0;
11610 }

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

Generate 32 byte random string for callid's etc.

Definition at line 4269 of file chan_sip.c.

References ast_random().

Referenced by build_callid_pvt(), and build_callid_registry().

04270 {
04271    long val[4];
04272    int x;
04273 
04274    for (x=0; x<4; x++)
04275       val[x] = ast_random();
04276    snprintf(buf, size, "%08lx%08lx%08lx%08lx", val[0], val[1], val[2], val[3]);
04277 
04278    return buf;
04279 }

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

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

Referenced by handle_request_bye().

08907 {
08908    char tmp[256] = "", *c, *a;
08909    struct sip_request *req = oreq ? oreq : &p->initreq;
08910    struct sip_refer *referdata = p->refer;
08911    const char *transfer_context = NULL;
08912    
08913    ast_copy_string(tmp, get_header(req, "Also"), sizeof(tmp));
08914    c = get_in_brackets(tmp);
08915 
08916    if (pedanticsipchecking)
08917       ast_uri_decode(c);
08918    
08919    if (strncasecmp(c, "sip:", 4)) {
08920       ast_log(LOG_WARNING, "Huh?  Not a SIP header in Also: transfer (%s)?\n", c);
08921       return -1;
08922    }
08923    c += 4;
08924    if ((a = strchr(c, ';')))  /* Remove arguments */
08925       *a = '\0';
08926    
08927    if ((a = strchr(c, '@'))) {   /* Separate Domain */
08928       *a++ = '\0';
08929       ast_copy_string(referdata->refer_to_domain, a, sizeof(referdata->refer_to_domain));
08930    }
08931    
08932    if (sip_debug_test_pvt(p))
08933       ast_verbose("Looking for %s in %s\n", c, p->context);
08934 
08935    if (p->owner)  /* Mimic behaviour in res_features.c */
08936       transfer_context = pbx_builtin_getvar_helper(p->owner, "TRANSFER_CONTEXT");
08937 
08938    /* By default, use the context in the channel sending the REFER */
08939    if (ast_strlen_zero(transfer_context)) {
08940       transfer_context = S_OR(p->owner->macrocontext,
08941                S_OR(p->context, default_context));
08942    }
08943    if (ast_exists_extension(NULL, transfer_context, c, 1, NULL)) {
08944       /* This is a blind transfer */
08945       if (option_debug)
08946          ast_log(LOG_DEBUG,"SIP Bye-also transfer to Extension %s@%s \n", c, transfer_context);
08947       ast_copy_string(referdata->refer_to, c, sizeof(referdata->refer_to));
08948       ast_copy_string(referdata->referred_by, "", sizeof(referdata->referred_by));
08949       ast_copy_string(referdata->refer_contact, "", sizeof(referdata->refer_contact));
08950       referdata->refer_call = NULL;
08951       /* Set new context */
08952       ast_string_field_set(p, context, transfer_context);
08953       return 0;
08954    } else if (ast_canmatch_extension(NULL, p->context, c, 1, NULL)) {
08955       return 1;
08956    }
08957 
08958    return -1;
08959 }

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

Get a specific line from the message body.

Definition at line 4068 of file chan_sip.c.

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

Referenced by handle_request_info().

04069 {
04070    int x;
04071    int len = strlen(name);
04072    char *r;
04073 
04074    for (x = 0; x < req->lines; x++) {
04075       r = get_body_by_line(req->line[x], name, len);
04076       if (r[0] != '\0')
04077          return r;
04078    }
04079 
04080    return "";
04081 }

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

Referenced by get_body(), and get_sdp_iterate().

04035 {
04036    if (strncasecmp(line, name, nameLen) == 0 && line[nameLen] == '=')
04037       return ast_skip_blanks(line + nameLen + 1);
04038 
04039    return "";
04040 }

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

Get caller id name from SIP headers.

Definition at line 9013 of file chan_sip.c.

Referenced by check_user_full().

09014 {
09015    const char *end = strchr(input,'<');   /* first_bracket */
09016    const char *tmp = strchr(input,'"');   /* first quote */
09017    int bytes = 0;
09018    int maxbytes = outputsize - 1;
09019 
09020    if (!end || end == input)  /* we require a part in brackets */
09021       return NULL;
09022 
09023    end--; /* move just before "<" */
09024 
09025    if (tmp && tmp <= end) {
09026       /* The quote (tmp) precedes the bracket (end+1).
09027        * Find the matching quote and return the content.
09028        */
09029       end = strchr(tmp+1, '"');
09030       if (!end)
09031          return NULL;
09032       bytes = (int) (end - tmp);
09033       /* protect the output buffer */
09034       if (bytes > maxbytes)
09035          bytes = maxbytes;
09036       ast_copy_string(output, tmp + 1, bytes);
09037    } else {
09038       /* No quoted string, or it is inside brackets. */
09039       /* clear the empty characters in the begining*/
09040       input = ast_skip_blanks(input);
09041       /* clear the empty characters in the end */
09042       while(*end && *end < 33 && end > input)
09043          end--;
09044       if (end >= input) {
09045          bytes = (int) (end - input) + 2;
09046          /* protect the output buffer */
09047          if (bytes > maxbytes)
09048             bytes = maxbytes;
09049          ast_copy_string(output, input, bytes);
09050       } else
09051          return NULL;
09052    }
09053    return output;
09054 }

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

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

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

08581 {
08582    char tmp[256] = "", *uri, *a;
08583    char tmpf[256] = "", *from;
08584    struct sip_request *req;
08585    char *colon;
08586    
08587    req = oreq;
08588    if (!req)
08589       req = &p->initreq;
08590 
08591    /* Find the request URI */
08592    if (req->rlPart2)
08593       ast_copy_string(tmp, req->rlPart2, sizeof(tmp));
08594    
08595    if (pedanticsipchecking)
08596       ast_uri_decode(tmp);
08597 
08598    uri = get_in_brackets(tmp);
08599 
08600    if (strncasecmp(uri, "sip:", 4)) {
08601       ast_log(LOG_WARNING, "Huh?  Not a SIP header (%s)?\n", uri);
08602       return -1;
08603    }
08604    uri += 4;
08605 
08606    /* Now find the From: caller ID and name */
08607    ast_copy_string(tmpf, get_header(req, "From"), sizeof(tmpf));
08608    if (!ast_strlen_zero(tmpf)) {
08609       if (pedanticsipchecking)
08610          ast_uri_decode(tmpf);
08611       from = get_in_brackets(tmpf);
08612    } else {
08613       from = NULL;
08614    }
08615    
08616    if (!ast_strlen_zero(from)) {
08617       if (strncasecmp(from, "sip:", 4)) {
08618          ast_log(LOG_WARNING, "Huh?  Not a SIP header (%s)?\n", from);
08619          return -1;
08620       }
08621       from += 4;
08622       if ((a = strchr(from, '@')))
08623          *a++ = '\0';
08624       else
08625          a = from;   /* just a domain */
08626       from = strsep(&from, ";"); /* Remove userinfo options */
08627       a = strsep(&a, ";");    /* Remove URI options */
08628       ast_string_field_set(p, fromdomain, a);
08629    }
08630 
08631    /* Skip any options and find the domain */
08632 
08633    /* Get the target domain */
08634    if ((a = strchr(uri, '@'))) {
08635       *a++ = '\0';
08636    } else { /* No username part */
08637       a = uri;
08638       uri = "s";  /* Set extension to "s" */
08639    }
08640    colon = strchr(a, ':'); /* Remove :port */
08641    if (colon)
08642       *colon = '\0';
08643 
08644    uri = strsep(&uri, ";");   /* Remove userinfo options */
08645    a = strsep(&a, ";");    /* Remove URI options */
08646 
08647    ast_string_field_set(p, domain, a);
08648 
08649    if (!AST_LIST_EMPTY(&domain_list)) {
08650       char domain_context[AST_MAX_EXTENSION];
08651 
08652       domain_context[0] = '\0';
08653       if (!check_sip_domain(p->domain, domain_context, sizeof(domain_context))) {
08654          if (!allow_external_domains && (req->method == SIP_INVITE || req->method == SIP_REFER)) {
08655             if (option_debug)
08656                ast_log(LOG_DEBUG, "Got SIP %s to non-local domain '%s'; refusing request.\n", sip_methods[req->method].text, p->domain);
08657             return -2;
08658          }
08659       }
08660       /* If we have a context defined, overwrite the original context */
08661       if (!ast_strlen_zero(domain_context))
08662          ast_string_field_set(p, context, domain_context);
08663    }
08664 
08665    if (sip_debug_test_pvt(p))
08666       ast_verbose("Looking for %s in %s (domain %s)\n", uri, p->context, p->domain);
08667 
08668    /* Check the dialplan for the username part of the request URI,
08669       the domain will be stored in the SIPDOMAIN variable
08670       Return 0 if we have a matching extension */
08671    if (ast_exists_extension(NULL, p->context, uri, 1, from) ||
08672       !strcmp(uri, ast_pickup_ext())) {
08673       if (!oreq)
08674          ast_string_field_set(p, exten, uri);
08675       return 0;
08676    }
08677 
08678    /* Return 1 for pickup extension or overlap dialling support (if we support it) */
08679    if((ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP) && 
08680        ast_canmatch_extension(NULL, p->context, uri, 1, from)) ||
08681        !strncmp(uri, ast_pickup_ext(), strlen(uri))) {
08682       return 1;
08683    }
08684    
08685    return -1;
08686 }

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

Get header from SIP request.

Definition at line 4157 of file chan_sip.c.

References __get_header().

04158 {
04159    int start = 0;
04160    return __get_header(req, name, &start);
04161 }

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

02283 {
02284    const char *parse = tmp;
02285    char *first_bracket;
02286 
02287    /*
02288     * Skip any quoted text until we find the part in brackets.
02289          * On any error give up and return the full string.
02290          */
02291         while ( (first_bracket = strchr(parse, '<')) ) {
02292                 char *first_quote = strchr(parse, '"');
02293 
02294       if (!first_quote || first_quote > first_bracket)
02295          break; /* no need to look at quoted part */
02296       /* the bracket is within quotes, so ignore it */
02297       parse = find_closing_quote(first_quote + 1, NULL);
02298       if (!*parse) { /* not found, return full string ? */
02299          /* XXX or be robust and return in-bracket part ? */
02300          ast_log(LOG_WARNING, "No closing quote found in '%s'\n", tmp);
02301          break;
02302       }
02303       parse++;
02304    }
02305    if (first_bracket) {
02306       char *second_bracket = strchr(first_bracket + 1, '>');
02307       if (second_bracket) {
02308          *second_bracket = '\0';
02309          tmp = first_bracket + 1;
02310       } else {
02311          ast_log(LOG_WARNING, "No closing bracket found in '%s'\n", tmp);
02312       }
02313    }
02314    return tmp;
02315 }

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

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

Referenced by handle_request_notify(), and receive_message().

09421 {
09422    int x;
09423    int y;
09424 
09425    buf[0] = '\0';
09426    y = len - strlen(buf) - 5;
09427    if (y < 0)
09428       y = 0;
09429    for (x=0;x<req->lines;x++) {
09430       strncat(buf, req->line[x], y); /* safe */
09431       y -= strlen(req->line[x]) + 1;
09432       if (y < 0)
09433          y = 0;
09434       if (y != 0)
09435          strcat(buf, "\n"); /* safe */
09436    }
09437    return 0;
09438 }

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

Get referring dnis.

Definition at line 8551 of file chan_sip.c.

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

Referenced by handle_request_invite().

08552 {
08553    char tmp[256], *c, *a;
08554    struct sip_request *req;
08555    
08556    req = oreq;
08557    if (!req)
08558       req = &p->initreq;
08559    ast_copy_string(tmp, get_header(req, "Diversion"), sizeof(tmp));
08560    if (ast_strlen_zero(tmp))
08561       return 0;
08562    c = get_in_brackets(tmp);
08563    if (strncasecmp(c, "sip:", 4)) {
08564       ast_log(LOG_WARNING, "Huh?  Not an RDNIS SIP header (%s)?\n", c);
08565       return -1;
08566    }
08567    c += 4;
08568    a = c;
08569    strsep(&a, "@;"); /* trim anything after @ or ; */
08570    if (sip_debug_test_pvt(p))
08571       ast_verbose("RDNIS is %s\n", c);
08572    ast_string_field_set(p, rdnis, c);
08573 
08574    return 0;
08575 }

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

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

Referenced by handle_request_refer().

08746 {
08747 
08748    const char *p_referred_by = NULL;
08749    char *h_refer_to = NULL; 
08750    char *h_referred_by = NULL;
08751    char *refer_to;
08752    const char *p_refer_to;
08753    char *referred_by_uri = NULL;
08754    char *ptr;
08755    struct sip_request *req = NULL;
08756    const char *transfer_context = NULL;
08757    struct sip_refer *referdata;
08758 
08759 
08760    req = outgoing_req;
08761    referdata = transferer->refer;
08762 
08763    if (!req)
08764       req = &transferer->initreq;
08765 
08766    p_refer_to = get_header(req, "Refer-To");
08767    if (ast_strlen_zero(p_refer_to)) {
08768       ast_log(LOG_WARNING, "Refer-To Header missing. Skipping transfer.\n");
08769       return -2;  /* Syntax error */
08770    }
08771    h_refer_to = ast_strdupa(p_refer_to);
08772    refer_to = get_in_brackets(h_refer_to);
08773    if (pedanticsipchecking)
08774       ast_uri_decode(refer_to);
08775 
08776    if (strncasecmp(refer_to, "sip:", 4)) {
08777       ast_log(LOG_WARNING, "Can't transfer to non-sip: URI.  (Refer-to: %s)?\n", refer_to);
08778       return -3;
08779    }
08780    refer_to += 4;       /* Skip sip: */
08781 
08782    /* Get referred by header if it exists */
08783    p_referred_by = get_header(req, "Referred-By");
08784    if (!ast_strlen_zero(p_referred_by)) {
08785       char *lessthan;
08786       h_referred_by = ast_strdupa(p_referred_by);
08787       if (pedanticsipchecking)
08788          ast_uri_decode(h_referred_by);
08789 
08790       /* Store referrer's caller ID name */
08791       ast_copy_string(referdata->referred_by_name, h_referred_by, sizeof(referdata->referred_by_name));
08792       if ((lessthan = strchr(referdata->referred_by_name, '<'))) {
08793          *(lessthan - 1) = '\0'; /* Space */
08794       }
08795 
08796       referred_by_uri = get_in_brackets(h_referred_by);
08797       if(strncasecmp(referred_by_uri, "sip:", 4)) {
08798          ast_log(LOG_WARNING, "Huh?  Not a sip: header (Referred-by: %s). Skipping.\n", referred_by_uri);
08799          referred_by_uri = (char *) NULL;
08800       } else {
08801          referred_by_uri += 4;      /* Skip sip: */
08802       }
08803    }
08804 
08805    /* Check for arguments in the refer_to header */
08806    if ((ptr = strchr(refer_to, '?'))) { /* Search for arguments */
08807       *ptr++ = '\0';
08808       if (!strncasecmp(ptr, "REPLACES=", 9)) {
08809          char *to = NULL, *from = NULL;
08810 
08811          /* This is an attended transfer */
08812          referdata->attendedtransfer = 1;
08813          ast_copy_string(referdata->replaces_callid, ptr+9, sizeof(referdata->replaces_callid));
08814          ast_uri_decode(referdata->replaces_callid);
08815          if ((ptr = strchr(referdata->replaces_callid, ';')))  /* Find options */ {
08816             *ptr++ = '\0';
08817          }
08818 
08819          if (ptr) {
08820             /* Find the different tags before we destroy the string */
08821             to = strcasestr(ptr, "to-tag=");
08822             from = strcasestr(ptr, "from-tag=");
08823          }
08824 
08825          /* Grab the to header */
08826          if (to) {
08827             ptr = to + 7;
08828             if ((to = strchr(ptr, '&')))
08829                *to = '\0';
08830             if ((to = strchr(ptr, ';')))
08831                *to = '\0';
08832             ast_copy_string(referdata->replaces_callid_totag, ptr, sizeof(referdata->replaces_callid_totag));
08833          }
08834 
08835          if (from) {
08836             ptr = from + 9;
08837             if ((to = strchr(ptr, '&')))
08838                *to = '\0';
08839             if ((to = strchr(ptr, ';')))
08840                *to = '\0';
08841             ast_copy_string(referdata->replaces_callid_fromtag, ptr, sizeof(referdata->replaces_callid_fromtag));
08842          }
08843 
08844          if (option_debug > 1) {
08845             if (!pedanticsipchecking)
08846                ast_log(LOG_DEBUG,"Attended transfer: Will use Replace-Call-ID : %s (No check of from/to tags)\n", referdata->replaces_callid );
08847             else
08848                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>" );
08849          }
08850       }
08851    }
08852    
08853    if ((ptr = strchr(refer_to, '@'))) {   /* Separate domain */
08854       char *urioption;
08855 
08856       *ptr++ = '\0';
08857       if ((urioption = strchr(ptr, ';')))
08858          *urioption++ = '\0';
08859       /* Save the domain for the dial plan */
08860       ast_copy_string(referdata->refer_to_domain, ptr, sizeof(referdata->refer_to_domain));
08861       if (urioption)
08862          ast_copy_string(referdata->refer_to_urioption, urioption, sizeof(referdata->refer_to_urioption));
08863    }
08864 
08865    if ((ptr = strchr(refer_to, ';')))  /* Remove options */
08866       *ptr = '\0';
08867    ast_copy_string(referdata->refer_to, refer_to, sizeof(referdata->refer_to));
08868    
08869    if (referred_by_uri) {
08870       if ((ptr = strchr(referred_by_uri, ';')))    /* Remove options */
08871          *ptr = '\0';
08872       ast_copy_string(referdata->referred_by, referred_by_uri, sizeof(referdata->referred_by));
08873    } else {
08874       referdata->referred_by[0] = '\0';
08875    }
08876 
08877    /* Determine transfer context */
08878    if (transferer->owner)  /* Mimic behaviour in res_features.c */
08879       transfer_context = pbx_builtin_getvar_helper(transferer->owner, "TRANSFER_CONTEXT");
08880 
08881    /* By default, use the context in the channel sending the REFER */
08882    if (ast_strlen_zero(transfer_context)) {
08883       transfer_context = S_OR(transferer->owner->macrocontext,
08884                S_OR(transferer->context, default_context));
08885    }
08886 
08887    ast_copy_string(referdata->refer_to_context, transfer_context, sizeof(referdata->refer_to_context));
08888    
08889    /* Either an existing extension or the parking extension */
08890    if (ast_exists_extension(NULL, transfer_context, refer_to, 1, NULL) ) {
08891       if (sip_debug_test_pvt(transferer)) {
08892          ast_verbose("SIP transfer to extension %s@%s by %s\n", refer_to, transfer_context, referred_by_uri);
08893       }
08894       /* We are ready to transfer to the extension */
08895       return 0;
08896    } 
08897    if (sip_debug_test_pvt(transferer))
08898       ast_verbose("Failed SIP Transfer to non-existing extension %s in context %s\n n", refer_to, transfer_context);
08899 
08900    /* Failure, we can't find this extension */
08901    return -1;
08902 }

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

References AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED.

Referenced by check_user_full().

09061 {
09062    char *start;
09063    char *end;
09064 
09065    start = strchr(input,':');
09066    if (!start) {
09067       output[0] = '\0';
09068       return 0;
09069    }
09070    start++;
09071 
09072    /* we found "number" */
09073    ast_copy_string(output,start,maxlen);
09074    output[maxlen-1] = '\0';
09075 
09076    end = strchr(output,'@');
09077    if (end)
09078       *end = '\0';
09079    else
09080       output[0] = '\0';
09081    if (strstr(input,"privacy=full") || strstr(input,"privacy=uri"))
09082       return AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED;
09083 
09084    return 0;
09085 }

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

Get a line from an SDP message body.

Definition at line 4060 of file chan_sip.c.

References get_sdp_iterate().

04061 {
04062    int dummy = 0;
04063 
04064    return get_sdp_iterate(&dummy, req, name);
04065 }

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

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

04047 {
04048    int len = strlen(name);
04049 
04050    while (*start < req->sdp_end) {
04051       const char *r = get_body_by_line(req->line[(*start)++], name, len);
04052       if (r[0] != '\0')
04053          return r;
04054    }
04055 
04056    return "";
04057 }

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

Lock interface lock and find matching pvt lock

Definition at line 8693 of file chan_sip.c.

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

Referenced by handle_request_invite(), and local_attended_transfer().

08694 {
08695    struct sip_pvt *sip_pvt_ptr;
08696 
08697    ast_mutex_lock(&iflock);
08698 
08699    if (option_debug > 3 && totag)
08700       ast_log(LOG_DEBUG, "Looking for callid %s (fromtag %s totag %s)\n", callid, fromtag ? fromtag : "<no fromtag>", totag ? totag : "<no totag>");
08701 
08702    /* Search interfaces and find the match */
08703    for (sip_pvt_ptr = iflist; sip_pvt_ptr; sip_pvt_ptr = sip_pvt_ptr->next) {
08704       if (!strcmp(sip_pvt_ptr->callid, callid)) {
08705          int match = 1;
08706          char *ourtag = sip_pvt_ptr->tag;
08707 
08708          /* Go ahead and lock it (and its owner) before returning */
08709          ast_mutex_lock(&sip_pvt_ptr->lock);
08710 
08711          /* Check if tags match. If not, this is not the call we want
08712             (With a forking SIP proxy, several call legs share the
08713             call id, but have different tags)
08714          */
08715          if (pedanticsipchecking && (strcmp(fromtag, sip_pvt_ptr->theirtag) || (!ast_strlen_zero(totag) && strcmp(totag, ourtag))))
08716             match = 0;
08717 
08718          if (!match) {
08719             ast_mutex_unlock(&sip_pvt_ptr->lock);
08720             continue;
08721          }
08722 
08723          if (option_debug > 3 && totag)             
08724             ast_log(LOG_DEBUG, "Matched %s call - their tag is %s Our tag is %s\n",
08725                ast_test_flag(&sip_pvt_ptr->flags[0], SIP_OUTGOING) ? "OUTGOING": "INCOMING",
08726                sip_pvt_ptr->theirtag, sip_pvt_ptr->tag);
08727 
08728          /* deadlock avoidance... */
08729          while (sip_pvt_ptr->owner && ast_channel_trylock(sip_pvt_ptr->owner)) {
08730             ast_mutex_unlock(&sip_pvt_ptr->lock);
08731             usleep(1);
08732             ast_mutex_lock(&sip_pvt_ptr->lock);
08733          }
08734          break;
08735       }
08736    }
08737    ast_mutex_unlock(&iflock);
08738    if (option_debug > 3 && !sip_pvt_ptr)
08739       ast_log(LOG_DEBUG, "Found no match for callid %s to-tag %s from-tag %s\n", callid, totag, fromtag);
08740    return sip_pvt_ptr;
08741 }

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

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

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

13009 {
13010    const char *thetag;
13011 
13012    if (!tagbuf)
13013       return NULL;
13014    tagbuf[0] = '\0';    /* reset the buffer */
13015    thetag = get_header(req, header);
13016    thetag = strcasestr(thetag, ";tag=");
13017    if (thetag) {
13018       thetag += 5;
13019       ast_copy_string(tagbuf, thetag, tagbufsize);
13020       return strsep(&tagbuf, ";");
13021    }
13022    return NULL;
13023 }

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

References ast_clear_flag, ast_false(), ast_log(), ast_set2_flag, ast_set_flag, ast_true(), ast_variable::lineno, LOG_WARNING, ast_variable::name, set_insecure_flags(), SIP_DTMF, SIP_DTMF_AUTO, SIP_DTMF_INBAND, SIP_DTMF_INFO, SIP_DTMF_RFC2833, SIP_G726_NONSTANDARD, SIP_INSECURE_INVITE, SIP_INSECURE_PORT, SIP_NAT, SIP_NAT_ALWAYS, SIP_NAT_NEVER, SIP_NAT_RFC3581, SIP_NAT_ROUTE, SIP_PAGE2_ALLOWOVERLAP, SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PAGE2_BUGGY_MWI, SIP_PAGE2_RFC2833_COMPENSATE, SIP_PAGE2_T38SUPPORT_RTP, SIP_PAGE2_T38SUPPORT_TCP, SIP_PAGE2_T38SUPPORT_UDPTL, SIP_PAGE2_VIDEOSUPPORT, SIP_PROG_INBAND, SIP_PROG_INBAND_NO, SIP_PROG_INBAND_YES, SIP_PROMISCREDIR, SIP_REINVITE, SIP_SENDRPID, SIP_TRUSTRPID, SIP_USECLIENTCODE, strsep(), and ast_variable::value.

Referenced by build_peer(), build_user(), and reload_config().

15714 {
15715    int res = 1;
15716    static int dep_insecure_very = 0;
15717    static int dep_insecure_yes = 0;
15718 
15719    if (!strcasecmp(v->name, "trustrpid")) {
15720       ast_set_flag(&mask[0], SIP_TRUSTRPID);
15721       ast_set2_flag(&flags[0], ast_true(v->value), SIP_TRUSTRPID);
15722    } else if (!strcasecmp(v->name, "sendrpid")) {
15723       ast_set_flag(&mask[0], SIP_SENDRPID);
15724       ast_set2_flag(&flags[0], ast_true(v->value), SIP_SENDRPID);
15725    } else if (!strcasecmp(v->name, "g726nonstandard")) {
15726       ast_set_flag(&mask[0], SIP_G726_NONSTANDARD);
15727       ast_set2_flag(&flags[0], ast_true(v->value), SIP_G726_NONSTANDARD);
15728    } else if (!strcasecmp(v->name, "useclientcode")) {
15729       ast_set_flag(&mask[0], SIP_USECLIENTCODE);
15730       ast_set2_flag(&flags[0], ast_true(v->value), SIP_USECLIENTCODE);
15731    } else if (!strcasecmp(v->name, "dtmfmode")) {
15732       ast_set_flag(&mask[0], SIP_DTMF);
15733       ast_clear_flag(&flags[0], SIP_DTMF);
15734       if (!strcasecmp(v->value, "inband"))
15735          ast_set_flag(&flags[0], SIP_DTMF_INBAND);
15736       else if (!strcasecmp(v->value, "rfc2833"))
15737          ast_set_flag(&flags[0], SIP_DTMF_RFC2833);
15738       else if (!strcasecmp(v->value, "info"))
15739          ast_set_flag(&flags[0], SIP_DTMF_INFO);
15740       else if (!strcasecmp(v->value, "auto"))
15741          ast_set_flag(&flags[0], SIP_DTMF_AUTO);
15742       else {
15743          ast_log(LOG_WARNING, "Unknown dtmf mode '%s' on line %d, using rfc2833\n", v->value, v->lineno);
15744          ast_set_flag(&flags[0], SIP_DTMF_RFC2833);
15745       }
15746    } else if (!strcasecmp(v->name, "nat")) {
15747       ast_set_flag(&mask[0], SIP_NAT);
15748       ast_clear_flag(&flags[0], SIP_NAT);
15749       if (!strcasecmp(v->value, "never"))
15750          ast_set_flag(&flags[0], SIP_NAT_NEVER);
15751       else if (!strcasecmp(v->value, "route"))
15752          ast_set_flag(&flags[0], SIP_NAT_ROUTE);
15753       else if (ast_true(v->value))
15754          ast_set_flag(&flags[0], SIP_NAT_ALWAYS);
15755       else
15756          ast_set_flag(&flags[0], SIP_NAT_RFC3581);
15757    } else if (!strcasecmp(v->name, "canreinvite")) {
15758       ast_set_flag(&mask[0], SIP_REINVITE);
15759       ast_clear_flag(&flags[0], SIP_REINVITE);
15760       set_insecure_flags(flags, v->value, v->lineno);
15761    } else if (!strcasecmp(v->name, "insecure")) {
15762       ast_set_flag(&mask[0], SIP_INSECURE_PORT | SIP_INSECURE_INVITE);
15763       ast_clear_flag(&flags[0], SIP_INSECURE_PORT | SIP_INSECURE_INVITE);
15764       if (!strcasecmp(v->value, "very")) {
15765          ast_set_flag(&flags[0], SIP_INSECURE_PORT | SIP_INSECURE_INVITE);
15766          if (!dep_insecure_very) {
15767             ast_log(LOG_WARNING, "insecure=very at line %d is deprecated; use insecure=port,invite instead\n", v->lineno);
15768             dep_insecure_very = 1;
15769          }
15770       }
15771       else if (ast_true(v->value)) {
15772          ast_set_flag(&flags[0], SIP_INSECURE_PORT);
15773          if (!dep_insecure_yes) {
15774             ast_log(LOG_WARNING, "insecure=%s at line %d is deprecated; use insecure=port instead\n", v->value, v->lineno);
15775             dep_insecure_yes = 1;
15776          }
15777       }
15778       else if (!ast_false(v->value)) {
15779          char buf[64];
15780          char *word, *next;
15781 
15782          ast_copy_string(buf, v->value, sizeof(buf));
15783          next = buf;
15784          while ((word = strsep(&next, ","))) {
15785             if (!strcasecmp(word, "port"))
15786                ast_set_flag(&flags[0], SIP_INSECURE_PORT);
15787             else if (!strcasecmp(word, "invite"))
15788                ast_set_flag(&flags[0], SIP_INSECURE_INVITE);
15789             else
15790                ast_log(LOG_WARNING, "Unknown insecure mode '%s' on line %d\n", v->value, v->lineno);
15791          }
15792       }
15793    } else if (!strcasecmp(v->name, "progressinband")) {
15794       ast_set_flag(&mask[0], SIP_PROG_INBAND);
15795       ast_clear_flag(&flags[0], SIP_PROG_INBAND);
15796       if (ast_true(v->value))
15797          ast_set_flag(&flags[0], SIP_PROG_INBAND_YES);
15798       else if (strcasecmp(v->value, "never"))
15799          ast_set_flag(&flags[0], SIP_PROG_INBAND_NO);
15800    } else if (!strcasecmp(v->name, "promiscredir")) {
15801       ast_set_flag(&mask[0], SIP_PROMISCREDIR);
15802       ast_set2_flag(&flags[0], ast_true(v->value), SIP_PROMISCREDIR);
15803    } else if (!strcasecmp(v->name, "videosupport")) {
15804       ast_set_flag(&mask[1], SIP_PAGE2_VIDEOSUPPORT);
15805       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_VIDEOSUPPORT);
15806    } else if (!strcasecmp(v->name, "allowoverlap")) {
15807       ast_set_flag(&mask[1], SIP_PAGE2_ALLOWOVERLAP);
15808       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_ALLOWOVERLAP);
15809    } else if (!strcasecmp(v->name, "allowsubscribe")) {
15810       ast_set_flag(&mask[1], SIP_PAGE2_ALLOWSUBSCRIBE);
15811       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_ALLOWSUBSCRIBE);
15812    } else if (!strcasecmp(v->name, "t38pt_udptl")) {
15813       ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT_UDPTL);
15814       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_T38SUPPORT_UDPTL);
15815 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS
15816    } else if (!strcasecmp(v->name, "t38pt_rtp")) {
15817       ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT_RTP);
15818       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_T38SUPPORT_RTP);
15819    } else if (!strcasecmp(v->name, "t38pt_tcp")) {
15820       ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT_TCP);
15821       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_T38SUPPORT_TCP);
15822 #endif
15823    } else if (!strcasecmp(v->name, "rfc2833compensate")) {
15824       ast_set_flag(&mask[1], SIP_PAGE2_RFC2833_COMPENSATE);
15825       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_RFC2833_COMPENSATE);
15826    } else if (!strcasecmp(v->name, "buggymwi")) {
15827       ast_set_flag(&mask[1], SIP_PAGE2_BUGGY_MWI);
15828       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_BUGGY_MWI);
15829    } else
15830       res = 0;
15831 
15832    return res;
15833 }

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

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

Referenced by handle_request_invite().

13182 {
13183    struct ast_frame *f;
13184    int earlyreplace = 0;
13185    int oneleggedreplace = 0;     /* Call with no bridge, propably IVR or voice message */
13186    struct ast_channel *c = p->owner;   /* Our incoming call */
13187    struct ast_channel *replacecall = p->refer->refer_call->owner; /* The channel we're about to take over */
13188    struct ast_channel *targetcall;     /* The bridge to the take-over target */
13189 
13190    /* Check if we're in ring state */
13191    if (replacecall->_state == AST_STATE_RING)
13192       earlyreplace = 1;
13193 
13194    /* Check if we have a bridge */
13195    if (!(targetcall = ast_bridged_channel(replacecall))) {
13196       /* We have no bridge */
13197       if (!earlyreplace) {
13198          if (option_debug > 1)
13199             ast_log(LOG_DEBUG, " Attended transfer attempted to replace call with no bridge (maybe ringing). Channel %s!\n", replacecall->name);
13200          oneleggedreplace = 1;
13201       }
13202    } 
13203    if (option_debug > 3 && targetcall && targetcall->_state == AST_STATE_RINGING)
13204          ast_log(LOG_DEBUG, "SIP transfer: Target channel is in ringing state\n");
13205 
13206    if (option_debug > 3) {
13207       if (targetcall) 
13208          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); 
13209       else
13210          ast_log(LOG_DEBUG, "SIP transfer: Invite Replace incoming channel should replace and hang up channel %s (one call leg)\n", replacecall->name); 
13211    }
13212 
13213    if (ignore) {
13214       ast_log(LOG_NOTICE, "Ignoring this INVITE with replaces in a stupid way.\n");
13215       /* We should answer something here. If we are here, the
13216          call we are replacing exists, so an accepted 
13217          can't harm */
13218       transmit_response_with_sdp(p, "200 OK", req, XMIT_RELIABLE);
13219       /* Do something more clever here */
13220       ast_channel_unlock(c);
13221       ast_mutex_unlock(&p->refer->refer_call->lock);
13222       return 1;
13223    } 
13224    if (!c) {
13225       /* What to do if no channel ??? */
13226       ast_log(LOG_ERROR, "Unable to create new channel.  Invite/replace failed.\n");
13227       transmit_response_reliable(p, "503 Service Unavailable", req);
13228       append_history(p, "Xfer", "INVITE/Replace Failed. No new channel.");
13229       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
13230       ast_mutex_unlock(&p->refer->refer_call->lock);
13231       return 1;
13232    }
13233    append_history(p, "Xfer", "INVITE/Replace received");
13234    /* We have three channels to play with
13235       channel c: New incoming call
13236       targetcall: Call from PBX to target
13237       p->refer->refer_call: SIP pvt dialog from transferer to pbx.
13238       replacecall: The owner of the previous
13239       We need to masq C into refer_call to connect to 
13240       targetcall;
13241       If we are talking to internal audio stream, target call is null.
13242    */
13243 
13244    /* Fake call progress */
13245    transmit_response(p, "100 Trying", req);
13246    ast_setstate(c, AST_STATE_RING);
13247 
13248    /* Masquerade the new call into the referred call to connect to target call 
13249       Targetcall is not touched by the masq */
13250 
13251    /* Answer the incoming call and set channel to UP state */
13252    transmit_response_with_sdp(p, "200 OK", req, XMIT_RELIABLE);
13253       
13254    ast_setstate(c, AST_STATE_UP);
13255    
13256    /* Stop music on hold and other generators */
13257    ast_quiet_chan(replacecall);
13258    ast_quiet_chan(targetcall);
13259    if (option_debug > 3)
13260       ast_log(LOG_DEBUG, "Invite/Replaces: preparing to masquerade %s into %s\n", c->name, replacecall->name);
13261    /* Unlock clone, but not original (replacecall) */
13262    ast_channel_unlock(c);
13263 
13264    /* Unlock PVT */
13265    ast_mutex_unlock(&p->refer->refer_call->lock);
13266 
13267    /* Make sure that the masq does not free our PVT for the old call */
13268    if (! earlyreplace && ! oneleggedreplace )
13269       ast_set_flag(&p->refer->refer_call->flags[0], SIP_DEFER_BYE_ON_TRANSFER);  /* Delay hangup */
13270       
13271    /* Prepare the masquerade - if this does not happen, we will be gone */
13272    if(ast_channel_masquerade(replacecall, c))
13273       ast_log(LOG_ERROR, "Failed to masquerade C into Replacecall\n");
13274    else if (option_debug > 3)
13275       ast_log(LOG_DEBUG, "Invite/Replaces: Going to masquerade %s into %s\n", c->name, replacecall->name);
13276 
13277    /* The masquerade will happen as soon as someone reads a frame from the channel */
13278 
13279    /* C should now be in place of replacecall */
13280    /* ast_read needs to lock channel */
13281    ast_channel_unlock(c);
13282    
13283    if (earlyreplace || oneleggedreplace ) {
13284       /* Force the masq to happen */
13285       if ((f = ast_read(replacecall))) {  /* Force the masq to happen */
13286          ast_frfree(f);
13287          f = NULL;
13288          if (option_debug > 3)
13289             ast_log(LOG_DEBUG, "Invite/Replace:  Could successfully read frame from RING channel!\n");
13290       } else {
13291          ast_log(LOG_WARNING, "Invite/Replace:  Could not read frame from RING channel \n");
13292       }
13293       c->hangupcause = AST_CAUSE_SWITCH_CONGESTION;
13294       ast_channel_unlock(replacecall);
13295    } else { /* Bridged call, UP channel */
13296       if ((f = ast_read(replacecall))) {  /* Force the masq to happen */
13297          /* Masq ok */
13298          ast_frfree(f);
13299          f = NULL;
13300          if (option_debug > 2)
13301             ast_log(LOG_DEBUG, "Invite/Replace:  Could successfully read frame from channel! Masq done.\n");
13302       } else {
13303          ast_log(LOG_WARNING, "Invite/Replace:  Could not read frame from channel. Transfer failed\n");
13304       }
13305       ast_channel_unlock(replacecall);
13306    }
13307    ast_mutex_unlock(&p->refer->refer_call->lock);
13308 
13309    ast_setstate(c, AST_STATE_DOWN);
13310    if (option_debug > 3) {
13311       struct ast_channel *test;
13312       ast_log(LOG_DEBUG, "After transfer:----------------------------\n");
13313       ast_log(LOG_DEBUG, " -- C:        %s State %s\n", c->name, ast_state2str(c->_state));
13314       if (replacecall)
13315          ast_log(LOG_DEBUG, " -- replacecall:        %s State %s\n", replacecall->name, ast_state2str(replacecall->_state));
13316       if (p->owner) {
13317          ast_log(LOG_DEBUG, " -- P->owner: %s State %s\n", p->owner->name, ast_state2str(p->owner->_state));
13318          test = ast_bridged_channel(p->owner);
13319          if (test)
13320             ast_log(LOG_DEBUG, " -- Call bridged to P->owner: %s State %s\n", test->name, ast_state2str(test->_state));
13321          else
13322             ast_log(LOG_DEBUG, " -- No call bridged to C->owner \n");
13323       } else 
13324          ast_log(LOG_DEBUG, " -- No channel yet \n");
13325       ast_log(LOG_DEBUG, "End After transfer:----------------------------\n");
13326    }
13327 
13328    ast_channel_unlock(p->owner); /* Unlock new owner */
13329    ast_mutex_unlock(&p->lock);   /* Unlock SIP structure */
13330 
13331    /* The call should be down with no ast_channel, so hang it up */
13332    c->tech_pvt = NULL;
13333    ast_hangup(c);
13334    return 0;
13335 }

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

References __sip_ack(), append_history, ast_inet_ntoa(), ast_log(), ast_set_flag, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_verbose(), check_pendings(), debug, DEFAULT_TRANS_TIMEOUT, error(), extract_uri(), FALSE, find_sdp(), FLAG_RESPONSE, sip_pvt::flags, get_header(), gettag(), handle_request_bye(), handle_request_cancel(), handle_request_info(), handle_request_invite(), handle_request_message(), handle_request_notify(), handle_request_options(), handle_request_refer(), handle_request_register(), handle_request_subscribe(), handle_response(), sip_request::header, sip_request::headers, sip_pvt::icseq, cfsip_methods::id, sip_pvt::initreq, INV_TERMINATED, sip_pvt::invitestate, sip_pvt::lastinvite, sip_pvt::lastmsg, len, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, LOG_WARNING, sip_pvt::method, sip_request::method, sip_pvt::ocseq, option_debug, sip_pvt::pendinginvite, process_sdp(), sip_request::rlPart1, sip_request::rlPart2, sip_pvt::sa, SIP_ACK, SIP_ALREADYGONE, SIP_BYE, SIP_CANCEL, sip_debug_test_pvt(), SIP_INFO, SIP_INVITE, SIP_MESSAGE, sip_methods, SIP_NEEDDESTROY, SIP_NOTIFY, SIP_OPTIONS, SIP_PKT_DEBUG, SIP_PKT_IGNORE, SIP_PKT_IGNORE_REQ, SIP_PKT_IGNORE_RESP, SIP_PKT_WITH_TOTAG, SIP_REFER, SIP_REGISTER, SIP_RESPONSE, sip_scheddestroy(), SIP_SUBSCRIBE, sip_pvt::tag, cfsip_methods::text, transmit_response(), transmit_response_reliable(), transmit_response_with_allow(), and TRUE.

14835 {
14836    /* Called with p->lock held, as well as p->owner->lock if appropriate, keeping things
14837       relatively static */
14838    const char *cmd;
14839    const char *cseq;
14840    const char *useragent;
14841    int seqno;
14842    int len;
14843    int ignore = FALSE;
14844    int respid;
14845    int res = 0;
14846    int debug = sip_debug_test_pvt(p);
14847    char *e;
14848    int error = 0;
14849 
14850    /* Get Method and Cseq */
14851    cseq = get_header(req, "Cseq");
14852    cmd = req->header[0];
14853 
14854    /* Must have Cseq */
14855    if (ast_strlen_zero(cmd) || ast_strlen_zero(cseq)) {
14856       ast_log(LOG_ERROR, "Missing Cseq. Dropping this SIP message, it's incomplete.\n");
14857       error = 1;
14858    }
14859    if (!error && sscanf(cseq, "%d%n", &seqno, &len) != 1) {
14860       ast_log(LOG_ERROR, "No seqno in '%s'. Dropping incomplete message.\n", cmd);
14861       error = 1;
14862    }
14863    if (error) {
14864       if (!p->initreq.headers)   /* New call */
14865          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); /* Make sure we destroy this dialog */
14866       return -1;
14867    }
14868    /* Get the command XXX */
14869 
14870    cmd = req->rlPart1;
14871    e = req->rlPart2;
14872 
14873    /* Save useragent of the client */
14874    useragent = get_header(req, "User-Agent");
14875    if (!ast_strlen_zero(useragent))
14876       ast_string_field_set(p, useragent, useragent);
14877 
14878    /* Find out SIP method for incoming request */
14879    if (req->method == SIP_RESPONSE) {  /* Response to our request */
14880       /* Response to our request -- Do some sanity checks */   
14881       if (!p->initreq.headers) {
14882          if (option_debug)
14883             ast_log(LOG_DEBUG, "That's odd...  Got a response on a call we dont know about. Cseq %d Cmd %s\n", seqno, cmd);
14884          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
14885          return 0;
14886       } else if (p->ocseq && (p->ocseq < seqno)) {
14887          if (option_debug)
14888             ast_log(LOG_DEBUG, "Ignoring out of order response %d (expecting %d)\n", seqno, p->ocseq);
14889          return -1;
14890       } else if (p->ocseq && (p->ocseq != seqno)) {
14891          /* ignore means "don't do anything with it" but still have to 
14892             respond appropriately  */
14893          ignore = TRUE;
14894          ast_set_flag(req, SIP_PKT_IGNORE);
14895          ast_set_flag(req, SIP_PKT_IGNORE_RESP);
14896          append_history(p, "Ignore", "Ignoring this retransmit\n");
14897       } else if (e) {
14898          e = ast_skip_blanks(e);
14899          if (sscanf(e, "%d %n", &respid, &len) != 1) {
14900             ast_log(LOG_WARNING, "Invalid response: '%s'\n", e);
14901          } else {
14902             if (respid <= 0) {
14903                ast_log(LOG_WARNING, "Invalid SIP response code: '%d'\n", respid);
14904                return 0;
14905             }
14906             /* More SIP ridiculousness, we have to ignore bogus contacts in 100 etc responses */
14907             if ((respid == 200) || ((respid >= 300) && (respid <= 399)))
14908                extract_uri(p, req);
14909             handle_response(p, respid, e + len, req, ignore, seqno);
14910          }
14911       }
14912       return 0;
14913    }
14914 
14915    /* New SIP request coming in 
14916       (could be new request in existing SIP dialog as well...) 
14917     */         
14918    
14919    p->method = req->method;   /* Find out which SIP method they are using */
14920    if (option_debug > 3)
14921       ast_log(LOG_DEBUG, "**** Received %s (%d) - Command in SIP %s\n", sip_methods[p->method].text, sip_methods[p->method].id, cmd); 
14922 
14923    if (p->icseq && (p->icseq > seqno)) {
14924       if (option_debug)
14925          ast_log(LOG_DEBUG, "Ignoring too old SIP packet packet %d (expecting >= %d)\n", seqno, p->icseq);
14926       if (req->method != SIP_ACK)
14927          transmit_response(p, "503 Server error", req);  /* We must respond according to RFC 3261 sec 12.2 */
14928       return -1;
14929    } else if (p->icseq &&
14930          p->icseq == seqno &&
14931          req->method != SIP_ACK &&
14932          (p->method != SIP_CANCEL || ast_test_flag(&p->flags[0], SIP_ALREADYGONE))) {
14933       /* ignore means "don't do anything with it" but still have to 
14934          respond appropriately.  We do this if we receive a repeat of
14935          the last sequence number  */
14936       ignore = 2;
14937       ast_set_flag(req, SIP_PKT_IGNORE);
14938       ast_set_flag(req, SIP_PKT_IGNORE_REQ);
14939       if (option_debug > 2)
14940          ast_log(LOG_DEBUG, "Ignoring SIP message because of retransmit (%s Seqno %d, ours %d)\n", sip_methods[p->method].text, p->icseq, seqno);
14941    }
14942       
14943    if (seqno >= p->icseq)
14944       /* Next should follow monotonically (but not necessarily 
14945          incrementally -- thanks again to the genius authors of SIP --
14946          increasing */
14947       p->icseq = seqno;
14948 
14949    /* Find their tag if we haven't got it */
14950    if (ast_strlen_zero(p->theirtag)) {
14951       char tag[128];
14952 
14953       gettag(req, "From", tag, sizeof(tag));
14954       ast_string_field_set(p, theirtag, tag);
14955    }
14956    snprintf(p->lastmsg, sizeof(p->lastmsg), "Rx: %s", cmd);
14957 
14958    if (pedanticsipchecking) {
14959       /* If this is a request packet without a from tag, it's not
14960          correct according to RFC 3261  */
14961       /* Check if this a new request in a new dialog with a totag already attached to it,
14962          RFC 3261 - section 12.2 - and we don't want to mess with recovery  */
14963       if (!p->initreq.headers && ast_test_flag(req, SIP_PKT_WITH_TOTAG)) {
14964          /* If this is a first request and it got a to-tag, it is not for us */
14965          if (!ast_test_flag(req, SIP_PKT_IGNORE) && req->method == SIP_INVITE) {
14966             transmit_response_reliable(p, "481 Call/Transaction Does Not Exist", req);
14967             /* Will cease to exist after ACK */
14968          } else if (req->method != SIP_ACK) {
14969             transmit_response(p, "481 Call/Transaction Does Not Exist", req);
14970             sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
14971          }
14972          return res;
14973       }
14974    }
14975 
14976    if (!e && (p->method == SIP_INVITE || p->method == SIP_SUBSCRIBE || p->method == SIP_REGISTER || p->method == SIP_NOTIFY)) {
14977       transmit_response(p, "400 Bad request", req);
14978       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
14979       return -1;
14980    }
14981 
14982    /* Handle various incoming SIP methods in requests */
14983    switch (p->method) {
14984    case SIP_OPTIONS:
14985       res = handle_request_options(p, req);
14986       break;
14987    case SIP_INVITE:
14988       res = handle_request_invite(p, req, debug, seqno, sin, recount, e, nounlock);
14989       break;
14990    case SIP_REFER:
14991       res = handle_request_refer(p, req, debug, ignore, seqno, nounlock);
14992       break;
14993    case SIP_CANCEL:
14994       res = handle_request_cancel(p, req);
14995       break;
14996    case SIP_BYE:
14997       res = handle_request_bye(p, req);
14998       break;
14999    case SIP_MESSAGE:
15000       res = handle_request_message(p, req);
15001       break;
15002    case SIP_SUBSCRIBE:
15003       res = handle_request_subscribe(p, req, sin, seqno, e);
15004       break;
15005    case SIP_REGISTER:
15006       res = handle_request_register(p, req, sin, e);
15007       break;
15008    case SIP_INFO:
15009       if (ast_test_flag(req, SIP_PKT_DEBUG))
15010          ast_verbose("Receiving INFO!\n");
15011       if (!ignore) 
15012          handle_request_info(p, req);
15013       else  /* if ignoring, transmit response */
15014          transmit_response(p, "200 OK", req);
15015       break;
15016    case SIP_NOTIFY:
15017       res = handle_request_notify(p, req, sin, seqno, e);
15018       break;
15019    case SIP_ACK:
15020       /* Make sure we don't ignore this */
15021       if (seqno == p->pendinginvite) {
15022          p->invitestate = INV_TERMINATED;
15023          p->pendinginvite = 0;
15024          __sip_ack(p, seqno, FLAG_RESPONSE, 0);
15025          if (find_sdp(req)) {
15026             if (process_sdp(p, req))
15027                return -1;
15028          } 
15029          check_pendings(p);
15030       }
15031       /* Got an ACK that we did not match. Ignore silently */
15032       if (!p->lastinvite && ast_strlen_zero(p->randdata))
15033          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
15034       break;
15035    default:
15036       transmit_response_with_allow(p, "501 Method Not Implemented", req, 0);
15037       ast_log(LOG_NOTICE, "Unknown SIP command '%s' from '%s'\n", 
15038          cmd, ast_inet_ntoa(p->sa.sin_addr));
15039       /* If this is some new method, and we don't have a call, destroy it now */
15040       if (!p->initreq.headers)
15041          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
15042       break;
15043    }
15044    return res;
15045 }

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

Handle incoming BYE request.

Definition at line 14401 of file chan_sip.c.

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

Referenced by handle_request().

14402 {
14403    struct ast_channel *c=NULL;
14404    int res;
14405    struct ast_channel *bridged_to;
14406    
14407    /* If we have an INCOMING invite that we haven't answered, terminate that transaction */
14408    if (p->pendinginvite && !ast_test_flag(&p->flags[0], SIP_OUTGOING) && !ast_test_flag(req, SIP_PKT_IGNORE) && !p->owner) 
14409       transmit_response_reliable(p, "487 Request Terminated", &p->initreq);
14410 
14411    p->invitestate = INV_TERMINATED;
14412 
14413    copy_request(&p->initreq, req);
14414    check_via(p, req);
14415    sip_alreadygone(p);
14416 
14417    /* Get RTCP quality before end of call */
14418    if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY) || p->owner) {
14419       char *audioqos, *videoqos;
14420       if (p->rtp) {
14421          audioqos = ast_rtp_get_quality(p->rtp, NULL);
14422          if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY))
14423             append_history(p, "RTCPaudio", "Quality:%s", audioqos);
14424          if (p->owner)
14425             pbx_builtin_setvar_helper(p->owner, "RTPAUDIOQOS", audioqos);
14426       }
14427       if (p->vrtp) {
14428          videoqos = ast_rtp_get_quality(p->vrtp, NULL);
14429          if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY))
14430             append_history(p, "RTCPvideo", "Quality:%s", videoqos);
14431          if (p->owner)
14432             pbx_builtin_setvar_helper(p->owner, "RTPVIDEOQOS", videoqos);
14433       }
14434    }
14435 
14436    stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */
14437 
14438    if (!ast_strlen_zero(get_header(req, "Also"))) {
14439       ast_log(LOG_NOTICE, "Client '%s' using deprecated BYE/Also transfer method.  Ask vendor to support REFER instead\n",
14440          ast_inet_ntoa(p->recv.sin_addr));
14441       if (ast_strlen_zero(p->context))
14442          ast_string_field_set(p, context, default_context);
14443       res = get_also_info(p, req);
14444       if (!res) {
14445          c = p->owner;
14446          if (c) {
14447             bridged_to = ast_bridged_channel(c);
14448             if (bridged_to) {
14449                /* Don't actually hangup here... */
14450                ast_queue_control(c, AST_CONTROL_UNHOLD);
14451                ast_async_goto(bridged_to, p->context, p->refer->refer_to,1);
14452             } else
14453                ast_queue_hangup(p->owner);
14454          }
14455       } else {
14456          ast_log(LOG_WARNING, "Invalid transfer information from '%s'\n", ast_inet_ntoa(p->recv.sin_addr));
14457          if (p->owner)
14458             ast_queue_hangup(p->owner);
14459       }
14460    } else if (p->owner) {
14461       ast_queue_hangup(p->owner);
14462       if (option_debug > 2)
14463          ast_log(LOG_DEBUG, "Received bye, issuing owner hangup\n");
14464    } else {
14465       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
14466       if (option_debug > 2)
14467          ast_log(LOG_DEBUG, "Received bye, no owner, selfdestruct soon.\n");
14468    }
14469    transmit_response(p, "200 OK", req);
14470 
14471    return 1;
14472 }

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

Handle incoming CANCEL request.

Definition at line 14303 of file chan_sip.c.

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

Referenced by handle_request().

14304 {
14305       
14306    check_via(p, req);
14307    sip_alreadygone(p);
14308    p->invitestate = INV_CANCELLED;
14309    
14310    if (p->owner && p->owner->_state == AST_STATE_UP) {
14311       /* This call is up, cancel is ignored, we need a bye */
14312       transmit_response(p, "200 OK", req);
14313       if (option_debug)
14314          ast_log(LOG_DEBUG, "Got CANCEL on an answered call. Ignoring... \n");
14315       return 0;
14316    }
14317 
14318    if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) 
14319       update_call_counter(p, DEC_CALL_LIMIT);
14320 
14321    stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */
14322 
14323    if (p->owner)
14324       ast_queue_hangup(p->owner);
14325    else
14326       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
14327    if (p->initreq.len > 0) {
14328       transmit_response_reliable(p, "487 Request Terminated", &p->initreq);
14329       transmit_response(p, "200 OK", req);
14330       return 1;
14331    } else {
14332       transmit_response(p, "481 Call Leg Does Not Exist", req);
14333       return 0;
14334    }
14335 }

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

References ast_bridged_channel(), ast_cdr_setuserfield(), AST_CONTROL_FLASH, AST_CONTROL_VIDUPDATE, AST_FRAME_CONTROL, AST_FRAME_DTMF, ast_log(), ast_queue_control(), ast_queue_frame(), ast_strlen_zero(), ast_test_flag, ast_verbose(), ast_channel::cdr, DEFAULT_TRANS_TIMEOUT, event, sip_pvt::flags, get_body(), get_header(), ast_frame::len, LOG_WARNING, sip_pvt::owner, sip_scheddestroy(), SIP_USECLIENTCODE, sipdebug, ast_frame::subclass, and transmit_response().

Referenced by handle_request().

10887 {
10888    char buf[1024];
10889    unsigned int event;
10890    const char *c = get_header(req, "Content-Type");
10891 
10892    /* Need to check the media/type */
10893    if (!strcasecmp(c, "application/dtmf-relay") ||
10894        !strcasecmp(c, "application/vnd.nortelnetworks.digits")) {
10895       unsigned int duration = 0;
10896 
10897       /* Try getting the "signal=" part */
10898       if (ast_strlen_zero(c = get_body(req, "Signal")) && ast_strlen_zero(c = get_body(req, "d"))) {
10899          ast_log(LOG_WARNING, "Unable to retrieve DTMF signal from INFO message from %s\n", p->callid);
10900          transmit_response(p, "200 OK", req); /* Should return error */
10901          return;
10902       } else {
10903          ast_copy_string(buf, c, sizeof(buf));
10904       }
10905 
10906       if (!ast_strlen_zero((c = get_body(req, "Duration"))))
10907          duration = atoi(c);
10908       if (!duration)
10909          duration = 100; /* 100 ms */
10910 
10911       if (!p->owner) {  /* not a PBX call */
10912          transmit_response(p, "481 Call leg/transaction does not exist", req);
10913          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
10914          return;
10915       }
10916 
10917       if (ast_strlen_zero(buf)) {
10918          transmit_response(p, "200 OK", req);
10919          return;
10920       }
10921 
10922       if (buf[0] == '*')
10923          event = 10;
10924       else if (buf[0] == '#')
10925          event = 11;
10926       else if ((buf[0] >= 'A') && (buf[0] <= 'D'))
10927          event = 12 + buf[0] - 'A';
10928       else
10929          event = atoi(buf);
10930       if (event == 16) {
10931          /* send a FLASH event */
10932          struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_FLASH, };
10933          ast_queue_frame(p->owner, &f);
10934          if (sipdebug)
10935             ast_verbose("* DTMF-relay event received: FLASH\n");
10936       } else {
10937          /* send a DTMF event */
10938          struct ast_frame f = { AST_FRAME_DTMF, };
10939          if (event < 10) {
10940             f.subclass = '0' + event;
10941          } else if (event < 11) {
10942             f.subclass = '*';
10943          } else if (event < 12) {
10944             f.subclass = '#';
10945          } else if (event < 16) {
10946             f.subclass = 'A' + (event - 12);
10947          }
10948          f.len = duration;
10949          ast_queue_frame(p->owner, &f);
10950          if (sipdebug)
10951             ast_verbose("* DTMF-relay event received: %c\n", f.subclass);
10952       }
10953       transmit_response(p, "200 OK", req);
10954       return;
10955    } else if (!strcasecmp(c, "application/media_control+xml")) {
10956       /* Eh, we'll just assume it's a fast picture update for now */
10957       if (p->owner)
10958          ast_queue_control(p->owner, AST_CONTROL_VIDUPDATE);
10959       transmit_response(p, "200 OK", req);
10960       return;
10961    } else if (!ast_strlen_zero(c = get_header(req, "X-ClientCode"))) {
10962       /* Client code (from SNOM phone) */
10963       if (ast_test_flag(&p->flags[0], SIP_USECLIENTCODE)) {
10964          if (p->owner && p->owner->cdr)
10965             ast_cdr_setuserfield(p->owner, c);
10966          if (p->owner && ast_bridged_channel(p->owner) && ast_bridged_channel(p->owner)->cdr)
10967             ast_cdr_setuserfield(ast_bridged_channel(p->owner), c);
10968          transmit_response(p, "200 OK", req);
10969       } else {
10970          transmit_response(p, "403 Unauthorized", req);
10971       }
10972       return;
10973    }
10974    /* Other type of INFO message, not really understood by Asterisk */
10975    /* if (get_msg_text(buf, sizeof(buf), req)) { */
10976 
10977    ast_log(LOG_WARNING, "Unable to parse INFO message from %s. Content %s\n", p->callid, buf);
10978    transmit_response(p, "415 Unsupported media type", req);
10979    return;
10980 }

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

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

Referenced by handle_request().

13345 {
13346    int res = 1;
13347    int gotdest;
13348    const char *p_replaces;
13349    char *replace_id = NULL;
13350    const char *required;
13351    unsigned int required_profile = 0;
13352    struct ast_channel *c = NULL;    /* New channel */
13353    int reinvite = 0;
13354 
13355    /* Find out what they support */
13356    if (!p->sipoptions) {
13357       const char *supported = get_header(req, "Supported");
13358       if (!ast_strlen_zero(supported))
13359          parse_sip_options(p, supported);
13360    }
13361 
13362    /* Find out what they require */
13363    required = get_header(req, "Require");
13364    if (!ast_strlen_zero(required)) {
13365       required_profile = parse_sip_options(NULL, required);
13366       if (required_profile && required_profile != SIP_OPT_REPLACES) {
13367          /* At this point we only support REPLACES */
13368          transmit_response_with_unsupported(p, "420 Bad extension (unsupported)", req, required);
13369          ast_log(LOG_WARNING,"Received SIP INVITE with unsupported required extension: %s\n", required);
13370          p->invitestate = INV_COMPLETED;
13371          if (!p->lastinvite)
13372             sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
13373          return -1;
13374       }
13375    }
13376 
13377    /* Check if this is a loop */
13378    if (ast_test_flag(&p->flags[0], SIP_OUTGOING) && p->owner && (p->owner->_state != AST_STATE_UP)) {
13379       /* This is a call to ourself.  Send ourselves an error code and stop
13380          processing immediately, as SIP really has no good mechanism for
13381          being able to call yourself */
13382       /* If pedantic is on, we need to check the tags. If they're different, this is
13383          in fact a forked call through a SIP proxy somewhere. */
13384       transmit_response(p, "482 Loop Detected", req);
13385       p->invitestate = INV_COMPLETED;
13386       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
13387       return 0;
13388    }
13389    
13390    if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->pendinginvite) {
13391       /* We already have a pending invite. Sorry. You are on hold. */
13392       transmit_response(p, "491 Request Pending", req);
13393       if (option_debug)
13394          ast_log(LOG_DEBUG, "Got INVITE on call where we already have pending INVITE, deferring that - %s\n", p->callid);
13395       /* Don't destroy dialog here */
13396       return 0;
13397    }
13398 
13399    p_replaces = get_header(req, "Replaces");
13400    if (!ast_strlen_zero(p_replaces)) {
13401       /* We have a replaces header */
13402       char *ptr;
13403       char *fromtag = NULL;
13404       char *totag = NULL;
13405       char *start, *to;
13406       int error = 0;
13407 
13408       if (p->owner) {
13409          if (option_debug > 2)
13410             ast_log(LOG_DEBUG, "INVITE w Replaces on existing call? Refusing action. [%s]\n", p->callid);
13411          transmit_response(p, "400 Bad request", req);   /* The best way to not not accept the transfer */
13412          /* Do not destroy existing call */
13413          return -1;
13414       }
13415 
13416       if (sipdebug && option_debug > 2)
13417          ast_log(LOG_DEBUG, "INVITE part of call transfer. Replaces [%s]\n", p_replaces);
13418       /* Create a buffer we can manipulate */
13419       replace_id = ast_strdupa(p_replaces);
13420       ast_uri_decode(replace_id);
13421 
13422       if (!p->refer && !sip_refer_allocate(p)) {
13423          transmit_response(p, "500 Server Internal Error", req);
13424          append_history(p, "Xfer", "INVITE/Replace Failed. Out of memory.");
13425          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
13426          p->invitestate = INV_COMPLETED;
13427          return -1;
13428       }
13429 
13430       /*  Todo: (When we find phones that support this)
13431          if the replaces header contains ";early-only"
13432          we can only replace the call in early
13433          stage, not after it's up.
13434 
13435          If it's not in early mode, 486 Busy.
13436       */
13437       
13438       /* Skip leading whitespace */
13439       replace_id = ast_skip_blanks(replace_id);
13440 
13441       start = replace_id;
13442       while ( (ptr = strsep(&start, ";")) ) {
13443          ptr = ast_skip_blanks(ptr); /* XXX maybe unnecessary ? */
13444          if ( (to = strcasestr(ptr, "to-tag=") ) )
13445             totag = to + 7;   /* skip the keyword */
13446          else if ( (to = strcasestr(ptr, "from-tag=") ) ) {
13447             fromtag = to + 9; /* skip the keyword */
13448             fromtag = strsep(&fromtag, "&"); /* trim what ? */
13449          }
13450       }
13451 
13452       if (sipdebug && option_debug > 3) 
13453          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>");
13454 
13455 
13456       /* Try to find call that we are replacing 
13457          If we have a Replaces  header, we need to cancel that call if we succeed with this call 
13458       */
13459       if ((p->refer->refer_call = get_sip_pvt_byid_locked(replace_id, totag, fromtag)) == NULL) {
13460          ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-existent call id (%s)!\n", replace_id);
13461          transmit_response(p, "481 Call Leg Does Not Exist (Replaces)", req);
13462          error = 1;
13463       }
13464 
13465       /* At this point, bot the pvt and the owner of the call to be replaced is locked */
13466 
13467       /* The matched call is the call from the transferer to Asterisk .
13468          We want to bridge the bridged part of the call to the 
13469          incoming invite, thus taking over the refered call */
13470 
13471       if (p->refer->refer_call == p) {
13472          ast_log(LOG_NOTICE, "INVITE with replaces into it's own call id (%s == %s)!\n", replace_id, p->callid);
13473          p->refer->refer_call = NULL;
13474          transmit_response(p, "400 Bad request", req);   /* The best way to not not accept the transfer */
13475          error = 1;
13476       }
13477 
13478       if (!error && !p->refer->refer_call->owner) {
13479          /* Oops, someting wrong anyway, no owner, no call */
13480          ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-existing call id (%s)!\n", replace_id);
13481          /* Check for better return code */
13482          transmit_response(p, "481 Call Leg Does Not Exist (Replace)", req);
13483          error = 1;
13484       }
13485 
13486       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 ) {
13487          ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-ringing or active call id (%s)!\n", replace_id);
13488          transmit_response(p, "603 Declined (Replaces)", req);
13489          error = 1;
13490       }
13491 
13492       if (error) {   /* Give up this dialog */
13493          append_history(p, "Xfer", "INVITE/Replace Failed.");
13494          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
13495          ast_mutex_unlock(&p->lock);
13496          if (p->refer->refer_call) {
13497             ast_mutex_unlock(&p->refer->refer_call->lock);
13498             ast_channel_unlock(p->refer->refer_call->owner);
13499          }
13500          p->invitestate = INV_COMPLETED;
13501          return -1;
13502       }
13503    }
13504 
13505 
13506    /* Check if this is an INVITE that sets up a new dialog or
13507       a re-invite in an existing dialog */
13508 
13509    if (!ast_test_flag(req, SIP_PKT_IGNORE)) {
13510       int newcall = (p->initreq.headers ? TRUE : FALSE);
13511 
13512       sip_cancel_destroy(p);
13513       /* This also counts as a pending invite */
13514       p->pendinginvite = seqno;
13515       check_via(p, req);
13516 
13517       copy_request(&p->initreq, req);     /* Save this INVITE as the transaction basis */
13518       if (!p->owner) {  /* Not a re-invite */
13519          if (debug)
13520             ast_verbose("Using INVITE request as basis request - %s\n", p->callid);
13521          if (newcall)
13522             append_history(p, "Invite", "New call: %s", p->callid);
13523          parse_ok_contact(p, req);
13524       } else { /* Re-invite on existing call */
13525          ast_clear_flag(&p->flags[0], SIP_OUTGOING);  /* This is now an inbound dialog */
13526          /* Handle SDP here if we already have an owner */
13527          if (find_sdp(req)) {
13528             if (process_sdp(p, req)) {
13529                transmit_response(p, "488 Not acceptable here", req);
13530                if (!p->lastinvite)
13531                   sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
13532                return -1;
13533             }
13534          } else {
13535             p->jointcapability = p->capability;
13536             if (option_debug > 2)
13537                ast_log(LOG_DEBUG, "Hm....  No sdp for the moment\n");
13538             /* Some devices signal they want to be put off hold by sending a re-invite
13539                *without* an SDP, which is supposed to mean "Go back to your state"
13540                and since they put os on remote hold, we go back to off hold */
13541             if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD))
13542                change_hold_state(p, req, FALSE, 0);
13543          }
13544          if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) /* This is a response, note what it was for */
13545             append_history(p, "ReInv", "Re-invite received");
13546       }
13547    } else if (debug)
13548       ast_verbose("Ignoring this INVITE request\n");
13549 
13550    
13551    if (!p->lastinvite && !ast_test_flag(req, SIP_PKT_IGNORE) && !p->owner) {
13552       /* This is a new invite */
13553       /* Handle authentication if this is our first invite */
13554       res = check_user(p, req, SIP_INVITE, e, XMIT_RELIABLE, sin);
13555       if (res == AUTH_CHALLENGE_SENT) {
13556          p->invitestate = INV_COMPLETED;     /* Needs to restart in another INVITE transaction */
13557          return 0;
13558       }
13559       if (res < 0) { /* Something failed in authentication */
13560          if (res == AUTH_FAKE_AUTH) {
13561             ast_log(LOG_NOTICE, "Sending fake auth rejection for user %s\n", get_header(req, "From"));
13562             transmit_fake_auth_response(p, req, 1);
13563          } else {
13564             ast_log(LOG_NOTICE, "Failed to authenticate user %s\n", get_header(req, "From"));
13565             transmit_response_reliable(p, "403 Forbidden", req);
13566          }
13567          p->invitestate = INV_COMPLETED;  
13568          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
13569          ast_string_field_free(p, theirtag);
13570          return 0;
13571       }
13572 
13573       /* We have a succesful authentication, process the SDP portion if there is one */
13574       if (find_sdp(req)) {
13575          if (process_sdp(p, req)) {
13576             /* Unacceptable codecs */
13577             transmit_response_reliable(p, "488 Not acceptable here", req);
13578             p->invitestate = INV_COMPLETED;  
13579             sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
13580             if (option_debug)
13581                ast_log(LOG_DEBUG, "No compatible codecs for this SIP call.\n");
13582             return -1;
13583          }
13584       } else { /* No SDP in invite, call control session */
13585          p->jointcapability = p->capability;
13586          if (option_debug > 1)
13587             ast_log(LOG_DEBUG, "No SDP in Invite, third party call control\n");
13588       }
13589 
13590       /* Queue NULL frame to prod ast_rtp_bridge if appropriate */
13591       /* This seems redundant ... see !p-owner above */
13592       if (p->owner)
13593          ast_queue_frame(p->owner, &ast_null_frame);
13594 
13595 
13596       /* Initialize the context if it hasn't been already */
13597       if (ast_strlen_zero(p->context))
13598          ast_string_field_set(p, context, default_context);
13599 
13600 
13601       /* Check number of concurrent calls -vs- incoming limit HERE */
13602       if (option_debug)
13603          ast_log(LOG_DEBUG, "Checking SIP call limits for device %s\n", p->username);
13604       if ((res = update_call_counter(p, INC_CALL_LIMIT))) {
13605          if (res < 0) {
13606             ast_log(LOG_NOTICE, "Failed to place call for user %s, too many calls\n", p->username);
13607             transmit_response_reliable(p, "480 Temporarily Unavailable (Call limit) ", req);
13608             sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
13609             p->invitestate = INV_COMPLETED;  
13610          }
13611          return 0;
13612       }
13613       gotdest = get_destination(p, NULL); /* Get destination right away */
13614       get_rdnis(p, NULL);        /* Get redirect information */
13615       extract_uri(p, req);       /* Get the Contact URI */
13616       build_contact(p);       /* Build our contact header */
13617 
13618       if (p->rtp) {
13619          ast_rtp_setdtmf(p->rtp, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833);
13620          ast_rtp_setdtmfcompensate(p->rtp, ast_test_flag(&p->flags[1], SIP_PAGE2_RFC2833_COMPENSATE));
13621       }
13622 
13623       if (!replace_id && gotdest) { /* No matching extension found */
13624          if (gotdest == 1 && ast_test_flag(&p->flags[1], SIP_PAGE2_ALLOWOVERLAP))
13625             transmit_response_reliable(p, "484 Address Incomplete", req);
13626          else
13627             transmit_response_reliable(p, "404 Not Found", req);
13628          p->invitestate = INV_COMPLETED;  
13629          update_call_counter(p, DEC_CALL_LIMIT);
13630          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
13631          return 0;
13632       } else {
13633          /* If no extension was specified, use the s one */
13634          /* Basically for calling to IP/Host name only */
13635          if (ast_strlen_zero(p->exten))
13636             ast_string_field_set(p, exten, "s");
13637          /* Initialize our tag */   
13638 
13639          make_our_tag(p->tag, sizeof(p->tag));
13640          /* First invitation - create the channel */
13641          c = sip_new(p, AST_STATE_DOWN, S_OR(p->username, NULL));
13642          *recount = 1;
13643 
13644          /* Save Record-Route for any later requests we make on this dialogue */
13645          build_route(p, req, 0);
13646 
13647          if (c) {
13648             /* Pre-lock the call */
13649             ast_channel_lock(c);
13650          }
13651       }
13652    } else {
13653       if (option_debug > 1 && sipdebug) {
13654          if (!ast_test_flag(req, SIP_PKT_IGNORE))
13655             ast_log(LOG_DEBUG, "Got a SIP re-invite for call %s\n", p->callid);
13656          else
13657             ast_log(LOG_DEBUG, "Got a SIP re-transmit of INVITE for call %s\n", p->callid);
13658       }
13659       reinvite = 1;
13660       c = p->owner;
13661    }
13662 
13663    if (!ast_test_flag(req, SIP_PKT_IGNORE) && p)
13664       p->lastinvite = seqno;
13665 
13666    if (replace_id) {    /* Attended transfer or call pickup - we're the target */
13667       /* Go and take over the target call */
13668       if (sipdebug && option_debug > 3)
13669          ast_log(LOG_DEBUG, "Sending this call to the invite/replcaes handler %s\n", p->callid);
13670       return handle_invite_replaces(p, req, debug, ast_test_flag(req, SIP_PKT_IGNORE), seqno, sin);
13671    }
13672 
13673 
13674    if (c) { /* We have a call  -either a new call or an old one (RE-INVITE) */
13675       switch(c->_state) {
13676       case AST_STATE_DOWN:
13677          if (option_debug > 1)
13678             ast_log(LOG_DEBUG, "%s: New call is still down.... Trying... \n", c->name);
13679          transmit_response(p, "100 Trying", req);
13680          p->invitestate = INV_PROCEEDING;
13681          ast_setstate(c, AST_STATE_RING);
13682          if (strcmp(p->exten, ast_pickup_ext())) { /* Call to extension -start pbx on this call */
13683             enum ast_pbx_result res;
13684 
13685             res = ast_pbx_start(c);
13686 
13687             switch(res) {
13688             case AST_PBX_FAILED:
13689                ast_log(LOG_WARNING, "Failed to start PBX :(\n");
13690                p->invitestate = INV_COMPLETED;
13691                if (ast_test_flag(req, SIP_PKT_IGNORE))
13692                   transmit_response(p, "503 Unavailable", req);
13693                else
13694                   transmit_response_reliable(p, "503 Unavailable", req);
13695                break;
13696             case AST_PBX_CALL_LIMIT:
13697                ast_log(LOG_WARNING, "Failed to start PBX (call limit reached) \n");
13698                p->invitestate = INV_COMPLETED;
13699                if (ast_test_flag(req, SIP_PKT_IGNORE))
13700                   transmit_response(p, "480 Temporarily Unavailable", req);
13701                else
13702                   transmit_response_reliable(p, "480 Temporarily Unavailable", req);
13703                break;
13704             case AST_PBX_SUCCESS:
13705                /* nothing to do */
13706                break;
13707             }
13708 
13709             if (res) {
13710 
13711                /* Unlock locks so ast_hangup can do its magic */
13712                ast_mutex_unlock(&c->lock);
13713                ast_mutex_unlock(&p->lock);
13714                ast_hangup(c);
13715                ast_mutex_lock(&p->lock);
13716                c = NULL;
13717             }
13718          } else { /* Pickup call in call group */
13719             ast_channel_unlock(c);
13720             *nounlock = 1;
13721             if (ast_pickup_call(c)) {
13722                ast_log(LOG_NOTICE, "Nothing to pick up for %s\n", p->callid);
13723                if (ast_test_flag(req, SIP_PKT_IGNORE))
13724                   transmit_response(p, "503 Unavailable", req);   /* OEJ - Right answer? */
13725                else
13726                   transmit_response_reliable(p, "503 Unavailable", req);
13727                sip_alreadygone(p);
13728                /* Unlock locks so ast_hangup can do its magic */
13729                ast_mutex_unlock(&p->lock);
13730                c->hangupcause = AST_CAUSE_CALL_REJECTED;
13731             } else {
13732                ast_mutex_unlock(&p->lock);
13733                ast_setstate(c, AST_STATE_DOWN);
13734                c->hangupcause = AST_CAUSE_NORMAL_CLEARING;
13735             }
13736             p->invitestate = INV_COMPLETED;
13737             ast_hangup(c);
13738             ast_mutex_lock(&p->lock);
13739             c = NULL;
13740          }
13741          break;
13742       case AST_STATE_RING:
13743          transmit_response(p, "100 Trying", req);
13744          p->invitestate = INV_PROCEEDING;
13745          break;
13746       case AST_STATE_RINGING:
13747          transmit_response(p, "180 Ringing", req);
13748          p->invitestate = INV_PROCEEDING;
13749          break;
13750       case AST_STATE_UP:
13751          if (option_debug > 1)
13752             ast_log(LOG_DEBUG, "%s: This call is UP.... \n", c->name);
13753 
13754          transmit_response(p, "100 Trying", req);
13755 
13756          if (p->t38.state == T38_PEER_REINVITE) {
13757             struct ast_channel *bridgepeer = NULL;
13758             struct sip_pvt *bridgepvt = NULL;
13759             
13760             if ((bridgepeer = ast_bridged_channel(p->owner))) {
13761                /* 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*/
13762                /*! XXX: we should also check here does the other side supports t38 at all !!! XXX */
13763                if (bridgepeer->tech == &sip_tech || bridgepeer->tech == &sip_tech_info) {
13764                   bridgepvt = (struct sip_pvt*)bridgepeer->tech_pvt;
13765                   if (bridgepvt->t38.state == T38_DISABLED) {
13766                      if (bridgepvt->udptl) { /* If everything is OK with other side's udptl struct */
13767                         /* Send re-invite to the bridged channel */
13768                         sip_handle_t38_reinvite(bridgepeer, p, 1);
13769                      } else { /* Something is wrong with peers udptl struct */
13770                         ast_log(LOG_WARNING, "Strange... The other side of the bridge don't have udptl struct\n");
13771                         ast_mutex_lock(&bridgepvt->lock);
13772                         bridgepvt->t38.state = T38_DISABLED;
13773                         ast_mutex_unlock(&bridgepvt->lock);
13774                         if (option_debug > 1)
13775                            ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", bridgepvt->t38.state, bridgepeer->name);
13776                         if (ast_test_flag(req, SIP_PKT_IGNORE))
13777                            transmit_response(p, "488 Not acceptable here", req);
13778                         else
13779                            transmit_response_reliable(p, "488 Not acceptable here", req);
13780                      
13781                      }
13782                   } else {
13783                      /* The other side is already setup for T.38 most likely so we need to acknowledge this too */
13784                      transmit_response_with_t38_sdp(p, "200 OK", req, XMIT_CRITICAL);
13785                      p->t38.state = T38_ENABLED;
13786                      if (option_debug)
13787                         ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>");
13788                   }
13789                } else {
13790                   /* Other side is not a SIP channel */
13791                   if (ast_test_flag(req, SIP_PKT_IGNORE))
13792                      transmit_response(p, "488 Not acceptable here", req);
13793                   else
13794                      transmit_response_reliable(p, "488 Not acceptable here", req);
13795                   p->t38.state = T38_DISABLED;
13796                   if (option_debug > 1)
13797                      ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>");
13798 
13799                   if (!p->lastinvite) /* Only destroy if this is *not* a re-invite */
13800                      sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
13801                }
13802             } else {
13803                /* we are not bridged in a call */
13804                transmit_response_with_t38_sdp(p, "200 OK", req, XMIT_CRITICAL);
13805                p->t38.state = T38_ENABLED;
13806                if (option_debug)
13807                   ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>");
13808             }
13809          } else if (p->t38.state == T38_DISABLED) { /* Channel doesn't have T38 offered or enabled */
13810             int sendok = TRUE;
13811 
13812             /* If we are bridged to a channel that has T38 enabled than this is a case of RTP re-invite after T38 session */
13813             /* so handle it here (re-invite other party to RTP) */
13814             struct ast_channel *bridgepeer = NULL;
13815             struct sip_pvt *bridgepvt = NULL;
13816             if ((bridgepeer = ast_bridged_channel(p->owner))) {
13817                if (bridgepeer->tech == &sip_tech || bridgepeer->tech == &sip_tech_info) {
13818                   bridgepvt = (struct sip_pvt*)bridgepeer->tech_pvt;
13819                   /* Does the bridged peer have T38 ? */
13820                   if (bridgepvt->t38.state == T38_ENABLED) {
13821                      ast_log(LOG_WARNING, "RTP re-invite after T38 session not handled yet !\n");
13822                      /* Insted of this we should somehow re-invite the other side of the bridge to RTP */
13823                      if (ast_test_flag(req, SIP_PKT_IGNORE))
13824                         transmit_response(p, "488 Not Acceptable Here (unsupported)", req);
13825                      else
13826                         transmit_response_reliable(p, "488 Not Acceptable Here (unsupported)", req);
13827                      sendok = FALSE;
13828                   } 
13829                   /* No bridged peer with T38 enabled*/
13830                }
13831             } 
13832             /* Respond to normal re-invite */
13833             if (sendok)
13834                /* If this is not a re-invite or something to ignore - it's critical */
13835                transmit_response_with_sdp(p, "200 OK", req, (reinvite || ast_test_flag(req, SIP_PKT_IGNORE)) ?  XMIT_UNRELIABLE : XMIT_CRITICAL);
13836          }
13837          p->invitestate = INV_TERMINATED;
13838          break;
13839       default:
13840          ast_log(LOG_WARNING, "Don't know how to handle INVITE in state %d\n", c->_state);
13841          transmit_response(p, "100 Trying", req);
13842          break;
13843       }
13844    } else {
13845       if (p && (p->autokillid == -1)) {
13846          const char *msg;
13847 
13848          if (!p->jointcapability)
13849             msg = "488 Not Acceptable Here (codec error)";
13850          else {
13851             ast_log(LOG_NOTICE, "Unable to create/find SIP channel for this INVITE\n");
13852             msg = "503 Unavailable";
13853          }
13854          if (ast_test_flag(req, SIP_PKT_IGNORE))
13855             transmit_response(p, msg, req);
13856          else
13857             transmit_response_reliable(p, msg, req);
13858          p->invitestate = INV_COMPLETED;
13859          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
13860       }
13861    }
13862    return res;
13863 }

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

Handle incoming MESSAGE request.

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

14476 {
14477    if (!ast_test_flag(req, SIP_PKT_IGNORE)) {
14478       if (ast_test_flag(req, SIP_PKT_DEBUG))
14479          ast_verbose("Receiving message!\n");
14480       receive_message(p, req);
14481    } else
14482       transmit_response(p, "202 Accepted", req);
14483    return 1;
14484 }

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

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

Referenced by handle_request().

13027 {
13028    /* This is mostly a skeleton for future improvements */
13029    /* Mostly created to return proper answers on notifications on outbound REFER's */
13030    int res = 0;
13031    const char *event = get_header(req, "Event");
13032    char *eventid = NULL;
13033    char *sep;
13034 
13035    if( (sep = strchr(event, ';')) ) {  /* XXX bug here - overwriting string ? */
13036       *sep++ = '\0';
13037       eventid = sep;
13038    }
13039    
13040    if (option_debug > 1 && sipdebug)
13041       ast_log(LOG_DEBUG, "Got NOTIFY Event: %s\n", event);
13042 
13043    if (strcmp(event, "refer")) {
13044       /* We don't understand this event. */
13045       /* Here's room to implement incoming voicemail notifications :-) */
13046       transmit_response(p, "489 Bad event", req);
13047       res = -1;
13048    } else {
13049       /* Save nesting depth for now, since there might be other events we will
13050          support in the future */
13051 
13052       /* Handle REFER notifications */
13053 
13054       char buf[1024];
13055       char *cmd, *code;
13056       int respcode;
13057       int success = TRUE;
13058 
13059       /* EventID for each transfer... EventID is basically the REFER cseq 
13060 
13061        We are getting notifications on a call that we transfered
13062        We should hangup when we are getting a 200 OK in a sipfrag
13063        Check if we have an owner of this event */
13064       
13065       /* Check the content type */
13066       if (strncasecmp(get_header(req, "Content-Type"), "message/sipfrag", strlen("message/sipfrag"))) {
13067          /* We need a sipfrag */
13068          transmit_response(p, "400 Bad request", req);
13069          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
13070          return -1;
13071       }
13072 
13073       /* Get the text of the attachment */
13074       if (get_msg_text(buf, sizeof(buf), req)) {
13075          ast_log(LOG_WARNING, "Unable to retrieve attachment from NOTIFY %s\n", p->callid);
13076          transmit_response(p, "400 Bad request", req);
13077          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
13078          return -1;
13079       }
13080 
13081       /*
13082       From the RFC...
13083       A minimal, but complete, implementation can respond with a single
13084          NOTIFY containing either the body:
13085                SIP/2.0 100 Trying
13086       
13087          if the subscription is pending, the body:
13088                SIP/2.0 200 OK
13089          if the reference was successful, the body:
13090                SIP/2.0 503 Service Unavailable
13091          if the reference failed, or the body:
13092                SIP/2.0 603 Declined
13093 
13094          if the REFER request was accepted before approval to follow the
13095          reference could be obtained and that approval was subsequently denied
13096          (see Section 2.4.7).
13097       
13098       If there are several REFERs in the same dialog, we need to
13099       match the ID of the event header...
13100       */
13101       if (option_debug > 2)
13102          ast_log(LOG_DEBUG, "* SIP Transfer NOTIFY Attachment: \n---%s\n---\n", buf);
13103       cmd = ast_skip_blanks(buf);
13104       code = cmd;
13105       /* We are at SIP/2.0 */
13106       while(*code && (*code > 32)) {   /* Search white space */
13107          code++;
13108       }
13109       *code++ = '\0';
13110       code = ast_skip_blanks(code);
13111       sep = code;
13112       sep++;
13113       while(*sep && (*sep > 32)) {  /* Search white space */
13114          sep++;
13115       }
13116       *sep++ = '\0';       /* Response string */
13117       respcode = atoi(code);
13118       switch (respcode) {
13119       case 100:   /* Trying: */
13120       case 101:   /* dialog establishment */
13121          /* Don't do anything yet */
13122          break;
13123       case 183:   /* Ringing: */
13124          /* Don't do anything yet */
13125          break;
13126       case 200:   /* OK: The new call is up, hangup this call */
13127          /* Hangup the call that we are replacing */
13128          break;
13129       case 301: /* Moved permenantly */
13130       case 302: /* Moved temporarily */
13131          /* Do we get the header in the packet in this case? */
13132          success = FALSE;
13133          break;
13134       case 503:   /* Service Unavailable: The new call failed */
13135             /* Cancel transfer, continue the call */
13136          success = FALSE;
13137          break;
13138       case 603:   /* Declined: Not accepted */
13139             /* Cancel transfer, continue the current call */
13140          success = FALSE;
13141          break;
13142       }
13143       if (!success) {
13144          ast_log(LOG_NOTICE, "Transfer failed. Sorry. Nothing further to do with this call\n");
13145       }
13146       
13147       /* Confirm that we received this packet */
13148       transmit_response(p, "200 OK", req);
13149    };
13150 
13151    if (!p->lastinvite)
13152       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
13153 
13154    return res;
13155 }

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

Handle incoming OPTIONS request.

Definition at line 13158 of file chan_sip.c.

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

13159 {
13160    int res;
13161 
13162    res = get_destination(p, req);
13163    build_contact(p);
13164    /* XXX Should we authenticate OPTIONS? XXX */
13165    if (ast_strlen_zero(p->context))
13166       ast_string_field_set(p, context, default_context);
13167    if (res < 0)
13168       transmit_response_with_allow(p, "404 Not Found", req, 0);
13169    else 
13170       transmit_response_with_allow(p, "200 OK", req, 0);
13171    /* Destroy if this OPTIONS was the opening request, but not if
13172       it's in the middle of a normal call flow. */
13173    if (!p->lastinvite)
13174       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
13175 
13176    return res;
13177 }

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

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

Referenced by handle_request().

14032 {
14033    struct sip_dual current;   /* Chan1: Call between asterisk and transferer */
14034                /* Chan2: Call between asterisk and transferee */
14035 
14036    int res = 0;
14037 
14038    if (ast_test_flag(req, SIP_PKT_DEBUG))
14039       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");
14040 
14041    if (!p->owner) {
14042       /* This is a REFER outside of an existing SIP dialog */
14043       /* We can't handle that, so decline it */
14044       if (option_debug > 2)
14045          ast_log(LOG_DEBUG, "Call %s: Declined REFER, outside of dialog...\n", p->callid);
14046       transmit_response(p, "603 Declined (No dialog)", req);
14047       if (!ast_test_flag(req, SIP_PKT_IGNORE)) {
14048          append_history(p, "Xfer", "Refer failed. Outside of dialog.");
14049          sip_alreadygone(p);
14050          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
14051       }
14052       return 0;
14053    }  
14054 
14055 
14056    /* Check if transfer is allowed from this device */
14057    if (p->allowtransfer == TRANSFER_CLOSED ) {
14058       /* Transfer not allowed, decline */
14059       transmit_response(p, "603 Declined (policy)", req);
14060       append_history(p, "Xfer", "Refer failed. Allowtransfer == closed.");
14061       /* Do not destroy SIP session */
14062       return 0;
14063    }
14064 
14065    if(!ignore && ast_test_flag(&p->flags[0], SIP_GOTREFER)) {
14066       /* Already have a pending REFER */  
14067       transmit_response(p, "491 Request pending", req);
14068       append_history(p, "Xfer", "Refer failed. Request pending.");
14069       return 0;
14070    }
14071 
14072    /* Allocate memory for call transfer data */
14073    if (!p->refer && !sip_refer_allocate(p)) {
14074       transmit_response(p, "500 Internal Server Error", req);
14075       append_history(p, "Xfer", "Refer failed. Memory allocation error.");
14076       return -3;
14077    }
14078 
14079    res = get_refer_info(p, req); /* Extract headers */
14080 
14081    p->refer->status = REFER_SENT;
14082 
14083    if (res != 0) {
14084       switch (res) {
14085       case -2: /* Syntax error */
14086          transmit_response(p, "400 Bad Request (Refer-to missing)", req);
14087          append_history(p, "Xfer", "Refer failed. Refer-to missing.");
14088          if (ast_test_flag(req, SIP_PKT_DEBUG) && option_debug)
14089             ast_log(LOG_DEBUG, "SIP transfer to black hole can't be handled (no refer-to: )\n");
14090          break;
14091       case -3:
14092          transmit_response(p, "603 Declined (Non sip: uri)", req);
14093          append_history(p, "Xfer", "Refer failed. Non SIP uri");
14094          if (ast_test_flag(req, SIP_PKT_DEBUG) && option_debug)
14095             ast_log(LOG_DEBUG, "SIP transfer to non-SIP uri denied\n");
14096          break;
14097       default:
14098          /* Refer-to extension not found, fake a failed transfer */
14099          transmit_response(p, "202 Accepted", req);
14100          append_history(p, "Xfer", "Refer failed. Bad extension.");
14101          transmit_notify_with_sipfrag(p, seqno, "404 Not found", TRUE);
14102          ast_clear_flag(&p->flags[0], SIP_GOTREFER);  
14103          if (ast_test_flag(req, SIP_PKT_DEBUG) && option_debug)
14104             ast_log(LOG_DEBUG, "SIP transfer to bad extension: %s\n", p->refer->refer_to);
14105          break;
14106       } 
14107       return 0;
14108    }
14109    if (ast_strlen_zero(p->context))
14110       ast_string_field_set(p, context, default_context);
14111 
14112    /* If we do not support SIP domains, all transfers are local */
14113    if (allow_external_domains && check_sip_domain(p->refer->refer_to_domain, NULL, 0)) {
14114       p->refer->localtransfer = 1;
14115       if (sipdebug && option_debug > 2)
14116          ast_log(LOG_DEBUG, "This SIP transfer is local : %s\n", p->refer->refer_to_domain);
14117    } else if (AST_LIST_EMPTY(&domain_list)) {
14118       /* This PBX don't bother with SIP domains, so all transfers are local */
14119       p->refer->localtransfer = 1;
14120    } else
14121       if (sipdebug && option_debug > 2)
14122          ast_log(LOG_DEBUG, "This SIP transfer is to a remote SIP extension (remote domain %s)\n", p->refer->refer_to_domain);
14123    
14124    /* Is this a repeat of a current request? Ignore it */
14125    /* Don't know what else to do right now. */
14126    if (ignore) 
14127       return res;
14128 
14129    /* If this is a blind transfer, we have the following
14130       channels to work with:
14131       - chan1, chan2: The current call between transferer and transferee (2 channels)
14132       - target_channel: A new call from the transferee to the target (1 channel)
14133       We need to stay tuned to what happens in order to be able
14134       to bring back the call to the transferer */
14135 
14136    /* If this is a attended transfer, we should have all call legs within reach:
14137       - chan1, chan2: The call between the transferer and transferee (2 channels)
14138       - target_channel, targetcall_pvt: The call between the transferer and the target (2 channels)
14139    We want to bridge chan2 with targetcall_pvt!
14140    
14141       The replaces call id in the refer message points
14142       to the call leg between Asterisk and the transferer.
14143       So we need to connect the target and the transferee channel
14144       and hangup the two other channels silently 
14145    
14146       If the target is non-local, the call ID could be on a remote
14147       machine and we need to send an INVITE with replaces to the
14148       target. We basically handle this as a blind transfer
14149       and let the sip_call function catch that we need replaces
14150       header in the INVITE.
14151    */
14152 
14153 
14154    /* Get the transferer's channel */
14155    current.chan1 = p->owner;
14156 
14157    /* Find the other part of the bridge (2) - transferee */
14158    current.chan2 = ast_bridged_channel(current.chan1);
14159    
14160    if (sipdebug && option_debug > 2)
14161       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>");
14162 
14163    if (!current.chan2 && !p->refer->attendedtransfer) {
14164       /* No bridged channel, propably IVR or echo or similar... */
14165       /* Guess we should masquerade or something here */
14166       /* Until we figure it out, refuse transfer of such calls */
14167       if (sipdebug && option_debug > 2)
14168          ast_log(LOG_DEBUG,"Refused SIP transfer on non-bridged channel.\n");
14169       p->refer->status = REFER_FAILED;
14170       append_history(p, "Xfer", "Refer failed. Non-bridged channel.");
14171       transmit_response(p, "603 Declined", req);
14172       return -1;
14173    }
14174 
14175    if (current.chan2) {
14176       if (sipdebug && option_debug > 3)
14177          ast_log(LOG_DEBUG, "Got SIP transfer, applying to bridged peer '%s'\n", current.chan2->name);
14178 
14179       ast_queue_control(current.chan1, AST_CONTROL_UNHOLD);
14180    }
14181 
14182    ast_set_flag(&p->flags[0], SIP_GOTREFER); 
14183 
14184    /* Attended transfer: Find all call legs and bridge transferee with target*/
14185    if (p->refer->attendedtransfer) {
14186       if ((res = local_attended_transfer(p, &current, req, seqno)))
14187          return res; /* We're done with the transfer */
14188       /* Fall through for remote transfers that we did not find locally */
14189       if (sipdebug && option_debug > 3)
14190          ast_log(LOG_DEBUG, "SIP attended transfer: Still not our call - generating INVITE with replaces\n");
14191       /* Fallthrough if we can't find the call leg internally */
14192    }
14193 
14194 
14195    /* Parking a call */
14196    if (p->refer->localtransfer && !strcmp(p->refer->refer_to, ast_parking_ext())) {
14197       /* Must release c's lock now, because it will not longer be accessible after the transfer! */
14198       *nounlock = 1;
14199       ast_channel_unlock(current.chan1);
14200       copy_request(&current.req, req);
14201       ast_clear_flag(&p->flags[0], SIP_GOTREFER);  
14202       p->refer->status = REFER_200OK;
14203       append_history(p, "Xfer", "REFER to call parking.");
14204       if (sipdebug && option_debug > 3)
14205          ast_log(LOG_DEBUG, "SIP transfer to parking: trying to park %s. Parked by %s\n", current.chan2->name, current.chan1->name);
14206       sip_park(current.chan2, current.chan1, req, seqno);
14207       return res;
14208    } 
14209 
14210    /* Blind transfers and remote attended xfers */
14211    transmit_response(p, "202 Accepted", req);
14212 
14213    if (current.chan1 && current.chan2) {
14214       if (option_debug > 2)
14215          ast_log(LOG_DEBUG, "chan1->name: %s\n", current.chan1->name);
14216       pbx_builtin_setvar_helper(current.chan1, "BLINDTRANSFER", current.chan2->name);
14217    }
14218    if (current.chan2) {
14219       pbx_builtin_setvar_helper(current.chan2, "BLINDTRANSFER", current.chan1->name);
14220       pbx_builtin_setvar_helper(current.chan2, "SIPDOMAIN", p->refer->refer_to_domain);
14221       pbx_builtin_setvar_helper(current.chan2, "SIPTRANSFER", "yes");
14222       /* One for the new channel */
14223       pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER", "yes");
14224       /* Attended transfer to remote host, prepare headers for the INVITE */
14225       if (p->refer->referred_by) 
14226          pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER_REFERER", p->refer->referred_by);
14227    }
14228    /* Generate a Replaces string to be used in the INVITE during attended transfer */
14229    if (p->refer->replaces_callid && !ast_strlen_zero(p->refer->replaces_callid)) {
14230       char tempheader[BUFSIZ];
14231       snprintf(tempheader, sizeof(tempheader), "%s%s%s%s%s", p->refer->replaces_callid, 
14232             p->refer->replaces_callid_totag ? ";to-tag=" : "", 
14233             p->refer->replaces_callid_totag, 
14234             p->refer->replaces_callid_fromtag ? ";from-tag=" : "",
14235             p->refer->replaces_callid_fromtag);
14236       if (current.chan2)
14237          pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER_REPLACES", tempheader);
14238    }
14239    /* Must release lock now, because it will not longer
14240          be accessible after the transfer! */
14241    *nounlock = 1;
14242    ast_channel_unlock(current.chan1);
14243 
14244    /* Connect the call */
14245 
14246    /* FAKE ringing if not attended transfer */
14247    if (!p->refer->attendedtransfer)
14248       transmit_notify_with_sipfrag(p, seqno, "183 Ringing", FALSE); 
14249       
14250    /* For blind transfer, this will lead to a new call */
14251    /* For attended transfer to remote host, this will lead to
14252          a new SIP call with a replaces header, if the dial plan allows it 
14253    */
14254    if (!current.chan2) {
14255       /* We have no bridge, so we're talking with Asterisk somehow */
14256       /* We need to masquerade this call */
14257       /* What to do to fix this situation:
14258          * Set up the new call in a new channel 
14259          * Let the new channel masq into this channel
14260          Please add that code here :-)
14261       */
14262       p->refer->status = REFER_FAILED;
14263       transmit_notify_with_sipfrag(p, seqno, "503 Service Unavailable (can't handle one-legged xfers)", TRUE);
14264       ast_clear_flag(&p->flags[0], SIP_GOTREFER);  
14265       append_history(p, "Xfer", "Refer failed (only bridged calls).");
14266       return -1;
14267    }
14268    ast_set_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER);   /* Delay hangup */
14269 
14270    /* For blind transfers, move the call to the new extensions. For attended transfers on multiple
14271       servers - generate an INVITE with Replaces. Either way, let the dial plan decided  */
14272    res = ast_async_goto(current.chan2, p->refer->refer_to_context, p->refer->refer_to, 1);
14273 
14274    if (!res) {
14275       /* Success  - we have a new channel */
14276       if (option_debug > 2)
14277          ast_log(LOG_DEBUG, "%s transfer succeeded. Telling transferer.\n", p->refer->attendedtransfer? "Attended" : "Blind");
14278       transmit_notify_with_sipfrag(p, seqno, "200 Ok", TRUE);
14279       if (p->refer->localtransfer)
14280          p->refer->status = REFER_200OK;
14281       if (p->owner)
14282          p->owner->hangupcause = AST_CAUSE_NORMAL_CLEARING;
14283       append_history(p, "Xfer", "Refer succeeded.");
14284       ast_clear_flag(&p->flags[0], SIP_GOTREFER);  
14285       /* Do not hangup call, the other side do that when we say 200 OK */
14286       /* We could possibly implement a timer here, auto congestion */
14287       res = 0;
14288    } else {
14289       ast_clear_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Don't delay hangup */
14290       if (option_debug > 2)
14291          ast_log(LOG_DEBUG, "%s transfer failed. Resuming original call.\n", p->refer->attendedtransfer? "Attended" : "Blind");
14292       append_history(p, "Xfer", "Refer failed.");
14293       /* Failure of some kind */
14294       p->refer->status = REFER_FAILED;
14295       transmit_notify_with_sipfrag(p, seqno, "503 Service Unavailable", TRUE);
14296       ast_clear_flag(&p->flags[0], SIP_GOTREFER);  
14297       res = -1;
14298    }
14299    return res;
14300 }

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

14782 {
14783    enum check_auth_result res;
14784 
14785    /* Use this as the basis */
14786    if (ast_test_flag(req, SIP_PKT_DEBUG))
14787       ast_verbose("Using latest REGISTER request as basis request\n");
14788    copy_request(&p->initreq, req);
14789    check_via(p, req);
14790    if ((res = register_verify(p, sin, req, e)) < 0) {
14791       const char *reason;
14792 
14793       switch (res) {
14794       case AUTH_SECRET_FAILED:
14795          reason = "Wrong password";
14796          break;
14797       case AUTH_USERNAME_MISMATCH:
14798          reason = "Username/auth name mismatch";
14799          break;
14800       case AUTH_NOT_FOUND:
14801          reason = "No matching peer found";
14802          break;
14803       case AUTH_UNKNOWN_DOMAIN:
14804          reason = "Not a local domain";
14805          break;
14806       case AUTH_PEER_NOT_DYNAMIC:
14807          reason = "Peer is not supposed to register";
14808          break;
14809       case AUTH_ACL_FAILED:
14810          reason = "Device does not match ACL";
14811          break;
14812       default:
14813          reason = "Unknown failure";
14814          break;
14815       }
14816       ast_log(LOG_NOTICE, "Registration from '%s' failed for '%s' - %s\n",
14817          get_header(req, "To"), ast_inet_ntoa(sin->sin_addr),
14818          reason);
14819       append_history(p, "RegRequest", "Failed : Account %s : %s", get_header(req, "To"), reason);
14820    } else
14821       append_history(p, "RegRequest", "Succeeded : Account %s", get_header(req, "To"));
14822 
14823    if (res < 1) {
14824       /* Destroy the session, but keep us around for just a bit in case they don't
14825          get our 200 OK */
14826       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
14827    }
14828    return res;
14829 }

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 14487 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_string_field_set, ast_strlen_zero(), ast_test_flag, ast_verbose(), ASTOBJ_UNLOCK, ASTOBJ_UNREF, ASTOBJ_WRLOCK, AUTH_CHALLENGE_SENT, AUTH_FAKE_AUTH, sip_pvt::autokillid, build_contact(), cb_extensionstate(), check_user_full(), check_via(), context, copy_request(), CPIM_PIDF_XML, DIALOG_INFO_XML, sip_pvt::dialogver, event, sip_pvt::expiry, FALSE, sip_pvt::flags, get_destination(), get_header(), sip_request::headers, iflist, sip_pvt::initreq, sip_pvt::lastinvite, sip_pvt::laststate, sip_pvt::lock, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, sip_peer::mailbox, make_our_tag(), sip_request::method, MWI_NOTIFICATION, sip_peer::mwipvt, sip_pvt::next, NONE, option_debug, parse_ok_contact(), PIDF_XML, sip_pvt::relatedpeer, sip_pvt::sa, sip_cancel_destroy(), sip_destroy(), sip_destroy_peer(), sip_methods, SIP_NEEDDESTROY, SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PKT_DEBUG, SIP_PKT_IGNORE, sip_scheddestroy(), sip_send_mwi_to_peer(), SIP_SUBSCRIBE, sipdebug, sip_pvt::stateid, sip_pvt::subscribed, sip_pvt::tag, cfsip_methods::text, transmit_fake_auth_response(), transmit_response(), transmit_response_reliable(), transmit_state_notify(), and XPIDF_XML.

Referenced by handle_request().

14488 {
14489    int gotdest;
14490    int res = 0;
14491    int firststate = AST_EXTENSION_REMOVED;
14492    struct sip_peer *authpeer = NULL;
14493    const char *eventheader = get_header(req, "Event");   /* Get Event package name */
14494    const char *accept = get_header(req, "Accept");
14495    int resubscribe = (p->subscribed != NONE);
14496    char *temp, *event;
14497 
14498    if (p->initreq.headers) {  
14499       /* We already have a dialog */
14500       if (p->initreq.method != SIP_SUBSCRIBE) {
14501          /* This is a SUBSCRIBE within another SIP dialog, which we do not support */
14502          /* For transfers, this could happen, but since we haven't seen it happening, let us just refuse this */
14503          transmit_response(p, "403 Forbidden (within dialog)", req);
14504          /* Do not destroy session, since we will break the call if we do */
14505          if (option_debug)
14506             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);
14507          return 0;
14508       } else if (ast_test_flag(req, SIP_PKT_DEBUG)) {
14509          if (option_debug) {
14510             if (resubscribe)
14511                ast_log(LOG_DEBUG, "Got a re-subscribe on existing subscription %s\n", p->callid);
14512             else
14513                ast_log(LOG_DEBUG, "Got a new subscription %s (possibly with auth)\n", p->callid);
14514          }
14515       }
14516    }
14517 
14518    /* Check if we have a global disallow setting on subscriptions. 
14519       if so, we don't have to check peer/user settings after auth, which saves a lot of processing
14520    */
14521    if (!global_allowsubscribe) {
14522       transmit_response(p, "403 Forbidden (policy)", req);
14523       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
14524       return 0;
14525    }
14526 
14527    if (!ast_test_flag(req, SIP_PKT_IGNORE) && !resubscribe) {  /* Set up dialog, new subscription */
14528       /* Use this as the basis */
14529       if (ast_test_flag(req, SIP_PKT_DEBUG))
14530          ast_verbose("Creating new subscription\n");
14531 
14532       copy_request(&p->initreq, req);
14533       check_via(p, req);
14534    } else if (ast_test_flag(req, SIP_PKT_DEBUG) && ast_test_flag(req, SIP_PKT_IGNORE))
14535       ast_verbose("Ignoring this SUBSCRIBE request\n");
14536 
14537    /* Find parameters to Event: header value and remove them for now */
14538    if (ast_strlen_zero(eventheader)) {
14539       transmit_response(p, "489 Bad Event", req);
14540       if (option_debug > 1)
14541          ast_log(LOG_DEBUG, "Received SIP subscribe for unknown event package: <none>\n");
14542       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
14543       return 0;
14544    }
14545 
14546    if ( (strchr(eventheader, ';'))) {
14547       event = ast_strdupa(eventheader);   /* Since eventheader is a const, we can't change it */
14548       temp = strchr(event, ';');       
14549       *temp = '\0';           /* Remove any options for now */
14550                      /* We might need to use them later :-) */
14551    } else
14552       event = (char *) eventheader;    /* XXX is this legal ? */
14553 
14554    /* Handle authentication */
14555    res = check_user_full(p, req, SIP_SUBSCRIBE, e, 0, sin, &authpeer);
14556    /* if an authentication response was sent, we are done here */
14557    if (res == AUTH_CHALLENGE_SENT) {
14558       if (authpeer)
14559          ASTOBJ_UNREF(authpeer, sip_destroy_peer);
14560       return 0;
14561    }
14562    if (res < 0) {
14563       if (res == AUTH_FAKE_AUTH) {
14564          ast_log(LOG_NOTICE, "Sending fake auth rejection for user %s\n", get_header(req, "From"));
14565          transmit_fake_auth_response(p, req, 1);
14566       } else {
14567          ast_log(LOG_NOTICE, "Failed to authenticate user %s for SUBSCRIBE\n", get_header(req, "From"));
14568          transmit_response_reliable(p, "403 Forbidden", req);
14569       }
14570       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
14571       if (authpeer)
14572          ASTOBJ_UNREF(authpeer, sip_destroy_peer);
14573       return 0;
14574    }
14575 
14576    /* Check if this user/peer is allowed to subscribe at all */
14577    if (!ast_test_flag(&p->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)) {
14578       transmit_response(p, "403 Forbidden (policy)", req);
14579       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
14580       if (authpeer)
14581          ASTOBJ_UNREF(authpeer, sip_destroy_peer);
14582       return 0;
14583    }
14584 
14585    /* Get destination right away */
14586    gotdest = get_destination(p, NULL);
14587 
14588    /* Initialize the context if it hasn't been already;
14589       note this is done _after_ handling any domain lookups,
14590       because the context specified there is for calls, not
14591       subscriptions
14592    */
14593    if (!ast_strlen_zero(p->subscribecontext))
14594       ast_string_field_set(p, context, p->subscribecontext);
14595    else if (ast_strlen_zero(p->context))
14596       ast_string_field_set(p, context, default_context);
14597 
14598    /* Get full contact header - this needs to be used as a request URI in NOTIFY's */
14599    parse_ok_contact(p, req);
14600 
14601    build_contact(p);
14602    if (gotdest) {
14603       transmit_response(p, "404 Not Found", req);
14604       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
14605       if (authpeer)
14606          ASTOBJ_UNREF(authpeer, sip_destroy_peer);
14607       return 0;
14608    }
14609 
14610    /* Initialize tag for new subscriptions */   
14611    if (ast_strlen_zero(p->tag))
14612       make_our_tag(p->tag, sizeof(p->tag));
14613 
14614    if (!strcmp(event, "presence") || !strcmp(event, "dialog")) { /* Presence, RFC 3842 */
14615       if (authpeer)  /* No need for authpeer here */
14616          ASTOBJ_UNREF(authpeer, sip_destroy_peer);
14617 
14618       /* Header from Xten Eye-beam Accept: multipart/related, application/rlmi+xml, application/pidf+xml, application/xpidf+xml */
14619       /* Polycom phones only handle xpidf+xml, even if they say they can
14620          handle pidf+xml as well
14621       */
14622       if (strstr(p->useragent, "Polycom")) {
14623          p->subscribed = XPIDF_XML;
14624       } else if (strstr(accept, "application/pidf+xml")) {
14625          p->subscribed = PIDF_XML;         /* RFC 3863 format */
14626       } else if (strstr(accept, "application/dialog-info+xml")) {
14627          p->subscribed = DIALOG_INFO_XML;
14628          /* IETF draft: draft-ietf-sipping-dialog-package-05.txt */
14629       } else if (strstr(accept, "application/cpim-pidf+xml")) {
14630          p->subscribed = CPIM_PIDF_XML;    /* RFC 3863 format */
14631       } else if (strstr(accept, "application/xpidf+xml")) {
14632          p->subscribed = XPIDF_XML;        /* Early pre-RFC 3863 format with MSN additions (Microsoft Messenger) */
14633       } else if (ast_strlen_zero(accept)) {
14634          if (p->subscribed == NONE) { /* if the subscribed field is not already set, and there is no accept header... */
14635             transmit_response(p, "489 Bad Event", req);
14636   
14637             ast_log(LOG_WARNING,"SUBSCRIBE failure: no Accept header: pvt: stateid: %d, laststate: %d, dialogver: %d, subscribecont: '%s', subscribeuri: '%s'\n",
14638                p->stateid, p->laststate, p->dialogver, p->subscribecontext, p->subscribeuri);
14639             ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
14640             return 0;
14641          }
14642          /* if p->subscribed is non-zero, then accept is not obligatory; according to rfc 3265 section 3.1.3, at least.
14643             so, we'll just let it ride, keeping the value from a previous subscription, and not abort the subscription */
14644       } else {
14645          /* Can't find a format for events that we know about */
14646          char mybuf[200];
14647          snprintf(mybuf,sizeof(mybuf),"489 Bad Event (format %s)", accept);
14648          transmit_response(p, mybuf, req);
14649  
14650          ast_log(LOG_WARNING,"SUBSCRIBE failure: unrecognized format: '%s' pvt: subscribed: %d, stateid: %d, laststate: %d, dialogver: %d, subscribecont: '%s', subscribeuri: '%s'\n",
14651             accept, (int)p->subscribed, p->stateid, p->laststate, p->dialogver, p->subscribecontext, p->subscribeuri);
14652          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
14653          return 0;
14654       }
14655    } else if (!strcmp(event, "message-summary")) { 
14656       if (!ast_strlen_zero(accept) && strcmp(accept, "application/simple-message-summary")) {
14657          /* Format requested that we do not support */
14658          transmit_response(p, "406 Not Acceptable", req);
14659          if (option_debug > 1)
14660             ast_log(LOG_DEBUG, "Received SIP mailbox subscription for unknown format: %s\n", accept);
14661          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
14662          if (authpeer)  /* No need for authpeer here */
14663             ASTOBJ_UNREF(authpeer, sip_destroy_peer);
14664          return 0;
14665       }
14666       /* Looks like they actually want a mailbox status 
14667         This version of Asterisk supports mailbox subscriptions
14668         The subscribed URI needs to exist in the dial plan
14669         In most devices, this is configurable to the voicemailmain extension you use
14670       */
14671       if (!authpeer || ast_strlen_zero(authpeer->mailbox)) {
14672          transmit_response(p, "404 Not found (no mailbox)", req);
14673          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
14674          ast_log(LOG_NOTICE, "Received SIP subscribe for peer without mailbox: %s\n", authpeer->name);
14675          if (authpeer)  /* No need for authpeer here */
14676             ASTOBJ_UNREF(authpeer, sip_destroy_peer);
14677          return 0;
14678       }
14679 
14680       p->subscribed = MWI_NOTIFICATION;
14681       if (authpeer->mwipvt && authpeer->mwipvt != p)  /* Destroy old PVT if this is a new one */
14682          /* We only allow one subscription per peer */
14683          sip_destroy(authpeer->mwipvt);
14684       authpeer->mwipvt = p;      /* Link from peer to pvt */
14685       p->relatedpeer = authpeer; /* Link from pvt to peer */
14686    } else { /* At this point, Asterisk does not understand the specified event */
14687       transmit_response(p, "489 Bad Event", req);
14688       if (option_debug > 1)
14689          ast_log(LOG_DEBUG, "Received SIP subscribe for unknown event package: %s\n", event);
14690       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
14691       if (authpeer)  /* No need for authpeer here */
14692          ASTOBJ_UNREF(authpeer, sip_destroy_peer);
14693       return 0;
14694    }
14695 
14696    if (p->subscribed != MWI_NOTIFICATION && !resubscribe) {
14697       if (p->stateid > -1)
14698          ast_extension_state_del(p->stateid, cb_extensionstate);
14699       p->stateid = ast_extension_state_add(p->context, p->exten, cb_extensionstate, p);
14700    }
14701 
14702    if (!ast_test_flag(req, SIP_PKT_IGNORE) && p)
14703       p->lastinvite = seqno;
14704    if (p && !ast_test_flag(&p->flags[0], SIP_NEEDDESTROY)) {
14705       p->expiry = atoi(get_header(req, "Expires"));
14706 
14707       /* check if the requested expiry-time is within the approved limits from sip.conf */
14708       if (p->expiry > max_expiry)
14709          p->expiry = max_expiry;
14710       if (p->expiry < min_expiry && p->expiry > 0)
14711          p->expiry = min_expiry;
14712 
14713       if (sipdebug || option_debug > 1) {
14714          if (p->subscribed == MWI_NOTIFICATION && p->relatedpeer)
14715             ast_log(LOG_DEBUG, "Adding subscription for mailbox notification - peer %s Mailbox %s\n", p->relatedpeer->name, p->relatedpeer->mailbox);
14716          else
14717             ast_log(LOG_DEBUG, "Adding subscription for extension %s context %s for peer %s\n", p->exten, p->context, p->username);
14718       }
14719       if (p->autokillid > -1)
14720          sip_cancel_destroy(p);  /* Remove subscription expiry for renewals */
14721       if (p->expiry > 0)
14722          sip_scheddestroy(p, (p->expiry + 10) * 1000);   /* Set timer for destruction of call at expiration */
14723 
14724       if (p->subscribed == MWI_NOTIFICATION) {
14725          transmit_response(p, "200 OK", req);
14726          if (p->relatedpeer) {   /* Send first notification */
14727             ASTOBJ_WRLOCK(p->relatedpeer);
14728             sip_send_mwi_to_peer(p->relatedpeer);
14729             ASTOBJ_UNLOCK(p->relatedpeer);
14730          }
14731       } else {
14732          struct sip_pvt *p_old;
14733 
14734          if ((firststate = ast_extension_state(NULL, p->context, p->exten)) < 0) {
14735 
14736             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));
14737             transmit_response(p, "404 Not found", req);
14738             ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
14739             return 0;
14740          }
14741 
14742          transmit_response(p, "200 OK", req);
14743          transmit_state_notify(p, firststate, 1, FALSE); /* Send first notification */
14744          append_history(p, "Subscribestatus", "%s", ast_extension_state2str(firststate));
14745          /* hide the 'complete' exten/context in the refer_to field for later display */
14746          ast_string_field_build(p, subscribeuri, "%s@%s", p->exten, p->context);
14747 
14748          /* remove any old subscription from this peer for the same exten/context,
14749          as the peer has obviously forgotten about it and it's wasteful to wait
14750          for it to expire and send NOTIFY messages to the peer only to have them
14751          ignored (or generate errors)
14752          */
14753          ast_mutex_lock(&iflock);
14754          for (p_old = iflist; p_old; p_old = p_old->next) {
14755             if (p_old == p)
14756                continue;
14757             if (p_old->initreq.method != SIP_SUBSCRIBE)
14758                continue;
14759             if (p_old->subscribed == NONE)
14760                continue;
14761             ast_mutex_lock(&p_old->lock);
14762             if (!strcmp(p_old->username, p->username)) {
14763                if (!strcmp(p_old->exten, p->exten) &&
14764                    !strcmp(p_old->context, p->context)) {
14765                   ast_set_flag(&p_old->flags[0], SIP_NEEDDESTROY);
14766                   ast_mutex_unlock(&p_old->lock);
14767                   break;
14768                }
14769             }
14770             ast_mutex_unlock(&p_old->lock);
14771          }
14772          ast_mutex_unlock(&iflock);
14773       }
14774       if (!p->expiry)
14775          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
14776    }
14777    return 1;
14778 }

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

References __sip_ack(), __sip_semi_ack(), AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_PROGRESS, ast_inet_ntoa(), ast_log(), ast_queue_control(), ast_queue_hangup(), ast_set_flag, ast_string_field_build, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_verbose(), sip_pvt::authtries, do_proxy_auth(), FALSE, find_sdp(), find_sip_method(), sip_pvt::flags, get_header(), gettag(), handle_response_invite(), handle_response_peerpoke(), handle_response_refer(), handle_response_register(), hangup_sip2cause(), ast_channel::hangupcause, sip_pvt::initreq, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, MAX_AUTHTRIES, sip_pvt::method, NONE, option_debug, option_verbose, sip_pvt::owner, parse_moved_contact(), process_sdp(), sip_pvt::recv, sip_pvt::refer, sip_pvt::registry, sip_pvt::relatedpeer, sip_pvt::sa, SIP_ACK, sip_alreadygone(), SIP_BYE, SIP_CANCEL, sip_cancel_destroy(), SIP_INFO, SIP_INVITE, SIP_MESSAGE, sip_methods, SIP_NEEDDESTROY, SIP_NOTIFY, SIP_OPTIONS, SIP_OUTGOING, SIP_PKT_DEBUG, SIP_PKT_IGNORE, SIP_REFER, SIP_REGISTER, sipdebug, stop_media_flows(), sip_pvt::subscribed, text, transmit_request(), VERBOSE_PREFIX_3, and XMIT_UNRELIABLE.

12341 {
12342    struct ast_channel *owner;
12343    int sipmethod;
12344    int res = 1;
12345    const char *c = get_header(req, "Cseq");
12346    const char *msg = strchr(c, ' ');
12347 
12348    if (!msg)
12349       msg = "";
12350    else
12351       msg++;
12352    sipmethod = find_sip_method(msg);
12353 
12354    owner = p->owner;
12355    if (owner) 
12356       owner->hangupcause = hangup_sip2cause(resp);
12357 
12358    /* Acknowledge whatever it is destined for */
12359    if ((resp >= 100) && (resp <= 199))
12360       __sip_semi_ack(p, seqno, 0, sipmethod);
12361    else
12362       __sip_ack(p, seqno, 0, sipmethod);
12363 
12364    /* Get their tag if we haven't already */
12365    if (ast_strlen_zero(p->theirtag) || (resp >= 200)) {
12366       char tag[128];
12367 
12368       gettag(req, "To", tag, sizeof(tag));
12369       ast_string_field_set(p, theirtag, tag);
12370    }
12371    if (p->relatedpeer && p->method == SIP_OPTIONS) {
12372       /* We don't really care what the response is, just that it replied back. 
12373          Well, as long as it's not a 100 response...  since we might
12374          need to hang around for something more "definitive" */
12375       if (resp != 100)
12376          handle_response_peerpoke(p, resp, req);
12377    } else if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
12378       switch(resp) {
12379       case 100:   /* 100 Trying */
12380       case 101:   /* 101 Dialog establishment */
12381          if (sipmethod == SIP_INVITE) 
12382             handle_response_invite(p, resp, rest, req, seqno);
12383          break;
12384       case 183:   /* 183 Session Progress */
12385          if (sipmethod == SIP_INVITE) 
12386             handle_response_invite(p, resp, rest, req, seqno);
12387          break;
12388       case 180:   /* 180 Ringing */
12389          if (sipmethod == SIP_INVITE) 
12390             handle_response_invite(p, resp, rest, req, seqno);
12391          break;
12392       case 200:   /* 200 OK */
12393          p->authtries = 0; /* Reset authentication counter */
12394          if (sipmethod == SIP_MESSAGE || sipmethod == SIP_INFO) {
12395             /* We successfully transmitted a message 
12396                or a video update request in INFO */
12397             /* Nothing happens here - the message is inside a dialog */
12398          } else if (sipmethod == SIP_INVITE) {
12399             handle_response_invite(p, resp, rest, req, seqno);
12400          } else if (sipmethod == SIP_NOTIFY) {
12401             /* They got the notify, this is the end */
12402             if (p->owner) {
12403                if (!p->refer) {
12404                   ast_log(LOG_WARNING, "Notify answer on an owned channel? - %s\n", p->owner->name);
12405                   ast_queue_hangup(p->owner);
12406                } else if (option_debug > 3) 
12407                   ast_log(LOG_DEBUG, "Got OK on REFER Notify message\n");
12408             } else {
12409                if (p->subscribed == NONE) 
12410                   ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12411             }
12412          } else if (sipmethod == SIP_REGISTER) 
12413             res = handle_response_register(p, resp, rest, req, ignore, seqno);
12414          else if (sipmethod == SIP_BYE)      /* Ok, we're ready to go */
12415             ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12416          break;
12417       case 202:   /* Transfer accepted */
12418          if (sipmethod == SIP_REFER) 
12419             handle_response_refer(p, resp, rest, req, seqno);
12420          break;
12421       case 401: /* Not www-authorized on SIP method */
12422          if (sipmethod == SIP_INVITE)
12423             handle_response_invite(p, resp, rest, req, seqno);
12424          else if (sipmethod == SIP_REFER)
12425             handle_response_refer(p, resp, rest, req, seqno);
12426          else if (p->registry && sipmethod == SIP_REGISTER)
12427             res = handle_response_register(p, resp, rest, req, ignore, seqno);
12428          else if (sipmethod == SIP_BYE) {
12429             if (ast_strlen_zero(p->authname)) {
12430                ast_log(LOG_WARNING, "Asked to authenticate %s, to %s:%d but we have no matching peer!\n",
12431                      msg, ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port));
12432                ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12433             } else if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, "WWW-Authenticate", "Authorization", sipmethod, 0)) {
12434                ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From"));
12435                ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12436                /* We fail to auth bye on our own call, but still needs to tear down the call. 
12437                   Life, they call it. */
12438             }
12439          } else {
12440             ast_log(LOG_WARNING, "Got authentication request (401) on unknown %s to '%s'\n", sip_methods[sipmethod].text, get_header(req, "To"));
12441             ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12442          }
12443          break;
12444       case 403: /* Forbidden - we failed authentication */
12445          if (sipmethod == SIP_INVITE)
12446             handle_response_invite(p, resp, rest, req, seqno);
12447          else if (p->registry && sipmethod == SIP_REGISTER) 
12448             res = handle_response_register(p, resp, rest, req, ignore, seqno);
12449          else {
12450             ast_log(LOG_WARNING, "Forbidden - maybe wrong password on authentication for %s\n", msg);
12451             ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12452          }
12453          break;
12454       case 404: /* Not found */
12455          if (p->registry && sipmethod == SIP_REGISTER)
12456             res = handle_response_register(p, resp, rest, req, ignore, seqno);
12457          else if (sipmethod == SIP_INVITE)
12458             handle_response_invite(p, resp, rest, req, seqno);
12459          else if (owner)
12460             ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
12461          break;
12462       case 407: /* Proxy auth required */
12463          if (sipmethod == SIP_INVITE)
12464             handle_response_invite(p, resp, rest, req, seqno);
12465          else if (sipmethod == SIP_REFER)
12466             handle_response_refer(p, resp, rest, req, seqno);
12467          else if (p->registry && sipmethod == SIP_REGISTER)
12468             res = handle_response_register(p, resp, rest, req, ignore, seqno);
12469          else if (sipmethod == SIP_BYE) {
12470             if (ast_strlen_zero(p->authname)) {
12471                ast_log(LOG_WARNING, "Asked to authenticate %s, to %s:%d but we have no matching peer!\n",
12472                      msg, ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port));
12473                ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12474             } else if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, "Proxy-Authenticate", "Proxy-Authorization", sipmethod, 0)) {
12475                ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From"));
12476                ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12477             }
12478          } else   /* We can't handle this, giving up in a bad way */
12479             ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12480 
12481          break;
12482       case 408: /* Request timeout - terminate dialog */
12483          if (sipmethod == SIP_INVITE)
12484             handle_response_invite(p, resp, rest, req, seqno);
12485          else if (sipmethod == SIP_REGISTER) 
12486             res = handle_response_register(p, resp, rest, req, ignore, seqno);
12487          else if (sipmethod == SIP_BYE) {
12488             ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12489             if (option_debug)
12490                ast_log(LOG_DEBUG, "Got timeout on bye. Thanks for the answer. Now, kill this call\n");
12491          } else {
12492             if (owner)
12493                ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
12494             ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12495          }
12496          break;
12497       case 481: /* Call leg does not exist */
12498          if (sipmethod == SIP_INVITE) {
12499             handle_response_invite(p, resp, rest, req, seqno);
12500          } else if (sipmethod == SIP_REFER) {
12501             handle_response_refer(p, resp, rest, req, seqno);
12502          } else if (sipmethod == SIP_BYE) {
12503             /* The other side has no transaction to bye,
12504             just assume it's all right then */
12505             ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid);
12506          } else if (sipmethod == SIP_CANCEL) {
12507             /* The other side has no transaction to cancel,
12508             just assume it's all right then */
12509             ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid);
12510          } else {
12511             ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid);
12512             /* Guessing that this is not an important request */
12513          }
12514          break;
12515       case 487:
12516          if (sipmethod == SIP_INVITE)
12517             handle_response_invite(p, resp, rest, req, seqno);
12518          break;
12519       case 488: /* Not acceptable here - codec error */
12520          if (sipmethod == SIP_INVITE)
12521             handle_response_invite(p, resp, rest, req, seqno);
12522          break;
12523       case 491: /* Pending */
12524          if (sipmethod == SIP_INVITE)
12525             handle_response_invite(p, resp, rest, req, seqno);
12526          else {
12527             if (option_debug)
12528                ast_log(LOG_DEBUG, "Got 491 on %s, unspported. Call ID %s\n", sip_methods[sipmethod].text, p->callid);
12529             ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12530          }
12531          break;
12532       case 501: /* Not Implemented */
12533          if (sipmethod == SIP_INVITE)
12534             handle_response_invite(p, resp, rest, req, seqno);
12535          else if (sipmethod == SIP_REFER)
12536             handle_response_refer(p, resp, rest, req, seqno);
12537          else
12538             ast_log(LOG_WARNING, "Host '%s' does not implement '%s'\n", ast_inet_ntoa(p->sa.sin_addr), msg);
12539          break;
12540       case 603:   /* Declined transfer */
12541          if (sipmethod == SIP_REFER) {
12542             handle_response_refer(p, resp, rest, req, seqno);
12543             break;
12544          }
12545          /* Fallthrough */
12546       default:
12547          if ((resp >= 300) && (resp < 700)) {
12548             /* Fatal response */
12549             if ((option_verbose > 2) && (resp != 487))
12550                ast_verbose(VERBOSE_PREFIX_3 "Got SIP response %d \"%s\" back from %s\n", resp, rest, ast_inet_ntoa(p->sa.sin_addr));
12551    
12552             if (sipmethod == SIP_INVITE)
12553                stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */
12554 
12555             /* XXX Locking issues?? XXX */
12556             switch(resp) {
12557             case 300: /* Multiple Choices */
12558             case 301: /* Moved permenantly */
12559             case 302: /* Moved temporarily */
12560             case 305: /* Use Proxy */
12561                parse_moved_contact(p, req);
12562                /* Fall through */
12563             case 486: /* Busy here */
12564             case 600: /* Busy everywhere */
12565             case 603: /* Decline */
12566                if (p->owner)
12567                   ast_queue_control(p->owner, AST_CONTROL_BUSY);
12568                break;
12569             case 482: /*
12570                \note SIP is incapable of performing a hairpin call, which
12571                is yet another failure of not having a layer 2 (again, YAY
12572                 IETF for thinking ahead).  So we treat this as a call
12573                 forward and hope we end up at the right place... */
12574                if (option_debug)
12575                   ast_log(LOG_DEBUG, "Hairpin detected, setting up call forward for what it's worth\n");
12576                if (p->owner)
12577                   ast_string_field_build(p->owner, call_forward,
12578                                "Local/%s@%s", p->username, p->context);
12579                /* Fall through */
12580             case 480: /* Temporarily Unavailable */
12581             case 404: /* Not Found */
12582             case 410: /* Gone */
12583             case 400: /* Bad Request */
12584             case 500: /* Server error */
12585                if (sipmethod == SIP_REFER) {
12586                   handle_response_refer(p, resp, rest, req, seqno);
12587                   break;
12588                }
12589                /* Fall through */
12590             case 503: /* Service Unavailable */
12591             case 504: /* Server Timeout */
12592                if (owner)
12593                   ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
12594                break;
12595             default:
12596                /* Send hangup */ 
12597                if (owner && sipmethod != SIP_MESSAGE && sipmethod != SIP_INFO && sipmethod != SIP_BYE)
12598                   ast_queue_hangup(p->owner);
12599                break;
12600             }
12601             /* ACK on invite */
12602             if (sipmethod == SIP_INVITE) 
12603                transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
12604             if (sipmethod != SIP_MESSAGE && sipmethod != SIP_INFO) 
12605                sip_alreadygone(p);
12606             if (!p->owner)
12607                ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12608          } else if ((resp >= 100) && (resp < 200)) {
12609             if (sipmethod == SIP_INVITE) {
12610                if (!ast_test_flag(req, SIP_PKT_IGNORE))
12611                   sip_cancel_destroy(p);
12612                if (find_sdp(req))
12613                   process_sdp(p, req);
12614                if (p->owner) {
12615                   /* Queue a progress frame */
12616                   ast_queue_control(p->owner, AST_CONTROL_PROGRESS);
12617                }
12618             }
12619          } else
12620             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));
12621       }
12622    } else { 
12623       /* Responses to OUTGOING SIP requests on INCOMING calls 
12624          get handled here. As well as out-of-call message responses */
12625       if (ast_test_flag(req, SIP_PKT_DEBUG))
12626          ast_verbose("SIP Response message for INCOMING dialog %s arrived\n", msg);
12627 
12628       if (sipmethod == SIP_INVITE && resp == 200) {
12629          /* Tags in early session is replaced by the tag in 200 OK, which is 
12630          the final reply to our INVITE */
12631          char tag[128];
12632 
12633          gettag(req, "To", tag, sizeof(tag));
12634          ast_string_field_set(p, theirtag, tag);
12635       }
12636 
12637       switch(resp) {
12638       case 200:
12639          if (sipmethod == SIP_INVITE) {
12640             handle_response_invite(p, resp, rest, req, seqno);
12641          } else if (sipmethod == SIP_CANCEL) {
12642             if (option_debug)
12643                ast_log(LOG_DEBUG, "Got 200 OK on CANCEL\n");
12644 
12645             /* Wait for 487, then destroy */
12646          } else if (sipmethod == SIP_NOTIFY) {
12647             /* They got the notify, this is the end */
12648             if (p->owner) {
12649                if (p->refer) {
12650                   if (option_debug)
12651                      ast_log(LOG_DEBUG, "Got 200 OK on NOTIFY for transfer\n");
12652                } else
12653                   ast_log(LOG_WARNING, "Notify answer on an owned channel?\n");
12654                /* ast_queue_hangup(p->owner); Disabled */
12655             } else {
12656                if (!p->subscribed && !p->refer)
12657                   ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12658             }
12659          } else if (sipmethod == SIP_BYE)
12660             ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12661          else if (sipmethod == SIP_MESSAGE || sipmethod == SIP_INFO)
12662             /* We successfully transmitted a message or
12663                a video update request in INFO */
12664             ;
12665          else if (sipmethod == SIP_BYE) 
12666             /* Ok, we're ready to go */
12667             ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12668          break;
12669       case 202:   /* Transfer accepted */
12670          if (sipmethod == SIP_REFER) 
12671             handle_response_refer(p, resp, rest, req, seqno);
12672          break;
12673       case 401:   /* www-auth */
12674       case 407:
12675          if (sipmethod == SIP_REFER)
12676             handle_response_refer(p, resp, rest, req, seqno);
12677          else if (sipmethod == SIP_INVITE) 
12678             handle_response_invite(p, resp, rest, req, seqno);
12679          else if (sipmethod == SIP_BYE) {
12680             char *auth, *auth2;
12681 
12682             auth = (resp == 407 ? "Proxy-Authenticate" : "WWW-Authenticate");
12683             auth2 = (resp == 407 ? "Proxy-Authorization" : "Authorization");
12684             if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, auth, auth2, sipmethod, 0)) {
12685                ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From"));
12686                ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12687             }
12688          }
12689          break;
12690       case 481:   /* Call leg does not exist */
12691          if (sipmethod == SIP_INVITE) {
12692             /* Re-invite failed */
12693             handle_response_invite(p, resp, rest, req, seqno);
12694          } else if (sipmethod == SIP_BYE) {
12695             ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12696          } else if (sipdebug) {
12697             ast_log  (LOG_DEBUG, "Remote host can't match request %s to call '%s'. Giving up\n", sip_methods[sipmethod].text, p->callid);
12698          }
12699          break;
12700       case 501: /* Not Implemented */
12701          if (sipmethod == SIP_INVITE) 
12702             handle_response_invite(p, resp, rest, req, seqno);
12703          else if (sipmethod == SIP_REFER) 
12704             handle_response_refer(p, resp, rest, req, seqno);
12705          break;
12706       case 603:   /* Declined transfer */
12707          if (sipmethod == SIP_REFER) {
12708             handle_response_refer(p, resp, rest, req, seqno);
12709             break;
12710          }
12711          /* Fallthrough */
12712       default: /* Errors without handlers */
12713          if ((resp >= 100) && (resp < 200)) {
12714             if (sipmethod == SIP_INVITE) {   /* re-invite */
12715                if (!ast_test_flag(req, SIP_PKT_IGNORE))
12716                   sip_cancel_destroy(p);
12717             }
12718          }
12719          if ((resp >= 300) && (resp < 700)) {
12720             if ((option_verbose > 2) && (resp != 487))
12721                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));
12722             switch(resp) {
12723             case 488: /* Not acceptable here - codec error */
12724             case 603: /* Decline */
12725             case 500: /* Server error */
12726             case 503: /* Service Unavailable */
12727             case 504: /* Server timeout */
12728 
12729                if (sipmethod == SIP_INVITE) {   /* re-invite failed */
12730                   sip_cancel_destroy(p);
12731                }
12732                break;
12733             }
12734          }
12735          break;
12736       }
12737    }
12738 }

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 11781 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_rtp_set_rtptimers_onhold(), ast_sched_del(), ast_set_flag, ast_setstate(), AST_STATE_RINGING, AST_STATE_UP, ast_string_field_free, ast_test_flag, sip_invite_param::auth_type, authenticate(), sip_pvt::authtries, build_route(), check_pendings(), DEC_CALL_LIMIT, DEC_CALL_RINGING, DEFAULT_TRANS_TIMEOUT, do_proxy_auth(), FALSE, find_sdp(), sip_pvt::flags, get_header(), sip_pvt::initid, sip_pvt::initreq, INV_CALLING, INV_COMPLETED, INV_EARLY_MEDIA, INV_PROCEEDING, INV_TERMINATED, sip_pvt::invitestate, sip_pvt::lock, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, LOG_WARNING, MAX_AUTHTRIES, option_debug, sip_pvt::options, sip_pvt::owner, parse_ok_contact(), process_sdp(), PROXY_AUTH, sip_pvt::rtp, set_address_from_contact(), SIP_ACK, sip_alreadygone(), SIP_ALREADYGONE, sip_cancel_destroy(), sip_handle_t38_reinvite(), SIP_INVITE, SIP_NEEDDESTROY, SIP_OUTGOING, SIP_PENDINGBYE, SIP_PKT_IGNORE, sip_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, WWW_AUTH, XMIT_ERROR, and XMIT_UNRELIABLE.

Referenced by handle_response().

11782 {
11783    int outgoing = ast_test_flag(&p->flags[0], SIP_OUTGOING);
11784    int res = 0;
11785    int xmitres = 0;
11786    int reinvite = (p->owner && p->owner->_state == AST_STATE_UP);
11787    struct ast_channel *bridgepeer = NULL;
11788    
11789    if (option_debug > 3) {
11790       if (reinvite)
11791          ast_log(LOG_DEBUG, "SIP response %d to RE-invite on %s call %s\n", resp, outgoing ? "outgoing" : "incoming", p->callid);
11792       else
11793          ast_log(LOG_DEBUG, "SIP response %d to standard invite\n", resp);
11794    }
11795 
11796    if (ast_test_flag(&p->flags[0], SIP_ALREADYGONE)) { /* This call is already gone */
11797       if (option_debug)
11798          ast_log(LOG_DEBUG, "Got response on call that is already terminated: %s (ignoring)\n", p->callid);
11799       return;
11800    }
11801 
11802    /* Acknowledge sequence number - This only happens on INVITE from SIP-call */
11803    if (p->initid > -1) {
11804       /* Don't auto congest anymore since we've gotten something useful back */
11805       ast_sched_del(sched, p->initid);
11806       p->initid = -1;
11807    }
11808 
11809    /* RFC3261 says we must treat every 1xx response (but not 100)
11810       that we don't recognize as if it was 183.
11811    */
11812    if (resp > 100 && resp < 200 && resp!=101 && resp != 180 && resp != 183)
11813       resp = 183;
11814 
11815    /* Any response between 100 and 199 is PROCEEDING */
11816    if (resp >= 100 && resp < 200 && p->invitestate == INV_CALLING)
11817       p->invitestate = INV_PROCEEDING;
11818  
11819    /* Final response, not 200 ? */
11820    if (resp >= 300 && (p->invitestate == INV_CALLING || p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA ))
11821       p->invitestate = INV_COMPLETED;
11822       
11823 
11824    switch (resp) {
11825    case 100:   /* Trying */
11826    case 101:   /* Dialog establishment */
11827       if (!ast_test_flag(req, SIP_PKT_IGNORE))
11828          sip_cancel_destroy(p);
11829       check_pendings(p);
11830       break;
11831 
11832    case 180:   /* 180 Ringing */
11833       if (!ast_test_flag(req, SIP_PKT_IGNORE))
11834          sip_cancel_destroy(p);
11835       if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) {
11836          ast_queue_control(p->owner, AST_CONTROL_RINGING);
11837          if (p->owner->_state != AST_STATE_UP) {
11838             ast_setstate(p->owner, AST_STATE_RINGING);
11839          }
11840       }
11841       if (find_sdp(req)) {
11842          p->invitestate = INV_EARLY_MEDIA;
11843          res = process_sdp(p, req);
11844          if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) {
11845             /* Queue a progress frame only if we have SDP in 180 */
11846             ast_queue_control(p->owner, AST_CONTROL_PROGRESS);
11847          }
11848       }
11849       check_pendings(p);
11850       break;
11851 
11852    case 183:   /* Session progress */
11853       if (!ast_test_flag(req, SIP_PKT_IGNORE))
11854          sip_cancel_destroy(p);
11855       /* Ignore 183 Session progress without SDP */
11856       if (find_sdp(req)) {
11857          p->invitestate = INV_EARLY_MEDIA;
11858          res = process_sdp(p, req);
11859          if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) {
11860             /* Queue a progress frame */
11861             ast_queue_control(p->owner, AST_CONTROL_PROGRESS);
11862          }
11863       }
11864       check_pendings(p);
11865       break;
11866 
11867    case 200:   /* 200 OK on invite - someone's answering our call */
11868       if (!ast_test_flag(req, SIP_PKT_IGNORE))
11869          sip_cancel_destroy(p);
11870       p->authtries = 0;
11871       if (find_sdp(req)) {
11872          if ((res = process_sdp(p, req)) && !ast_test_flag(req, SIP_PKT_IGNORE))
11873             if (!reinvite)
11874                /* This 200 OK's SDP is not acceptable, so we need to ack, then hangup */
11875                /* For re-invites, we try to recover */
11876                ast_set_flag(&p->flags[0], SIP_PENDINGBYE);  
11877       }
11878 
11879       /* Parse contact header for continued conversation */
11880       /* When we get 200 OK, we know which device (and IP) to contact for this call */
11881       /* This is important when we have a SIP proxy between us and the phone */
11882       if (outgoing) {
11883          update_call_counter(p, DEC_CALL_RINGING);
11884          parse_ok_contact(p, req);
11885          if(set_address_from_contact(p)) {
11886             /* Bad contact - we don't know how to reach this device */
11887             /* We need to ACK, but then send a bye */
11888             /* OEJ: Possible issue that may need a check:
11889                If we have a proxy route between us and the device,
11890                should we care about resolving the contact
11891                or should we just send it?
11892             */
11893             if (!ast_test_flag(req, SIP_PKT_IGNORE))
11894                ast_set_flag(&p->flags[0], SIP_PENDINGBYE);  
11895          } 
11896 
11897          /* Save Record-Route for any later requests we make on this dialogue */
11898          build_route(p, req, 1);
11899       }
11900       
11901       if (p->owner && (p->owner->_state == AST_STATE_UP) && (bridgepeer = ast_bridged_channel(p->owner))) { /* if this is a re-invite */
11902          struct sip_pvt *bridgepvt = NULL;
11903 
11904          if (!bridgepeer->tech) {
11905             ast_log(LOG_WARNING, "Ooooh.. no tech!  That's REALLY bad\n");
11906             break;
11907          }
11908          if (bridgepeer->tech == &sip_tech || bridgepeer->tech == &sip_tech_info) {
11909             bridgepvt = (struct sip_pvt*)(bridgepeer->tech_pvt);
11910             if (bridgepvt->udptl) {
11911                if (p->t38.state == T38_PEER_REINVITE) {
11912                   sip_handle_t38_reinvite(bridgepeer, p, 0);
11913                   ast_rtp_set_rtptimers_onhold(p->rtp);
11914                   if (p->vrtp)
11915                      ast_rtp_set_rtptimers_onhold(p->vrtp); /* Turn off RTP timers while we send fax */
11916                } else if (p->t38.state == T38_DISABLED && bridgepeer && (bridgepvt->t38.state == T38_ENABLED)) {
11917                   ast_log(LOG_WARNING, "RTP re-invite after T38 session not handled yet !\n");
11918                   /* Insted of this we should somehow re-invite the other side of the bridge to RTP */
11919                   /* XXXX Should we really destroy this session here, without any response at all??? */
11920                   sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
11921                }
11922             } else {
11923                if (option_debug > 1)
11924                   ast_log(LOG_DEBUG, "Strange... The other side of the bridge does not have a udptl struct\n");
11925                ast_mutex_lock(&bridgepvt->lock);
11926                bridgepvt->t38.state = T38_DISABLED;
11927                ast_mutex_unlock(&bridgepvt->lock);
11928                if (option_debug)
11929                   ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", bridgepvt->t38.state, bridgepeer->tech->type);
11930                p->t38.state = T38_DISABLED;
11931                if (option_debug > 1)
11932                   ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>");
11933             }
11934          } else {
11935             /* Other side is not a SIP channel */
11936             if (option_debug > 1)
11937                ast_log(LOG_DEBUG, "Strange... The other side of the bridge is not a SIP channel\n");
11938             p->t38.state = T38_DISABLED;
11939             if (option_debug > 1)
11940                ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>");
11941          }
11942       }
11943       if ((p->t38.state == T38_LOCAL_REINVITE) || (p->t38.state == T38_LOCAL_DIRECT)) {
11944          /* If there was T38 reinvite and we are supposed to answer with 200 OK than this should set us to T38 negotiated mode */
11945          p->t38.state = T38_ENABLED;
11946          if (option_debug)
11947             ast_log(LOG_DEBUG, "T38 changed state to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>");
11948       }
11949 
11950       if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) {
11951          if (!reinvite) {
11952             ast_queue_control(p->owner, AST_CONTROL_ANSWER);
11953          } else { /* RE-invite */
11954             ast_queue_frame(p->owner, &ast_null_frame);
11955          }
11956       } else {
11957           /* It's possible we're getting an 200 OK after we've tried to disconnect
11958               by sending CANCEL */
11959          /* First send ACK, then send bye */
11960          if (!ast_test_flag(req, SIP_PKT_IGNORE))
11961             ast_set_flag(&p->flags[0], SIP_PENDINGBYE);  
11962       }
11963       /* If I understand this right, the branch is different for a non-200 ACK only */
11964       p->invitestate = INV_TERMINATED;
11965       xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, TRUE);
11966       check_pendings(p);
11967       break;
11968    case 407: /* Proxy authentication */
11969    case 401: /* Www auth */
11970       /* First we ACK */
11971       xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
11972       if (p->options)
11973          p->options->auth_type = (resp == 401 ? WWW_AUTH : PROXY_AUTH);
11974 
11975       /* Then we AUTH */
11976       ast_string_field_free(p, theirtag); /* forget their old tag, so we don't match tags when getting response */
11977       if (!ast_test_flag(req, SIP_PKT_IGNORE)) {
11978          char *authenticate = (resp == 401 ? "WWW-Authenticate" : "Proxy-Authenticate");
11979          char *authorization = (resp == 401 ? "Authorization" : "Proxy-Authorization");
11980          if (p->authtries < MAX_AUTHTRIES)
11981             p->invitestate = INV_CALLING;
11982          if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, authenticate, authorization, SIP_INVITE, 1)) {
11983             ast_log(LOG_NOTICE, "Failed to authenticate on INVITE to '%s'\n", get_header(&p->initreq, "From"));
11984             ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
11985             sip_alreadygone(p);
11986             if (p->owner)
11987                ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
11988          }
11989       }
11990       break;
11991 
11992    case 403: /* Forbidden */
11993       /* First we ACK */
11994       xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
11995       ast_log(LOG_WARNING, "Received response: \"Forbidden\" from '%s'\n", get_header(&p->initreq, "From"));
11996       if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner)
11997          ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
11998       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
11999       sip_alreadygone(p);
12000       break;
12001 
12002    case 404: /* Not found */
12003       xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
12004       if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE))
12005          ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
12006       sip_alreadygone(p);
12007       break;
12008 
12009    case 408: /* Request timeout */
12010    case 481: /* Call leg does not exist */
12011       /* Could be REFER caused INVITE with replaces */
12012       ast_log(LOG_WARNING, "Re-invite to non-existing call leg on other UA. SIP dialog '%s'. Giving up.\n", p->callid);
12013       xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
12014       if (p->owner)
12015          ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
12016       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
12017       break;
12018    case 487: /* Cancelled transaction */
12019       /* We have sent CANCEL on an outbound INVITE 
12020          This transaction is already scheduled to be killed by sip_hangup().
12021       */
12022       xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
12023       if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) {
12024          ast_queue_hangup(p->owner);
12025          append_history(p, "Hangup", "Got 487 on CANCEL request from us. Queued AST hangup request");
12026       } else if (!ast_test_flag(req, SIP_PKT_IGNORE)) {
12027          update_call_counter(p, DEC_CALL_LIMIT);
12028          append_history(p, "Hangup", "Got 487 on CANCEL request from us on call without owner. Killing this dialog.");
12029          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12030          sip_alreadygone(p);
12031       }
12032       break;
12033    case 488: /* Not acceptable here */
12034       xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
12035       if (reinvite && p->udptl) {
12036          /* If this is a T.38 call, we should go back to 
12037             audio. If this is an audio call - something went
12038             terribly wrong since we don't renegotiate codecs,
12039             only IP/port .
12040          */
12041          p->t38.state = T38_DISABLED;
12042          /* Try to reset RTP timers */
12043          ast_rtp_set_rtptimers_onhold(p->rtp);
12044          ast_log(LOG_ERROR, "Got error on T.38 re-invite. Bad configuration. Peer needs to have T.38 disabled.\n");
12045 
12046          /*! \bug Is there any way we can go back to the audio call on both
12047             sides here? 
12048          */
12049          /* While figuring that out, hangup the call */
12050          if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE))
12051             ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
12052          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12053       } else {
12054          /* We can't set up this call, so give up */
12055          if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE))
12056             ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
12057          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12058       }
12059       break;
12060    case 491: /* Pending */
12061       /* we really should have to wait a while, then retransmit */
12062          /* We should support the retry-after at some point */
12063       /* At this point, we treat this as a congestion */
12064       xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
12065       if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE))
12066          ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
12067       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12068       break;
12069 
12070    case 501: /* Not implemented */
12071       xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
12072       if (p->owner)
12073          ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
12074       break;
12075    }
12076    if (xmitres == XMIT_ERROR)
12077       ast_log(LOG_WARNING, "Could not transmit message in dialog %s\n", p->callid);
12078 }

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

Handle qualification responses (OPTIONS).

Definition at line 12280 of file chan_sip.c.

References ast_device_state_changed(), ast_log(), ast_sched_add(), ast_sched_del(), ast_set_flag, sip_peer::call, DEFAULT_FREQ_NOTOK, DEFAULT_FREQ_OK, EVENT_FLAG_SYSTEM, sip_pvt::flags, sip_peer::lastms, LOG_NOTICE, manager_event(), sip_peer::maxms, sip_peer::pokeexpire, sip_peer::ps, sip_pvt::relatedpeer, s, SIP_NEEDDESTROY, and sip_poke_peer_s().

Referenced by handle_response().

12281 {
12282    struct sip_peer *peer = p->relatedpeer;
12283    int statechanged, is_reachable, was_reachable;
12284    int pingtime = ast_tvdiff_ms(ast_tvnow(), peer->ps);
12285 
12286    /*
12287     * Compute the response time to a ping (goes in peer->lastms.)
12288     * -1 means did not respond, 0 means unknown,
12289     * 1..maxms is a valid response, >maxms means late response.
12290     */
12291    if (pingtime < 1) /* zero = unknown, so round up to 1 */
12292       pingtime = 1;
12293 
12294    /* Now determine new state and whether it has changed.
12295     * Use some helper variables to simplify the writing
12296     * of the expressions.
12297     */
12298    was_reachable = peer->lastms > 0 && peer->lastms <= peer->maxms;
12299    is_reachable = pingtime <= peer->maxms;
12300    statechanged = peer->lastms == 0 /* yes, unknown before */
12301       || was_reachable != is_reachable;
12302 
12303    peer->lastms = pingtime;
12304    peer->call = NULL;
12305    if (statechanged) {
12306       const char *s = is_reachable ? "Reachable" : "Lagged";
12307 
12308       ast_log(LOG_NOTICE, "Peer '%s' is now %s. (%dms / %dms)\n",
12309          peer->name, s, pingtime, peer->maxms);
12310       ast_device_state_changed("SIP/%s", peer->name);
12311       manager_event(EVENT_FLAG_SYSTEM, "PeerStatus",
12312          "Peer: SIP/%s\r\nPeerStatus: %s\r\nTime: %d\r\n",
12313          peer->name, s, pingtime);
12314    }
12315 
12316    if (peer->pokeexpire > -1)
12317       ast_sched_del(sched, peer->pokeexpire);
12318    ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12319 
12320    /* Try again eventually */
12321    peer->pokeexpire = ast_sched_add(sched,
12322       is_reachable ? DEFAULT_FREQ_OK : DEFAULT_FREQ_NOTOK,
12323       sip_poke_peer_s, peer);
12324 }

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

Definition at line 12083 of file chan_sip.c.

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

Referenced by handle_response().

12084 {
12085    char *auth = "Proxy-Authenticate";
12086    char *auth2 = "Proxy-Authorization";
12087 
12088    /* If no refer structure exists, then do nothing */
12089    if (!p->refer)
12090       return;
12091 
12092    switch (resp) {
12093    case 202:   /* Transfer accepted */
12094       /* We need  to do something here */
12095       /* The transferee is now sending INVITE to target */
12096       p->refer->status = REFER_ACCEPTED;
12097       /* Now wait for next message */
12098       if (option_debug > 2)
12099          ast_log(LOG_DEBUG, "Got 202 accepted on transfer\n");
12100       /* We should hang along, waiting for NOTIFY's here */
12101       break;
12102 
12103    case 401:   /* Not www-authorized on SIP method */
12104    case 407:   /* Proxy auth */
12105       if (ast_strlen_zero(p->authname)) {
12106          ast_log(LOG_WARNING, "Asked to authenticate REFER to %s:%d but we have no matching peer or realm auth!\n",
12107             ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port));
12108          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
12109       }
12110       if (resp == 401) {
12111          auth = "WWW-Authenticate";
12112          auth2 = "Authorization";
12113       }
12114       if ((p->authtries > 1) || do_proxy_auth(p, req, auth, auth2, SIP_REFER, 0)) {
12115          ast_log(LOG_NOTICE, "Failed to authenticate on REFER to '%s'\n", get_header(&p->initreq, "From"));
12116          p->refer->status = REFER_NOAUTH;
12117          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
12118       }
12119       break;
12120    case 481: /* Call leg does not exist */
12121 
12122       /* A transfer with Replaces did not work */
12123       /* OEJ: We should Set flag, cancel the REFER, go back
12124       to original call - but right now we can't */
12125       ast_log(LOG_WARNING, "Remote host can't match REFER request to call '%s'. Giving up.\n", p->callid);
12126       if (p->owner)
12127          ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
12128       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
12129       break;
12130 
12131    case 500:   /* Server error */
12132    case 501:   /* Method not implemented */
12133       /* Return to the current call onhold */
12134       /* Status flag needed to be reset */
12135       ast_log(LOG_NOTICE, "SIP transfer to %s failed, call miserably fails. \n", p->refer->refer_to);
12136       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
12137       p->refer->status = REFER_FAILED;
12138       break;
12139    case 603:   /* Transfer declined */
12140       ast_log(LOG_NOTICE, "SIP transfer to %s declined, call miserably fails. \n", p->refer->refer_to);
12141       p->refer->status = REFER_FAILED;
12142       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
12143       break;
12144    }
12145 }

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

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

Referenced by handle_response().

12149 {
12150    int expires, expires_ms;
12151    struct sip_registry *r;
12152    r=p->registry;
12153 
12154    switch (resp) {
12155    case 401:   /* Unauthorized */
12156       if ((p->authtries == MAX_AUTHTRIES) || do_register_auth(p, req, "WWW-Authenticate", "Authorization")) {
12157          ast_log(LOG_NOTICE, "Failed to authenticate on REGISTER to '%s@%s' (Tries %d)\n", p->registry->username, p->registry->hostname, p->authtries);
12158          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12159          }
12160       break;
12161    case 403:   /* Forbidden */
12162       ast_log(LOG_WARNING, "Forbidden - wrong password on authentication for REGISTER for '%s' to '%s'\n", p->registry->username, p->registry->hostname);
12163       if (global_regattempts_max)
12164          p->registry->regattempts = global_regattempts_max+1;
12165       ast_sched_del(sched, r->timeout);
12166       r->timeout = -1;
12167       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12168       break;
12169    case 404:   /* Not found */
12170       ast_log(LOG_WARNING, "Got 404 Not found on SIP register to service %s@%s, giving up\n", p->registry->username,p->registry->hostname);
12171       if (global_regattempts_max)
12172          p->registry->regattempts = global_regattempts_max+1;
12173       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12174       r->call = NULL;
12175       ast_sched_del(sched, r->timeout);
12176       r->timeout = -1;
12177       break;
12178    case 407:   /* Proxy auth */
12179       if ((p->authtries == MAX_AUTHTRIES) || do_register_auth(p, req, "Proxy-Authenticate", "Proxy-Authorization")) {
12180          ast_log(LOG_NOTICE, "Failed to authenticate on REGISTER to '%s' (tries '%d')\n", get_header(&p->initreq, "From"), p->authtries);
12181          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12182       }
12183       break;
12184    case 408:   /* Request timeout */
12185       if (global_regattempts_max)
12186          p->registry->regattempts = global_regattempts_max+1;
12187       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12188       r->call = NULL;
12189       ast_sched_del(sched, r->timeout);
12190       r->timeout = -1;
12191       break;
12192    case 479:   /* SER: Not able to process the URI - address is wrong in register*/
12193       ast_log(LOG_WARNING, "Got error 479 on register to %s@%s, giving up (check config)\n", p->registry->username,p->registry->hostname);
12194       if (global_regattempts_max)
12195          p->registry->regattempts = global_regattempts_max+1;
12196       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12197       r->call = NULL;
12198       ast_sched_del(sched, r->timeout);
12199       r->timeout = -1;
12200       break;
12201    case 200:   /* 200 OK */
12202       if (!r) {
12203          ast_log(LOG_WARNING, "Got 200 OK on REGISTER that isn't a register\n");
12204          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12205          return 0;
12206       }
12207 
12208       r->regstate = REG_STATE_REGISTERED;
12209       r->regtime = time(NULL);      /* Reset time of last succesful registration */
12210       manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelDriver: SIP\r\nDomain: %s\r\nStatus: %s\r\n", r->hostname, regstate2str(r->regstate));
12211       r->regattempts = 0;
12212       if (option_debug)
12213          ast_log(LOG_DEBUG, "Registration successful\n");
12214       if (r->timeout > -1) {
12215          if (option_debug)
12216             ast_log(LOG_DEBUG, "Cancelling timeout %d\n", r->timeout);
12217          ast_sched_del(sched, r->timeout);
12218       }
12219       r->timeout=-1;
12220       r->call = NULL;
12221       p->registry = NULL;
12222       /* Let this one hang around until we have all the responses */
12223       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
12224       /* ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); */
12225 
12226       /* set us up for re-registering */
12227       /* figure out how long we got registered for */
12228       if (r->expire > -1)
12229          ast_sched_del(sched, r->expire);
12230       /* according to section 6.13 of RFC, contact headers override
12231          expires headers, so check those first */
12232       expires = 0;
12233 
12234       /* XXX todo: try to save the extra call */
12235       if (!ast_strlen_zero(get_header(req, "Contact"))) {
12236          const char *contact = NULL;
12237          const char *tmptmp = NULL;
12238          int start = 0;
12239          for(;;) {
12240             contact = __get_header(req, "Contact", &start);
12241             /* this loop ensures we get a contact header about our register request */
12242             if(!ast_strlen_zero(contact)) {
12243                if( (tmptmp=strstr(contact, p->our_contact))) {
12244                   contact=tmptmp;
12245                   break;
12246                }
12247             } else
12248                break;
12249          }
12250          tmptmp = strcasestr(contact, "expires=");
12251          if (tmptmp) {
12252             if (sscanf(tmptmp + 8, "%d;", &expires) != 1)
12253                expires = 0;
12254          }
12255 
12256       }
12257       if (!expires) 
12258          expires=atoi(get_header(req, "expires"));
12259       if (!expires)
12260          expires=default_expiry;
12261 
12262       expires_ms = expires * 1000;
12263       if (expires <= EXPIRY_GUARD_LIMIT)
12264          expires_ms -= MAX((expires_ms * EXPIRY_GUARD_PCT),EXPIRY_GUARD_MIN);
12265       else
12266          expires_ms -= EXPIRY_GUARD_SECS * 1000;
12267       if (sipdebug)
12268          ast_log(LOG_NOTICE, "Outbound Registration: Expiry for %s is %d sec (Scheduling reregistration in %d s)\n", r->hostname, expires, expires_ms/1000); 
12269 
12270       r->refresh= (int) expires_ms / 1000;
12271 
12272       /* Schedule re-registration before we expire */
12273       r->expire=ast_sched_add(sched, expires_ms, sip_reregister, r); 
12274       ASTOBJ_UNREF(r, sip_registry_destroy);
12275    }
12276    return 1;
12277 }

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

References AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_CALL_REJECTED, AST_CAUSE_CHAN_NOT_IMPLEMENTED, AST_CAUSE_CONGESTION, AST_CAUSE_DESTINATION_OUT_OF_ORDER, AST_CAUSE_FACILITY_REJECTED, AST_CAUSE_FAILURE, AST_CAUSE_INVALID_NUMBER_FORMAT, AST_CAUSE_NO_ANSWER, AST_CAUSE_NO_ROUTE_DESTINATION, AST_CAUSE_NO_ROUTE_TRANSIT_NET, AST_CAUSE_NO_USER_RESPONSE, AST_CAUSE_NORMAL_UNSPECIFIED, AST_CAUSE_NOTDEFINED, AST_CAUSE_NUMBER_CHANGED, AST_CAUSE_SWITCH_CONGESTION, AST_CAUSE_UNALLOCATED, AST_CAUSE_USER_BUSY, ast_log(), LOG_DEBUG, and option_debug.

Referenced by sip_hangup().

03338 {
03339    switch (cause) {
03340       case AST_CAUSE_UNALLOCATED:      /* 1 */
03341       case AST_CAUSE_NO_ROUTE_DESTINATION:   /* 3 IAX2: Can't find extension in context */
03342       case AST_CAUSE_NO_ROUTE_TRANSIT_NET:   /* 2 */
03343          return "404 Not Found";
03344       case AST_CAUSE_CONGESTION:    /* 34 */
03345       case AST_CAUSE_SWITCH_CONGESTION:   /* 42 */
03346          return "503 Service Unavailable";
03347       case AST_CAUSE_NO_USER_RESPONSE: /* 18 */
03348          return "408 Request Timeout";
03349       case AST_CAUSE_NO_ANSWER:     /* 19 */
03350          return "480 Temporarily unavailable";
03351       case AST_CAUSE_CALL_REJECTED:    /* 21 */
03352          return "403 Forbidden";
03353       case AST_CAUSE_NUMBER_CHANGED:      /* 22 */
03354          return "410 Gone";
03355       case AST_CAUSE_NORMAL_UNSPECIFIED:  /* 31 */
03356          return "480 Temporarily unavailable";
03357       case AST_CAUSE_INVALID_NUMBER_FORMAT:
03358          return "484 Address incomplete";
03359       case AST_CAUSE_USER_BUSY:
03360          return "486 Busy here";
03361       case AST_CAUSE_FAILURE:
03362          return "500 Server internal failure";
03363       case AST_CAUSE_FACILITY_REJECTED:   /* 29 */
03364          return "501 Not Implemented";
03365       case AST_CAUSE_CHAN_NOT_IMPLEMENTED:
03366          return "503 Service Unavailable";
03367       /* Used in chan_iax2 */
03368       case AST_CAUSE_DESTINATION_OUT_OF_ORDER:
03369          return "502 Bad Gateway";
03370       case AST_CAUSE_BEARERCAPABILITY_NOTAVAIL: /* Can't find codec to connect to host */
03371          return "488 Not Acceptable Here";
03372          
03373       case AST_CAUSE_NOTDEFINED:
03374       default:
03375          if (option_debug)
03376             ast_log(LOG_DEBUG, "AST hangup cause %d (no match found in SIP)\n", cause);
03377          return NULL;
03378    }
03379 
03380    /* Never reached */
03381    return 0;
03382 }

static int hangup_sip2cause ( int  cause  )  [static]

Convert SIP hangup causes to Asterisk hangup causes.

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

03226 {
03227    /* Possible values taken from causes.h */
03228 
03229    switch(cause) {
03230       case 401:   /* Unauthorized */
03231          return AST_CAUSE_CALL_REJECTED;
03232       case 403:   /* Not found */
03233          return AST_CAUSE_CALL_REJECTED;
03234       case 404:   /* Not found */
03235          return AST_CAUSE_UNALLOCATED;
03236       case 405:   /* Method not allowed */
03237          return AST_CAUSE_INTERWORKING;
03238       case 407:   /* Proxy authentication required */
03239          return AST_CAUSE_CALL_REJECTED;
03240       case 408:   /* No reaction */
03241          return AST_CAUSE_NO_USER_RESPONSE;
03242       case 409:   /* Conflict */
03243          return AST_CAUSE_NORMAL_TEMPORARY_FAILURE;
03244       case 410:   /* Gone */
03245          return AST_CAUSE_UNALLOCATED;
03246       case 411:   /* Length required */
03247          return AST_CAUSE_INTERWORKING;
03248       case 413:   /* Request entity too large */
03249          return AST_CAUSE_INTERWORKING;
03250       case 414:   /* Request URI too large */
03251          return AST_CAUSE_INTERWORKING;
03252       case 415:   /* Unsupported media type */
03253          return AST_CAUSE_INTERWORKING;
03254       case 420:   /* Bad extension */
03255          return AST_CAUSE_NO_ROUTE_DESTINATION;
03256       case 480:   /* No answer */
03257          return AST_CAUSE_NO_ANSWER;
03258       case 481:   /* No answer */
03259          return AST_CAUSE_INTERWORKING;
03260       case 482:   /* Loop detected */
03261          return AST_CAUSE_INTERWORKING;
03262       case 483:   /* Too many hops */
03263          return AST_CAUSE_NO_ANSWER;
03264       case 484:   /* Address incomplete */
03265          return AST_CAUSE_INVALID_NUMBER_FORMAT;
03266       case 485:   /* Ambigous */
03267          return AST_CAUSE_UNALLOCATED;
03268       case 486:   /* Busy everywhere */
03269          return AST_CAUSE_BUSY;
03270       case 487:   /* Request terminated */
03271          return AST_CAUSE_INTERWORKING;
03272       case 488:   /* No codecs approved */
03273          return AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;
03274       case 491:   /* Request pending */
03275          return AST_CAUSE_INTERWORKING;
03276       case 493:   /* Undecipherable */
03277          return AST_CAUSE_INTERWORKING;
03278       case 500:   /* Server internal failure */
03279          return AST_CAUSE_FAILURE;
03280       case 501:   /* Call rejected */
03281          return AST_CAUSE_FACILITY_REJECTED;
03282       case 502:   
03283          return AST_CAUSE_DESTINATION_OUT_OF_ORDER;
03284       case 503:   /* Service unavailable */
03285          return AST_CAUSE_CONGESTION;
03286       case 504:   /* Gateway timeout */
03287          return AST_CAUSE_RECOVERY_ON_TIMER_EXPIRE;
03288       case 505:   /* SIP version not supported */
03289          return AST_CAUSE_INTERWORKING;
03290       case 600:   /* Busy everywhere */
03291          return AST_CAUSE_USER_BUSY;
03292       case 603:   /* Decline */
03293          return AST_CAUSE_CALL_REJECTED;
03294       case 604:   /* Does not exist anywhere */
03295          return AST_CAUSE_UNALLOCATED;
03296       case 606:   /* Not acceptable */
03297          return AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;
03298       default:
03299          return AST_CAUSE_NORMAL;
03300    }
03301    /* Never reached */
03302    return 0;
03303 }

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

Initialize SIP request.

Definition at line 5677 of file chan_sip.c.

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

05678 {
05679    /* Initialize a request */
05680    memset(req, 0, sizeof(*req));
05681         req->method = sipmethod;
05682    req->header[0] = req->data;
05683    snprintf(req->header[0], sizeof(req->data), "%s %s SIP/2.0\r\n", sip_methods[sipmethod].text, recip);
05684    req->len = strlen(req->header[0]);
05685    req->headers++;
05686    return 0;
05687 }

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

Initialize SIP response, based on SIP request.

Definition at line 5664 of file chan_sip.c.

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

05665 {
05666    /* Initialize a response */
05667    memset(resp, 0, sizeof(*resp));
05668    resp->method = SIP_RESPONSE;
05669    resp->header[0] = resp->data;
05670    snprintf(resp->header[0], sizeof(resp->data), "SIP/2.0 %s\r\n", msg);
05671    resp->len = strlen(resp->header[0]);
05672    resp->headers++;
05673    return 0;
05674 }

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

01628 {
01629    if (p->initreq.headers && option_debug) {
01630       ast_log(LOG_DEBUG, "Initializing already initialized SIP dialog %s (presumably reinvite)\n", p->callid);
01631    }
01632    /* Use this as the basis */
01633    copy_request(&p->initreq, req);
01634    parse_request(&p->initreq);
01635    if (ast_test_flag(req, SIP_PKT_DEBUG))
01636       ast_verbose("%d headers, %d lines\n", p->initreq.headers, p->initreq.lines);
01637 }

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

Initiate new SIP request to peer/user.

Definition at line 6758 of file chan_sip.c.

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

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

06759 {
06760    char invite_buf[256] = "";
06761    char *invite = invite_buf;
06762    size_t invite_max = sizeof(invite_buf);
06763    char from[256];
06764    char to[256];
06765    char tmp[BUFSIZ/2];
06766    char tmp2[BUFSIZ/2];
06767    const char *l = NULL, *n = NULL;
06768    const char *urioptions = "";
06769 
06770    if (ast_test_flag(&p->flags[0], SIP_USEREQPHONE)) {
06771       const char *s = p->username;  /* being a string field, cannot be NULL */
06772 
06773       /* Test p->username against allowed characters in AST_DIGIT_ANY
06774          If it matches the allowed characters list, then sipuser = ";user=phone"
06775          If not, then sipuser = ""
06776       */
06777       /* + is allowed in first position in a tel: uri */
06778       if (*s == '+')
06779          s++;
06780       for (; *s; s++) {
06781          if (!strchr(AST_DIGIT_ANYNUM, *s) )
06782             break;
06783       }
06784       /* If we have only digits, add ;user=phone to the uri */
06785       if (*s)
06786          urioptions = ";user=phone";
06787    }
06788 
06789 
06790    snprintf(p->lastmsg, sizeof(p->lastmsg), "Init: %s", sip_methods[sipmethod].text);
06791 
06792    if (p->owner) {
06793       l = p->owner->cid.cid_num;
06794       n = p->owner->cid.cid_name;
06795    }
06796    /* if we are not sending RPID and user wants his callerid restricted */
06797    if (!ast_test_flag(&p->flags[0], SIP_SENDRPID) &&
06798        ((p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED)) {
06799       l = CALLERID_UNKNOWN;
06800       n = l;
06801    }
06802    if (ast_strlen_zero(l))
06803       l = default_callerid;
06804    if (ast_strlen_zero(n))
06805       n = l;
06806    /* Allow user to be overridden */
06807    if (!ast_strlen_zero(p->fromuser))
06808       l = p->fromuser;
06809    else /* Save for any further attempts */
06810       ast_string_field_set(p, fromuser, l);
06811 
06812    /* Allow user to be overridden */
06813    if (!ast_strlen_zero(p->fromname))
06814       n = p->fromname;
06815    else /* Save for any further attempts */
06816       ast_string_field_set(p, fromname, n);
06817 
06818    if (pedanticsipchecking) {
06819       ast_uri_encode(n, tmp, sizeof(tmp), 0);
06820       n = tmp;
06821       ast_uri_encode(l, tmp2, sizeof(tmp2), 0);
06822       l = tmp2;
06823    }
06824 
06825    if (ourport != STANDARD_SIP_PORT && ast_strlen_zero(p->fromdomain))
06826       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);
06827    else
06828       snprintf(from, sizeof(from), "\"%s\" <sip:%s@%s>;tag=%s", n, l, S_OR(p->fromdomain, ast_inet_ntoa(p->ourip)), p->tag);
06829 
06830    /* If we're calling a registered SIP peer, use the fullcontact to dial to the peer */
06831    if (!ast_strlen_zero(p->fullcontact)) {
06832       /* If we have full contact, trust it */
06833       ast_build_string(&invite, &invite_max, "%s", p->fullcontact);
06834    } else {
06835       /* Otherwise, use the username while waiting for registration */
06836       ast_build_string(&invite, &invite_max, "sip:");
06837       if (!ast_strlen_zero(p->username)) {
06838          n = p->username;
06839          if (pedanticsipchecking) {
06840             ast_uri_encode(n, tmp, sizeof(tmp), 0);
06841             n = tmp;
06842          }
06843          ast_build_string(&invite, &invite_max, "%s@", n);
06844       }
06845       ast_build_string(&invite, &invite_max, "%s", p->tohost);
06846       if (ntohs(p->sa.sin_port) != STANDARD_SIP_PORT)
06847          ast_build_string(&invite, &invite_max, ":%d", ntohs(p->sa.sin_port));
06848       ast_build_string(&invite, &invite_max, "%s", urioptions);
06849    }
06850 
06851    /* If custom URI options have been provided, append them */
06852    if (p->options && p->options->uri_options)
06853       ast_build_string(&invite, &invite_max, ";%s", p->options->uri_options);
06854    
06855    ast_string_field_set(p, uri, invite_buf);
06856 
06857    if (sipmethod == SIP_NOTIFY && !ast_strlen_zero(p->theirtag)) { 
06858       /* If this is a NOTIFY, use the From: tag in the subscribe (RFC 3265) */
06859       snprintf(to, sizeof(to), "<sip:%s>;tag=%s", p->uri, p->theirtag);
06860    } else if (p->options && p->options->vxml_url) {
06861       /* If there is a VXML URL append it to the SIP URL */
06862       snprintf(to, sizeof(to), "<%s>;%s", p->uri, p->options->vxml_url);
06863    } else 
06864       snprintf(to, sizeof(to), "<%s>", p->uri);
06865    
06866    init_req(req, sipmethod, p->uri);
06867    snprintf(tmp, sizeof(tmp), "%d %s", ++p->ocseq, sip_methods[sipmethod].text);
06868 
06869    add_header(req, "Via", p->via);
06870    /* SLD: FIXME?: do Route: here too?  I think not cos this is the first request.
06871     * OTOH, then we won't have anything in p->route anyway */
06872    /* Build Remote Party-ID and From */
06873    if (ast_test_flag(&p->flags[0], SIP_SENDRPID) && (sipmethod == SIP_INVITE)) {
06874       build_rpid(p);
06875       add_header(req, "From", p->rpid_from);
06876    } else 
06877       add_header(req, "From", from);
06878    add_header(req, "To", to);
06879    ast_string_field_set(p, exten, l);
06880    build_contact(p);
06881    add_header(req, "Contact", p->our_contact);
06882    add_header(req, "Call-ID", p->callid);
06883    add_header(req, "CSeq", tmp);
06884    if (!ast_strlen_zero(global_useragent))
06885       add_header(req, "User-Agent", global_useragent);
06886    add_header(req, "Max-Forwards", DEFAULT_MAX_FORWARDS);
06887    if (!ast_strlen_zero(p->rpid))
06888       add_header(req, "Remote-Party-ID", p->rpid);
06889 }

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

Convert Insecure setting to printable string.

Definition at line 9841 of file chan_sip.c.

Referenced by _sip_show_peer().

09842 {
09843    if (port && invite)
09844       return "port,invite";
09845    else if (port)
09846       return "port";
09847    else if (invite)
09848       return "invite";
09849    else
09850       return "no";
09851 }

static void list_route ( struct sip_route route  )  [static]

List all routes - mostly for debugging.

Definition at line 8037 of file chan_sip.c.

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

Referenced by build_route().

08038 {
08039    if (!route)
08040       ast_verbose("list_route: no route\n");
08041    else {
08042       for (;route; route = route->next)
08043          ast_verbose("list_route: hop: <%s>\n", route->hop);
08044    }
08045 }

static int load_module ( void   )  [static]

PBX load module - initialization.

Definition at line 17634 of file chan_sip.c.

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

17635 {
17636    ASTOBJ_CONTAINER_INIT(&userl);   /* User object list */
17637    ASTOBJ_CONTAINER_INIT(&peerl);   /* Peer object list */
17638    ASTOBJ_CONTAINER_INIT(&regl); /* Registry object list */
17639 
17640    if (!(sched = sched_context_create())) {
17641       ast_log(LOG_ERROR, "Unable to create scheduler context\n");
17642       return AST_MODULE_LOAD_FAILURE;
17643    }
17644 
17645    if (!(io = io_context_create())) {
17646       ast_log(LOG_ERROR, "Unable to create I/O context\n");
17647       sched_context_destroy(sched);
17648       return AST_MODULE_LOAD_FAILURE;
17649    }
17650 
17651    sip_reloadreason = CHANNEL_MODULE_LOAD;
17652 
17653    if(reload_config(sip_reloadreason)) /* Load the configuration from sip.conf */
17654       return AST_MODULE_LOAD_DECLINE;
17655 
17656    /* Make sure we can register our sip channel type */
17657    if (ast_channel_register(&sip_tech)) {
17658       ast_log(LOG_ERROR, "Unable to register channel type 'SIP'\n");
17659       io_context_destroy(io);
17660       sched_context_destroy(sched);
17661       return AST_MODULE_LOAD_FAILURE;
17662    }
17663 
17664    /* Register all CLI functions for SIP */
17665    ast_cli_register_multiple(cli_sip, sizeof(cli_sip)/ sizeof(struct ast_cli_entry));
17666 
17667    /* Tell the RTP subdriver that we're here */
17668    ast_rtp_proto_register(&sip_rtp);
17669 
17670    /* Tell the UDPTL subdriver that we're here */
17671    ast_udptl_proto_register(&sip_udptl);
17672 
17673    /* Register dialplan applications */
17674    ast_register_application(app_dtmfmode, sip_dtmfmode, synopsis_dtmfmode, descrip_dtmfmode);
17675    ast_register_application(app_sipaddheader, sip_addheader, synopsis_sipaddheader, descrip_sipaddheader);
17676 
17677    /* Register dialplan functions */
17678    ast_custom_function_register(&sip_header_function);
17679    ast_custom_function_register(&sippeer_function);
17680    ast_custom_function_register(&sipchaninfo_function);
17681    ast_custom_function_register(&checksipdomain_function);
17682 
17683    /* Register manager commands */
17684    ast_manager_register2("SIPpeers", EVENT_FLAG_SYSTEM, manager_sip_show_peers,
17685          "List SIP peers (text format)", mandescr_show_peers);
17686    ast_manager_register2("SIPshowpeer", EVENT_FLAG_SYSTEM, manager_sip_show_peer,
17687          "Show SIP peer (text format)", mandescr_show_peer);
17688 
17689    sip_poke_all_peers();   
17690    sip_send_all_registers();
17691    
17692    /* And start the monitor for the first time */
17693    restart_monitor();
17694 
17695    return AST_MODULE_LOAD_SUCCESS;
17696 }

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

13868 {
13869    struct sip_dual target;    /* Chan 1: Call from tranferer to Asterisk */
13870                /* Chan 2: Call from Asterisk to target */
13871    int res = 0;
13872    struct sip_pvt *targetcall_pvt;
13873 
13874    /* Check if the call ID of the replaces header does exist locally */
13875    if (!(targetcall_pvt = get_sip_pvt_byid_locked(transferer->refer->replaces_callid, transferer->refer->replaces_callid_totag, 
13876       transferer->refer->replaces_callid_fromtag))) {
13877       if (transferer->refer->localtransfer) {
13878          /* We did not find the refered call. Sorry, can't accept then */
13879          transmit_response(transferer, "202 Accepted", req);
13880          /* Let's fake a response from someone else in order
13881             to follow the standard */
13882          transmit_notify_with_sipfrag(transferer, seqno, "481 Call leg/transaction does not exist", TRUE);
13883          append_history(transferer, "Xfer", "Refer failed");
13884          ast_clear_flag(&transferer->flags[0], SIP_GOTREFER);  
13885          transferer->refer->status = REFER_FAILED;
13886          return -1;
13887       }
13888       /* Fall through for remote transfers that we did not find locally */
13889       if (option_debug > 2)
13890          ast_log(LOG_DEBUG, "SIP attended transfer: Not our call - generating INVITE with replaces\n");
13891       return 0;
13892    }
13893 
13894    /* Ok, we can accept this transfer */
13895    transmit_response(transferer, "202 Accepted", req);
13896    append_history(transferer, "Xfer", "Refer accepted");
13897    if (!targetcall_pvt->owner) { /* No active channel */
13898       if (option_debug > 3)
13899          ast_log(LOG_DEBUG, "SIP attended transfer: Error: No owner of target call\n");
13900       /* Cancel transfer */
13901       transmit_notify_with_sipfrag(transferer, seqno, "503 Service Unavailable", TRUE);
13902       append_history(transferer, "Xfer", "Refer failed");
13903       ast_clear_flag(&transferer->flags[0], SIP_GOTREFER);
13904       transferer->refer->status = REFER_FAILED;
13905       ast_mutex_unlock(&targetcall_pvt->lock);
13906       ast_channel_unlock(current->chan1);
13907       return -1;
13908    }
13909 
13910    /* We have a channel, find the bridge */
13911    target.chan1 = targetcall_pvt->owner;           /* Transferer to Asterisk */
13912    target.chan2 = ast_bridged_channel(targetcall_pvt->owner);  /* Asterisk to target */
13913 
13914    if (!target.chan2 || !(target.chan2->_state == AST_STATE_UP || target.chan2->_state == AST_STATE_RINGING) ) {
13915       /* Wrong state of new channel */
13916       if (option_debug > 3) {
13917          if (target.chan2) 
13918             ast_log(LOG_DEBUG, "SIP attended transfer: Error: Wrong state of target call: %s\n", ast_state2str(target.chan2->_state));
13919          else if (target.chan1->_state != AST_STATE_RING)
13920             ast_log(LOG_DEBUG, "SIP attended transfer: Error: No target channel\n");
13921          else
13922             ast_log(LOG_DEBUG, "SIP attended transfer: Attempting transfer in ringing state\n");
13923       }
13924    }
13925 
13926    /* Transfer */
13927    if (option_debug > 3 && sipdebug) {
13928       if (current->chan2)  /* We have two bridges */
13929          ast_log(LOG_DEBUG, "SIP attended transfer: trying to bridge %s and %s\n", target.chan1->name, current->chan2->name);
13930       else        /* One bridge, propably transfer of IVR/voicemail etc */
13931          ast_log(LOG_DEBUG, "SIP attended transfer: trying to make %s take over (masq) %s\n", target.chan1->name, current->chan1->name);
13932    }
13933 
13934    ast_set_flag(&transferer->flags[0], SIP_DEFER_BYE_ON_TRANSFER);   /* Delay hangup */
13935 
13936    /* Perform the transfer */
13937    res = attempt_transfer(current, &target);
13938    ast_mutex_unlock(&targetcall_pvt->lock);
13939    if (res) {
13940       /* Failed transfer */
13941       transmit_notify_with_sipfrag(transferer, seqno, "486 Busy Here", TRUE);
13942       append_history(transferer, "Xfer", "Refer failed");
13943       transferer->refer->status = REFER_FAILED;
13944       if (targetcall_pvt->owner)
13945          ast_channel_unlock(targetcall_pvt->owner);
13946       /* Right now, we have to hangup, sorry. Bridge is destroyed */
13947       if (res != -2)
13948          ast_hangup(transferer->owner);
13949       else
13950          ast_clear_flag(&transferer->flags[0], SIP_DEFER_BYE_ON_TRANSFER);
13951    } else {
13952       /* Transfer succeeded! */
13953 
13954       /* Tell transferer that we're done. */
13955       transmit_notify_with_sipfrag(transferer, seqno, "200 OK", TRUE);
13956       append_history(transferer, "Xfer", "Refer succeeded");
13957       transferer->refer->status = REFER_200OK;
13958       if (targetcall_pvt->owner) {
13959          if (option_debug)
13960             ast_log(LOG_DEBUG, "SIP attended transfer: Unlocking channel %s\n", targetcall_pvt->owner->name);
13961          ast_channel_unlock(targetcall_pvt->owner);
13962       }
13963    }
13964    return 1;
13965 }

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

References t.

Referenced by sipsock_read().

04632 {
04633    int h = 0, t = 0; 
04634    int lws = 0; 
04635 
04636    for (; h < len;) { 
04637       /* Eliminate all CRs */ 
04638       if (msgbuf[h] == '\r') { 
04639          h++; 
04640          continue; 
04641       } 
04642       /* Check for end-of-line */ 
04643       if (msgbuf[h] == '\n') { 
04644          /* Check for end-of-message */ 
04645          if (h + 1 == len) 
04646             break; 
04647          /* Check for a continuation line */ 
04648          if (msgbuf[h + 1] == ' ' || msgbuf[h + 1] == '\t') { 
04649             /* Merge continuation line */ 
04650             h++; 
04651             continue; 
04652          } 
04653          /* Propagate LF and start new line */ 
04654          msgbuf[t++] = msgbuf[h++]; 
04655          lws = 0;
04656          continue; 
04657       } 
04658       if (msgbuf[h] == ' ' || msgbuf[h] == '\t') { 
04659          if (lws) { 
04660             h++; 
04661             continue; 
04662          } 
04663          msgbuf[t++] = msgbuf[h++]; 
04664          lws = 1; 
04665          continue; 
04666       } 
04667       msgbuf[t++] = msgbuf[h++]; 
04668       if (lws) 
04669          lws = 0; 
04670    } 
04671    msgbuf[t] = '\0'; 
04672    return t; 
04673 }

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

Make our SIP dialog tag.

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

04304 {
04305    snprintf(tagbuf, len, "as%08lx", ast_random());
04306 }

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

Show SIP peers in the manager API.

Definition at line 10086 of file chan_sip.c.

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

Referenced by load_module().

10087 {
10088    const char *a[4];
10089    const char *peer;
10090    int ret;
10091 
10092    peer = astman_get_header(m,"Peer");
10093    if (ast_strlen_zero(peer)) {
10094       astman_send_error(s, m, "Peer: <name> missing.\n");
10095       return 0;
10096    }
10097    a[0] = "sip";
10098    a[1] = "show";
10099    a[2] = "peer";
10100    a[3] = peer;
10101 
10102    ret = _sip_show_peer(1, -1, s, m, 4, a);
10103    astman_append(s, "\r\n\r\n" );
10104    return ret;
10105 }

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

Show SIP peers in the manager API.

Definition at line 9637 of file chan_sip.c.

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

Referenced by load_module().

09638 {
09639    const char *id = astman_get_header(m,"ActionID");
09640    const char *a[] = {"sip", "show", "peers"};
09641    char idtext[256] = "";
09642    int total = 0;
09643 
09644    if (!ast_strlen_zero(id))
09645       snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
09646 
09647    astman_send_ack(s, m, "Peer status list will follow");
09648    /* List the peers in separate manager events */
09649    _sip_show_peers(-1, &total, s, m, 3, a);
09650    /* Send final confirmation */
09651    astman_append(s,
09652    "Event: PeerlistComplete\r\n"
09653    "ListItems: %d\r\n"
09654    "%s"
09655    "\r\n", total, idtext);
09656    return 0;
09657 }

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

References len, sip_methods, and text.

Referenced by __sip_semi_ack(), and find_sip_method().

01654 {
01655    int len = strlen(sip_methods[id].text);
01656    int l_name = name ? strlen(name) : 0;
01657    /* true if the string is long enough, and ends with whitespace, and matches */
01658    return (l_name >= len && name[len] < 33 &&
01659       !strncasecmp(sip_methods[id].text, name, len));
01660 }

static char * nat2str ( int  nat  )  [static]

Convert NAT setting to text string.

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

09541 {
09542    switch(nat) {
09543    case SIP_NAT_NEVER:
09544       return "No";
09545    case SIP_NAT_ROUTE:
09546       return "Route";
09547    case SIP_NAT_ALWAYS:
09548       return "Always";
09549    case SIP_NAT_RFC3581:
09550       return "RFC3581";
09551    default:
09552       return "Unknown";
09553    }
09554 }

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

Copy SIP request, parse it.

Definition at line 2187 of file chan_sip.c.

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

Referenced by send_request(), and send_response().

02188 {
02189    memset(dst, 0, sizeof(*dst));
02190    memcpy(dst->data, src->data, sizeof(dst->data));
02191    dst->len = src->len;
02192    parse_request(dst);
02193 }

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

Parse 302 Moved temporalily response.

Definition at line 11709 of file chan_sip.c.

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

Referenced by handle_response().

11710 {
11711    char tmp[BUFSIZ];
11712    char *s, *e, *uri, *t;
11713    char *domain;
11714 
11715    ast_copy_string(tmp, get_header(req, "Contact"), sizeof(tmp));
11716    if ((t = strchr(tmp, ',')))
11717       *t = '\0';
11718    s = get_in_brackets(tmp);
11719    uri = ast_strdupa(s);
11720    if (ast_test_flag(&p->flags[0], SIP_PROMISCREDIR)) {
11721       if (!strncasecmp(s, "sip:", 4))
11722          s += 4;
11723       e = strchr(s, ';');
11724       if (e)
11725          *e = '\0';
11726       if (option_debug)
11727          ast_log(LOG_DEBUG, "Found promiscuous redirection to 'SIP/%s'\n", s);
11728       if (p->owner)
11729          ast_string_field_build(p->owner, call_forward, "SIP/%s", s);
11730    } else {
11731       e = strchr(tmp, '@');
11732       if (e) {
11733          *e++ = '\0';
11734          domain = e;
11735       } else {
11736          /* No username part */
11737          domain = tmp;
11738       }
11739       e = strchr(s, ';');  /* Strip of parameters in the username part */
11740       if (e)
11741          *e = '\0';
11742       e = strchr(domain, ';');   /* Strip of parameters in the domain part */
11743       if (e)
11744          *e = '\0';
11745    
11746       if (!strncasecmp(s, "sip:", 4))
11747          s += 4;
11748       if (option_debug > 1)
11749          ast_log(LOG_DEBUG, "Received 302 Redirect to extension '%s' (domain %s)\n", s, domain);
11750       if (p->owner) {
11751          pbx_builtin_setvar_helper(p->owner, "SIPREDIRECTURI", uri);
11752          pbx_builtin_setvar_helper(p->owner, "SIPDOMAIN", domain);
11753          ast_string_field_set(p->owner, call_forward, s);
11754       }
11755    }
11756 }

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

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

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

07794 {
07795    char contact[BUFSIZ]; 
07796    char *c;
07797 
07798    /* Look for brackets */
07799    ast_copy_string(contact, get_header(req, "Contact"), sizeof(contact));
07800    c = get_in_brackets(contact);
07801 
07802    /* Save full contact to call pvt for later bye or re-invite */
07803    ast_string_field_set(pvt, fullcontact, c);
07804 
07805    /* Save URI for later ACKs, BYE or RE-invites */
07806    ast_string_field_set(pvt, okcontacturi, c);
07807 
07808    /* We should return false for URI:s we can't handle,
07809       like sips:, tel:, mailto:,ldap: etc */
07810    return TRUE;      
07811 }

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

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

Referenced by register_verify().

07878 {
07879    char contact[BUFSIZ]; 
07880    char data[BUFSIZ];
07881    const char *expires = get_header(req, "Expires");
07882    int expiry = atoi(expires);
07883    char *curi, *n, *pt;
07884    int port;
07885    const char *useragent;
07886    struct hostent *hp;
07887    struct ast_hostent ahp;
07888    struct sockaddr_in oldsin;
07889 
07890    ast_copy_string(contact, get_header(req, "Contact"), sizeof(contact));
07891 
07892    if (ast_strlen_zero(expires)) {  /* No expires header */
07893       expires = strcasestr(contact, ";expires=");
07894       if (expires) {
07895          /* XXX bug here, we overwrite the string */
07896          expires = strsep((char **) &expires, ";"); /* trim ; and beyond */
07897          if (sscanf(expires + 9, "%d", &expiry) != 1)
07898             expiry = default_expiry;
07899       } else {
07900          /* Nothing has been specified */
07901          expiry = default_expiry;
07902       }
07903    }
07904 
07905    /* Look for brackets */
07906    curi = contact;
07907    if (strchr(contact, '<') == NULL)   /* No <, check for ; and strip it */
07908       strsep(&curi, ";");  /* This is Header options, not URI options */
07909    curi = get_in_brackets(contact);
07910 
07911    /* if they did not specify Contact: or Expires:, they are querying
07912       what we currently have stored as their contact address, so return
07913       it
07914    */
07915    if (ast_strlen_zero(curi) && ast_strlen_zero(expires)) {
07916       /* If we have an active registration, tell them when the registration is going to expire */
07917       if (peer->expire > -1 && !ast_strlen_zero(peer->fullcontact))
07918          pvt->expiry = ast_sched_when(sched, peer->expire);
07919       return PARSE_REGISTER_QUERY;
07920    } else if (!strcasecmp(curi, "*") || !expiry) { /* Unregister this peer */
07921       /* This means remove all registrations and return OK */
07922       memset(&peer->addr, 0, sizeof(peer->addr));
07923       if (peer->expire > -1)
07924          ast_sched_del(sched, peer->expire);
07925       peer->expire = -1;
07926 
07927       destroy_association(peer);
07928       
07929       register_peer_exten(peer, 0); /* Add extension from regexten= setting in sip.conf */
07930       peer->fullcontact[0] = '\0';
07931       peer->useragent[0] = '\0';
07932       peer->sipoptions = 0;
07933       peer->lastms = 0;
07934 
07935       if (option_verbose > 2)
07936          ast_verbose(VERBOSE_PREFIX_3 "Unregistered SIP '%s'\n", peer->name);
07937          manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unregistered\r\n", peer->name);
07938       return PARSE_REGISTER_UPDATE;
07939    }
07940 
07941    /* Store whatever we got as a contact from the client */
07942    ast_copy_string(peer->fullcontact, curi, sizeof(peer->fullcontact));
07943 
07944    /* For the 200 OK, we should use the received contact */
07945    ast_string_field_build(pvt, our_contact, "<%s>", curi);
07946 
07947    /* Make sure it's a SIP URL */
07948    if (strncasecmp(curi, "sip:", 4)) {
07949       ast_log(LOG_NOTICE, "'%s' is not a valid SIP contact (missing sip:) trying to use anyway\n", curi);
07950    } else
07951       curi += 4;
07952    /* Ditch q */
07953    curi = strsep(&curi, ";");
07954    /* Grab host */
07955    n = strchr(curi, '@');
07956    if (!n) {
07957       n = curi;
07958       curi = NULL;
07959    } else
07960       *n++ = '\0';
07961    pt = strchr(n, ':');
07962    if (pt) {
07963       *pt++ = '\0';
07964       port = atoi(pt);
07965    } else
07966       port = STANDARD_SIP_PORT;
07967    oldsin = peer->addr;
07968    if (!ast_test_flag(&peer->flags[0], SIP_NAT_ROUTE)) {
07969       /* XXX This could block for a long time XXX */
07970       hp = ast_gethostbyname(n, &ahp);
07971       if (!hp)  {
07972          ast_log(LOG_WARNING, "Invalid host '%s'\n", n);
07973          return PARSE_REGISTER_FAILED;
07974       }
07975       peer->addr.sin_family = AF_INET;
07976       memcpy(&peer->addr.sin_addr, hp->h_addr, sizeof(peer->addr.sin_addr));
07977       peer->addr.sin_port = htons(port);
07978    } else {
07979       /* Don't trust the contact field.  Just use what they came to us
07980          with */
07981       peer->addr = pvt->recv;
07982    }
07983 
07984    /* Save SIP options profile */
07985    peer->sipoptions = pvt->sipoptions;
07986 
07987    if (curi && ast_strlen_zero(peer->username))
07988       ast_copy_string(peer->username, curi, sizeof(peer->username));
07989 
07990    if (peer->expire > -1) {
07991       ast_sched_del(sched, peer->expire);
07992       peer->expire = -1;
07993    }
07994    if (expiry > max_expiry)
07995       expiry = max_expiry;
07996    if (expiry < min_expiry)
07997       expiry = min_expiry;
07998    peer->expire = ast_test_flag(&peer->flags[0], SIP_REALTIME) ? -1 :
07999       ast_sched_add(sched, (expiry + 10) * 1000, expire_register, peer);
08000    pvt->expiry = expiry;
08001    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);
08002    if (!ast_test_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT)) 
08003       ast_db_put("SIP/Registry", peer->name, data);
08004    manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Registered\r\n", peer->name);
08005 
08006    /* Is this a new IP address for us? */
08007    if (inaddrcmp(&peer->addr, &oldsin)) {
08008       sip_poke_peer(peer);
08009       if (option_verbose > 2)
08010          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);
08011       register_peer_exten(peer, 1);
08012    }
08013    
08014    /* Save User agent */
08015    useragent = get_header(req, "User-Agent");
08016    if (strcasecmp(useragent, peer->useragent)) {   /* XXX copy if they are different ? */
08017       ast_copy_string(peer->useragent, useragent, sizeof(peer->useragent));
08018       if (option_verbose > 3)
08019          ast_verbose(VERBOSE_PREFIX_3 "Saved useragent \"%s\" for peer %s\n", peer->useragent, peer->name);  
08020    }
08021    return PARSE_REGISTER_UPDATE;
08022 }

static void parse_request ( struct sip_request req  )  [static]

Parse a SIP message.

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

Definition at line 4678 of file chan_sip.c.

References ast_log(), ast_strlen_zero(), sip_request::data, determine_firstline_parts(), f, sip_request::header, sip_request::headers, sip_request::line, sip_request::lines, LOG_DEBUG, LOG_WARNING, option_debug, SIP_MAX_HEADERS, SIP_MAX_LINES, and sipdebug.

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

04679 {
04680    /* Divide fields by NULL's */
04681    char *c;
04682    int f = 0;
04683 
04684    c = req->data;
04685 
04686    /* First header starts immediately */
04687    req->header[f] = c;
04688    while(*c) {
04689       if (*c == '\n') {
04690          /* We've got a new header */
04691          *c = 0;
04692 
04693          if (sipdebug && option_debug > 3)
04694             ast_log(LOG_DEBUG, "Header %d: %s (%d)\n", f, req->header[f], (int) strlen(req->header[f]));
04695          if (ast_strlen_zero(req->header[f])) {
04696             /* Line by itself means we're now in content */
04697             c++;
04698             break;
04699          }
04700          if (f >= SIP_MAX_HEADERS - 1) {
04701             ast_log(LOG_WARNING, "Too many SIP headers. Ignoring.\n");
04702          } else
04703             f++;
04704          req->header[f] = c + 1;
04705       } else if (*c == '\r') {
04706          /* Ignore but eliminate \r's */
04707          *c = 0;
04708       }
04709       c++;
04710    }
04711    /* Check for last header */
04712    if (!ast_strlen_zero(req->header[f])) {
04713       if (sipdebug && option_debug > 3)
04714          ast_log(LOG_DEBUG, "Header %d: %s (%d)\n", f, req->header[f], (int) strlen(req->header[f]));
04715       f++;
04716    }
04717    req->headers = f;
04718    /* Now we process any mime content */
04719    f = 0;
04720    req->line[f] = c;
04721    while(*c) {
04722       if (*c == '\n') {
04723          /* We've got a new line */
04724          *c = 0;
04725          if (sipdebug && option_debug > 3)
04726             ast_log(LOG_DEBUG, "Line: %s (%d)\n", req->line[f], (int) strlen(req->line[f]));
04727          if (f >= SIP_MAX_LINES - 1) {
04728             ast_log(LOG_WARNING, "Too many SDP lines. Ignoring.\n");
04729          } else
04730             f++;
04731          req->line[f] = c + 1;
04732       } else if (*c == '\r') {
04733          /* Ignore and eliminate \r's */
04734          *c = 0;
04735       }
04736       c++;
04737    }
04738    /* Check for last line */
04739    if (!ast_strlen_zero(req->line[f])) 
04740       f++;
04741    req->lines = f;
04742    if (*c) 
04743       ast_log(LOG_WARNING, "Odd content, extra stuff left over ('%s')\n", c);
04744    /* Split up the first line parts */
04745    determine_firstline_parts(req);
04746 }

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

Parse supported header in incoming packet.

Definition at line 1677 of file chan_sip.c.

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

Referenced by handle_request_invite().

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

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

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

09560 {
09561    int res = 0;
09562    if (peer->maxms) {
09563       if (peer->lastms < 0) {
09564          ast_copy_string(status, "UNREACHABLE", statuslen);
09565       } else if (peer->lastms > peer->maxms) {
09566          snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms);
09567          res = 1;
09568       } else if (peer->lastms) {
09569          snprintf(status, statuslen, "OK (%d ms)", peer->lastms);
09570          res = 1;
09571       } else {
09572          ast_copy_string(status, "UNKNOWN", statuslen);
09573       }
09574    } else { 
09575       ast_copy_string(status, "Unmonitored", statuslen);
09576       /* Checking if port is 0 */
09577       res = -1;
09578    }
09579    return res;
09580 }

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

10028 {
10029    int x, codec;
10030 
10031    for(x = 0; x < 32 ; x++) {
10032       codec = ast_codec_pref_index(pref, x);
10033       if (!codec)
10034          break;
10035       ast_cli(fd, "%s", ast_getformatname(codec));
10036       ast_cli(fd, ":%d", pref->framing[x]);
10037       if (x < 31 && ast_codec_pref_index(pref, x + 1))
10038          ast_cli(fd, ",");
10039    }
10040    if (!x)
10041       ast_cli(fd, "none");
10042 }

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

Print call group and pickup group.

Definition at line 9818 of file chan_sip.c.

References ast_cli(), and ast_print_group().

Referenced by _sip_show_peer(), and sip_show_user().

09819 {
09820    char buf[256];
09821    ast_cli(fd, crlf ? "%s\r\n" : "%s\n", ast_print_group(buf, sizeof(buf), group) );
09822 }

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

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

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

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

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

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

Definition at line 2456 of file chan_sip.c.

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

02457 {
02458    struct sip_peer *peer=NULL;
02459    struct ast_variable *var;
02460    struct ast_config *peerlist = NULL;
02461    struct ast_variable *tmp;
02462    struct ast_flags flags = {0};
02463    const char *iabuf = NULL;
02464    char portstring[6]; /*up to five digits plus null terminator*/
02465    const char *insecure; 
02466    char *cat = NULL;
02467    unsigned short portnum;
02468 
02469    /* First check on peer name */
02470    if (newpeername) 
02471       var = ast_load_realtime("sippeers", "name", newpeername, NULL);
02472    else if (sin) {   /* Then check on IP address */
02473       iabuf = ast_inet_ntoa(sin->sin_addr);
02474       portnum = ntohs(sin->sin_port);
02475       sprintf(portstring, "%d", portnum);
02476       var = ast_load_realtime("sippeers", "host", iabuf, "port", portstring, NULL); /* First check for fixed IP hosts */
02477       if (!var)
02478          var = ast_load_realtime("sippeers", "ipaddr", iabuf, "port", portstring, NULL);  /* Then check for registered hosts */
02479       if (!var) { 
02480          peerlist = ast_load_realtime_multientry("sippeers", "host", iabuf, NULL); /*No exact match, see if port is insecure, try host match first*/
02481          if(peerlist){ 
02482             while((cat = ast_category_browse(peerlist, cat)))
02483             {
02484                insecure = ast_variable_retrieve(peerlist, cat, "insecure");
02485                set_insecure_flags(&flags, insecure, -1);
02486                if(ast_test_flag(&flags, SIP_INSECURE_PORT)) {
02487                   var = ast_category_root(peerlist, cat);
02488                   break;
02489                }
02490             }
02491          }
02492          if(!var) {
02493             ast_config_destroy(peerlist);
02494             peerlist = NULL; /*for safety's sake*/
02495             cat = NULL;
02496             peerlist = ast_load_realtime_multientry("sippeers", "ipaddr", iabuf, NULL); /*No exact match, see if port is insecure, now try ip address match*/
02497             if(peerlist) {
02498                while((cat = ast_category_browse(peerlist, cat)))
02499                {
02500                   insecure = ast_variable_retrieve(peerlist, cat, "insecure");
02501                   set_insecure_flags(&flags, insecure, -1);
02502                   if(ast_test_flag(&flags, SIP_INSECURE_PORT)) {
02503                      var = ast_category_root(peerlist, cat);
02504                      break;
02505                   }
02506                }
02507             }
02508          }
02509       }
02510    } else
02511       return NULL;
02512 
02513    if (!var) {
02514       if(peerlist)
02515          ast_config_destroy(peerlist);
02516       return NULL;
02517    }
02518 
02519    for (tmp = var; tmp; tmp = tmp->next) {
02520       /* If this is type=user, then skip this object. */
02521       if (!strcasecmp(tmp->name, "type") &&
02522           !strcasecmp(tmp->value, "user")) {
02523          ast_variables_destroy(var);
02524          return NULL;
02525       } else if (!newpeername && !strcasecmp(tmp->name, "name")) {
02526          newpeername = tmp->value;
02527       }
02528    }
02529    
02530    if (!newpeername) {  /* Did not find peer in realtime */
02531       ast_log(LOG_WARNING, "Cannot Determine peer name ip=%s\n", iabuf);
02532       if(peerlist)
02533          ast_config_destroy(peerlist);
02534       else
02535          ast_variables_destroy(var);
02536       return NULL;
02537    }
02538 
02539    /* Peer found in realtime, now build it in memory */
02540    peer = build_peer(newpeername, var, NULL, !ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS));
02541    if (!peer) {
02542       if(peerlist)
02543          ast_config_destroy(peerlist);
02544       else
02545          ast_variables_destroy(var);
02546       return NULL;
02547    }
02548 
02549    if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) {
02550       /* Cache peer */
02551       ast_copy_flags(&peer->flags[1],&global_flags[1], SIP_PAGE2_RTAUTOCLEAR|SIP_PAGE2_RTCACHEFRIENDS);
02552       if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTAUTOCLEAR)) {
02553          if (peer->expire > -1) {
02554             ast_sched_del(sched, peer->expire);
02555          }
02556          peer->expire = ast_sched_add(sched, (global_rtautoclear) * 1000, expire_register, (void *)peer);
02557       }
02558       ASTOBJ_CONTAINER_LINK(&peerl,peer);
02559    } else {
02560       ast_set_flag(&peer->flags[0], SIP_REALTIME);
02561    }
02562    if(peerlist)
02563       ast_config_destroy(peerlist);
02564    else
02565       ast_variables_destroy(var);
02566    return peer;
02567 }

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

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

02342 {
02343    char port[10];
02344    char ipaddr[INET_ADDRSTRLEN];
02345    char regseconds[20];
02346 
02347    char *sysname = ast_config_AST_SYSTEM_NAME;
02348    char *syslabel = NULL;
02349 
02350    time_t nowtime = time(NULL) + expirey;
02351    const char *fc = fullcontact ? "fullcontact" : NULL;
02352    
02353    snprintf(regseconds, sizeof(regseconds), "%d", (int)nowtime);  /* Expiration time */
02354    ast_copy_string(ipaddr, ast_inet_ntoa(sin->sin_addr), sizeof(ipaddr));
02355    snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port));
02356    
02357    if (ast_strlen_zero(sysname)) /* No system name, disable this */
02358       sysname = NULL;
02359    else if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTSAVE_SYSNAME))
02360       syslabel = "regserver";
02361 
02362    if (fc)
02363       ast_update_realtime("sippeers", "name", peername, "ipaddr", ipaddr,
02364          "port", port, "regseconds", regseconds,
02365          "username", username, fc, fullcontact, syslabel, sysname, NULL); /* note fc and syslabel _can_ be NULL */
02366    else
02367       ast_update_realtime("sippeers", "name", peername, "ipaddr", ipaddr,
02368          "port", port, "regseconds", regseconds,
02369          "username", username, syslabel, sysname, NULL); /* note syslabel _can_ be NULL */
02370 }

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

Load user from realtime storage Loads user from "sipusers" category in realtime (extconfig.conf) Users are matched on From: user name (the domain in skipped).

Definition at line 2617 of file chan_sip.c.

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

02618 {
02619    struct ast_variable *var;
02620    struct ast_variable *tmp;
02621    struct sip_user *user = NULL;
02622 
02623    var = ast_load_realtime("sipusers", "name", username, NULL);
02624 
02625    if (!var)
02626       return NULL;
02627 
02628    for (tmp = var; tmp; tmp = tmp->next) {
02629       if (!strcasecmp(tmp->name, "type") &&
02630          !strcasecmp(tmp->value, "peer")) {
02631          ast_variables_destroy(var);
02632          return NULL;
02633       }
02634    }
02635 
02636    user = build_user(username, var, !ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS));
02637    
02638    if (!user) {   /* No user found */
02639       ast_variables_destroy(var);
02640       return NULL;
02641    }
02642 
02643    if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) {
02644       ast_set_flag(&user->flags[1], SIP_PAGE2_RTCACHEFRIENDS);
02645       suserobjs++;
02646       ASTOBJ_CONTAINER_LINK(&userl,user);
02647    } else {
02648       /* Move counter from s to r... */
02649       suserobjs--;
02650       ruserobjs++;
02651       ast_set_flag(&user->flags[0], SIP_REALTIME);
02652    }
02653    ast_variables_destroy(var);
02654    return user;
02655 }

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

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

Referenced by handle_request_message().

09445 {
09446    char buf[1024];
09447    struct ast_frame f;
09448    const char *content_type = get_header(req, "Content-Type");
09449 
09450    if (strcmp(content_type, "text/plain")) { /* No text/plain attachment */
09451       transmit_response(p, "415 Unsupported Media Type", req); /* Good enough, or? */
09452       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
09453       return;
09454    }
09455 
09456    if (get_msg_text(buf, sizeof(buf), req)) {
09457       ast_log(LOG_WARNING, "Unable to retrieve text from %s\n", p->callid);
09458       transmit_response(p, "202 Accepted", req);
09459       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
09460       return;
09461    }
09462 
09463    if (p->owner) {
09464       if (sip_debug_test_pvt(p))
09465          ast_verbose("Message received: '%s'\n", buf);
09466       memset(&f, 0, sizeof(f));
09467       f.frametype = AST_FRAME_TEXT;
09468       f.subclass = 0;
09469       f.offset = 0;
09470       f.data = buf;
09471       f.datalen = strlen(buf);
09472       ast_queue_frame(p->owner, &f);
09473       transmit_response(p, "202 Accepted", req); /* We respond 202 accepted, since we relay the message */
09474    } else { /* Message outside of a call, we do not support that */
09475       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);
09476       transmit_response(p, "405 Method Not Allowed", req); /* Good enough, or? */
09477    }
09478    sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
09479    return;
09480 }

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

Convert transfer status to string.

Definition at line 1612 of file chan_sip.c.

References referstatusstrings, and c_referstatusstring::text.

Referenced by __sip_show_channels().

01613 {
01614    int i = (sizeof(referstatusstrings) / sizeof(referstatusstrings[0]));
01615    int x;
01616 
01617    for (x = 0; x < i; x++) {
01618       if (referstatusstrings[x].status ==  rstatus)
01619          return (char *) referstatusstrings[x].text;
01620    }
01621    return "";
01622 }

static void reg_source_db ( struct sip_peer peer  )  [static]

Get registration details from Asterisk DB.

Definition at line 7733 of file chan_sip.c.

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

07734 {
07735    char data[256];
07736    struct in_addr in;
07737    int expiry;
07738    int port;
07739    char *scan, *addr, *port_str, *expiry_str, *username, *contact;
07740 
07741    if (ast_test_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT)) 
07742       return;
07743    if (ast_db_get("SIP/Registry", peer->name, data, sizeof(data)))
07744       return;
07745 
07746    scan = data;
07747    addr = strsep(&scan, ":");
07748    port_str = strsep(&scan, ":");
07749    expiry_str = strsep(&scan, ":");
07750    username = strsep(&scan, ":");
07751    contact = scan;   /* Contact include sip: and has to be the last part of the database entry as long as we use : as a separator */
07752 
07753    if (!inet_aton(addr, &in))
07754       return;
07755 
07756    if (port_str)
07757       port = atoi(port_str);
07758    else
07759       return;
07760 
07761    if (expiry_str)
07762       expiry = atoi(expiry_str);
07763    else
07764       return;
07765 
07766    if (username)
07767       ast_copy_string(peer->username, username, sizeof(peer->username));
07768    if (contact)
07769       ast_copy_string(peer->fullcontact, contact, sizeof(peer->fullcontact));
07770 
07771    if (option_debug > 1)
07772       ast_log(LOG_DEBUG, "SIP Seeding peer from astdb: '%s' at %s@%s:%d for %d\n",
07773              peer->name, peer->username, ast_inet_ntoa(in), port, expiry);
07774 
07775    memset(&peer->addr, 0, sizeof(peer->addr));
07776    peer->addr.sin_family = AF_INET;
07777    peer->addr.sin_addr = in;
07778    peer->addr.sin_port = htons(port);
07779    if (sipsock < 0) {
07780       /* SIP isn't up yet, so schedule a poke only, pretty soon */
07781       if (peer->pokeexpire > -1)
07782          ast_sched_del(sched, peer->pokeexpire);
07783       peer->pokeexpire = ast_sched_add(sched, ast_random() % 5000 + 1, sip_poke_peer_s, peer);
07784    } else
07785       sip_poke_peer(peer);
07786    if (peer->expire > -1)
07787       ast_sched_del(sched, peer->expire);
07788    peer->expire = ast_sched_add(sched, (expiry + 10) * 1000, expire_register, peer);
07789    register_peer_exten(peer, TRUE);
07790 }

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

Automatically add peer extension to dial plan.

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

02374 {
02375    char multi[256];
02376    char *stringp, *ext, *context;
02377 
02378    /* XXX note that global_regcontext is both a global 'enable' flag and
02379     * the name of the global regexten context, if not specified
02380     * individually.
02381     */
02382    if (ast_strlen_zero(global_regcontext))
02383       return;
02384 
02385    ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi));
02386    stringp = multi;
02387    while ((ext = strsep(&stringp, "&"))) {
02388       if ((context = strchr(ext, '@'))) {
02389          *context++ = '\0';   /* split ext@context */
02390          if (!ast_context_find(context)) {
02391             ast_log(LOG_WARNING, "Context %s must exist in regcontext= in sip.conf!\n", context);
02392             continue;
02393          }
02394       } else {
02395          context = global_regcontext;
02396       }
02397       if (onoff)
02398          ast_add_extension(context, 1, ext, 1, NULL, NULL, "Noop",
02399              ast_strdup(peer->name), ast_free, "SIP");
02400       else
02401          ast_context_remove_extension(context, ext, 1, NULL);
02402    }
02403 }

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

References ast_apply_ha(), ast_copy_flags, ast_device_state_changed(), ast_inet_ntoa(), AST_LIST_EMPTY, ast_log(), ast_rtp_codec_setpref(), ast_string_field_set, ast_test_flag, ast_uri_decode(), ASTOBJ_CONTAINER_LINK, ASTOBJ_UNREF, AUTH_ACL_FAILED, AUTH_NOT_FOUND, AUTH_PEER_NOT_DYNAMIC, AUTH_SECRET_FAILED, AUTH_UNKNOWN_DOMAIN, AUTH_USERNAME_MISMATCH, sip_peer::autoframing, sip_pvt::autoframing, build_contact(), check_auth(), check_sip_domain(), EVENT_FLAG_SYSTEM, sip_pvt::expiry, exten, find_peer(), sip_pvt::flags, sip_peer::flags, get_header(), get_in_brackets(), sip_peer::ha, sip_pvt::initreq, sip_peer::lastmsgssent, LOG_ERROR, LOG_NOTICE, LOG_WARNING, manager_event(), sip_peer::md5secret, name, parse_register_contact(), PARSE_REGISTER_FAILED, PARSE_REGISTER_QUERY, PARSE_REGISTER_UPDATE, peerl, sip_peer::prefs, sip_pvt::rtp, sip_peer::secret, sip_cancel_destroy(), sip_destroy_peer(), SIP_NAT, SIP_PAGE2_DYNAMIC, SIP_PAGE2_SUBSCRIBEMWIONLY, SIP_PKT_IGNORE, SIP_REGISTER, strsep(), t, temp_peer(), transmit_fake_auth_response(), transmit_response(), transmit_response_with_date(), update_peer(), and XMIT_UNRELIABLE.

08388 {
08389    enum check_auth_result res = AUTH_NOT_FOUND;
08390    struct sip_peer *peer;
08391    char tmp[256];
08392    char *name, *c;
08393    char *t;
08394    char *domain;
08395 
08396    /* Terminate URI */
08397    t = uri;
08398    while(*t && (*t > 32) && (*t != ';'))
08399       t++;
08400    *t = '\0';
08401    
08402    ast_copy_string(tmp, get_header(req, "To"), sizeof(tmp));
08403    if (pedanticsipchecking)
08404       ast_uri_decode(tmp);
08405 
08406    c = get_in_brackets(tmp);
08407    c = strsep(&c, ";"); /* Ditch ;user=phone */
08408 
08409    if (!strncasecmp(c, "sip:", 4)) {
08410       name = c + 4;
08411    } else {
08412       name = c;
08413       ast_log(LOG_NOTICE, "Invalid to address: '%s' from %s (missing sip:) trying to use anyway...\n", c, ast_inet_ntoa(sin->sin_addr));
08414    }
08415 
08416    /* Strip off the domain name */
08417    if ((c = strchr(name, '@'))) {
08418       *c++ = '\0';
08419       domain = c;
08420       if ((c = strchr(domain, ':')))   /* Remove :port */
08421          *c = '\0';
08422       if (!AST_LIST_EMPTY(&domain_list)) {
08423          if (!check_sip_domain(domain, NULL, 0)) {
08424             transmit_response(p, "404 Not found (unknown domain)", &p->initreq);
08425             return AUTH_UNKNOWN_DOMAIN;
08426          }
08427       }
08428    }
08429 
08430    ast_string_field_set(p, exten, name);
08431    build_contact(p);
08432    peer = find_peer(name, NULL, 1);
08433    if (!(peer && ast_apply_ha(peer->ha, sin))) {
08434       /* Peer fails ACL check */
08435       if (peer) {
08436          ASTOBJ_UNREF(peer, sip_destroy_peer);
08437          peer = NULL;
08438          res = AUTH_ACL_FAILED;
08439       } else
08440          res = AUTH_NOT_FOUND;
08441    }
08442    if (peer) {
08443       /* Set Frame packetization */
08444       if (p->rtp) {
08445          ast_rtp_codec_setpref(p->rtp, &peer->prefs);
08446          p->autoframing = peer->autoframing;
08447       }
08448       if (!ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)) {
08449          ast_log(LOG_ERROR, "Peer '%s' is trying to register, but not configured as host=dynamic\n", peer->name);
08450          res = AUTH_PEER_NOT_DYNAMIC;
08451       } else {
08452          ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_NAT);
08453          transmit_response(p, "100 Trying", req);
08454          if (!(res = check_auth(p, req, peer->name, peer->secret, peer->md5secret, SIP_REGISTER, uri, XMIT_UNRELIABLE, ast_test_flag(req, SIP_PKT_IGNORE)))) {
08455             sip_cancel_destroy(p);
08456 
08457             /* We have a succesful registration attemp with proper authentication,
08458                now, update the peer */
08459             switch (parse_register_contact(p, peer, req)) {
08460             case PARSE_REGISTER_FAILED:
08461                ast_log(LOG_WARNING, "Failed to parse contact info\n");
08462                transmit_response_with_date(p, "400 Bad Request", req);
08463                peer->lastmsgssent = -1;
08464                res = 0;
08465                break;
08466             case PARSE_REGISTER_QUERY:
08467                transmit_response_with_date(p, "200 OK", req);
08468                peer->lastmsgssent = -1;
08469                res = 0;
08470                break;
08471             case PARSE_REGISTER_UPDATE:
08472                update_peer(peer, p->expiry);
08473                /* Say OK and ask subsystem to retransmit msg counter */
08474                transmit_response_with_date(p, "200 OK", req);
08475                if (!ast_test_flag((&peer->flags[1]), SIP_PAGE2_SUBSCRIBEMWIONLY))
08476                   peer->lastmsgssent = -1;
08477                res = 0;
08478                break;
08479             }
08480          } 
08481       }
08482    }
08483    if (!peer && autocreatepeer) {
08484       /* Create peer if we have autocreate mode enabled */
08485       peer = temp_peer(name);
08486       if (peer) {
08487          ASTOBJ_CONTAINER_LINK(&peerl, peer);
08488          sip_cancel_destroy(p);
08489          switch (parse_register_contact(p, peer, req)) {
08490          case PARSE_REGISTER_FAILED:
08491             ast_log(LOG_WARNING, "Failed to parse contact info\n");
08492             transmit_response_with_date(p, "400 Bad Request", req);
08493             peer->lastmsgssent = -1;
08494             res = 0;
08495             break;
08496          case PARSE_REGISTER_QUERY:
08497             transmit_response_with_date(p, "200 OK", req);
08498             peer->lastmsgssent = -1;
08499             res = 0;
08500             break;
08501          case PARSE_REGISTER_UPDATE:
08502             /* Say OK and ask subsystem to retransmit msg counter */
08503             transmit_response_with_date(p, "200 OK", req);
08504             manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Registered\r\n", peer->name);
08505             peer->lastmsgssent = -1;
08506             res = 0;
08507             break;
08508          }
08509       }
08510    }
08511    if (!res) {
08512       ast_device_state_changed("SIP/%s", peer->name);
08513    }
08514    if (res < 0) {
08515       switch (res) {
08516       case AUTH_SECRET_FAILED:
08517          /* Wrong password in authentication. Go away, don't try again until you fixed it */
08518          transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq);
08519          break;
08520       case AUTH_USERNAME_MISMATCH:
08521          /* Username and digest username does not match. 
08522             Asterisk uses the From: username for authentication. We need the
08523             users to use the same authentication user name until we support
08524             proper authentication by digest auth name */
08525          transmit_response(p, "403 Authentication user name does not match account name", &p->initreq);
08526          break;
08527       case AUTH_NOT_FOUND:
08528       case AUTH_PEER_NOT_DYNAMIC:
08529       case AUTH_ACL_FAILED:
08530          if (global_alwaysauthreject) {
08531             transmit_fake_auth_response(p, &p->initreq, 1);
08532          } else {
08533             /* URI not found */
08534             if (res == AUTH_UNKNOWN_DOMAIN || res == AUTH_PEER_NOT_DYNAMIC)
08535                transmit_response(p, "403 Forbidden", &p->initreq);
08536             else
08537                transmit_response(p, "404 Not found", &p->initreq);
08538          }
08539          break;
08540       default:
08541          break;
08542       }
08543    }
08544    if (peer)
08545       ASTOBJ_UNREF(peer, sip_destroy_peer);
08546 
08547    return res;
08548 }

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

Convert registration state status to string.

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

07233 {
07234    switch(regstate) {
07235    case REG_STATE_FAILED:
07236       return "Failed";
07237    case REG_STATE_UNREGISTERED:
07238       return "Unregistered";
07239    case REG_STATE_REGSENT:
07240       return "Request Sent";
07241    case REG_STATE_AUTHSENT:
07242       return "Auth. Sent";
07243    case REG_STATE_REGISTERED:
07244       return "Registered";
07245    case REG_STATE_REJECTED:
07246       return "Rejected";
07247    case REG_STATE_TIMEOUT:
07248       return "Timeout";
07249    case REG_STATE_NOAUTH:
07250       return "No Authentication";
07251    default:
07252       return "Unknown";
07253    }
07254 }

static int reload ( void   )  [static]

Part of Asterisk module interface.

Definition at line 17520 of file chan_sip.c.

References sip_reload().

17521 {
17522    return sip_reload(0, 0, NULL);
17523 }

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

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

16423 {
16424    struct ast_config *cfg, *ucfg;
16425    struct ast_variable *v;
16426    struct sip_peer *peer;
16427    struct sip_user *user;
16428    struct ast_hostent ahp;
16429    char *cat, *stringp, *context, *oldregcontext;
16430    char newcontexts[AST_MAX_CONTEXT], oldcontexts[AST_MAX_CONTEXT];
16431    struct hostent *hp;
16432    int format;
16433    struct ast_flags dummy[2];
16434    int auto_sip_domains = FALSE;
16435    struct sockaddr_in old_bindaddr = bindaddr;
16436    int registry_count = 0, peer_count = 0, user_count = 0;
16437    unsigned int temp_tos = 0;
16438    struct ast_flags debugflag = {0};
16439 
16440    cfg = ast_config_load(config);
16441 
16442    /* We *must* have a config file otherwise stop immediately */
16443    if (!cfg) {
16444       ast_log(LOG_NOTICE, "Unable to load config %s\n", config);
16445       return -1;
16446    }
16447    
16448    /* Initialize copy of current global_regcontext for later use in removing stale contexts */
16449    ast_copy_string(oldcontexts, global_regcontext, sizeof(oldcontexts));
16450    oldregcontext = oldcontexts;
16451 
16452    /* Clear all flags before setting default values */
16453    /* Preserve debugging settings for console */
16454    ast_copy_flags(&debugflag, &global_flags[1], SIP_PAGE2_DEBUG_CONSOLE);
16455    ast_clear_flag(&global_flags[0], AST_FLAGS_ALL);
16456    ast_clear_flag(&global_flags[1], AST_FLAGS_ALL);
16457    ast_copy_flags(&global_flags[1], &debugflag, SIP_PAGE2_DEBUG_CONSOLE);
16458 
16459    /* Reset IP addresses  */
16460    memset(&bindaddr, 0, sizeof(bindaddr));
16461    ast_free_ha(localaddr);
16462    memset(&localaddr, 0, sizeof(localaddr));
16463    memset(&externip, 0, sizeof(externip));
16464    memset(&default_prefs, 0 , sizeof(default_prefs));
16465    outboundproxyip.sin_port = htons(STANDARD_SIP_PORT);
16466    outboundproxyip.sin_family = AF_INET;  /* Type of address: IPv4 */
16467    ourport = STANDARD_SIP_PORT;
16468    srvlookup = DEFAULT_SRVLOOKUP;
16469    global_tos_sip = DEFAULT_TOS_SIP;
16470    global_tos_audio = DEFAULT_TOS_AUDIO;
16471    global_tos_video = DEFAULT_TOS_VIDEO;
16472    externhost[0] = '\0';         /* External host name (for behind NAT DynDNS support) */
16473    externexpire = 0;       /* Expiration for DNS re-issuing */
16474    externrefresh = 10;
16475    memset(&outboundproxyip, 0, sizeof(outboundproxyip));
16476 
16477    /* Reset channel settings to default before re-configuring */
16478    allow_external_domains = DEFAULT_ALLOW_EXT_DOM;          /* Allow external invites */
16479    global_regcontext[0] = '\0';
16480    expiry = DEFAULT_EXPIRY;
16481    global_notifyringing = DEFAULT_NOTIFYRINGING;
16482    global_limitonpeers = FALSE;
16483    global_directrtpsetup = FALSE;      /* Experimental feature, disabled by default */
16484    global_notifyhold = FALSE;
16485    global_alwaysauthreject = 0;
16486    global_allowsubscribe = FALSE;
16487    ast_copy_string(global_useragent, DEFAULT_USERAGENT, sizeof(global_useragent));
16488    ast_copy_string(default_notifymime, DEFAULT_NOTIFYMIME, sizeof(default_notifymime));
16489    if (ast_strlen_zero(ast_config_AST_SYSTEM_NAME))
16490       ast_copy_string(global_realm, DEFAULT_REALM, sizeof(global_realm));
16491    else
16492       ast_copy_string(global_realm, ast_config_AST_SYSTEM_NAME, sizeof(global_realm));
16493    ast_copy_string(default_callerid, DEFAULT_CALLERID, sizeof(default_callerid));
16494    compactheaders = DEFAULT_COMPACTHEADERS;
16495    global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT;
16496    global_regattempts_max = 0;
16497    pedanticsipchecking = DEFAULT_PEDANTIC;
16498    global_mwitime = DEFAULT_MWITIME;
16499    autocreatepeer = DEFAULT_AUTOCREATEPEER;
16500    global_autoframing = 0;
16501    global_allowguest = DEFAULT_ALLOWGUEST;
16502    global_rtptimeout = 0;
16503    global_rtpholdtimeout = 0;
16504    global_rtpkeepalive = 0;
16505    global_allowtransfer = TRANSFER_OPENFORALL;  /* Merrily accept all transfers by default */
16506    global_rtautoclear = 120;
16507    ast_set_flag(&global_flags[1], SIP_PAGE2_ALLOWSUBSCRIBE);   /* Default for peers, users: TRUE */
16508    ast_set_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP);     /* Default for peers, users: TRUE */
16509    ast_set_flag(&global_flags[1], SIP_PAGE2_RTUPDATE);
16510 
16511    /* Initialize some reasonable defaults at SIP reload (used both for channel and as default for peers and users */
16512    ast_copy_string(default_context, DEFAULT_CONTEXT, sizeof(default_context));
16513    default_subscribecontext[0] = '\0';
16514    default_language[0] = '\0';
16515    default_fromdomain[0] = '\0';
16516    default_qualify = DEFAULT_QUALIFY;
16517    default_maxcallbitrate = DEFAULT_MAX_CALL_BITRATE;
16518    ast_copy_string(default_mohinterpret, DEFAULT_MOHINTERPRET, sizeof(default_mohinterpret));
16519    ast_copy_string(default_mohsuggest, DEFAULT_MOHSUGGEST, sizeof(default_mohsuggest));
16520    ast_copy_string(default_vmexten, DEFAULT_VMEXTEN, sizeof(default_vmexten));
16521    ast_set_flag(&global_flags[0], SIP_DTMF_RFC2833);        /*!< Default DTMF setting: RFC2833 */
16522    ast_set_flag(&global_flags[0], SIP_NAT_RFC3581);         /*!< NAT support if requested by device with rport */
16523    ast_set_flag(&global_flags[0], SIP_CAN_REINVITE);        /*!< Allow re-invites */
16524 
16525    /* Debugging settings, always default to off */
16526    dumphistory = FALSE;
16527    recordhistory = FALSE;
16528    ast_clear_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONFIG);
16529 
16530    /* Misc settings for the channel */
16531    global_relaxdtmf = FALSE;
16532    global_callevents = FALSE;
16533    global_t1min = DEFAULT_T1MIN;    
16534 
16535    global_matchexterniplocally = FALSE;
16536 
16537    /* Copy the default jb config over global_jbconf */
16538    memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf));
16539 
16540    ast_clear_flag(&global_flags[1], SIP_PAGE2_VIDEOSUPPORT);
16541 
16542    /* Read the [general] config section of sip.conf (or from realtime config) */
16543    for (v = ast_variable_browse(cfg, "general"); v; v = v->next) {
16544       if (handle_common_options(&global_flags[0], &dummy[0], v))
16545          continue;
16546       /* handle jb conf */
16547       if (!ast_jb_read_conf(&global_jbconf, v->name, v->value))
16548          continue;
16549 
16550       /* Create the interface list */
16551       if (!strcasecmp(v->name, "context")) {
16552          ast_copy_string(default_context, v->value, sizeof(default_context));
16553       } else if (!strcasecmp(v->name, "allowguest")) {
16554          global_allowguest = ast_true(v->value) ? 1 : 0;
16555       } else if (!strcasecmp(v->name, "realm")) {
16556          ast_copy_string(global_realm, v->value, sizeof(global_realm));
16557       } else if (!strcasecmp(v->name, "useragent")) {
16558          ast_copy_string(global_useragent, v->value, sizeof(global_useragent));
16559          if (option_debug)
16560             ast_log(LOG_DEBUG, "Setting SIP channel User-Agent Name to %s\n", global_useragent);
16561       } else if (!strcasecmp(v->name, "allowtransfer")) {
16562          global_allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED;
16563       } else if (!strcasecmp(v->name, "rtcachefriends")) {
16564          ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_RTCACHEFRIENDS);   
16565       } else if (!strcasecmp(v->name, "rtsavesysname")) {
16566          ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_RTSAVE_SYSNAME);   
16567       } else if (!strcasecmp(v->name, "rtupdate")) {
16568          ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_RTUPDATE);   
16569       } else if (!strcasecmp(v->name, "ignoreregexpire")) {
16570          ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_IGNOREREGEXPIRE);  
16571       } else if (!strcasecmp(v->name, "t1min")) {
16572          global_t1min = atoi(v->value);
16573       } else if (!strcasecmp(v->name, "rtautoclear")) {
16574          int i = atoi(v->value);
16575          if (i > 0)
16576             global_rtautoclear = i;
16577          else
16578             i = 0;
16579          ast_set2_flag(&global_flags[1], i || ast_true(v->value), SIP_PAGE2_RTAUTOCLEAR);
16580       } else if (!strcasecmp(v->name, "usereqphone")) {
16581          ast_set2_flag(&global_flags[0], ast_true(v->value), SIP_USEREQPHONE);   
16582       } else if (!strcasecmp(v->name, "relaxdtmf")) {
16583          global_relaxdtmf = ast_true(v->value);
16584       } else if (!strcasecmp(v->name, "checkmwi")) {
16585          if ((sscanf(v->value, "%d", &global_mwitime) != 1) || (global_mwitime < 0)) {
16586             ast_log(LOG_WARNING, "'%s' is not a valid MWI time setting at line %d.  Using default (10).\n", v->value, v->lineno);
16587             global_mwitime = DEFAULT_MWITIME;
16588          }
16589       } else if (!strcasecmp(v->name, "vmexten")) {
16590          ast_copy_string(default_vmexten, v->value, sizeof(default_vmexten));
16591       } else if (!strcasecmp(v->name, "rtptimeout")) {
16592          if ((sscanf(v->value, "%d", &global_rtptimeout) != 1) || (global_rtptimeout < 0)) {
16593             ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d.  Using default.\n", v->value, v->lineno);
16594             global_rtptimeout = 0;
16595          }
16596       } else if (!strcasecmp(v->name, "rtpholdtimeout")) {
16597          if ((sscanf(v->value, "%d", &global_rtpholdtimeout) != 1) || (global_rtpholdtimeout < 0)) {
16598             ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d.  Using default.\n", v->value, v->lineno);
16599             global_rtpholdtimeout = 0;
16600          }
16601       } else if (!strcasecmp(v->name, "rtpkeepalive")) {
16602          if ((sscanf(v->value, "%d", &global_rtpkeepalive) != 1) || (global_rtpkeepalive < 0)) {
16603             ast_log(LOG_WARNING, "'%s' is not a valid RTP keepalive time at line %d.  Using default.\n", v->value, v->lineno);
16604             global_rtpkeepalive = 0;
16605          }
16606       } else if (!strcasecmp(v->name, "compactheaders")) {
16607          compactheaders = ast_true(v->value);
16608       } else if (!strcasecmp(v->name, "notifymimetype")) {
16609          ast_copy_string(default_notifymime, v->value, sizeof(default_notifymime));
16610       } else if (!strncasecmp(v->name, "limitonpeer", 11)) {
16611          global_limitonpeers = ast_true(v->value);
16612       } else if (!strcasecmp(v->name, "directrtpsetup")) {
16613          global_directrtpsetup = ast_true(v->value);
16614       } else if (!strcasecmp(v->name, "notifyringing")) {
16615          global_notifyringing = ast_true(v->value);
16616       } else if (!strcasecmp(v->name, "notifyhold")) {
16617          global_notifyhold = ast_true(v->value);
16618       } else if (!strcasecmp(v->name, "alwaysauthreject")) {
16619          global_alwaysauthreject = ast_true(v->value);
16620       } else if (!strcasecmp(v->name, "mohinterpret") 
16621          || !strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) {
16622          ast_copy_string(default_mohinterpret, v->value, sizeof(default_mohinterpret));
16623       } else if (!strcasecmp(v->name, "mohsuggest")) {
16624          ast_copy_string(default_mohsuggest, v->value, sizeof(default_mohsuggest));
16625       } else if (!strcasecmp(v->name, "language")) {
16626          ast_copy_string(default_language, v->value, sizeof(default_language));
16627       } else if (!strcasecmp(v->name, "regcontext")) {
16628          ast_copy_string(newcontexts, v->value, sizeof(newcontexts));
16629          stringp = newcontexts;
16630          /* Let's remove any contexts that are no longer defined in regcontext */
16631          cleanup_stale_contexts(stringp, oldregcontext);
16632          /* Create contexts if they don't exist already */
16633          while ((context = strsep(&stringp, "&"))) {
16634             if (!ast_context_find(context))
16635                ast_context_create(NULL, context,"SIP");
16636          }
16637          ast_copy_string(global_regcontext, v->value, sizeof(global_regcontext));
16638       } else if (!strcasecmp(v->name, "callerid")) {
16639          ast_copy_string(default_callerid, v->value, sizeof(default_callerid));
16640       } else if (!strcasecmp(v->name, "fromdomain")) {
16641          ast_copy_string(default_fromdomain, v->value, sizeof(default_fromdomain));
16642       } else if (!strcasecmp(v->name, "outboundproxy")) {
16643          if (ast_get_ip_or_srv(&outboundproxyip, v->value, srvlookup ? "_sip._udp" : NULL) < 0)
16644             ast_log(LOG_WARNING, "Unable to locate host '%s'\n", v->value);
16645       } else if (!strcasecmp(v->name, "outboundproxyport")) {
16646          /* Port needs to be after IP */
16647          sscanf(v->value, "%d", &format);
16648          outboundproxyip.sin_port = htons(format);
16649       } else if (!strcasecmp(v->name, "autocreatepeer")) {
16650          autocreatepeer = ast_true(v->value);
16651       } else if (!strcasecmp(v->name, "srvlookup")) {
16652          srvlookup = ast_true(v->value);
16653       } else if (!strcasecmp(v->name, "pedantic")) {
16654          pedanticsipchecking = ast_true(v->value);
16655       } else if (!strcasecmp(v->name, "maxexpirey") || !strcasecmp(v->name, "maxexpiry")) {
16656          max_expiry = atoi(v->value);
16657          if (max_expiry < 1)
16658             max_expiry = DEFAULT_MAX_EXPIRY;
16659       } else if (!strcasecmp(v->name, "minexpirey") || !strcasecmp(v->name, "minexpiry")) {
16660          min_expiry = atoi(v->value);
16661          if (min_expiry < 1)
16662             min_expiry = DEFAULT_MIN_EXPIRY;
16663       } else if (!strcasecmp(v->name, "defaultexpiry") || !strcasecmp(v->name, "defaultexpirey")) {
16664          default_expiry = atoi(v->value);
16665          if (default_expiry < 1)
16666             default_expiry = DEFAULT_DEFAULT_EXPIRY;
16667       } else if (!strcasecmp(v->name, "sipdebug")) {  /* XXX maybe ast_set2_flags ? */
16668          if (ast_true(v->value))
16669             ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONFIG);
16670       } else if (!strcasecmp(v->name, "dumphistory")) {
16671          dumphistory = ast_true(v->value);
16672       } else if (!strcasecmp(v->name, "recordhistory")) {
16673          recordhistory = ast_true(v->value);
16674       } else if (!strcasecmp(v->name, "registertimeout")) {
16675          global_reg_timeout = atoi(v->value);
16676          if (global_reg_timeout < 1)
16677             global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT;
16678       } else if (!strcasecmp(v->name, "registerattempts")) {
16679          global_regattempts_max = atoi(v->value);
16680       } else if (!strcasecmp(v->name, "bindaddr")) {
16681          if (!(hp = ast_gethostbyname(v->value, &ahp))) {
16682             ast_log(LOG_WARNING, "Invalid address: %s\n", v->value);
16683          } else {
16684             memcpy(&bindaddr.sin_addr, hp->h_addr, sizeof(bindaddr.sin_addr));
16685          }
16686       } else if (!strcasecmp(v->name, "localnet")) {
16687          struct ast_ha *na;
16688          if (!(na = ast_append_ha("d", v->value, localaddr)))
16689             ast_log(LOG_WARNING, "Invalid localnet value: %s\n", v->value);
16690          else
16691             localaddr = na;
16692       } else if (!strcasecmp(v->name, "localmask")) {
16693          ast_log(LOG_WARNING, "Use of localmask is no long supported -- use localnet with mask syntax\n");
16694       } else if (!strcasecmp(v->name, "externip")) {
16695          if (!(hp = ast_gethostbyname(v->value, &ahp))) 
16696             ast_log(LOG_WARNING, "Invalid address for externip keyword: %s\n", v->value);
16697          else
16698             memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr));
16699          externexpire = 0;
16700       } else if (!strcasecmp(v->name, "externhost")) {
16701          ast_copy_string(externhost, v->value, sizeof(externhost));
16702          if (!(hp = ast_gethostbyname(externhost, &ahp))) 
16703             ast_log(LOG_WARNING, "Invalid address for externhost keyword: %s\n", externhost);
16704          else
16705             memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr));
16706          externexpire = time(NULL);
16707       } else if (!strcasecmp(v->name, "externrefresh")) {
16708          if (sscanf(v->value, "%d", &externrefresh) != 1) {
16709             ast_log(LOG_WARNING, "Invalid externrefresh value '%s', must be an integer >0 at line %d\n", v->value, v->lineno);
16710             externrefresh = 10;
16711          }
16712       } else if (!strcasecmp(v->name, "allow")) {
16713          ast_parse_allow_disallow(&default_prefs, &global_capability, v->value, 1);
16714       } else if (!strcasecmp(v->name, "disallow")) {
16715          ast_parse_allow_disallow(&default_prefs, &global_capability, v->value, 0);
16716       } else if (!strcasecmp(v->name, "autoframing")) {
16717          global_autoframing = ast_true(v->value);
16718       } else if (!strcasecmp(v->name, "allowexternaldomains")) {
16719          allow_external_domains = ast_true(v->value);
16720       } else if (!strcasecmp(v->name, "autodomain")) {
16721          auto_sip_domains = ast_true(v->value);
16722       } else if (!strcasecmp(v->name, "domain")) {
16723          char *domain = ast_strdupa(v->value);
16724          char *context = strchr(domain, ',');
16725 
16726          if (context)
16727             *context++ = '\0';
16728 
16729          if (option_debug && ast_strlen_zero(context))
16730             ast_log(LOG_DEBUG, "No context specified at line %d for domain '%s'\n", v->lineno, domain);
16731          if (ast_strlen_zero(domain))
16732             ast_log(LOG_WARNING, "Empty domain specified at line %d\n", v->lineno);
16733          else
16734             add_sip_domain(ast_strip(domain), SIP_DOMAIN_CONFIG, context ? ast_strip(context) : "");
16735       } else if (!strcasecmp(v->name, "register")) {
16736          if (sip_register(v->value, v->lineno) == 0)
16737             registry_count++;
16738       } else if (!strcasecmp(v->name, "tos")) {
16739          if (!ast_str2tos(v->value, &temp_tos)) {
16740             global_tos_sip = temp_tos;
16741             global_tos_audio = temp_tos;
16742             global_tos_video = temp_tos;
16743             ast_log(LOG_WARNING, "tos value at line %d is deprecated.  See doc/ip-tos.txt for more information.\n", v->lineno);
16744          } else
16745             ast_log(LOG_WARNING, "Invalid tos value at line %d, See doc/ip-tos.txt for more information.\n", v->lineno);
16746       } else if (!strcasecmp(v->name, "tos_sip")) {
16747          if (ast_str2tos(v->value, &global_tos_sip))
16748             ast_log(LOG_WARNING, "Invalid tos_sip value at line %d, recommended value is 'cs3'. See doc/ip-tos.txt.\n", v->lineno);
16749       } else if (!strcasecmp(v->name, "tos_audio")) {
16750          if (ast_str2tos(v->value, &global_tos_audio))
16751             ast_log(LOG_WARNING, "Invalid tos_audio value at line %d, recommended value is 'ef'. See doc/ip-tos.txt.\n", v->lineno);
16752       } else if (!strcasecmp(v->name, "tos_video")) {
16753          if (ast_str2tos(v->value, &global_tos_video))
16754             ast_log(LOG_WARNING, "Invalid tos_video value at line %d, recommended value is 'af41'. See doc/ip-tos.txt.\n", v->lineno);
16755       } else if (!strcasecmp(v->name, "bindport")) {
16756          if (sscanf(v->value, "%d", &ourport) == 1) {
16757             bindaddr.sin_port = htons(ourport);
16758          } else {
16759             ast_log(LOG_WARNING, "Invalid port number '%s' at line %d of %s\n", v->value, v->lineno, config);
16760          }
16761       } else if (!strcasecmp(v->name, "qualify")) {
16762          if (!strcasecmp(v->value, "no")) {
16763             default_qualify = 0;
16764          } else if (!strcasecmp(v->value, "yes")) {
16765             default_qualify = DEFAULT_MAXMS;
16766          } else if (sscanf(v->value, "%d", &default_qualify) != 1) {
16767             ast_log(LOG_WARNING, "Qualification default should be 'yes', 'no', or a number of milliseconds at line %d of sip.conf\n", v->lineno);
16768             default_qualify = 0;
16769          }
16770       } else if (!strcasecmp(v->name, "callevents")) {
16771          global_callevents = ast_true(v->value);
16772       } else if (!strcasecmp(v->name, "maxcallbitrate")) {
16773          default_maxcallbitrate = atoi(v->value);
16774          if (default_maxcallbitrate < 0)
16775             default_maxcallbitrate = DEFAULT_MAX_CALL_BITRATE;
16776       } else if (!strcasecmp(v->name, "matchexterniplocally")) {
16777          global_matchexterniplocally = ast_true(v->value);
16778       }
16779    }
16780 
16781    if (!allow_external_domains && AST_LIST_EMPTY(&domain_list)) {
16782       ast_log(LOG_WARNING, "To disallow external domains, you need to configure local SIP domains.\n");
16783       allow_external_domains = 1;
16784    }
16785    
16786    /* Build list of authentication to various SIP realms, i.e. service providers */
16787    for (v = ast_variable_browse(cfg, "authentication"); v ; v = v->next) {
16788       /* Format for authentication is auth = username:password@realm */
16789       if (!strcasecmp(v->name, "auth"))
16790          authl = add_realm_authentication(authl, v->value, v->lineno);
16791    }
16792    
16793    ucfg = ast_config_load("users.conf");
16794    if (ucfg) {
16795       struct ast_variable *gen;
16796       int genhassip, genregistersip;
16797       const char *hassip, *registersip;
16798       
16799       genhassip = ast_true(ast_variable_retrieve(ucfg, "general", "hassip"));
16800       genregistersip = ast_true(ast_variable_retrieve(ucfg, "general", "registersip"));
16801       gen = ast_variable_browse(ucfg, "general");
16802       cat = ast_category_browse(ucfg, NULL);
16803       while (cat) {
16804          if (strcasecmp(cat, "general")) {
16805             hassip = ast_variable_retrieve(ucfg, cat, "hassip");
16806             registersip = ast_variable_retrieve(ucfg, cat, "registersip");
16807             if (ast_true(hassip) || (!hassip && genhassip)) {
16808                peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0);
16809                if (peer) {
16810                   ast_device_state_changed("SIP/%s", peer->name);
16811                   ASTOBJ_CONTAINER_LINK(&peerl,peer);
16812                   ASTOBJ_UNREF(peer, sip_destroy_peer);
16813                   peer_count++;
16814                }
16815             }
16816             if (ast_true(registersip) || (!registersip && genregistersip)) {
16817                char tmp[256];
16818                const char *host = ast_variable_retrieve(ucfg, cat, "host");
16819                const char *username = ast_variable_retrieve(ucfg, cat, "username");
16820                const char *secret = ast_variable_retrieve(ucfg, cat, "secret");
16821                const char *contact = ast_variable_retrieve(ucfg, cat, "contact");
16822                if (!host)
16823                   host = ast_variable_retrieve(ucfg, "general", "host");
16824                if (!username)
16825                   username = ast_variable_retrieve(ucfg, "general", "username");
16826                if (!secret)
16827                   secret = ast_variable_retrieve(ucfg, "general", "secret");
16828                if (!contact)
16829                   contact = "s";
16830                if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) {
16831                   if (!ast_strlen_zero(secret))
16832                      snprintf(tmp, sizeof(tmp), "%s:%s@%s/%s", username, secret, host, contact);
16833                   else
16834                      snprintf(tmp, sizeof(tmp), "%s@%s/%s", username, host, contact);
16835                   if (sip_register(tmp, 0) == 0)
16836                      registry_count++;
16837                }
16838             }
16839          }
16840          cat = ast_category_browse(ucfg, cat);
16841       }
16842       ast_config_destroy(ucfg);
16843    }
16844    
16845 
16846    /* Load peers, users and friends */
16847    cat = NULL;
16848    while ( (cat = ast_category_browse(cfg, cat)) ) {
16849       const char *utype;
16850       if (!strcasecmp(cat, "general") || !strcasecmp(cat, "authentication"))
16851          continue;
16852       utype = ast_variable_retrieve(cfg, cat, "type");
16853       if (!utype) {
16854          ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat);
16855          continue;
16856       } else {
16857          int is_user = 0, is_peer = 0;
16858          if (!strcasecmp(utype, "user"))
16859             is_user = 1;
16860          else if (!strcasecmp(utype, "friend"))
16861             is_user = is_peer = 1;
16862          else if (!strcasecmp(utype, "peer"))
16863             is_peer = 1;
16864          else {
16865             ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, "sip.conf");
16866             continue;
16867          }
16868          if (is_user) {
16869             user = build_user(cat, ast_variable_browse(cfg, cat), 0);
16870             if (user) {
16871                ASTOBJ_CONTAINER_LINK(&userl,user);
16872                ASTOBJ_UNREF(user, sip_destroy_user);
16873                user_count++;
16874             }
16875          }
16876          if (is_peer) {
16877             peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0);
16878             if (peer) {
16879                ASTOBJ_CONTAINER_LINK(&peerl,peer);
16880                ASTOBJ_UNREF(peer, sip_destroy_peer);
16881                peer_count++;
16882             }
16883          }
16884       }
16885    }
16886    if (ast_find_ourip(&__ourip, bindaddr)) {
16887       ast_log(LOG_WARNING, "Unable to get own IP address, SIP disabled\n");
16888       return 0;
16889    }
16890    if (!ntohs(bindaddr.sin_port))
16891       bindaddr.sin_port = ntohs(STANDARD_SIP_PORT);
16892    bindaddr.sin_family = AF_INET;
16893    ast_mutex_lock(&netlock);
16894    if ((sipsock > -1) && (memcmp(&old_bindaddr, &bindaddr, sizeof(struct sockaddr_in)))) {
16895       close(sipsock);
16896       sipsock = -1;
16897    }
16898    if (sipsock < 0) {
16899       sipsock = socket(AF_INET, SOCK_DGRAM, 0);
16900       if (sipsock < 0) {
16901          ast_log(LOG_WARNING, "Unable to create SIP socket: %s\n", strerror(errno));
16902          return -1;
16903       } else {
16904          /* Allow SIP clients on the same host to access us: */
16905          const int reuseFlag = 1;
16906 
16907          setsockopt(sipsock, SOL_SOCKET, SO_REUSEADDR,
16908                (const char*)&reuseFlag,
16909                sizeof reuseFlag);
16910 
16911          ast_enable_packet_fragmentation(sipsock);
16912 
16913          if (bind(sipsock, (struct sockaddr *)&bindaddr, sizeof(bindaddr)) < 0) {
16914             ast_log(LOG_WARNING, "Failed to bind to %s:%d: %s\n",
16915             ast_inet_ntoa(bindaddr.sin_addr), ntohs(bindaddr.sin_port),
16916             strerror(errno));
16917             close(sipsock);
16918             sipsock = -1;
16919          } else {
16920             if (option_verbose > 1) { 
16921                ast_verbose(VERBOSE_PREFIX_2 "SIP Listening on %s:%d\n", 
16922                ast_inet_ntoa(bindaddr.sin_addr), ntohs(bindaddr.sin_port));
16923                ast_verbose(VERBOSE_PREFIX_2 "Using SIP TOS: %s\n", ast_tos2str(global_tos_sip));
16924             }
16925             if (setsockopt(sipsock, IPPROTO_IP, IP_TOS, &global_tos_sip, sizeof(global_tos_sip))) 
16926                ast_log(LOG_WARNING, "Unable to set SIP TOS to %s\n", ast_tos2str(global_tos_sip));
16927          }
16928       }
16929    }
16930    ast_mutex_unlock(&netlock);
16931 
16932    /* Add default domains - host name, IP address and IP:port */
16933    /* Only do this if user added any sip domain with "localdomains" */
16934    /* In order to *not* break backwards compatibility */
16935    /*    Some phones address us at IP only, some with additional port number */
16936    if (auto_sip_domains) {
16937       char temp[MAXHOSTNAMELEN];
16938 
16939       /* First our default IP address */
16940       if (bindaddr.sin_addr.s_addr)
16941          add_sip_domain(ast_inet_ntoa(bindaddr.sin_addr), SIP_DOMAIN_AUTO, NULL);
16942       else
16943          ast_log(LOG_NOTICE, "Can't add wildcard IP address to domain list, please add IP address to domain manually.\n");
16944 
16945       /* Our extern IP address, if configured */
16946       if (externip.sin_addr.s_addr)
16947          add_sip_domain(ast_inet_ntoa(externip.sin_addr), SIP_DOMAIN_AUTO, NULL);
16948 
16949       /* Extern host name (NAT traversal support) */
16950       if (!ast_strlen_zero(externhost))
16951          add_sip_domain(externhost, SIP_DOMAIN_AUTO, NULL);
16952       
16953       /* Our host name */
16954       if (!gethostname(temp, sizeof(temp)))
16955          add_sip_domain(temp, SIP_DOMAIN_AUTO, NULL);
16956    }
16957 
16958    /* Release configuration from memory */
16959    ast_config_destroy(cfg);
16960 
16961    /* Load the list of manual NOTIFY types to support */
16962    if (notify_types)
16963       ast_config_destroy(notify_types);
16964    notify_types = ast_config_load(notify_config);
16965 
16966    /* Done, tell the manager */
16967    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\r\n", channelreloadreason2txt(reason), registry_count, peer_count, user_count);
16968 
16969    return 0;
16970 }

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

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

Referenced by do_proxy_auth(), and do_register_auth().

11225 {
11226    char tmp[512];
11227    char *c;
11228    char oldnonce[256];
11229 
11230    /* table of recognised keywords, and places where they should be copied */
11231    const struct x {
11232       const char *key;
11233       int field_index;
11234    } *i, keys[] = {
11235       { "realm=", ast_string_field_index(p, realm) },
11236       { "nonce=", ast_string_field_index(p, nonce) },
11237       { "opaque=", ast_string_field_index(p, opaque) },
11238       { "qop=", ast_string_field_index(p, qop) },
11239       { "domain=", ast_string_field_index(p, domain) },
11240       { NULL, 0 },
11241    };
11242 
11243    ast_copy_string(tmp, get_header(req, header), sizeof(tmp));
11244    if (ast_strlen_zero(tmp)) 
11245       return -1;
11246    if (strncasecmp(tmp, "Digest ", strlen("Digest "))) {
11247       ast_log(LOG_WARNING, "missing Digest.\n");
11248       return -1;
11249    }
11250    c = tmp + strlen("Digest ");
11251    ast_copy_string(oldnonce, p->nonce, sizeof(oldnonce));
11252    while (c && *(c = ast_skip_blanks(c))) {  /* lookup for keys */
11253       for (i = keys; i->key != NULL; i++) {
11254          char *src, *separator;
11255          if (strncasecmp(c, i->key, strlen(i->key)) != 0)
11256             continue;
11257          /* Found. Skip keyword, take text in quotes or up to the separator. */
11258          c += strlen(i->key);
11259          if (*c == '"') {
11260             src = ++c;
11261             separator = "\"";
11262          } else {
11263             src = c;
11264             separator = ",";
11265          }
11266          strsep(&c, separator); /* clear separator and move ptr */
11267          ast_string_field_index_set(p, i->field_index, src);
11268          break;
11269       }
11270       if (i->key == NULL) /* not found, try ',' */
11271          strsep(&c, ",");
11272    }
11273    /* Reset nonce count */
11274    if (strcmp(p->nonce, oldnonce)) 
11275       p->noncecount = 0;
11276 
11277    /* Save auth data for following registrations */
11278    if (p->registry) {
11279       struct sip_registry *r = p->registry;
11280 
11281       if (strcmp(r->nonce, p->nonce)) {
11282          ast_string_field_set(r, realm, p->realm);
11283          ast_string_field_set(r, nonce, p->nonce);
11284          ast_string_field_set(r, domain, p->domain);
11285          ast_string_field_set(r, opaque, p->opaque);
11286          ast_string_field_set(r, qop, p->qop);
11287          r->noncecount = 0;
11288       }
11289    }
11290    return build_reply_digest(p, sipmethod, digest, digest_len); 
11291 }

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

05740 {
05741    struct sip_request *orig = &p->initreq;
05742    char stripped[80];
05743    char tmp[80];
05744    char newto[256];
05745    const char *c;
05746    const char *ot, *of;
05747    int is_strict = FALSE;     /*!< Strict routing flag */
05748 
05749    memset(req, 0, sizeof(struct sip_request));
05750    
05751    snprintf(p->lastmsg, sizeof(p->lastmsg), "Tx: %s", sip_methods[sipmethod].text);
05752    
05753    if (!seqno) {
05754       p->ocseq++;
05755       seqno = p->ocseq;
05756    }
05757    
05758    if (newbranch) {
05759       p->branch ^= ast_random();
05760       build_via(p);
05761    }
05762 
05763    /* Check for strict or loose router */
05764    if (p->route && !ast_strlen_zero(p->route->hop) && strstr(p->route->hop,";lr") == NULL) {
05765       is_strict = TRUE;
05766       if (sipdebug)
05767          ast_log(LOG_DEBUG, "Strict routing enforced for session %s\n", p->callid);
05768    }
05769 
05770    if (sipmethod == SIP_CANCEL)
05771       c = p->initreq.rlPart2; /* Use original URI */
05772    else if (sipmethod == SIP_ACK) {
05773       /* Use URI from Contact: in 200 OK (if INVITE) 
05774       (we only have the contacturi on INVITEs) */
05775       if (!ast_strlen_zero(p->okcontacturi))
05776          c = is_strict ? p->route->hop : p->okcontacturi;
05777       else
05778          c = p->initreq.rlPart2;
05779    } else if (!ast_strlen_zero(p->okcontacturi)) 
05780       c = is_strict ? p->route->hop : p->okcontacturi; /* Use for BYE or REINVITE */
05781    else if (!ast_strlen_zero(p->uri)) 
05782       c = p->uri;
05783    else {
05784       char *n;
05785       /* We have no URI, use To: or From:  header as URI (depending on direction) */
05786       ast_copy_string(stripped, get_header(orig, (ast_test_flag(&p->flags[0], SIP_OUTGOING)) ? "To" : "From"),
05787             sizeof(stripped));
05788       n = get_in_brackets(stripped);
05789       c = strsep(&n, ";"); /* trim ; and beyond */
05790    }  
05791    init_req(req, sipmethod, c);
05792 
05793    snprintf(tmp, sizeof(tmp), "%d %s", seqno, sip_methods[sipmethod].text);
05794 
05795    add_header(req, "Via", p->via);
05796    if (p->route) {
05797       set_destination(p, p->route->hop);
05798       add_route(req, is_strict ? p->route->next : p->route);
05799    }
05800 
05801    ot = get_header(orig, "To");
05802    of = get_header(orig, "From");
05803 
05804    /* Add tag *unless* this is a CANCEL, in which case we need to send it exactly
05805       as our original request, including tag (or presumably lack thereof) */
05806    if (!strcasestr(ot, "tag=") && sipmethod != SIP_CANCEL) {
05807       /* Add the proper tag if we don't have it already.  If they have specified
05808          their tag, use it.  Otherwise, use our own tag */
05809       if (ast_test_flag(&p->flags[0], SIP_OUTGOING) && !ast_strlen_zero(p->theirtag))
05810          snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->theirtag);
05811       else if (!ast_test_flag(&p->flags[0], SIP_OUTGOING))
05812          snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->tag);
05813       else
05814          snprintf(newto, sizeof(newto), "%s", ot);
05815       ot = newto;
05816    }
05817 
05818    if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
05819       add_header(req, "From", of);
05820       add_header(req, "To", ot);
05821    } else {
05822       add_header(req, "From", ot);
05823       add_header(req, "To", of);
05824    }
05825    /* Do not add Contact for MESSAGE, BYE and Cancel requests */
05826    if (sipmethod != SIP_BYE && sipmethod != SIP_CANCEL && sipmethod != SIP_MESSAGE)
05827       add_header(req, "Contact", p->our_contact);
05828 
05829    copy_header(req, orig, "Call-ID");
05830    add_header(req, "CSeq", tmp);
05831 
05832    if (!ast_strlen_zero(global_useragent))
05833       add_header(req, "User-Agent", global_useragent);
05834    add_header(req, "Max-Forwards", DEFAULT_MAX_FORWARDS);
05835 
05836    if (!ast_strlen_zero(p->rpid))
05837       add_header(req, "Remote-Party-ID", p->rpid);
05838 
05839    return 0;
05840 }

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

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

05692 {
05693    char newto[256];
05694    const char *ot;
05695 
05696    init_resp(resp, msg);
05697    copy_via_headers(p, resp, req, "Via");
05698    if (msg[0] == '2')
05699       copy_all_header(resp, req, "Record-Route");
05700    copy_header(resp, req, "From");
05701    ot = get_header(req, "To");
05702    if (!strcasestr(ot, "tag=") && strncmp(msg, "100", 3)) {
05703       /* Add the proper tag if we don't have it already.  If they have specified
05704          their tag, use it.  Otherwise, use our own tag */
05705       if (!ast_strlen_zero(p->theirtag) && ast_test_flag(&p->flags[0], SIP_OUTGOING))
05706          snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->theirtag);
05707       else if (p->tag && !ast_test_flag(&p->flags[0], SIP_OUTGOING))
05708          snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->tag);
05709       else
05710          ast_copy_string(newto, ot, sizeof(newto));
05711       ot = newto;
05712    }
05713    add_header(resp, "To", ot);
05714    copy_header(resp, req, "Call-ID");
05715    copy_header(resp, req, "CSeq");
05716    if (!ast_strlen_zero(global_useragent))
05717       add_header(resp, "User-Agent", global_useragent);
05718    add_header(resp, "Allow", ALLOWED_METHODS);
05719    add_header(resp, "Supported", SUPPORTED_EXTENSIONS);
05720    if (msg[0] == '2' && (p->method == SIP_SUBSCRIBE || p->method == SIP_REGISTER)) {
05721       /* For registration responses, we also need expiry and
05722          contact info */
05723       char tmp[256];
05724 
05725       snprintf(tmp, sizeof(tmp), "%d", p->expiry);
05726       add_header(resp, "Expires", tmp);
05727       if (p->expiry) {  /* Only add contact if we have an expiry time */
05728          char contact[BUFSIZ];
05729          snprintf(contact, sizeof(contact), "%s;expires=%d", p->our_contact, p->expiry);
05730          add_header(resp, "Contact", contact);  /* Not when we unregister */
05731       }
05732    } else if (msg[0] != '4' && p->our_contact[0]) {
05733       add_header(resp, "Contact", p->our_contact);
05734    }
05735    return 0;
05736 }

static int restart_monitor ( void   )  [static]

Start the channel monitor thread.

Definition at line 15385 of file chan_sip.c.

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

15386 {
15387    /* If we're supposed to be stopped -- stay stopped */
15388    if (monitor_thread == AST_PTHREADT_STOP)
15389       return 0;
15390    ast_mutex_lock(&monlock);
15391    if (monitor_thread == pthread_self()) {
15392       ast_mutex_unlock(&monlock);
15393       ast_log(LOG_WARNING, "Cannot kill myself\n");
15394       return -1;
15395    }
15396    if (monitor_thread != AST_PTHREADT_NULL) {
15397       /* Wake up the thread */
15398       pthread_kill(monitor_thread, SIGURG);
15399    } else {
15400       /* Start a new monitor */
15401       if (ast_pthread_create_background(&monitor_thread, NULL, do_monitor, NULL) < 0) {
15402          ast_mutex_unlock(&monlock);
15403          ast_log(LOG_ERROR, "Unable to start monitor thread.\n");
15404          return -1;
15405       }
15406    }
15407    ast_mutex_unlock(&monlock);
15408    return 0;
15409 }

static int retrans_pkt ( void *  data  )  [static]

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

Definition at line 1867 of file chan_sip.c.

References __sip_xmit(), append_history, AST_CAUSE_NO_USER_RESPONSE, ast_channel_trylock, ast_channel_unlock, ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_queue_hangup(), ast_set_flag, ast_test_flag, ast_verbose(), sip_pkt::data, DEFAULT_RETRANS, FLAG_FATAL, FLAG_RESPONSE, sip_pvt::flags, free, ast_channel::hangupcause, sip_pvt::lock, LOG_DEBUG, LOG_WARNING, MAX_RETRANS, sip_pkt::method, sip_pkt::next, option_debug, sip_pvt::owner, sip_pkt::owner, sip_pkt::packetlen, sip_pvt::packets, sip_pkt::retrans, sip_pkt::retransid, sip_pkt::seqno, sip_alreadygone(), SIP_BYE, sip_debug_test_pvt(), SIP_INVITE, sip_methods, sip_nat_mode(), SIP_NEEDDESTROY, SIP_OPTIONS, sip_real_dst(), sipdebug, cfsip_methods::text, sip_pkt::timer_a, sip_pkt::timer_t1, and XMIT_ERROR.

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

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

02235 {
02236    int res;
02237 
02238    add_blank(req);
02239    if (sip_debug_test_pvt(p)) {
02240       if (ast_test_flag(&p->flags[0], SIP_NAT_ROUTE))
02241          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);
02242       else
02243          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);
02244    }
02245    if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) {
02246       struct sip_request tmp;
02247       parse_copy(&tmp, req);
02248       append_history(p, reliable ? "TxReqRel" : "TxReq", "%s / %s - %s", tmp.data, get_header(&tmp, "CSeq"), sip_methods[tmp.method].text);
02249    }
02250    res = (reliable) ?
02251       __sip_reliable_xmit(p, seqno, 0, req->data, req->len, (reliable == XMIT_CRITICAL), req->method) :
02252       __sip_xmit(p, req->data, req->len);
02253    return res;
02254 }

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

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

02207 {
02208    int res;
02209 
02210    add_blank(req);
02211    if (sip_debug_test_pvt(p)) {
02212       const struct sockaddr_in *dst = sip_real_dst(p);
02213 
02214       ast_verbose("\n<--- %sTransmitting (%s) to %s:%d --->\n%s\n<------------>\n",
02215          reliable ? "Reliably " : "", sip_nat_mode(p),
02216          ast_inet_ntoa(dst->sin_addr),
02217          ntohs(dst->sin_port), req->data);
02218    }
02219    if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) {
02220       struct sip_request tmp;
02221       parse_copy(&tmp, req);
02222       append_history(p, reliable ? "TxRespRel" : "TxResp", "%s / %s - %s", tmp.data, get_header(&tmp, "CSeq"), 
02223          (tmp.method == SIP_RESPONSE || tmp.method == SIP_UNKNOWN) ? tmp.rlPart2 : sip_methods[tmp.method].text);
02224    }
02225    res = (reliable) ?
02226        __sip_reliable_xmit(p, seqno, 1, req->data, req->len, (reliable == XMIT_CRITICAL), req->method) :
02227       __sip_xmit(p, req->data, req->len);
02228    if (res > 0)
02229       return 0;
02230    return res;
02231 }

static int set_address_from_contact ( struct sip_pvt pvt  )  [static]

Change the other partys IP address based on given contact.

Definition at line 7814 of file chan_sip.c.

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

Referenced by handle_response_invite().

07815 {
07816    struct hostent *hp;
07817    struct ast_hostent ahp;
07818    int port;
07819    char *c, *host, *pt;
07820    char *contact;
07821 
07822 
07823    if (ast_test_flag(&pvt->flags[0], SIP_NAT_ROUTE)) {
07824       /* NAT: Don't trust the contact field.  Just use what they came to us
07825          with. */
07826       pvt->sa = pvt->recv;
07827       return 0;
07828    }
07829 
07830 
07831    /* Work on a copy */
07832    contact = ast_strdupa(pvt->fullcontact);
07833 
07834    /* Make sure it's a SIP URL */
07835    if (strncasecmp(contact, "sip:", 4)) {
07836       ast_log(LOG_NOTICE, "'%s' is not a valid SIP contact (missing sip:) trying to use anyway\n", contact);
07837    } else
07838       contact += 4;
07839 
07840    /* Ditch arguments */
07841    /* XXX this code is replicated also shortly below */
07842 
07843    /* Grab host */
07844    host = strchr(contact, '@');
07845    if (!host) {   /* No username part */
07846       host = contact;
07847       c = NULL;
07848    } else {
07849       *host++ = '\0';
07850    }
07851    pt = strchr(host, ':');
07852    if (pt) {
07853       *pt++ = '\0';
07854       port = atoi(pt);
07855    } else
07856       port = STANDARD_SIP_PORT;
07857 
07858    contact = strsep(&contact, ";"); /* trim ; and beyond in username part */
07859    host = strsep(&host, ";");    /* trim ; and beyond in host/domain part */
07860 
07861    /* XXX This could block for a long time XXX */
07862    /* We should only do this if it's a name, not an IP */
07863    hp = ast_gethostbyname(host, &ahp);
07864    if (!hp)  {
07865       ast_log(LOG_WARNING, "Invalid host name in Contact: (can't resolve in DNS) : '%s'\n", host);
07866       return -1;
07867    }
07868    pvt->sa.sin_family = AF_INET;
07869    memcpy(&pvt->sa.sin_addr, hp->h_addr, sizeof(pvt->sa.sin_addr));
07870    pvt->sa.sin_port = htons(port);
07871 
07872    return 0;
07873 }

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

Set destination from SIP URI.

Definition at line 5600 of file chan_sip.c.

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

Referenced by reqprep().

05601 {
05602    char *h, *maddr, hostname[256];
05603    int port, hn;
05604    struct hostent *hp;
05605    struct ast_hostent ahp;
05606    int debug=sip_debug_test_pvt(p);
05607 
05608    /* Parse uri to h (host) and port - uri is already just the part inside the <> */
05609    /* general form we are expecting is sip[s]:username[:password]@host[:port][;...] */
05610 
05611    if (debug)
05612       ast_verbose("set_destination: Parsing <%s> for address/port to send to\n", uri);
05613 
05614    /* Find and parse hostname */
05615    h = strchr(uri, '@');
05616    if (h)
05617       ++h;
05618    else {
05619       h = uri;
05620       if (strncasecmp(h, "sip:", 4) == 0)
05621          h += 4;
05622       else if (strncasecmp(h, "sips:", 5) == 0)
05623          h += 5;
05624    }
05625    hn = strcspn(h, ":;>") + 1;
05626    if (hn > sizeof(hostname)) 
05627       hn = sizeof(hostname);
05628    ast_copy_string(hostname, h, hn);
05629    /* XXX bug here if string has been trimmed to sizeof(hostname) */
05630    h += hn - 1;
05631 
05632    /* Is "port" present? if not default to STANDARD_SIP_PORT */
05633    if (*h == ':') {
05634       /* Parse port */
05635       ++h;
05636       port = strtol(h, &h, 10);
05637    }
05638    else
05639       port = STANDARD_SIP_PORT;
05640 
05641    /* Got the hostname:port - but maybe there's a "maddr=" to override address? */
05642    maddr = strstr(h, "maddr=");
05643    if (maddr) {
05644       maddr += 6;
05645       hn = strspn(maddr, "0123456789.") + 1;
05646       if (hn > sizeof(hostname))
05647          hn = sizeof(hostname);
05648       ast_copy_string(hostname, maddr, hn);
05649    }
05650    
05651    hp = ast_gethostbyname(hostname, &ahp);
05652    if (hp == NULL)  {
05653       ast_log(LOG_WARNING, "Can't find address for host '%s'\n", hostname);
05654       return;
05655    }
05656    p->sa.sin_family = AF_INET;
05657    memcpy(&p->sa.sin_addr, hp->h_addr, sizeof(p->sa.sin_addr));
05658    p->sa.sin_port = htons(port);
05659    if (debug)
05660       ast_verbose("set_destination: set destination to %s, port %d\n", ast_inet_ntoa(p->sa.sin_addr), port);
05661 }

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

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

Referenced by handle_common_options(), and realtime_peer().

15685 {
15686    if (!strcasecmp(value, "very"))
15687       ast_set_flag(flags, SIP_INSECURE_PORT | SIP_INSECURE_INVITE);
15688    else if (ast_true(value))
15689       ast_set_flag(flags, SIP_INSECURE_PORT);
15690    else if (!ast_false(value)) {
15691       char buf[64];
15692       char *word, *next;
15693       ast_copy_string(buf, value, sizeof(buf));
15694       next = buf;
15695       while ((word = strsep(&next, ","))) {
15696          if (!strcasecmp(word, "port"))
15697             ast_set_flag(flags, SIP_INSECURE_PORT);
15698          else if (!strcasecmp(word, "invite"))
15699             ast_set_flag(flags, SIP_INSECURE_INVITE);
15700          else
15701             ast_log(LOG_WARNING, "Unknown insecure mode '%s' on line %d\n", value, lineno);
15702       }
15703    }
15704 }

static void set_peer_defaults ( struct sip_peer peer  )  [static]

Set peer defaults before configuring specific configurations.

Definition at line 16102 of file chan_sip.c.

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

Referenced by build_peer(), and temp_peer().

16103 {
16104    if (peer->expire == 0) {
16105       /* Don't reset expire or port time during reload 
16106          if we have an active registration 
16107       */
16108       peer->expire = -1;
16109       peer->pokeexpire = -1;
16110       peer->addr.sin_port = htons(STANDARD_SIP_PORT);
16111    }
16112    ast_copy_flags(&peer->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY);
16113    ast_copy_flags(&peer->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY);
16114    strcpy(peer->context, default_context);
16115    strcpy(peer->subscribecontext, default_subscribecontext);
16116    strcpy(peer->language, default_language);
16117    strcpy(peer->mohinterpret, default_mohinterpret);
16118    strcpy(peer->mohsuggest, default_mohsuggest);
16119    peer->addr.sin_family = AF_INET;
16120    peer->defaddr.sin_family = AF_INET;
16121    peer->capability = global_capability;
16122    peer->maxcallbitrate = default_maxcallbitrate;
16123    peer->rtptimeout = global_rtptimeout;
16124    peer->rtpholdtimeout = global_rtpholdtimeout;
16125    peer->rtpkeepalive = global_rtpkeepalive;
16126    peer->allowtransfer = global_allowtransfer;
16127    peer->autoframing = global_autoframing;
16128    strcpy(peer->vmexten, default_vmexten);
16129    peer->secret[0] = '\0';
16130    peer->md5secret[0] = '\0';
16131    peer->cid_num[0] = '\0';
16132    peer->cid_name[0] = '\0';
16133    peer->fromdomain[0] = '\0';
16134    peer->fromuser[0] = '\0';
16135    peer->regexten[0] = '\0';
16136    peer->mailbox[0] = '\0';
16137    peer->callgroup = 0;
16138    peer->pickupgroup = 0;
16139    peer->maxms = default_qualify;
16140    peer->prefs = default_prefs;
16141 }

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

Add a SIP header to an outbound INVITE.

Definition at line 17309 of file chan_sip.c.

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

Referenced by load_module().

17310 {
17311    int no = 0;
17312    int ok = FALSE;
17313    char varbuf[30];
17314    char *inbuf = (char *) data;
17315    
17316    if (ast_strlen_zero(inbuf)) {
17317       ast_log(LOG_WARNING, "This application requires the argument: Header\n");
17318       return 0;
17319    }
17320    ast_channel_lock(chan);
17321 
17322    /* Check for headers */
17323    while (!ok && no <= 50) {
17324       no++;
17325       snprintf(varbuf, sizeof(varbuf), "_SIPADDHEADER%.2d", no);
17326 
17327       /* Compare without the leading underscore */
17328       if( (pbx_builtin_getvar_helper(chan, (const char *) varbuf + 1) == (const char *) NULL) )
17329          ok = TRUE;
17330    }
17331    if (ok) {
17332       pbx_builtin_setvar_helper (chan, varbuf, inbuf);
17333       if (sipdebug)
17334          ast_log(LOG_DEBUG,"SIP Header added \"%s\" as %s\n", inbuf, varbuf);
17335    } else {
17336       ast_log(LOG_WARNING, "Too many SIP headers added, max 50\n");
17337    }
17338    ast_channel_unlock(chan);
17339    return 0;
17340 }

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

Support routine for find_peer.

Definition at line 2570 of file chan_sip.c.

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

Referenced by find_peer().

02571 {
02572    /* We know name is the first field, so we can cast */
02573    struct sip_peer *p = (struct sip_peer *) name;
02574    return   !(!inaddrcmp(&p->addr, sin) || 
02575                (ast_test_flag(&p->flags[0], SIP_INSECURE_PORT) &&
02576                (p->addr.sin_addr.s_addr == sin->sin_addr.s_addr)));
02577 }

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

Allocate SIP_PVT structure and set defaults.

Definition at line 4309 of file chan_sip.c.

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

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

04311 {
04312    struct sip_pvt *p;
04313 
04314    if (!(p = ast_calloc(1, sizeof(*p))))
04315       return NULL;
04316 
04317    if (ast_string_field_init(p, 512)) {
04318       free(p);
04319       return NULL;
04320    }
04321 
04322    ast_mutex_init(&p->lock);
04323 
04324    p->method = intended_method;
04325    p->initid = -1;
04326    p->autokillid = -1;
04327    p->subscribed = NONE;
04328    p->stateid = -1;
04329    p->prefs = default_prefs;     /* Set default codecs for this call */
04330 
04331    if (intended_method != SIP_OPTIONS) /* Peerpoke has it's own system */
04332       p->timer_t1 = 500;   /* Default SIP retransmission timer T1 (RFC 3261) */
04333 
04334    if (sin) {
04335       p->sa = *sin;
04336       if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
04337          p->ourip = __ourip;
04338    } else
04339       p->ourip = __ourip;
04340 
04341    /* Copy global flags to this PVT at setup. */
04342    ast_copy_flags(&p->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY);
04343    ast_copy_flags(&p->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY);
04344 
04345    ast_set2_flag(&p->flags[0], !recordhistory, SIP_NO_HISTORY);
04346 
04347    p->branch = ast_random();  
04348    make_our_tag(p->tag, sizeof(p->tag));
04349    p->ocseq = INITIAL_CSEQ;
04350 
04351    if (sip_methods[intended_method].need_rtp) {
04352       p->rtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr.sin_addr);
04353       /* If the global videosupport flag is on, we always create a RTP interface for video */
04354       if (ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT))
04355          p->vrtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr.sin_addr);
04356       if (ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT))
04357          p->udptl = ast_udptl_new_with_bindaddr(sched, io, 0, bindaddr.sin_addr);
04358       if (!p->rtp || (ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) && !p->vrtp)) {
04359          ast_log(LOG_WARNING, "Unable to create RTP audio %s session: %s\n",
04360             ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) ? "and video" : "", strerror(errno));
04361          ast_mutex_destroy(&p->lock);
04362          if (p->chanvars) {
04363             ast_variables_destroy(p->chanvars);
04364             p->chanvars = NULL;
04365          }
04366          free(p);
04367          return NULL;
04368       }
04369       ast_rtp_setdtmf(p->rtp, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833);
04370       ast_rtp_setdtmfcompensate(p->rtp, ast_test_flag(&p->flags[1], SIP_PAGE2_RFC2833_COMPENSATE));
04371       ast_rtp_settos(p->rtp, global_tos_audio);
04372       ast_rtp_set_rtptimeout(p->rtp, global_rtptimeout);
04373       ast_rtp_set_rtpholdtimeout(p->rtp, global_rtpholdtimeout);
04374       ast_rtp_set_rtpkeepalive(p->rtp, global_rtpkeepalive);
04375       if (p->vrtp) {
04376          ast_rtp_settos(p->vrtp, global_tos_video);
04377          ast_rtp_setdtmf(p->vrtp, 0);
04378          ast_rtp_setdtmfcompensate(p->vrtp, 0);
04379          ast_rtp_set_rtptimeout(p->vrtp, global_rtptimeout);
04380          ast_rtp_set_rtpholdtimeout(p->vrtp, global_rtpholdtimeout);
04381          ast_rtp_set_rtpkeepalive(p->vrtp, global_rtpkeepalive);
04382       }
04383       if (p->udptl)
04384          ast_udptl_settos(p->udptl, global_tos_audio);
04385       p->maxcallbitrate = default_maxcallbitrate;
04386    }
04387 
04388    if (useglobal_nat && sin) {
04389       /* Setup NAT structure according to global settings if we have an address */
04390       ast_copy_flags(&p->flags[0], &global_flags[0], SIP_NAT);
04391       p->recv = *sin;
04392       do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE);
04393    }
04394 
04395    if (p->method != SIP_REGISTER)
04396       ast_string_field_set(p, fromdomain, default_fromdomain);
04397    build_via(p);
04398    if (!callid)
04399       build_callid_pvt(p);
04400    else
04401       ast_string_field_set(p, callid, callid);
04402    /* Assign default music on hold class */
04403    ast_string_field_set(p, mohinterpret, default_mohinterpret);
04404    ast_string_field_set(p, mohsuggest, default_mohsuggest);
04405    p->capability = global_capability;
04406    p->allowtransfer = global_allowtransfer;
04407    if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) ||
04408        (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO))
04409       p->noncodeccapability |= AST_RTP_DTMF;
04410    if (p->udptl) {
04411       p->t38.capability = global_t38_capability;
04412       if (ast_udptl_get_error_correction_scheme(p->udptl) == UDPTL_ERROR_CORRECTION_REDUNDANCY)
04413          p->t38.capability |= T38FAX_UDP_EC_REDUNDANCY;
04414       else if (ast_udptl_get_error_correction_scheme(p->udptl) == UDPTL_ERROR_CORRECTION_FEC)
04415          p->t38.capability |= T38FAX_UDP_EC_FEC;
04416       else if (ast_udptl_get_error_correction_scheme(p->udptl) == UDPTL_ERROR_CORRECTION_NONE)
04417          p->t38.capability |= T38FAX_UDP_EC_NONE;
04418       p->t38.capability |= T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF;
04419       p->t38.jointcapability = p->t38.capability;
04420    }
04421    ast_string_field_set(p, context, default_context);
04422 
04423    /* Add to active dialog list */
04424    ast_mutex_lock(&iflock);
04425    p->next = iflist;
04426    iflist = p;
04427    ast_mutex_unlock(&iflock);
04428    if (option_debug)
04429       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");
04430    return p;
04431 }

static void sip_alreadygone ( struct sip_pvt dialog  )  [static]

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

01640 {
01641    if (option_debug > 2)
01642       ast_log(LOG_DEBUG, "Setting SIP_ALREADYGONE on dialog %s\n", dialog->callid);
01643    ast_set_flag(&dialog->flags[0], SIP_ALREADYGONE);
01644 }

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

References ast_channel::_state, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_setstate(), AST_STATE_UP, sip_pvt::initreq, sip_pvt::lock, LOG_DEBUG, option_debug, t38properties::state, sip_pvt::t38, T38_ENABLED, T38_PEER_DIRECT, ast_channel::tech_pvt, transmit_response_with_sdp(), transmit_response_with_t38_sdp(), try_suggested_sip_codec(), and XMIT_CRITICAL.

03569 {
03570    int res = 0;
03571    struct sip_pvt *p = ast->tech_pvt;
03572 
03573    ast_mutex_lock(&p->lock);
03574    if (ast->_state != AST_STATE_UP) {
03575       try_suggested_sip_codec(p);   
03576 
03577       ast_setstate(ast, AST_STATE_UP);
03578       if (option_debug)
03579          ast_log(LOG_DEBUG, "SIP answering channel: %s\n", ast->name);
03580       if (p->t38.state == T38_PEER_DIRECT) {
03581          p->t38.state = T38_ENABLED;
03582          if (option_debug > 1)
03583             ast_log(LOG_DEBUG,"T38State change to %d on channel %s\n", p->t38.state, ast->name);
03584          res = transmit_response_with_t38_sdp(p, "200 OK", &p->initreq, XMIT_CRITICAL);
03585       } else 
03586          res = transmit_response_with_sdp(p, "200 OK", &p->initreq, XMIT_CRITICAL);
03587    }
03588    ast_mutex_unlock(&p->lock);
03589    return res;
03590 }

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 2874 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_set_flag, AST_STATE_DOWN, AST_STATE_RESERVED, ast_string_field_set, ast_translate_available_formats(), ast_var_name(), ast_var_value(), auto_congest(), sip_pvt::callingpres, t38properties::capability, sip_pvt::capability, ast_channel::cid, cid_name, ast_callerid::cid_pres, sip_invite_param::distinctive_ring, sip_pvt::flags, INC_CALL_RINGING, sip_pvt::initid, INV_CALLING, sip_pvt::invitestate, t38properties::jointcapability, sip_pvt::jointcapability, sip_pvt::jointnoncodeccapability, LOG_DEBUG, LOG_WARNING, sip_pvt::maxtime, sip_pvt::noncodeccapability, option_debug, sip_pvt::options, sip_pvt::prefcodec, sip_invite_param::replaces, SIP_INVITE, SIP_OUTGOING, SIP_TRANS_TIMEOUT, sipdebug, t38properties::state, sip_pvt::t38, T38_LOCAL_DIRECT, ast_channel::tech_pvt, sip_invite_param::transfer, transmit_invite(), update_call_counter(), sip_invite_param::uri_options, ast_channel::varshead, sip_invite_param::vxml_url, and XMIT_ERROR.

02875 {
02876    int res, xmitres = 0;
02877    struct sip_pvt *p;
02878    struct varshead *headp;
02879    struct ast_var_t *current;
02880    const char *referer = NULL;   /* SIP refererer */  
02881 
02882    p = ast->tech_pvt;
02883    if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) {
02884       ast_log(LOG_WARNING, "sip_call called on %s, neither down nor reserved\n", ast->name);
02885       return -1;
02886    }
02887 
02888    /* Check whether there is vxml_url, distinctive ring variables */
02889    headp=&ast->varshead;
02890    AST_LIST_TRAVERSE(headp,current,entries) {
02891       /* Check whether there is a VXML_URL variable */
02892       if (!p->options->vxml_url && !strcasecmp(ast_var_name(current), "VXML_URL")) {
02893          p->options->vxml_url = ast_var_value(current);
02894       } else if (!p->options->uri_options && !strcasecmp(ast_var_name(current), "SIP_URI_OPTIONS")) {
02895          p->options->uri_options = ast_var_value(current);
02896       } else if (!p->options->distinctive_ring && !strcasecmp(ast_var_name(current), "ALERT_INFO")) {
02897          /* Check whether there is a ALERT_INFO variable */
02898          p->options->distinctive_ring = ast_var_value(current);
02899       } else if (!p->options->addsipheaders && !strncasecmp(ast_var_name(current), "SIPADDHEADER", strlen("SIPADDHEADER"))) {
02900          /* Check whether there is a variable with a name starting with SIPADDHEADER */
02901          p->options->addsipheaders = 1;
02902       } else if (!strcasecmp(ast_var_name(current), "SIPTRANSFER")) {
02903          /* This is a transfered call */
02904          p->options->transfer = 1;
02905       } else if (!strcasecmp(ast_var_name(current), "SIPTRANSFER_REFERER")) {
02906          /* This is the referer */
02907          referer = ast_var_value(current);
02908       } else if (!strcasecmp(ast_var_name(current), "SIPTRANSFER_REPLACES")) {
02909          /* We're replacing a call. */
02910          p->options->replaces = ast_var_value(current);
02911       } else if (!strcasecmp(ast_var_name(current), "T38CALL")) {
02912          p->t38.state = T38_LOCAL_DIRECT;
02913          if (option_debug)
02914             ast_log(LOG_DEBUG,"T38State change to %d on channel %s\n", p->t38.state, ast->name);
02915       }
02916 
02917    }
02918    
02919    res = 0;
02920    ast_set_flag(&p->flags[0], SIP_OUTGOING);
02921 
02922    if (p->options->transfer) {
02923       char buf[BUFSIZ/2];
02924 
02925       if (referer) {
02926          if (sipdebug && option_debug > 2)
02927             ast_log(LOG_DEBUG, "Call for %s transfered by %s\n", p->username, referer);
02928          snprintf(buf, sizeof(buf)-1, "-> %s (via %s)", p->cid_name, referer);
02929       } else 
02930          snprintf(buf, sizeof(buf)-1, "-> %s", p->cid_name);
02931       ast_string_field_set(p, cid_name, buf);
02932    } 
02933    if (option_debug)
02934       ast_log(LOG_DEBUG, "Outgoing Call for %s\n", p->username);
02935 
02936    res = update_call_counter(p, INC_CALL_RINGING);
02937    if ( res != -1 ) {
02938       p->callingpres = ast->cid.cid_pres;
02939       p->jointcapability = ast_translate_available_formats(p->capability, p->prefcodec);
02940       p->jointnoncodeccapability = p->noncodeccapability;
02941 
02942       /* If there are no audio formats left to offer, punt */
02943       if (!(p->jointcapability & AST_FORMAT_AUDIO_MASK)) {
02944          ast_log(LOG_WARNING, "No audio format found to offer. Cancelling call to %s\n", p->username);
02945          res = -1;
02946       } else {
02947          p->t38.jointcapability = p->t38.capability;
02948          if (option_debug > 1)
02949             ast_log(LOG_DEBUG,"Our T38 capability (%d), joint T38 capability (%d)\n", p->t38.capability, p->t38.jointcapability);
02950          xmitres = transmit_invite(p, SIP_INVITE, 1, 2);
02951          if (xmitres == XMIT_ERROR)
02952             return -1;  /* Transmission error */
02953 
02954          p->invitestate = INV_CALLING;
02955 
02956          /* Initialize auto-congest time */
02957          p->initid = ast_sched_add(sched, p->maxtime ? (p->maxtime * 4) : SIP_TRANS_TIMEOUT, auto_congest, p);
02958       }
02959    }
02960    return res;
02961 }

static void sip_cancel_destroy ( struct sip_pvt p  )  [static]

Cancel destruction of SIP dialog.

Definition at line 2094 of file chan_sip.c.

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

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

02095 {
02096    if (p->autokillid > -1) {
02097       ast_sched_del(sched, p->autokillid);
02098       append_history(p, "CancelDestroy", "");
02099       p->autokillid = -1;
02100    }
02101 }

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

See if we pass debug IP filter.

Definition at line 1721 of file chan_sip.c.

References debugaddr, and sipdebug.

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

01722 {
01723    if (!sipdebug)
01724       return 0;
01725    if (debugaddr.sin_addr.s_addr) {
01726       if (((ntohs(debugaddr.sin_port) != 0)
01727          && (debugaddr.sin_port != addr->sin_port))
01728          || (debugaddr.sin_addr.s_addr != addr->sin_addr.s_addr))
01729          return 0;
01730    }
01731    return 1;
01732 }

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

Test PVT for debugging output.

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

01748 {
01749    if (!sipdebug)
01750       return 0;
01751    return sip_debug_test_addr(sip_real_dst(p));
01752 }

static void sip_destroy ( struct sip_pvt p  )  [static]

Destroy SIP call structure.

Definition at line 3215 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(), sip_destroy_peer(), sip_do_reload(), sip_notify(), sip_poke_noanswer(), sip_poke_peer(), sip_registry_destroy(), sip_request_call(), sip_send_mwi_to_peer(), and transmit_register().

03216 {
03217    ast_mutex_lock(&iflock);
03218    if (option_debug > 2)
03219       ast_log(LOG_DEBUG, "Destroying SIP dialog %s\n", p->callid);
03220    __sip_destroy(p, 1);
03221    ast_mutex_unlock(&iflock);
03222 }

static void sip_destroy_peer ( struct sip_peer peer  )  [static]

Destroy peer object from memory.

Definition at line 2406 of file chan_sip.c.

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

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

02407 {
02408    if (option_debug > 2)
02409       ast_log(LOG_DEBUG, "Destroying SIP peer %s\n", peer->name);
02410 
02411    /* Delete it, it needs to disappear */
02412    if (peer->call)
02413       sip_destroy(peer->call);
02414 
02415    if (peer->mwipvt)    /* We have an active subscription, delete it */
02416       sip_destroy(peer->mwipvt);
02417 
02418    if (peer->chanvars) {
02419       ast_variables_destroy(peer->chanvars);
02420       peer->chanvars = NULL;
02421    }
02422    if (peer->expire > -1)
02423       ast_sched_del(sched, peer->expire);
02424 
02425    if (peer->pokeexpire > -1)
02426       ast_sched_del(sched, peer->pokeexpire);
02427    register_peer_exten(peer, FALSE);
02428    ast_free_ha(peer->ha);
02429    if (ast_test_flag(&peer->flags[1], SIP_PAGE2_SELFDESTRUCT))
02430       apeerobjs--;
02431    else if (ast_test_flag(&peer->flags[0], SIP_REALTIME))
02432       rpeerobjs--;
02433    else
02434       speerobjs--;
02435    clear_realm_authentication(peer->auth);
02436    peer->auth = NULL;
02437    free(peer);
02438 }

static void sip_destroy_user ( struct sip_user user  )  [static]

Remove user object from in-memory storage.

Definition at line 2598 of file chan_sip.c.

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

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

02599 {
02600    if (option_debug > 2)
02601       ast_log(LOG_DEBUG, "Destroying user object from memory: %s\n", user->name);
02602    ast_free_ha(user->ha);
02603    if (user->chanvars) {
02604       ast_variables_destroy(user->chanvars);
02605       user->chanvars = NULL;
02606    }
02607    if (ast_test_flag(&user->flags[0], SIP_REALTIME))
02608       ruserobjs--;
02609    else
02610       suserobjs--;
02611    free(user);
02612 }

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

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

15530 {
15531    char *host;
15532    char *tmp;
15533 
15534    struct hostent *hp;
15535    struct ast_hostent ahp;
15536    struct sip_peer *p;
15537 
15538    int res = AST_DEVICE_INVALID;
15539 
15540    /* make sure data is not null. Maybe unnecessary, but better be safe */
15541    host = ast_strdupa(data ? data : "");
15542    if ((tmp = strchr(host, '@')))
15543       host = tmp + 1;
15544 
15545    if (option_debug > 2) 
15546       ast_log(LOG_DEBUG, "Checking device state for peer %s\n", host);
15547 
15548    if ((p = find_peer(host, NULL, 1))) {
15549       if (p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) {
15550          /* we have an address for the peer */
15551       
15552          /* Check status in this order
15553             - Hold
15554             - Ringing
15555             - Busy (enforced only by call limit)
15556             - Inuse (we have a call)
15557             - Unreachable (qualify)
15558             If we don't find any of these state, report AST_DEVICE_NOT_INUSE
15559             for registered devices */
15560 
15561          if (p->onHold)
15562             /* First check for hold or ring states */
15563             res = AST_DEVICE_ONHOLD;
15564          else if (p->inRinging) {
15565             if (p->inRinging == p->inUse)
15566                res = AST_DEVICE_RINGING;
15567             else
15568                res = AST_DEVICE_RINGINUSE;
15569          } else if (p->call_limit && (p->inUse == p->call_limit))
15570             /* check call limit */
15571             res = AST_DEVICE_BUSY;
15572          else if (p->call_limit && p->inUse)
15573             /* Not busy, but we do have a call */
15574             res = AST_DEVICE_INUSE;
15575          else if (p->maxms && (p->lastms > p->maxms)) 
15576             /* We don't have a call. Are we reachable at all? Requires qualify= */
15577             res = AST_DEVICE_UNAVAILABLE;
15578          else  /* Default reply if we're registered and have no other data */
15579             res = AST_DEVICE_NOT_INUSE;
15580       } else {
15581          /* there is no address, it's unavailable */
15582          res = AST_DEVICE_UNAVAILABLE;
15583       }
15584       ASTOBJ_UNREF(p,sip_destroy_peer);
15585    } else {
15586       hp = ast_gethostbyname(host, &ahp);
15587       if (hp)
15588          res = AST_DEVICE_UNKNOWN;
15589    }
15590 
15591    return res;
15592 }

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

Turn on SIP debugging (CLI command).

Definition at line 11037 of file chan_sip.c.

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

11038 {
11039    int oldsipdebug = sipdebug_console;
11040    if (argc != 3) {
11041       if (argc != 5) 
11042          return RESULT_SHOWUSAGE;
11043       else if (strcmp(argv[3], "ip") == 0)
11044          return sip_do_debug_ip(fd, argc, argv);
11045       else if (strcmp(argv[3], "peer") == 0)
11046          return sip_do_debug_peer(fd, argc, argv);
11047       else
11048          return RESULT_SHOWUSAGE;
11049    }
11050    ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE);
11051    memset(&debugaddr, 0, sizeof(debugaddr));
11052    ast_cli(fd, "SIP Debugging %senabled\n", oldsipdebug ? "re-" : "");
11053    return RESULT_SUCCESS;
11054 }

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

Definition at line 11056 of file chan_sip.c.

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

11057 {
11058    int oldsipdebug = sipdebug_console;
11059    char *newargv[6] = { "sip", "set", "debug", NULL };
11060    if (argc != 2) {
11061       if (argc != 4) 
11062          return RESULT_SHOWUSAGE;
11063       else if (strcmp(argv[2], "ip") == 0) {
11064          newargv[3] = argv[2];
11065          newargv[4] = argv[3];
11066          return sip_do_debug_ip(fd, argc + 1, newargv);
11067       } else if (strcmp(argv[2], "peer") == 0) {
11068          newargv[3] = argv[2];
11069          newargv[4] = argv[3];
11070          return sip_do_debug_peer(fd, argc + 1, newargv);
11071       } else
11072          return RESULT_SHOWUSAGE;
11073    }
11074    ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE);
11075    memset(&debugaddr, 0, sizeof(debugaddr));
11076    ast_cli(fd, "SIP Debugging %senabled\n", oldsipdebug ? "re-" : "");
11077    return RESULT_SUCCESS;
11078 }

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

Enable SIP Debugging in CLI.

Definition at line 10983 of file chan_sip.c.

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

Referenced by sip_do_debug(), and sip_do_debug_deprecated().

10984 {
10985    struct hostent *hp;
10986    struct ast_hostent ahp;
10987    int port = 0;
10988    char *p, *arg;
10989 
10990    /* sip set debug ip <ip> */
10991    if (argc != 5)
10992       return RESULT_SHOWUSAGE;
10993    p = arg = argv[4];
10994    strsep(&p, ":");
10995    if (p)
10996       port = atoi(p);
10997    hp = ast_gethostbyname(arg, &ahp);
10998    if (hp == NULL)
10999       return RESULT_SHOWUSAGE;
11000 
11001    debugaddr.sin_family = AF_INET;
11002    memcpy(&debugaddr.sin_addr, hp->h_addr, sizeof(debugaddr.sin_addr));
11003    debugaddr.sin_port = htons(port);
11004    if (port == 0)
11005       ast_cli(fd, "SIP Debugging Enabled for IP: %s\n", ast_inet_ntoa(debugaddr.sin_addr));
11006    else
11007       ast_cli(fd, "SIP Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(debugaddr.sin_addr), port);
11008 
11009    ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE);
11010 
11011    return RESULT_SUCCESS;
11012 }

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

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

Referenced by sip_do_debug(), and sip_do_debug_deprecated().

11016 {
11017    struct sip_peer *peer;
11018    if (argc != 5)
11019       return RESULT_SHOWUSAGE;
11020    peer = find_peer(argv[4], NULL, 1);
11021    if (peer) {
11022       if (peer->addr.sin_addr.s_addr) {
11023          debugaddr.sin_family = AF_INET;
11024          debugaddr.sin_addr = peer->addr.sin_addr;
11025          debugaddr.sin_port = peer->addr.sin_port;
11026          ast_cli(fd, "SIP Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(debugaddr.sin_addr), ntohs(debugaddr.sin_port));
11027          ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE);
11028       } else
11029          ast_cli(fd, "Unable to get IP address of peer '%s'\n", argv[4]);
11030       ASTOBJ_UNREF(peer,sip_destroy_peer);
11031    } else
11032       ast_cli(fd, "No such peer '%s'\n", argv[4]);
11033    return RESULT_SUCCESS;
11034 }

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

Enable SIP History logging (CLI).

Definition at line 11156 of file chan_sip.c.

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

11157 {
11158    if (argc != 2) {
11159       return RESULT_SHOWUSAGE;
11160    }
11161    recordhistory = TRUE;
11162    ast_cli(fd, "SIP History Recording Enabled (use 'sip show history')\n");
11163    return RESULT_SUCCESS;
11164 }

static int sip_do_reload ( enum channelreloadreason  reason  )  [static]

Reload module.

Definition at line 17450 of file chan_sip.c.

References ast_log(), ASTOBJ_CONTAINER_DESTROYALL, ASTOBJ_CONTAINER_MARKALL, ASTOBJ_CONTAINER_PRUNE_MARKED, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, authl, clear_realm_authentication(), clear_sip_domains(), LOG_DEBUG, option_debug, peerl, regl, reload_config(), sip_destroy(), sip_destroy_peer(), sip_destroy_user(), sip_poke_all_peers(), sip_registry_destroy(), sip_send_all_registers(), and userl.

Referenced by do_monitor().

17451 {
17452    if (option_debug > 3)
17453       ast_log(LOG_DEBUG, "--------------- SIP reload started\n");
17454 
17455    clear_realm_authentication(authl);
17456    clear_sip_domains();
17457    authl = NULL;
17458 
17459    /* First, destroy all outstanding registry calls */
17460    /* This is needed, since otherwise active registry entries will not be destroyed */
17461    ASTOBJ_CONTAINER_TRAVERSE(&regl, 1, do {
17462       ASTOBJ_RDLOCK(iterator);
17463       if (iterator->call) {
17464          if (option_debug > 2)
17465             ast_log(LOG_DEBUG, "Destroying active SIP dialog for registry %s@%s\n", iterator->username, iterator->hostname);
17466          /* This will also remove references to the registry */
17467          sip_destroy(iterator->call);
17468       }
17469       ASTOBJ_UNLOCK(iterator);
17470    
17471    } while(0));
17472 
17473    /* Then, actually destroy users and registry */
17474    ASTOBJ_CONTAINER_DESTROYALL(&userl, sip_destroy_user);
17475    if (option_debug > 3)
17476       ast_log(LOG_DEBUG, "--------------- Done destroying user list\n");
17477    ASTOBJ_CONTAINER_DESTROYALL(&regl, sip_registry_destroy);
17478    if (option_debug > 3)
17479       ast_log(LOG_DEBUG, "--------------- Done destroying registry list\n");
17480    ASTOBJ_CONTAINER_MARKALL(&peerl);
17481    reload_config(reason);
17482 
17483    /* Prune peers who still are supposed to be deleted */
17484    ASTOBJ_CONTAINER_PRUNE_MARKED(&peerl, sip_destroy_peer);
17485    if (option_debug > 3)
17486       ast_log(LOG_DEBUG, "--------------- Done destroying pruned peers\n");
17487 
17488    /* Send qualify (OPTIONS) to all peers */
17489    sip_poke_all_peers();
17490 
17491    /* Register with all services */
17492    sip_send_all_registers();
17493 
17494    if (option_debug > 3)
17495       ast_log(LOG_DEBUG, "--------------- SIP reload done\n");
17496 
17497    return 0;
17498 }

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

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

Definition at line 17254 of file chan_sip.c.

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

Referenced by load_module().

17255 {
17256    struct sip_pvt *p;
17257    char *mode;
17258    if (data)
17259       mode = (char *)data;
17260    else {
17261       ast_log(LOG_WARNING, "This application requires the argument: info, inband, rfc2833\n");
17262       return 0;
17263    }
17264    ast_channel_lock(chan);
17265    if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) {
17266       ast_log(LOG_WARNING, "Call this application only on SIP incoming calls\n");
17267       ast_channel_unlock(chan);
17268       return 0;
17269    }
17270    p = chan->tech_pvt;
17271    if (!p) {
17272       ast_channel_unlock(chan);
17273       return 0;
17274    }
17275    ast_mutex_lock(&p->lock);
17276    if (!strcasecmp(mode,"info")) {
17277       ast_clear_flag(&p->flags[0], SIP_DTMF);
17278       ast_set_flag(&p->flags[0], SIP_DTMF_INFO);
17279       p->jointnoncodeccapability &= ~AST_RTP_DTMF;
17280    } else if (!strcasecmp(mode,"rfc2833")) {
17281       ast_clear_flag(&p->flags[0], SIP_DTMF);
17282       ast_set_flag(&p->flags[0], SIP_DTMF_RFC2833);
17283       p->jointnoncodeccapability |= AST_RTP_DTMF;
17284    } else if (!strcasecmp(mode,"inband")) { 
17285       ast_clear_flag(&p->flags[0], SIP_DTMF);
17286       ast_set_flag(&p->flags[0], SIP_DTMF_INBAND);
17287       p->jointnoncodeccapability &= ~AST_RTP_DTMF;
17288    } else
17289       ast_log(LOG_WARNING, "I don't know about this dtmf mode: %s\n",mode);
17290    if (p->rtp)
17291       ast_rtp_setdtmf(p->rtp, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833);
17292    if (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) {
17293       if (!p->vad) {
17294          p->vad = ast_dsp_new();
17295          ast_dsp_set_features(p->vad, DSP_FEATURE_DTMF_DETECT);
17296       }
17297    } else {
17298       if (p->vad) {
17299          ast_dsp_free(p->vad);
17300          p->vad = NULL;
17301       }
17302    }
17303    ast_mutex_unlock(&p->lock);
17304    ast_channel_unlock(chan);
17305    return 0;
17306 }

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

10854 {
10855    int x = 0;
10856    struct sip_history *hist;
10857    static int errmsg = 0;
10858 
10859    if (!dialog)
10860       return;
10861 
10862    if (!option_debug && !sipdebug) {
10863       if (!errmsg) {
10864          ast_log(LOG_NOTICE, "You must have debugging enabled (SIP or Asterisk) in order to dump SIP history.\n");
10865          errmsg = 1;
10866       }
10867       return;
10868    }
10869 
10870    ast_log(LOG_DEBUG, "\n---------- SIP HISTORY for '%s' \n", dialog->callid);
10871    if (dialog->subscribed)
10872       ast_log(LOG_DEBUG, "  * Subscription\n");
10873    else
10874       ast_log(LOG_DEBUG, "  * SIP Call\n");
10875    if (dialog->history)
10876       AST_LIST_TRAVERSE(dialog->history, hist, list)
10877          ast_log(LOG_DEBUG, "  %-3.3d. %s\n", ++x, hist->event);
10878    if (!x)
10879       ast_log(LOG_DEBUG, "Call '%s' has no history\n", dialog->callid);
10880    ast_log(LOG_DEBUG, "\n---------- END SIP HISTORY for '%s' \n", dialog->callid);
10881 }

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

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

03671 {
03672    int ret = -1;
03673    struct sip_pvt *p;
03674 
03675    if (newchan && ast_test_flag(newchan, AST_FLAG_ZOMBIE) && option_debug)
03676       ast_log(LOG_DEBUG, "New channel is zombie\n");
03677    if (oldchan && ast_test_flag(oldchan, AST_FLAG_ZOMBIE) && option_debug)
03678       ast_log(LOG_DEBUG, "Old channel is zombie\n");
03679 
03680    if (!newchan || !newchan->tech_pvt) {
03681       if (!newchan)
03682          ast_log(LOG_WARNING, "No new channel! Fixup of %s failed.\n", oldchan->name);
03683       else
03684          ast_log(LOG_WARNING, "No SIP tech_pvt! Fixup of %s failed.\n", oldchan->name);
03685       return -1;
03686    }
03687    p = newchan->tech_pvt;
03688 
03689    if (!p) {
03690       ast_log(LOG_WARNING, "No pvt after masquerade. Strange things may happen\n");
03691       return -1;
03692    }
03693 
03694    ast_mutex_lock(&p->lock);
03695    append_history(p, "Masq", "Old channel: %s\n", oldchan->name);
03696    append_history(p, "Masq (cont)", "...new owner: %s\n", newchan->name);
03697    if (p->owner != oldchan)
03698       ast_log(LOG_WARNING, "old channel wasn't %p but was %p\n", oldchan, p->owner);
03699    else {
03700       p->owner = newchan;
03701       ret = 0;
03702    }
03703    if (option_debug > 2)
03704       ast_log(LOG_DEBUG, "SIP Fixup: New owner for dialogue %s: %s (Old parent: %s)\n", p->callid, p->owner->name, oldchan->name);
03705 
03706    ast_mutex_unlock(&p->lock);
03707    return ret;
03708 }

static int sip_get_codec ( struct ast_channel chan  )  [static]

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

Definition at line 17399 of file chan_sip.c.

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

17400 {
17401    struct sip_pvt *p = chan->tech_pvt;
17402    return p->peercapability ? p->peercapability : p->capability;  
17403 }

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

17108 {
17109    struct sip_pvt *p = NULL;
17110    enum ast_rtp_get_result res = AST_RTP_TRY_PARTIAL;
17111 
17112    if (!(p = chan->tech_pvt))
17113       return AST_RTP_GET_FAILED;
17114 
17115    ast_mutex_lock(&p->lock);
17116    if (!(p->rtp)) {
17117       ast_mutex_unlock(&p->lock);
17118       return AST_RTP_GET_FAILED;
17119    }
17120 
17121    *rtp = p->rtp;
17122 
17123    if (ast_rtp_getnat(*rtp) && !ast_test_flag(&p->flags[0], SIP_CAN_REINVITE_NAT))
17124       res = AST_RTP_TRY_PARTIAL;
17125    else if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE))
17126       res = AST_RTP_TRY_NATIVE;
17127    else if (ast_test_flag(&global_jbconf, AST_JB_FORCED))
17128       res = AST_RTP_GET_FAILED;
17129 
17130    ast_mutex_unlock(&p->lock);
17131 
17132    return res;
17133 }

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

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

16973 {
16974    struct sip_pvt *p;
16975    struct ast_udptl *udptl = NULL;
16976    
16977    p = chan->tech_pvt;
16978    if (!p)
16979       return NULL;
16980    
16981    ast_mutex_lock(&p->lock);
16982    if (p->udptl && ast_test_flag(&p->flags[0], SIP_CAN_REINVITE))
16983       udptl = p->udptl;
16984    ast_mutex_unlock(&p->lock);
16985    return udptl;
16986 }

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

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

17137 {
17138    struct sip_pvt *p = NULL;
17139    enum ast_rtp_get_result res = AST_RTP_TRY_PARTIAL;
17140    
17141    if (!(p = chan->tech_pvt))
17142       return AST_RTP_GET_FAILED;
17143 
17144    ast_mutex_lock(&p->lock);
17145    if (!(p->vrtp)) {
17146       ast_mutex_unlock(&p->lock);
17147       return AST_RTP_GET_FAILED;
17148    }
17149 
17150    *rtp = p->vrtp;
17151 
17152    if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE))
17153       res = AST_RTP_TRY_NATIVE;
17154 
17155    ast_mutex_unlock(&p->lock);
17156 
17157    return res;
17158 }

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

Handle T38 reinvite.

T38 negotiation helper function

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

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

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

Definition at line 17024 of file chan_sip.c.

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

Referenced by handle_request_invite(), and handle_response_invite().

17025 {
17026    struct sip_pvt *p;
17027    int flag = 0;
17028    
17029    p = chan->tech_pvt;
17030    if (!p || !pvt->udptl)
17031       return -1;
17032    
17033    /* Setup everything on the other side like offered/responded from first side */
17034    ast_mutex_lock(&p->lock);
17035 
17036    /*! \todo check if this is not set earlier when setting up the PVT. If not
17037       maybe it should move there. */
17038    p->t38.jointcapability = p->t38.peercapability = pvt->t38.jointcapability;
17039 
17040    ast_udptl_set_far_max_datagram(p->udptl, ast_udptl_get_local_max_datagram(pvt->udptl));
17041    ast_udptl_set_local_max_datagram(p->udptl, ast_udptl_get_local_max_datagram(pvt->udptl));
17042    ast_udptl_set_error_correction_scheme(p->udptl, ast_udptl_get_error_correction_scheme(pvt->udptl));
17043    
17044    if (reinvite) {      /* If we are handling sending re-invite to the other side of the bridge */
17045       /*! \note The SIP_CAN_REINVITE flag is for RTP media redirects,
17046          not really T38 re-invites which are different. In this
17047          case it's used properly, to see if we can reinvite over
17048          NAT 
17049       */
17050       if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE) && ast_test_flag(&pvt->flags[0], SIP_CAN_REINVITE)) {
17051          ast_udptl_get_peer(pvt->udptl, &p->udptlredirip);
17052          flag =1;
17053       } else {
17054          memset(&p->udptlredirip, 0, sizeof(p->udptlredirip));
17055       }
17056       if (!ast_test_flag(&p->flags[0], SIP_GOTREFER)) {
17057          if (!p->pendinginvite) {
17058             if (option_debug > 2) {
17059                if (flag)
17060                   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));
17061                else
17062                   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));
17063             }
17064             transmit_reinvite_with_t38_sdp(p);
17065          } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) {
17066             if (option_debug > 2) {
17067                if (flag)
17068                   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));
17069                else
17070                   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));
17071             }
17072             ast_set_flag(&p->flags[0], SIP_NEEDREINVITE);
17073          }
17074       }
17075       /* Reset lastrtprx timer */
17076       p->lastrtprx = p->lastrtptx = time(NULL);
17077       ast_mutex_unlock(&p->lock);
17078       return 0;
17079    } else { /* If we are handling sending 200 OK to the other side of the bridge */
17080       if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE) && ast_test_flag(&pvt->flags[0], SIP_CAN_REINVITE)) {
17081          ast_udptl_get_peer(pvt->udptl, &p->udptlredirip);
17082          flag = 1;
17083       } else {
17084          memset(&p->udptlredirip, 0, sizeof(p->udptlredirip));
17085       }
17086       if (option_debug > 2) {
17087          if (flag)
17088             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));
17089          else
17090             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));
17091       }
17092       pvt->t38.state = T38_ENABLED;
17093       p->t38.state = T38_ENABLED;
17094       if (option_debug > 1) {
17095          ast_log(LOG_DEBUG, "T38 changed state to %d on channel %s\n", pvt->t38.state, pvt->owner ? pvt->owner->name : "<none>");
17096          ast_log(LOG_DEBUG, "T38 changed state to %d on channel %s\n", p->t38.state, chan ? chan->name : "<none>");
17097       }
17098       transmit_response_with_t38_sdp(p, "200 OK", &p->initreq, XMIT_CRITICAL);
17099       p->lastrtprx = p->lastrtptx = time(NULL);
17100       ast_mutex_unlock(&p->lock);
17101       return 0;
17102    }
17103 }

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 3387 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_set_flag, ast_state2str(), AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, ast_strlen_zero(), ast_test_flag, sip_pvt::autokillid, sip_request::data, DEC_CALL_LIMIT, DEFAULT_TRANS_TIMEOUT, FALSE, sip_pvt::flags, hangup_cause2sip(), ast_channel::hangupcause, INC_CALL_LIMIT, sip_pvt::initid, sip_pvt::initreq, INV_CALLING, INV_COMPLETED, sip_pvt::invitestate, sip_pvt::lock, LOG_DEBUG, LOG_WARNING, sip_pvt::ocseq, option_debug, sip_pvt::owner, pbx_builtin_setvar_helper(), sip_pvt::pendinginvite, sip_pvt::refer, sip_pvt::rtp, SIP_ALREADYGONE, SIP_BYE, SIP_CANCEL, sip_cancel_destroy(), SIP_DEFER_BYE_ON_TRANSFER, SIP_INC_COUNT, SIP_NEEDDESTROY, SIP_NEEDREINVITE, SIP_NO_HISTORY, SIP_OUTGOING, SIP_PAGE2_CALL_ONHOLD, SIP_PENDINGBYE, sip_scheddestroy(), sipdebug, stop_media_flows(), ast_channel::tech_pvt, transmit_request(), transmit_request_with_auth(), transmit_response_reliable(), TRUE, update_call_counter(), sip_pvt::vad, sip_pvt::vrtp, and XMIT_RELIABLE.

03388 {
03389    struct sip_pvt *p = ast->tech_pvt;
03390    int needcancel = FALSE;
03391    int needdestroy = 0;
03392    struct ast_channel *oldowner = ast;
03393 
03394    if (!p) {
03395       if (option_debug)
03396          ast_log(LOG_DEBUG, "Asked to hangup channel that was not connected\n");
03397       return 0;
03398    }
03399 
03400    if (ast_test_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER)) {
03401       if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) {
03402          if (option_debug && sipdebug)
03403             ast_log(LOG_DEBUG, "update_call_counter(%s) - decrement call limit counter on hangup\n", p->username);
03404          update_call_counter(p, DEC_CALL_LIMIT);
03405       }
03406       if (option_debug >3)
03407          ast_log(LOG_DEBUG, "SIP Transfer: Not hanging up right now... Rescheduling hangup for %s.\n", p->callid);
03408       if (p->autokillid > -1)
03409          sip_cancel_destroy(p);
03410       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
03411       ast_clear_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Really hang up next time */
03412       ast_clear_flag(&p->flags[0], SIP_NEEDDESTROY);
03413       p->owner->tech_pvt = NULL;
03414       p->owner = NULL;  /* Owner will be gone after we return, so take it away */
03415       return 0;
03416    }
03417    if (option_debug) {
03418       if (ast_test_flag(ast, AST_FLAG_ZOMBIE) && p->refer && option_debug)
03419                ast_log(LOG_DEBUG, "SIP Transfer: Hanging up Zombie channel %s after transfer ... Call-ID: %s\n", ast->name, p->callid);
03420       else  {
03421          if (option_debug)
03422             ast_log(LOG_DEBUG, "Hangup call %s, SIP callid %s)\n", ast->name, p->callid);
03423       }
03424    }
03425    if (option_debug && ast_test_flag(ast, AST_FLAG_ZOMBIE)) 
03426       ast_log(LOG_DEBUG, "Hanging up zombie call. Be scared.\n");
03427 
03428    ast_mutex_lock(&p->lock);
03429    if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) {
03430       if (option_debug && sipdebug)
03431          ast_log(LOG_DEBUG, "update_call_counter(%s) - decrement call limit counter on hangup\n", p->username);
03432       update_call_counter(p, DEC_CALL_LIMIT);
03433    }
03434 
03435    /* Determine how to disconnect */
03436    if (p->owner != ast) {
03437       ast_log(LOG_WARNING, "Huh?  We aren't the owner? Can't hangup call.\n");
03438       ast_mutex_unlock(&p->lock);
03439       return 0;
03440    }
03441    /* If the call is not UP, we need to send CANCEL instead of BYE */
03442    if (ast->_state == AST_STATE_RING || ast->_state == AST_STATE_RINGING || (p->invitestate < INV_COMPLETED && ast->_state != AST_STATE_UP)) {
03443       needcancel = TRUE;
03444       if (option_debug > 3)
03445          ast_log(LOG_DEBUG, "Hanging up channel in state %s (not UP)\n", ast_state2str(ast->_state));
03446    }
03447 
03448    stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */
03449 
03450    append_history(p, needcancel ? "Cancel" : "Hangup", "Cause %s", p->owner ? ast_cause2str(p->owner->hangupcause) : "Unknown");
03451 
03452    /* Disconnect */
03453    if (p->vad)
03454       ast_dsp_free(p->vad);
03455 
03456    p->owner = NULL;
03457    ast->tech_pvt = NULL;
03458 
03459    ast_module_unref(ast_module_info->self);
03460 
03461    /* Do not destroy this pvt until we have timeout or
03462       get an answer to the BYE or INVITE/CANCEL 
03463       If we get no answer during retransmit period, drop the call anyway.
03464       (Sorry, mother-in-law, you can't deny a hangup by sending
03465       603 declined to BYE...)
03466    */
03467    if (ast_test_flag(&p->flags[0], SIP_ALREADYGONE))
03468       needdestroy = 1;  /* Set destroy flag at end of this function */
03469    else if (p->invitestate != INV_CALLING)
03470       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
03471 
03472    /* Start the process if it's not already started */
03473    if (!ast_test_flag(&p->flags[0], SIP_ALREADYGONE) && !ast_strlen_zero(p->initreq.data)) {
03474       if (needcancel) { /* Outgoing call, not up */
03475          if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
03476             /* stop retransmitting an INVITE that has not received a response */
03477             __sip_pretend_ack(p);
03478 
03479             /* if we can't send right now, mark it pending */
03480             if (p->invitestate == INV_CALLING) {
03481                /* We can't send anything in CALLING state */
03482                ast_set_flag(&p->flags[0], SIP_PENDINGBYE);
03483                /* 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. */
03484                sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
03485                append_history(p, "DELAY", "Not sending cancel, waiting for timeout");
03486             } else {
03487                /* Send a new request: CANCEL */
03488                transmit_request(p, SIP_CANCEL, p->ocseq, XMIT_RELIABLE, FALSE);
03489                /* Actually don't destroy us yet, wait for the 487 on our original 
03490                   INVITE, but do set an autodestruct just in case we never get it. */
03491                needdestroy = 0;
03492                sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
03493             }
03494             if ( p->initid != -1 ) {
03495                /* channel still up - reverse dec of inUse counter
03496                   only if the channel is not auto-congested */
03497                update_call_counter(p, INC_CALL_LIMIT);
03498             }
03499          } else { /* Incoming call, not up */
03500             const char *res;
03501             if (ast->hangupcause && (res = hangup_cause2sip(ast->hangupcause)))
03502                transmit_response_reliable(p, res, &p->initreq);
03503             else 
03504                transmit_response_reliable(p, "603 Declined", &p->initreq);
03505          }
03506       } else { /* Call is in UP state, send BYE */
03507          if (!p->pendinginvite) {
03508             char *audioqos = "";
03509             char *videoqos = "";
03510             if (p->rtp)
03511                audioqos = ast_rtp_get_quality(p->rtp, NULL);
03512             if (p->vrtp)
03513                videoqos = ast_rtp_get_quality(p->vrtp, NULL);
03514             /* Send a hangup */
03515             transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, 1);
03516 
03517             /* Get RTCP quality before end of call */
03518             if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) {
03519                if (p->rtp)
03520                   append_history(p, "RTCPaudio", "Quality:%s", audioqos);
03521                if (p->vrtp)
03522                   append_history(p, "RTCPvideo", "Quality:%s", videoqos);
03523             }
03524             if (p->rtp && oldowner)
03525                pbx_builtin_setvar_helper(oldowner, "RTPAUDIOQOS", audioqos);
03526             if (p->vrtp && oldowner)
03527                pbx_builtin_setvar_helper(oldowner, "RTPVIDEOQOS", videoqos);
03528          } else {
03529             /* Note we will need a BYE when this all settles out
03530                but we can't send one while we have "INVITE" outstanding. */
03531             ast_set_flag(&p->flags[0], SIP_PENDINGBYE);  
03532             ast_clear_flag(&p->flags[0], SIP_NEEDREINVITE); 
03533             sip_cancel_destroy(p);
03534          }
03535       }
03536    }
03537    if (needdestroy)
03538       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
03539    ast_mutex_unlock(&p->lock);
03540    return 0;
03541 }

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

References ast_channel::_state, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_HOLD, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_RINGING, AST_CONTROL_UNHOLD, AST_CONTROL_VIDUPDATE, ast_log(), ast_moh_start(), ast_moh_stop(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), AST_STATE_RING, AST_STATE_UP, ast_test_flag, sip_pvt::flags, sip_pvt::initreq, INV_COMPLETED, INV_EARLY_MEDIA, INV_PROCEEDING, sip_pvt::invitestate, sip_pvt::lock, LOG_WARNING, sip_alreadygone(), SIP_NOVIDEO, SIP_OUTGOING, SIP_PROG_INBAND, SIP_PROG_INBAND_NEVER, SIP_PROG_INBAND_YES, SIP_PROGRESS_SENT, SIP_RINGING, ast_channel::tech_pvt, transmit_info_with_vidupdate(), transmit_response(), transmit_response_with_sdp(), sip_pvt::vrtp, and XMIT_UNRELIABLE.

03780 {
03781    struct sip_pvt *p = ast->tech_pvt;
03782    int res = 0;
03783 
03784    ast_mutex_lock(&p->lock);
03785    switch(condition) {
03786    case AST_CONTROL_RINGING:
03787       if (ast->_state == AST_STATE_RING) {
03788          p->invitestate = INV_EARLY_MEDIA;
03789          if (!ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) ||
03790              (ast_test_flag(&p->flags[0], SIP_PROG_INBAND) == SIP_PROG_INBAND_NEVER)) {            
03791             /* Send 180 ringing if out-of-band seems reasonable */
03792             transmit_response(p, "180 Ringing", &p->initreq);
03793             ast_set_flag(&p->flags[0], SIP_RINGING);
03794             if (ast_test_flag(&p->flags[0], SIP_PROG_INBAND) != SIP_PROG_INBAND_YES)
03795                break;
03796          } else {
03797             /* Well, if it's not reasonable, just send in-band */
03798          }
03799       }
03800       res = -1;
03801       break;
03802    case AST_CONTROL_BUSY:
03803       if (ast->_state != AST_STATE_UP) {
03804          transmit_response(p, "486 Busy Here", &p->initreq);
03805          p->invitestate = INV_COMPLETED;
03806          sip_alreadygone(p);
03807          ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV);
03808          break;
03809       }
03810       res = -1;
03811       break;
03812    case AST_CONTROL_CONGESTION:
03813       if (ast->_state != AST_STATE_UP) {
03814          transmit_response(p, "503 Service Unavailable", &p->initreq);
03815          p->invitestate = INV_COMPLETED;
03816          sip_alreadygone(p);
03817          ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV);
03818          break;
03819       }
03820       res = -1;
03821       break;
03822    case AST_CONTROL_PROCEEDING:
03823       if ((ast->_state != AST_STATE_UP) &&
03824           !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) &&
03825           !ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
03826          transmit_response(p, "100 Trying", &p->initreq);
03827          p->invitestate = INV_PROCEEDING;  
03828          break;
03829       }
03830       res = -1;
03831       break;
03832    case AST_CONTROL_PROGRESS:
03833       if ((ast->_state != AST_STATE_UP) &&
03834           !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) &&
03835           !ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
03836          p->invitestate = INV_EARLY_MEDIA;
03837          transmit_response_with_sdp(p, "183 Session Progress", &p->initreq, XMIT_UNRELIABLE);
03838          ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT);  
03839          break;
03840       }
03841       res = -1;
03842       break;
03843    case AST_CONTROL_HOLD:
03844       ast_moh_start(ast, data, p->mohinterpret);
03845       break;
03846    case AST_CONTROL_UNHOLD:
03847       ast_moh_stop(ast);
03848       break;
03849    case AST_CONTROL_VIDUPDATE:   /* Request a video frame update */
03850       if (p->vrtp && !ast_test_flag(&p->flags[0], SIP_NOVIDEO)) {
03851          transmit_info_with_vidupdate(p);
03852          /* ast_rtcp_send_h261fur(p->vrtp); */
03853       } else
03854          res = -1;
03855       break;
03856    case -1:
03857       res = -1;
03858       break;
03859    default:
03860       ast_log(LOG_WARNING, "Don't know how to indicate condition %d\n", condition);
03861       res = -1;
03862       break;
03863    }
03864    ast_mutex_unlock(&p->lock);
03865    return res;
03866 }

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

Display SIP nat mode.

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

01742 {
01743    return ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE ? "NAT" : "no NAT";
01744 }

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

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

Definition at line 3875 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_string_field_set, ast_strlen_zero(), ast_test_flag, ast_udptl_fd(), 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_name, ast_callerid::cid_num, ast_callerid::cid_pres, ast_callerid::cid_rdnis, ast_channel::context, DSP_DIGITMODE_DTMF, DSP_DIGITMODE_RELAXDTMF, DSP_FEATURE_DTMF_DETECT, ast_channel::exten, ast_channel::fds, sip_pvt::flags, fmt, global_jbconf, ast_channel::hangupcause, sip_pvt::jointcapability, language, sip_pvt::lock, LOG_DEBUG, LOG_WARNING, ast_variable::name, ast_channel::nativeformats, ast_variable::next, option_debug, sip_pvt::owner, pbx_builtin_setvar_helper(), sip_pvt::pickupgroup, ast_channel::pickupgroup, sip_pvt::prefcodec, sip_pvt::prefs, ast_channel::priority, ast_channel::rawreadformat, ast_channel::rawwriteformat, ast_channel::readformat, ast_channel::rings, sip_pvt::rtp, SIP_DTMF, SIP_DTMF_INBAND, SIP_DTMF_INFO, SIP_NO_HISTORY, sip_tech, sip_tech_info, ast_channel::tech, ast_channel::tech_pvt, sip_pvt::udptl, sip_pvt::vad, ast_variable::value, sip_pvt::vrtp, and ast_channel::writeformat.

Referenced by handle_request_invite(), and sip_request_call().

03876 {
03877    struct ast_channel *tmp;
03878    struct ast_variable *v = NULL;
03879    int fmt;
03880    int what;
03881    int needvideo = 0;
03882    {
03883       const char *my_name;    /* pick a good name */
03884 
03885       if (title)
03886          my_name = title;
03887       else if ( (my_name = strchr(i->fromdomain,':')) )
03888          my_name++;      /* skip ':' */
03889       else
03890          my_name = i->fromdomain;
03891 
03892       ast_mutex_unlock(&i->lock);
03893       /* Don't hold a sip pvt lock while we allocate a channel */
03894       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);
03895 
03896    }
03897    if (!tmp) {
03898       ast_log(LOG_WARNING, "Unable to allocate AST channel structure for SIP channel\n");
03899       return NULL;
03900    }
03901    ast_mutex_lock(&i->lock);
03902 
03903    if (ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_INFO)
03904       tmp->tech = &sip_tech_info;
03905    else
03906       tmp->tech = &sip_tech;
03907 
03908    /* Select our native format based on codec preference until we receive
03909       something from another device to the contrary. */
03910    if (i->jointcapability)    /* The joint capabilities of us and peer */
03911       what = i->jointcapability;
03912    else if (i->capability)    /* Our configured capability for this peer */
03913       what = i->capability;
03914    else
03915       what = global_capability;  /* Global codec support */
03916 
03917    /* Set the native formats for audio  and merge in video */
03918    tmp->nativeformats = ast_codec_choose(&i->prefs, what, 1) | (i->jointcapability & AST_FORMAT_VIDEO_MASK);
03919    if (option_debug > 2) {
03920       char buf[BUFSIZ];
03921       ast_log(LOG_DEBUG, "*** Our native formats are %s \n", ast_getformatname_multiple(buf, BUFSIZ, tmp->nativeformats));
03922       ast_log(LOG_DEBUG, "*** Joint capabilities are %s \n", ast_getformatname_multiple(buf, BUFSIZ, i->jointcapability));
03923       ast_log(LOG_DEBUG, "*** Our capabilities are %s \n", ast_getformatname_multiple(buf, BUFSIZ, i->capability));
03924       ast_log(LOG_DEBUG, "*** AST_CODEC_CHOOSE formats are %s \n", ast_getformatname_multiple(buf, BUFSIZ, ast_codec_choose(&i->prefs, what, 1)));
03925       if (i->prefcodec)
03926          ast_log(LOG_DEBUG, "*** Our preferred formats from the incoming channel are %s \n", ast_getformatname_multiple(buf, BUFSIZ, i->prefcodec));
03927    }
03928 
03929    /* XXX Why are we choosing a codec from the native formats?? */
03930    fmt = ast_best_codec(tmp->nativeformats);
03931 
03932    /* If we have a prefcodec setting, we have an inbound channel that set a 
03933       preferred format for this call. Otherwise, we check the jointcapability
03934       We also check for vrtp. If it's not there, we are not allowed do any video anyway.
03935     */
03936    if (i->vrtp) {
03937       if (i->prefcodec)
03938          needvideo = i->prefcodec & AST_FORMAT_VIDEO_MASK;  /* Outbound call */
03939       else
03940          needvideo = i->jointcapability & AST_FORMAT_VIDEO_MASK;  /* Inbound call */
03941    }
03942 
03943    if (option_debug > 2) {
03944       if (needvideo) 
03945          ast_log(LOG_DEBUG, "This channel can handle video! HOLLYWOOD next!\n");
03946       else
03947          ast_log(LOG_DEBUG, "This channel will not be able to handle video.\n");
03948    }
03949 
03950 
03951 
03952    if (ast_test_flag(&i->flags[0], SIP_DTMF) ==  SIP_DTMF_INBAND) {
03953       i->vad = ast_dsp_new();
03954       ast_dsp_set_features(i->vad, DSP_FEATURE_DTMF_DETECT);
03955       if (global_relaxdtmf)
03956          ast_dsp_digitmode(i->vad, DSP_DIGITMODE_DTMF | DSP_DIGITMODE_RELAXDTMF);
03957    }
03958    if (i->rtp) {
03959       tmp->fds[0] = ast_rtp_fd(i->rtp);
03960       tmp->fds[1] = ast_rtcp_fd(i->rtp);
03961    }
03962    if (needvideo && i->vrtp) {
03963       tmp->fds[2] = ast_rtp_fd(i->vrtp);
03964       tmp->fds[3] = ast_rtcp_fd(i->vrtp);
03965    }
03966    if (i->udptl) {
03967       tmp->fds[5] = ast_udptl_fd(i->udptl);
03968    }
03969    if (state == AST_STATE_RING)
03970       tmp->rings = 1;
03971    tmp->adsicpe = AST_ADSI_UNAVAILABLE;
03972    tmp->writeformat = fmt;
03973    tmp->rawwriteformat = fmt;
03974    tmp->readformat = fmt;
03975    tmp->rawreadformat = fmt;
03976    tmp->tech_pvt = i;
03977 
03978    tmp->callgroup = i->callgroup;
03979    tmp->pickupgroup = i->pickupgroup;
03980    tmp->cid.cid_pres = i->callingpres;
03981    if (!ast_strlen_zero(i->accountcode))
03982       ast_string_field_set(tmp, accountcode, i->accountcode);
03983    if (i->amaflags)
03984       tmp->amaflags = i->amaflags;
03985    if (!ast_strlen_zero(i->language))
03986       ast_string_field_set(tmp, language, i->language);
03987    i->owner = tmp;
03988    ast_module_ref(ast_module_info->self);
03989    ast_copy_string(tmp->context, i->context, sizeof(tmp->context));
03990    ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten));
03991 
03992 
03993    /* Don't use ast_set_callerid() here because it will
03994     * generate an unnecessary NewCallerID event  */
03995    tmp->cid.cid_num = ast_strdup(i->cid_num);
03996    tmp->cid.cid_ani = ast_strdup(i->cid_num);
03997    tmp->cid.cid_name = ast_strdup(i->cid_name);
03998    if (!ast_strlen_zero(i->rdnis))
03999       tmp->cid.cid_rdnis = ast_strdup(i->rdnis);
04000    
04001    if (!ast_strlen_zero(i->exten) && strcmp(i->exten, "s"))
04002       tmp->cid.cid_dnid = ast_strdup(i->exten);
04003 
04004    tmp->priority = 1;
04005    if (!ast_strlen_zero(i->uri))
04006       pbx_builtin_setvar_helper(tmp, "SIPURI", i->uri);
04007    if (!ast_strlen_zero(i->domain))
04008       pbx_builtin_setvar_helper(tmp, "SIPDOMAIN", i->domain);
04009    if (!ast_strlen_zero(i->useragent))
04010       pbx_builtin_setvar_helper(tmp, "SIPUSERAGENT", i->useragent);
04011    if (!ast_strlen_zero(i->callid))
04012       pbx_builtin_setvar_helper(tmp, "SIPCALLID", i->callid);
04013    if (i->rtp)
04014       ast_jb_configure(tmp, &global_jbconf);
04015 
04016    /* Set channel variables for this call from configuration */
04017    for (v = i->chanvars ; v ; v = v->next)
04018       pbx_builtin_setvar_helper(tmp, v->name, v->value);
04019 
04020    if (state != AST_STATE_DOWN && ast_pbx_start(tmp)) {
04021       ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
04022       tmp->hangupcause = AST_CAUSE_SWITCH_CONGESTION;
04023       ast_hangup(tmp);
04024       tmp = NULL;
04025    }
04026 
04027    if (!ast_test_flag(&i->flags[0], SIP_NO_HISTORY))
04028       append_history(i, "NewChan", "Channel %s - from %s", tmp->name, i->callid);
04029 
04030    return tmp;
04031 }

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

Disable SIP Debugging in CLI.

Definition at line 11137 of file chan_sip.c.

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

11138 {
11139    if (argc != 4)
11140       return RESULT_SHOWUSAGE;
11141    ast_clear_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE);
11142    ast_cli(fd, "SIP Debugging Disabled\n");
11143    return RESULT_SUCCESS;
11144 }

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

Definition at line 11146 of file chan_sip.c.

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

11147 {
11148    if (argc != 3)
11149       return RESULT_SHOWUSAGE;
11150    ast_clear_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE);
11151    ast_cli(fd, "SIP Debugging Disabled\n");
11152    return RESULT_SUCCESS;
11153 }

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

Disable SIP History logging (CLI).

Definition at line 11167 of file chan_sip.c.

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

11168 {
11169    if (argc != 3) {
11170       return RESULT_SHOWUSAGE;
11171    }
11172    recordhistory = FALSE;
11173    ast_cli(fd, "SIP History Recording Disabled\n");
11174    return RESULT_SUCCESS;
11175 }

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

Cli command to send SIP notify to peer.

Definition at line 11081 of file chan_sip.c.

References __ourip, add_header(), ast_cli(), ast_log(), ast_sip_ouraddrfor(), ast_variable_browse(), build_callid_pvt(), build_via(), create_addr(), DEFAULT_TRANS_TIMEOUT, initreqprep(), LOG_WARNING, ast_variable::name, ast_variable::next, notify_types, sip_pvt::ourip, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, sip_pvt::sa, sip_alloc(), sip_destroy(), SIP_NOTIFY, sip_scheddestroy(), transmit_sip_request(), ast_variable::value, and var.

11082 {
11083    struct ast_variable *varlist;
11084    int i;
11085 
11086    if (argc < 4)
11087       return RESULT_SHOWUSAGE;
11088 
11089    if (!notify_types) {
11090       ast_cli(fd, "No %s file found, or no types listed there\n", notify_config);
11091       return RESULT_FAILURE;
11092    }
11093 
11094    varlist = ast_variable_browse(notify_types, argv[2]);
11095 
11096    if (!varlist) {
11097       ast_cli(fd, "Unable to find notify type '%s'\n", argv[2]);
11098       return RESULT_FAILURE;
11099    }
11100 
11101    for (i = 3; i < argc; i++) {
11102       struct sip_pvt *p;
11103       struct sip_request req;
11104       struct ast_variable *var;
11105 
11106       if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY))) {
11107          ast_log(LOG_WARNING, "Unable to build sip pvt data for notify (memory/socket error)\n");
11108          return RESULT_FAILURE;
11109       }
11110 
11111       if (create_addr(p, argv[i])) {
11112          /* Maybe they're not registered, etc. */
11113          sip_destroy(p);
11114          ast_cli(fd, "Could not create address for '%s'\n", argv[i]);
11115          continue;
11116       }
11117 
11118       initreqprep(&req, p, SIP_NOTIFY);
11119 
11120       for (var = varlist; var; var = var->next)
11121          add_header(&req, var->name, var->value);
11122 
11123       /* Recalculate our side, and recalculate Call ID */
11124       if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
11125          p->ourip = __ourip;
11126       build_via(p);
11127       build_callid_pvt(p);
11128       ast_cli(fd, "Sending NOTIFY of type '%s' to '%s'\n", argv[2], argv[i]);
11129       transmit_sip_request(p, &req);
11130       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
11131    }
11132 
11133    return RESULT_SUCCESS;
11134 }

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 12813 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_unlock, ast_do_masquerade(), ast_hangup(), ast_log(), ast_pthread_create_background, AST_STATE_DOWN, sip_dual::chan1, sip_dual::chan2, ast_channel::context, copy_request(), ast_channel::exten, free, ast_channel::hangupcause, LOG_DEBUG, LOG_WARNING, option_debug, ast_channel::priority, ast_channel::readformat, sip_dual::req, sip_dual::seqno, sip_park_thread(), and ast_channel::writeformat.

Referenced by handle_request_refer().

12814 {
12815    struct sip_dual *d;
12816    struct ast_channel *transferee, *transferer;
12817       /* Chan2m: The transferer, chan1m: The transferee */
12818    pthread_t th;
12819 
12820    transferee = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan1->accountcode, chan1->exten, chan1->context, chan1->amaflags, "Parking/%s", chan1->name);
12821    transferer = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->amaflags, "SIPPeer/%s", chan2->name);
12822    if ((!transferer) || (!transferee)) {
12823       if (transferee) {
12824          transferee->hangupcause = AST_CAUSE_SWITCH_CONGESTION;
12825          ast_hangup(transferee);
12826       }
12827       if (transferer) {
12828          transferer->hangupcause = AST_CAUSE_SWITCH_CONGESTION;
12829          ast_hangup(transferer);
12830       }
12831       return -1;
12832    }
12833 
12834    /* Make formats okay */
12835    transferee->readformat = chan1->readformat;
12836    transferee->writeformat = chan1->writeformat;
12837 
12838    /* Prepare for taking over the channel */
12839    ast_channel_masquerade(transferee, chan1);
12840 
12841    /* Setup the extensions and such */
12842    ast_copy_string(transferee->context, chan1->context, sizeof(transferee->context));
12843    ast_copy_string(transferee->exten, chan1->exten, sizeof(transferee->exten));
12844    transferee->priority = chan1->priority;
12845       
12846    /* We make a clone of the peer channel too, so we can play
12847       back the announcement */
12848 
12849    /* Make formats okay */
12850    transferer->readformat = chan2->readformat;
12851    transferer->writeformat = chan2->writeformat;
12852 
12853    /* Prepare for taking over the channel */
12854    ast_channel_masquerade(transferer, chan2);
12855 
12856    /* Setup the extensions and such */
12857    ast_copy_string(transferer->context, chan2->context, sizeof(transferer->context));
12858    ast_copy_string(transferer->exten, chan2->exten, sizeof(transferer->exten));
12859    transferer->priority = chan2->priority;
12860 
12861    ast_channel_lock(transferer);
12862    if (ast_do_masquerade(transferer)) {
12863       ast_log(LOG_WARNING, "Masquerade failed :(\n");
12864       ast_channel_unlock(transferer);
12865       transferer->hangupcause = AST_CAUSE_SWITCH_CONGESTION;
12866       ast_hangup(transferer);
12867       return -1;
12868    }
12869    ast_channel_unlock(transferer);
12870    if (!transferer || !transferee) {
12871       if (!transferer) { 
12872          if (option_debug)
12873             ast_log(LOG_DEBUG, "No transferer channel, giving up parking\n");
12874       }
12875       if (!transferee) {
12876          if (option_debug)
12877             ast_log(LOG_DEBUG, "No transferee channel, giving up parking\n");
12878       }
12879       return -1;
12880    }
12881    if ((d = ast_calloc(1, sizeof(*d)))) {
12882       pthread_attr_t attr;
12883 
12884       pthread_attr_init(&attr);
12885       pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);   
12886 
12887       /* Save original request for followup */
12888       copy_request(&d->req, req);
12889       d->chan1 = transferee;  /* Transferee */
12890       d->chan2 = transferer;  /* Transferer */
12891       d->seqno = seqno;
12892       if (ast_pthread_create_background(&th, &attr, sip_park_thread, d) < 0) {
12893          /* Could not start thread */
12894          free(d); /* We don't need it anymore. If thread is created, d will be free'd
12895                   by sip_park_thread() */
12896          pthread_attr_destroy(&attr);
12897          return 0;
12898       }
12899       pthread_attr_destroy(&attr);
12900    } 
12901    return -1;
12902 }

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

References append_history, AST_CAUSE_NORMAL_CLEARING, ast_channel_lock, ast_channel_unlock, ast_do_masquerade(), ast_hangup(), ast_log(), ast_park_call(), sip_dual::chan1, sip_dual::chan2, copy_request(), ext, free, ast_channel::hangupcause, LOG_DEBUG, LOG_ERROR, LOG_WARNING, option_debug, sip_dual::req, sip_dual::seqno, ast_channel::tech_pvt, transmit_message_with_text(), transmit_notify_with_sipfrag(), transmit_response(), and TRUE.

Referenced by sip_park().

12747 {
12748    struct ast_channel *transferee, *transferer; /* Chan1: The transferee, Chan2: The transferer */
12749    struct sip_dual *d;
12750    struct sip_request req;
12751    int ext;
12752    int res;
12753 
12754    d = stuff;
12755    transferee = d->chan1;
12756    transferer = d->chan2;
12757    copy_request(&req, &d->req);
12758    free(d);
12759 
12760    if (!transferee || !transferer) {
12761       ast_log(LOG_ERROR, "Missing channels for parking! Transferer %s Transferee %s\n", transferer ? "<available>" : "<missing>", transferee ? "<available>" : "<missing>" );
12762       return NULL;
12763    }
12764    if (option_debug > 3) 
12765       ast_log(LOG_DEBUG, "SIP Park: Transferer channel %s, Transferee %s\n", transferer->name, transferee->name);
12766 
12767    ast_channel_lock(transferee);
12768    if (ast_do_masquerade(transferee)) {
12769       ast_log(LOG_WARNING, "Masquerade failed.\n");
12770       transmit_response(transferer->tech_pvt, "503 Internal error", &req);
12771       ast_channel_unlock(transferee);
12772       return NULL;
12773    } 
12774    ast_channel_unlock(transferee);
12775 
12776    res = ast_park_call(transferee, transferer, 0, &ext);
12777    
12778 
12779 #ifdef WHEN_WE_KNOW_THAT_THE_CLIENT_SUPPORTS_MESSAGE
12780    if (!res) {
12781       transmit_message_with_text(transferer->tech_pvt, "Unable to park call.\n");
12782    } else {
12783       /* Then tell the transferer what happened */
12784       sprintf(buf, "Call parked on extension '%d'", ext);
12785       transmit_message_with_text(transferer->tech_pvt, buf);
12786    }
12787 #endif
12788 
12789    /* Any way back to the current call??? */
12790    /* Transmit response to the REFER request */
12791    transmit_response(transferer->tech_pvt, "202 Accepted", &req);
12792    if (!res)   {
12793       /* Transfer succeeded */
12794       append_history(transferer->tech_pvt, "SIPpark","Parked call on %d", ext);
12795       transmit_notify_with_sipfrag(transferer->tech_pvt, d->seqno, "200 OK", TRUE);
12796       transferer->hangupcause = AST_CAUSE_NORMAL_CLEARING;
12797       ast_hangup(transferer); /* This will cause a BYE */
12798       if (option_debug)
12799          ast_log(LOG_DEBUG, "SIP Call parked on extension '%d'\n", ext);
12800    } else {
12801       transmit_notify_with_sipfrag(transferer->tech_pvt, d->seqno, "503 Service Unavailable", TRUE);
12802       append_history(transferer->tech_pvt, "SIPpark","Parking failed\n");
12803       if (option_debug)
12804          ast_log(LOG_DEBUG, "SIP Call parked failed \n");
12805       /* Do not hangup call */
12806    }
12807    return NULL;
12808 }

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

08319 {
08320    struct sip_peer *peer = find_peer(p->peername, NULL, 1);
08321 
08322    if (!peer)
08323       return;
08324 
08325    /* If they put someone on hold, increment the value... otherwise decrement it */
08326    if (hold)
08327       peer->onHold++;
08328    else
08329       peer->onHold--;
08330 
08331    /* Request device state update */
08332    ast_device_state_changed("SIP/%s", peer->name);
08333 
08334    return;
08335 }

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

References ast_sched_add(), ast_sched_del(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_UNLOCK, ASTOBJ_WRLOCK, peerl, and sip_poke_peer_s().

Referenced by load_module(), and sip_do_reload().

17410 {
17411    int ms = 0;
17412    
17413    if (!speerobjs)   /* No peers, just give up */
17414       return;
17415 
17416    ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do {
17417       ASTOBJ_WRLOCK(iterator);
17418       if (iterator->pokeexpire > -1)
17419          ast_sched_del(sched, iterator->pokeexpire);
17420       ms += 100;
17421       iterator->pokeexpire = ast_sched_add(sched, ms, sip_poke_peer_s, iterator);
17422       ASTOBJ_UNLOCK(iterator);
17423    } while (0)
17424    );
17425 }

static int sip_poke_noanswer ( void *  data  )  [static]

React to lack of answer to Qualify poke.

Definition at line 15412 of file chan_sip.c.

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

Referenced by sip_poke_peer().

15413 {
15414    struct sip_peer *peer = data;
15415    
15416    peer->pokeexpire = -1;
15417    if (peer->lastms > -1) {
15418       ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE!  Last qualify: %d\n", peer->name, peer->lastms);
15419       manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, -1);
15420    }
15421    if (peer->call)
15422       sip_destroy(peer->call);
15423    peer->call = NULL;
15424    peer->lastms = -1;
15425    ast_device_state_changed("SIP/%s", peer->name);
15426    /* Try again quickly */
15427    peer->pokeexpire = ast_sched_add(sched, DEFAULT_FREQ_NOTOK, sip_poke_peer_s, peer);
15428    return 0;
15429 }

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

References __ourip, sip_peer::addr, ast_copy_flags, ast_inet_ntoa(), ast_log(), ast_sched_add(), ast_sched_del(), ast_set_flag, ast_sip_ouraddrfor(), ast_string_field_set, ast_strlen_zero(), build_callid_pvt(), build_via(), sip_peer::call, DEFAULT_MAXMS, sip_peer::flags, sip_pvt::flags, sip_peer::fullcontact, sip_peer::lastms, LOG_NOTICE, sip_peer::maxms, sip_pvt::ourip, sip_peer::pokeexpire, sip_peer::ps, sip_pvt::recv, sip_pvt::relatedpeer, sip_pvt::sa, sip_alloc(), sip_destroy(), SIP_FLAGS_TO_COPY, SIP_INVITE, SIP_OPTIONS, SIP_OUTGOING, SIP_PAGE2_FLAGS_TO_COPY, sip_poke_noanswer(), sipdebug, sip_peer::tohost, transmit_invite(), and XMIT_ERROR.

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

15435 {
15436    struct sip_pvt *p;
15437    int xmitres = 0;
15438 
15439    if (!peer->maxms || !peer->addr.sin_addr.s_addr) {
15440       /* IF we have no IP, or this isn't to be monitored, return
15441         imeediately after clearing things out */
15442       if (peer->pokeexpire > -1)
15443          ast_sched_del(sched, peer->pokeexpire);
15444       peer->lastms = 0;
15445       peer->pokeexpire = -1;
15446       peer->call = NULL;
15447       return 0;
15448    }
15449    if (peer->call) {
15450       if (sipdebug)
15451          ast_log(LOG_NOTICE, "Still have a QUALIFY dialog active, deleting\n");
15452       sip_destroy(peer->call);
15453    }
15454    if (!(p = peer->call = sip_alloc(NULL, NULL, 0, SIP_OPTIONS)))
15455       return -1;
15456    
15457    p->sa = peer->addr;
15458    p->recv = peer->addr;
15459    ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY);
15460    ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY);
15461 
15462    /* Send OPTIONs to peer's fullcontact */
15463    if (!ast_strlen_zero(peer->fullcontact))
15464       ast_string_field_set(p, fullcontact, peer->fullcontact);
15465 
15466    if (!ast_strlen_zero(peer->tohost))
15467       ast_string_field_set(p, tohost, peer->tohost);
15468    else
15469       ast_string_field_set(p, tohost, ast_inet_ntoa(peer->addr.sin_addr));
15470 
15471    /* Recalculate our side, and recalculate Call ID */
15472    if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
15473       p->ourip = __ourip;
15474    build_via(p);
15475    build_callid_pvt(p);
15476 
15477    if (peer->pokeexpire > -1)
15478       ast_sched_del(sched, peer->pokeexpire);
15479    p->relatedpeer = peer;
15480    ast_set_flag(&p->flags[0], SIP_OUTGOING);
15481 #ifdef VOCAL_DATA_HACK
15482    ast_copy_string(p->username, "__VOCAL_DATA_SHOULD_READ_THE_SIP_SPEC__", sizeof(p->username));
15483    xmitres = transmit_invite(p, SIP_INVITE, 0, 2);
15484 #else
15485    xmitres = transmit_invite(p, SIP_OPTIONS, 0, 2);
15486 #endif
15487    gettimeofday(&peer->ps, NULL);
15488    if (xmitres == XMIT_ERROR)
15489       sip_poke_noanswer(peer);   /* Immediately unreachable, network problems */
15490    else
15491       peer->pokeexpire = ast_sched_add(sched, DEFAULT_MAXMS * 2, sip_poke_noanswer, peer);
15492 
15493    return 0;
15494 }

static int sip_poke_peer_s ( void *  data  )  [static]

Poke peer (send qualify to check if peer is alive and well).

Definition at line 7723 of file chan_sip.c.

References sip_peer::pokeexpire, and sip_poke_peer().

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

07724 {
07725    struct sip_peer *peer = data;
07726 
07727    peer->pokeexpire = -1;
07728    sip_poke_peer(peer);
07729    return 0;
07730 }

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

Remove temporary realtime objects from memory (CLI).

Definition at line 9880 of file chan_sip.c.

References ast_cli(), ast_test_flag, ASTOBJ_CONTAINER_FIND_UNLINK, ASTOBJ_CONTAINER_LINK, ASTOBJ_CONTAINER_PRUNE_MARKED, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_CONTAINER_UNLOCK, ASTOBJ_CONTAINER_WRLOCK, ASTOBJ_MARK, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, ASTOBJ_UNREF, FALSE, sip_user::flags, sip_peer::flags, name, peerl, RESULT_SHOWUSAGE, RESULT_SUCCESS, sip_destroy_peer(), sip_destroy_user(), SIP_PAGE2_RTCACHEFRIENDS, TRUE, and userl.

09881 {
09882    struct sip_peer *peer;
09883    struct sip_user *user;
09884    int pruneuser = FALSE;
09885    int prunepeer = FALSE;
09886    int multi = FALSE;
09887    char *name = NULL;
09888    regex_t regexbuf;
09889 
09890    switch (argc) {
09891    case 4:
09892       if (!strcasecmp(argv[3], "user"))
09893          return RESULT_SHOWUSAGE;
09894       if (!strcasecmp(argv[3], "peer"))
09895          return RESULT_SHOWUSAGE;
09896       if (!strcasecmp(argv[3], "like"))
09897          return RESULT_SHOWUSAGE;
09898       if (!strcasecmp(argv[3], "all")) {
09899          multi = TRUE;
09900          pruneuser = prunepeer = TRUE;
09901       } else {
09902          pruneuser = prunepeer = TRUE;
09903          name = argv[3];
09904       }
09905       break;
09906    case 5:
09907       if (!strcasecmp(argv[4], "like"))
09908          return RESULT_SHOWUSAGE;
09909       if (!strcasecmp(argv[3], "all"))
09910          return RESULT_SHOWUSAGE;
09911       if (!strcasecmp(argv[3], "like")) {
09912          multi = TRUE;
09913          name = argv[4];
09914          pruneuser = prunepeer = TRUE;
09915       } else if (!strcasecmp(argv[3], "user")) {
09916          pruneuser = TRUE;
09917          if (!strcasecmp(argv[4], "all"))
09918             multi = TRUE;
09919          else
09920             name = argv[4];
09921       } else if (!strcasecmp(argv[3], "peer")) {
09922          prunepeer = TRUE;
09923          if (!strcasecmp(argv[4], "all"))
09924             multi = TRUE;
09925          else
09926             name = argv[4];
09927       } else
09928          return RESULT_SHOWUSAGE;
09929       break;
09930    case 6:
09931       if (strcasecmp(argv[4], "like"))
09932          return RESULT_SHOWUSAGE;
09933       if (!strcasecmp(argv[3], "user")) {
09934          pruneuser = TRUE;
09935          name = argv[5];
09936       } else if (!strcasecmp(argv[3], "peer")) {
09937          prunepeer = TRUE;
09938          name = argv[5];
09939       } else
09940          return RESULT_SHOWUSAGE;
09941       break;
09942    default:
09943       return RESULT_SHOWUSAGE;
09944    }
09945 
09946    if (multi && name) {
09947       if (regcomp(&regexbuf, name, REG_EXTENDED | REG_NOSUB))
09948          return RESULT_SHOWUSAGE;
09949    }
09950 
09951    if (multi) {
09952       if (prunepeer) {
09953          int pruned = 0;
09954 
09955          ASTOBJ_CONTAINER_WRLOCK(&peerl);
09956          ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do {
09957             ASTOBJ_RDLOCK(iterator);
09958             if (name && regexec(&regexbuf, iterator->name, 0, NULL, 0)) {
09959                ASTOBJ_UNLOCK(iterator);
09960                continue;
09961             };
09962             if (ast_test_flag(&iterator->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) {
09963                ASTOBJ_MARK(iterator);
09964                pruned++;
09965             }
09966             ASTOBJ_UNLOCK(iterator);
09967          } while (0) );
09968          if (pruned) {
09969             ASTOBJ_CONTAINER_PRUNE_MARKED(&peerl, sip_destroy_peer);
09970             ast_cli(fd, "%d peers pruned.\n", pruned);
09971          } else
09972             ast_cli(fd, "No peers found to prune.\n");
09973          ASTOBJ_CONTAINER_UNLOCK(&peerl);
09974       }
09975       if (pruneuser) {
09976          int pruned = 0;
09977 
09978          ASTOBJ_CONTAINER_WRLOCK(&userl);
09979          ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do {
09980             ASTOBJ_RDLOCK(iterator);
09981             if (name && regexec(&regexbuf, iterator->name, 0, NULL, 0)) {
09982                ASTOBJ_UNLOCK(iterator);
09983                continue;
09984             };
09985             if (ast_test_flag(&iterator->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) {
09986                ASTOBJ_MARK(iterator);
09987                pruned++;
09988             }
09989             ASTOBJ_UNLOCK(iterator);
09990          } while (0) );
09991          if (pruned) {
09992             ASTOBJ_CONTAINER_PRUNE_MARKED(&userl, sip_destroy_user);
09993             ast_cli(fd, "%d users pruned.\n", pruned);
09994          } else
09995             ast_cli(fd, "No users found to prune.\n");
09996          ASTOBJ_CONTAINER_UNLOCK(&userl);
09997       }
09998    } else {
09999       if (prunepeer) {
10000          if ((peer = ASTOBJ_CONTAINER_FIND_UNLINK(&peerl, name))) {
10001             if (!ast_test_flag(&peer->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) {
10002                ast_cli(fd, "Peer '%s' is not a Realtime peer, cannot be pruned.\n", name);
10003                ASTOBJ_CONTAINER_LINK(&peerl, peer);
10004             } else
10005                ast_cli(fd, "Peer '%s' pruned.\n", name);
10006             ASTOBJ_UNREF(peer, sip_destroy_peer);
10007          } else
10008             ast_cli(fd, "Peer '%s' not found.\n", name);
10009       }
10010       if (pruneuser) {
10011          if ((user = ASTOBJ_CONTAINER_FIND_UNLINK(&userl, name))) {
10012             if (!ast_test_flag(&user->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) {
10013                ast_cli(fd, "User '%s' is not a Realtime user, cannot be pruned.\n", name);
10014                ASTOBJ_CONTAINER_LINK(&userl, user);
10015             } else
10016                ast_cli(fd, "User '%s' pruned.\n", name);
10017             ASTOBJ_UNREF(user, sip_destroy_user);
10018          } else
10019             ast_cli(fd, "User '%s' not found.\n", name);
10020       }
10021    }
10022 
10023    return RESULT_SUCCESS;
10024 }

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

Read SIP RTP from channel.

Definition at line 4234 of file chan_sip.c.

References ast_bridged_channel(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_test_flag, FALSE, sip_pvt::flags, sip_pvt::lastrtprx, sip_pvt::lock, LOG_DEBUG, option_debug, sip_pvt::pendinginvite, SIP_GOTREFER, SIP_NEEDREINVITE, SIP_PAGE2_T38SUPPORT_UDPTL, SIP_PENDINGBYE, sip_rtp_read(), t38properties::state, sip_pvt::t38, T38_DISABLED, T38_LOCAL_REINVITE, t38properties::t38support, ast_channel::tech_pvt, and transmit_reinvite_with_t38_sdp().

04235 {
04236    struct ast_frame *fr;
04237    struct sip_pvt *p = ast->tech_pvt;
04238    int faxdetected = FALSE;
04239 
04240    ast_mutex_lock(&p->lock);
04241    fr = sip_rtp_read(ast, p, &faxdetected);
04242    p->lastrtprx = time(NULL);
04243 
04244    /* If we are NOT bridged to another channel, and we have detected fax tone we issue T38 re-invite to a peer */
04245    /* 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 */
04246    if (faxdetected && ast_test_flag(&p->t38.t38support, SIP_PAGE2_T38SUPPORT_UDPTL) && (p->t38.state == T38_DISABLED) && !(ast_bridged_channel(ast))) {
04247       if (!ast_test_flag(&p->flags[0], SIP_GOTREFER)) {
04248          if (!p->pendinginvite) {
04249             if (option_debug > 2)
04250                ast_log(LOG_DEBUG, "Sending reinvite on SIP (%s) for T.38 negotiation.\n",ast->name);
04251             p->t38.state = T38_LOCAL_REINVITE;
04252             transmit_reinvite_with_t38_sdp(p);
04253             if (option_debug > 1)
04254                ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, ast->name);
04255          }
04256       } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) {
04257          if (option_debug > 2)
04258             ast_log(LOG_DEBUG, "Deferring reinvite on SIP (%s) - it will be re-negotiated for T.38\n", ast->name);
04259          ast_set_flag(&p->flags[0], SIP_NEEDREINVITE);
04260       }
04261    }
04262 
04263    ast_mutex_unlock(&p->lock);
04264    return fr;
04265 }

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

The real destination address for a write.

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

01736 {
01737    return ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE ? &p->recv : &p->sa;
01738 }

static int sip_refer_allocate ( struct sip_pvt p  )  [static]

Allocate SIP refer structure.

Definition at line 7532 of file chan_sip.c.

References ast_calloc, and sip_pvt::refer.

Referenced by handle_request_invite(), handle_request_refer(), and transmit_refer().

07533 {
07534    p->refer = ast_calloc(1, sizeof(struct sip_refer)); 
07535    return p->refer ? 1 : 0;
07536 }

static int sip_reg_timeout ( void *  data  )  [static]

Registration timeout, register again.

Definition at line 7289 of file chan_sip.c.

References __sip_pretend_ack(), ast_log(), ast_set_flag, ASTOBJ_REF, ASTOBJ_UNREF, sip_registry::call, EVENT_FLAG_SYSTEM, sip_pvt::flags, LOG_NOTICE, manager_event(), REG_STATE_FAILED, REG_STATE_UNREGISTERED, sip_registry::regattempts, sip_pvt::registry, sip_registry::regstate, regstate2str(), SIP_NEEDDESTROY, SIP_REGISTER, sip_registry_destroy(), sip_registry::timeout, and transmit_register().

Referenced by transmit_register().

07290 {
07291 
07292    /* if we are here, our registration timed out, so we'll just do it over */
07293    struct sip_registry *r = ASTOBJ_REF((struct sip_registry *) data);
07294    struct sip_pvt *p;
07295    int res;
07296 
07297    /* if we couldn't get a reference to the registry object, punt */
07298    if (!r)
07299       return 0;
07300 
07301    ast_log(LOG_NOTICE, "   -- Registration for '%s@%s' timed out, trying again (Attempt #%d)\n", r->username, r->hostname, r->regattempts); 
07302    if (r->call) {
07303       /* Unlink us, destroy old call.  Locking is not relevant here because all this happens
07304          in the single SIP manager thread. */
07305       p = r->call;
07306       if (p->registry)
07307          ASTOBJ_UNREF(p->registry, sip_registry_destroy);
07308       r->call = NULL;
07309       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
07310       /* Pretend to ACK anything just in case */
07311       __sip_pretend_ack(p); /* XXX we need p locked, not sure we have */
07312    }
07313    /* If we have a limit, stop registration and give up */
07314    if (global_regattempts_max && (r->regattempts > global_regattempts_max)) {
07315       /* Ok, enough is enough. Don't try any more */
07316       /* We could add an external notification here... 
07317          steal it from app_voicemail :-) */
07318       ast_log(LOG_NOTICE, "   -- Giving up forever trying to register '%s@%s'\n", r->username, r->hostname);
07319       r->regstate = REG_STATE_FAILED;
07320    } else {
07321       r->regstate = REG_STATE_UNREGISTERED;
07322       r->timeout = -1;
07323       res=transmit_register(r, SIP_REGISTER, NULL, NULL);
07324    }
07325    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));
07326    ASTOBJ_UNREF(r, sip_registry_destroy);
07327    return 0;
07328 }

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

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

Definition at line 4553 of file chan_sip.c.

References ast_calloc, ast_log(), ast_string_field_init, ast_string_field_set, ast_strlen_zero(), ASTOBJ_CONTAINER_LINK, ASTOBJ_INIT, ASTOBJ_UNREF, sip_registry::callid_valid, sip_registry::expire, FALSE, free, hostname, INITIAL_CSEQ, LOG_ERROR, LOG_WARNING, sip_registry::ocseq, sip_registry::portno, sip_registry::refresh, regl, secret, sip_registry_destroy(), sip_registry::timeout, and username.

Referenced by reload_config().

04554 {
04555    struct sip_registry *reg;
04556    int portnum = 0;
04557    char username[256] = "";
04558    char *hostname=NULL, *secret=NULL, *authuser=NULL;
04559    char *porta=NULL;
04560    char *contact=NULL;
04561 
04562    if (!value)
04563       return -1;
04564    ast_copy_string(username, value, sizeof(username));
04565    /* First split around the last '@' then parse the two components. */
04566    hostname = strrchr(username, '@'); /* allow @ in the first part */
04567    if (hostname)
04568       *hostname++ = '\0';
04569    if (ast_strlen_zero(username) || ast_strlen_zero(hostname)) {
04570       ast_log(LOG_WARNING, "Format for registration is user[:secret[:authuser]]@host[:port][/contact] at line %d\n", lineno);
04571       return -1;
04572    }
04573    /* split user[:secret[:authuser]] */
04574    secret = strchr(username, ':');
04575    if (secret) {
04576       *secret++ = '\0';
04577       authuser = strchr(secret, ':');
04578       if (authuser)
04579          *authuser++ = '\0';
04580    }
04581    /* split host[:port][/contact] */
04582    contact = strchr(hostname, '/');
04583    if (contact)
04584       *contact++ = '\0';
04585    if (ast_strlen_zero(contact))
04586       contact = "s";
04587    porta = strchr(hostname, ':');
04588    if (porta) {
04589       *porta++ = '\0';
04590       portnum = atoi(porta);
04591       if (portnum == 0) {
04592          ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno);
04593          return -1;
04594       }
04595    }
04596    if (!(reg = ast_calloc(1, sizeof(*reg)))) {
04597       ast_log(LOG_ERROR, "Out of memory. Can't allocate SIP registry entry\n");
04598       return -1;
04599    }
04600 
04601    if (ast_string_field_init(reg, 256)) {
04602       ast_log(LOG_ERROR, "Out of memory. Can't allocate SIP registry strings\n");
04603       free(reg);
04604       return -1;
04605    }
04606 
04607    regobjs++;
04608    ASTOBJ_INIT(reg);
04609    ast_string_field_set(reg, contact, contact);
04610    if (!ast_strlen_zero(username))
04611       ast_string_field_set(reg, username, username);
04612    if (hostname)
04613       ast_string_field_set(reg, hostname, hostname);
04614    if (authuser)
04615       ast_string_field_set(reg, authuser, authuser);
04616    if (secret)
04617       ast_string_field_set(reg, secret, secret);
04618    reg->expire = -1;
04619    reg->timeout =  -1;
04620    reg->refresh = default_expiry;
04621    reg->portno = portnum;
04622    reg->callid_valid = FALSE;
04623    reg->ocseq = INITIAL_CSEQ;
04624    ASTOBJ_CONTAINER_LINK(&regl, reg);  /* Add the new registry entry to the list */
04625    ASTOBJ_UNREF(reg,sip_registry_destroy);
04626    return 0;
04627 }

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

References ast_log(), ast_sched_del(), ast_string_field_free_pools, sip_registry::call, sip_registry::expire, free, LOG_DEBUG, option_debug, sip_pvt::registry, sip_destroy(), and sip_registry::timeout.

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

02966 {
02967    /* Really delete */
02968    if (option_debug > 2)
02969       ast_log(LOG_DEBUG, "Destroying registry entry for %s@%s\n", reg->username, reg->hostname);
02970 
02971    if (reg->call) {
02972       /* Clear registry before destroying to ensure
02973          we don't get reentered trying to grab the registry lock */
02974       reg->call->registry = NULL;
02975       if (option_debug > 2)
02976          ast_log(LOG_DEBUG, "Destroying active SIP dialog for registry %s@%s\n", reg->username, reg->hostname);
02977       sip_destroy(reg->call);
02978    }
02979    if (reg->expire > -1)
02980       ast_sched_del(sched, reg->expire);
02981    if (reg->timeout > -1)
02982       ast_sched_del(sched, reg->timeout);
02983    ast_string_field_free_pools(reg);
02984    regobjs--;
02985    free(reg);
02986    
02987 }

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

Force reload of module from cli.

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

17502 {
17503    ast_mutex_lock(&sip_reload_lock);
17504    if (sip_reloading) 
17505       ast_verbose("Previous SIP reload not yet done\n");
17506    else {
17507       sip_reloading = TRUE;
17508       if (fd)
17509          sip_reloadreason = CHANNEL_CLI_RELOAD;
17510       else
17511          sip_reloadreason = CHANNEL_MODULE_RELOAD;
17512    }
17513    ast_mutex_unlock(&sip_reload_lock);
17514    restart_monitor();
17515 
17516    return 0;
17517 }

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

PBX interface function -build SIP pvt structure SIP calls initiated by the PBX arrive here.

Note:
This is added to help splitting up chan_sip.c into several files in coming releases

Definition at line 15596 of file chan_sip.c.

References __ourip, ast_calloc, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_SWITCH_CONGESTION, AST_CAUSE_UNREGISTERED, AST_FORMAT_MAX_AUDIO, ast_getformatname(), ast_getformatname_multiple(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_sip_ouraddrfor(), AST_STATE_DOWN, ast_string_field_free, ast_string_field_set, ast_strlen_zero(), ast_update_use_count(), build_callid_pvt(), build_via(), create_addr(), ext, sip_pvt::flags, sip_pvt::lock, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, option_debug, sip_pvt::options, sip_pvt::ourip, sip_pvt::prefcodec, restart_monitor(), sip_pvt::sa, sip_alloc(), sip_destroy(), SIP_INVITE, sip_new(), SIP_PAGE2_OUTGOING_CALL, and username.

15597 {
15598    int oldformat;
15599    struct sip_pvt *p;
15600    struct ast_channel *tmpc = NULL;
15601    char *ext, *host;
15602    char tmp[256];
15603    char *dest = data;
15604 
15605    oldformat = format;
15606    if (!(format &= ((AST_FORMAT_MAX_AUDIO << 1) - 1))) {
15607       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));
15608       *cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;   /* Can't find codec to connect to host */
15609       return NULL;
15610    }
15611    if (option_debug)
15612       ast_log(LOG_DEBUG, "Asked to create a SIP channel with formats: %s\n", ast_getformatname_multiple(tmp, sizeof(tmp), oldformat));
15613 
15614    if (!(p = sip_alloc(NULL, NULL, 0, SIP_INVITE))) {
15615       ast_log(LOG_ERROR, "Unable to build sip pvt data for '%s' (Out of memory or socket error)\n", (char *)data);
15616       *cause = AST_CAUSE_SWITCH_CONGESTION;
15617       return NULL;
15618    }
15619 
15620    ast_set_flag(&p->flags[1], SIP_PAGE2_OUTGOING_CALL);
15621 
15622    if (!(p->options = ast_calloc(1, sizeof(*p->options)))) {
15623       sip_destroy(p);
15624       ast_log(LOG_ERROR, "Unable to build option SIP data structure - Out of memory\n");
15625       *cause = AST_CAUSE_SWITCH_CONGESTION;
15626       return NULL;
15627    }
15628 
15629    ast_copy_string(tmp, dest, sizeof(tmp));
15630    host = strchr(tmp, '@');
15631    if (host) {
15632       *host++ = '\0';
15633       ext = tmp;
15634    } else {
15635       ext = strchr(tmp, '/');
15636       if (ext) 
15637          *ext++ = '\0';
15638       host = tmp;
15639    }
15640 
15641    if (create_addr(p, host)) {
15642       *cause = AST_CAUSE_UNREGISTERED;
15643       if (option_debug > 2)
15644          ast_log(LOG_DEBUG, "Cant create SIP call - target device not registred\n");
15645       sip_destroy(p);
15646       return NULL;
15647    }
15648    if (ast_strlen_zero(p->peername) && ext)
15649       ast_string_field_set(p, peername, ext);
15650    /* Recalculate our side, and recalculate Call ID */
15651    if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
15652       p->ourip = __ourip;
15653    build_via(p);
15654    build_callid_pvt(p);
15655    
15656    /* We have an extension to call, don't use the full contact here */
15657    /* This to enable dialing registered peers with extension dialling,
15658       like SIP/peername/extension   
15659       SIP/peername will still use the full contact */
15660    if (ext) {
15661       ast_string_field_set(p, username, ext);
15662       ast_string_field_free(p, fullcontact);
15663    }
15664 #if 0
15665    printf("Setting up to call extension '%s' at '%s'\n", ext ? ext : "<none>", host);
15666 #endif
15667    p->prefcodec = oldformat;           /* Format for this call */
15668    ast_mutex_lock(&p->lock);
15669    tmpc = sip_new(p, AST_STATE_DOWN, host);  /* Place the call */
15670    ast_mutex_unlock(&p->lock);
15671    if (!tmpc)
15672       sip_destroy(p);
15673    ast_update_use_count();
15674    restart_monitor();
15675    return tmpc;
15676 }

static int sip_reregister ( void *  data  )  [static]

Update registration with SIP Proxy.

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

07258 {
07259    /* if we are here, we know that we need to reregister. */
07260    struct sip_registry *r= ASTOBJ_REF((struct sip_registry *) data);
07261 
07262    /* if we couldn't get a reference to the registry object, punt */
07263    if (!r)
07264       return 0;
07265 
07266    if (r->call && !ast_test_flag(&r->call->flags[0], SIP_NO_HISTORY))
07267       append_history(r->call, "RegistryRenew", "Account: %s@%s", r->username, r->hostname);
07268    /* Since registry's are only added/removed by the the monitor thread, this
07269       may be overkill to reference/dereference at all here */
07270    if (sipdebug)
07271       ast_log(LOG_NOTICE, "   -- Re-registration for  %s@%s\n", r->username, r->hostname);
07272 
07273    r->expire = -1;
07274    __sip_do_register(r);
07275    ASTOBJ_UNREF(r, sip_registry_destroy);
07276    return 0;
07277 }

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

Read RTP from network.

Definition at line 4164 of file chan_sip.c.

References ast_dsp_process(), AST_FORMAT_AUDIO_MASK, AST_FORMAT_VIDEO_MASK, AST_FRAME_DTMF, AST_FRAME_VOICE, ast_getformatname(), ast_log(), ast_null_frame, ast_rtcp_read(), ast_rtp_read(), ast_set_read_format(), ast_set_write_format(), ast_test_flag, ast_udptl_read(), f, ast_channel::fdno, sip_pvt::flags, ast_frame::frametype, sip_pvt::jointcapability, LOG_DEBUG, ast_channel::nativeformats, option_debug, sip_pvt::owner, ast_channel::readformat, sip_pvt::rtp, SIP_DTMF, SIP_DTMF_INBAND, SIP_DTMF_RFC2833, SIP_PAGE2_T38SUPPORT_UDPTL, ast_frame::subclass, sip_pvt::t38, t38properties::t38support, sip_pvt::udptl, sip_pvt::vad, sip_pvt::vrtp, and ast_channel::writeformat.

Referenced by sip_read().

04165 {
04166    /* Retrieve audio/etc from channel.  Assumes p->lock is already held. */
04167    struct ast_frame *f;
04168    
04169    if (!p->rtp) {
04170       /* We have no RTP allocated for this channel */
04171       return &ast_null_frame;
04172    }
04173 
04174    switch(ast->fdno) {
04175    case 0:
04176       f = ast_rtp_read(p->rtp);  /* RTP Audio */
04177       break;
04178    case 1:
04179       f = ast_rtcp_read(p->rtp); /* RTCP Control Channel */
04180       break;
04181    case 2:
04182       f = ast_rtp_read(p->vrtp); /* RTP Video */
04183       break;
04184    case 3:
04185       f = ast_rtcp_read(p->vrtp);   /* RTCP Control Channel for video */
04186       break;
04187    case 5:
04188       f = ast_udptl_read(p->udptl); /* UDPTL for T.38 */
04189       break;
04190    default:
04191       f = &ast_null_frame;
04192    }
04193    /* Don't forward RFC2833 if we're not supposed to */
04194    if (f && (f->frametype == AST_FRAME_DTMF) &&
04195        (ast_test_flag(&p->flags[0], SIP_DTMF) != SIP_DTMF_RFC2833))
04196       return &ast_null_frame;
04197 
04198       /* We already hold the channel lock */
04199    if (!p->owner || (f && f->frametype != AST_FRAME_VOICE))
04200       return f;
04201 
04202    if (f && f->subclass != (p->owner->nativeformats & AST_FORMAT_AUDIO_MASK)) {
04203       if (!(f->subclass & p->jointcapability)) {
04204          if (option_debug) {
04205             ast_log(LOG_DEBUG, "Bogus frame of format '%s' received from '%s'!\n",
04206                ast_getformatname(f->subclass), p->owner->name);
04207          }
04208          return &ast_null_frame;
04209       }
04210       if (option_debug)
04211          ast_log(LOG_DEBUG, "Oooh, format changed to %d\n", f->subclass);
04212       p->owner->nativeformats = (p->owner->nativeformats & AST_FORMAT_VIDEO_MASK) | f->subclass;
04213       ast_set_read_format(p->owner, p->owner->readformat);
04214       ast_set_write_format(p->owner, p->owner->writeformat);
04215    }
04216 
04217    if (f && (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) && p->vad) {
04218       f = ast_dsp_process(p->owner, p->vad, f);
04219       if (f && f->frametype == AST_FRAME_DTMF) {
04220          if (ast_test_flag(&p->t38.t38support, SIP_PAGE2_T38SUPPORT_UDPTL) && f->subclass == 'f') {
04221             if (option_debug)
04222                ast_log(LOG_DEBUG, "Fax CNG detected on %s\n", ast->name);
04223             *faxdetect = 1;
04224          } else if (option_debug) {
04225             ast_log(LOG_DEBUG, "* Detected inband DTMF '%c'\n", f->subclass);
04226          }
04227       }
04228    }
04229    
04230    return f;
04231 }

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

Schedule destruction of SIP dialog.

Definition at line 2076 of file chan_sip.c.

References __sip_autodestruct(), append_history, ast_sched_add(), ast_sched_del(), ast_test_flag, ast_verbose(), sip_pvt::autokillid, sip_pvt::flags, sip_pvt::method, sip_debug_test_pvt(), sip_methods, SIP_NO_HISTORY, cfsip_methods::text, 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().

02077 {
02078    if (ms < 0) {
02079       if (p->timer_t1 == 0)
02080          p->timer_t1 = 500;   /* Set timer T1 if not set (RFC 3261) */
02081       ms = p->timer_t1 * 64;
02082    }
02083    if (sip_debug_test_pvt(p))
02084       ast_verbose("Scheduling destruction of SIP dialog '%s' in %d ms (Method: %s)\n", p->callid, ms, sip_methods[p->method].text);
02085    if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY))
02086       append_history(p, "SchedDestroy", "%d ms", ms);
02087 
02088    if (p->autokillid > -1)
02089       ast_sched_del(sched, p->autokillid);
02090    p->autokillid = ast_sched_add(sched, ms, __sip_autodestruct, p);
02091 }

static void sip_send_all_registers ( void   )  [static]

Send all known registrations.

Definition at line 17428 of file chan_sip.c.

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

Referenced by load_module(), and sip_do_reload().

17429 {
17430    int ms;
17431    int regspacing;
17432    if (!regobjs)
17433       return;
17434    regspacing = default_expiry * 1000/regobjs;
17435    if (regspacing > 100)
17436       regspacing = 100;
17437    ms = regspacing;
17438    ASTOBJ_CONTAINER_TRAVERSE(&regl, 1, do {
17439       ASTOBJ_WRLOCK(iterator);
17440       if (iterator->expire > -1)
17441          ast_sched_del(sched, iterator->expire);
17442       ms += regspacing;
17443       iterator->expire = ast_sched_add(sched, ms, sip_reregister, iterator);
17444       ASTOBJ_UNLOCK(iterator);
17445    } while (0)
17446    );
17447 }

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

References __ourip, sip_peer::addr, ast_app_inboxcount(), ast_set_flag, ast_sip_ouraddrfor(), build_callid_pvt(), build_via(), create_addr_from_peer(), sip_peer::defaddr, DEFAULT_TRANS_TIMEOUT, sip_pvt::flags, sip_peer::lastmsgcheck, sip_peer::lastmsgssent, sip_peer::mailbox, sip_peer::mwipvt, sip_pvt::ourip, sip_pvt::sa, sip_alloc(), sip_destroy(), SIP_NOTIFY, SIP_OUTGOING, sip_scheddestroy(), transmit_notify_with_mwi(), and sip_peer::vmexten.

Referenced by do_monitor(), and handle_request_subscribe().

15154 {
15155    /* Called with peerl lock, but releases it */
15156    struct sip_pvt *p;
15157    int newmsgs, oldmsgs;
15158 
15159    /* Do we have an IP address? If not, skip this peer */
15160    if (!peer->addr.sin_addr.s_addr && !peer->defaddr.sin_addr.s_addr) 
15161       return 0;
15162 
15163    /* Check for messages */
15164    ast_app_inboxcount(peer->mailbox, &newmsgs, &oldmsgs);
15165    
15166    peer->lastmsgcheck = time(NULL);
15167    
15168    /* Return now if it's the same thing we told them last time */
15169    if (((newmsgs > 0x7fff ? 0x7fff0000 : (newmsgs << 16)) | (oldmsgs > 0xffff ? 0xffff : oldmsgs)) == peer->lastmsgssent) {
15170       return 0;
15171    }
15172    
15173    
15174    peer->lastmsgssent = ((newmsgs > 0x7fff ? 0x7fff0000 : (newmsgs << 16)) | (oldmsgs > 0xffff ? 0xffff : oldmsgs));
15175 
15176    if (peer->mwipvt) {
15177       /* Base message on subscription */
15178       p = peer->mwipvt;
15179    } else {
15180       /* Build temporary dialog for this message */
15181       if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY))) 
15182          return -1;
15183       if (create_addr_from_peer(p, peer)) {
15184          /* Maybe they're not registered, etc. */
15185          sip_destroy(p);
15186          return 0;
15187       }
15188       /* Recalculate our side, and recalculate Call ID */
15189       if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
15190          p->ourip = __ourip;
15191       build_via(p);
15192       build_callid_pvt(p);
15193       /* Destroy this session after 32 secs */
15194       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
15195    }
15196    /* Send MWI */
15197    ast_set_flag(&p->flags[0], SIP_OUTGOING);
15198    transmit_notify_with_mwi(p, newmsgs, oldmsgs, peer->vmexten);
15199    return 0;
15200 }

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

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

03711 {
03712    struct sip_pvt *p = ast->tech_pvt;
03713    int res = 0;
03714 
03715    ast_mutex_lock(&p->lock);
03716    switch (ast_test_flag(&p->flags[0], SIP_DTMF)) {
03717    case SIP_DTMF_INBAND:
03718       res = -1; /* Tell Asterisk to generate inband indications */
03719       break;
03720    case SIP_DTMF_RFC2833:
03721       if (p->rtp)
03722          ast_rtp_senddigit_begin(p->rtp, digit);
03723       break;
03724    default:
03725       break;
03726    }
03727    ast_mutex_unlock(&p->lock);
03728 
03729    return res;
03730 }

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

References ast_mutex_lock(), ast_mutex_unlock(), ast_rtp_senddigit_end(), ast_test_flag, sip_pvt::flags, sip_pvt::lock, sip_pvt::rtp, SIP_DTMF, SIP_DTMF_INBAND, SIP_DTMF_INFO, SIP_DTMF_RFC2833, ast_channel::tech_pvt, and transmit_info_with_digit().

03735 {
03736    struct sip_pvt *p = ast->tech_pvt;
03737    int res = 0;
03738 
03739    ast_mutex_lock(&p->lock);
03740    switch (ast_test_flag(&p->flags[0], SIP_DTMF)) {
03741    case SIP_DTMF_INFO:
03742       transmit_info_with_digit(p, digit, duration);
03743       break;
03744    case SIP_DTMF_RFC2833:
03745       if (p->rtp)
03746          ast_rtp_senddigit_end(p->rtp, digit);
03747       break;
03748    case SIP_DTMF_INBAND:
03749       res = -1; /* Tell Asterisk to stop inband indications */
03750       break;
03751    }
03752    ast_mutex_unlock(&p->lock);
03753 
03754    return res;
03755 }

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

02320 {
02321    struct sip_pvt *p = ast->tech_pvt;
02322    int debug = sip_debug_test_pvt(p);
02323 
02324    if (debug)
02325       ast_verbose("Sending text %s on %s\n", text, ast->name);
02326    if (!p)
02327       return -1;
02328    if (ast_strlen_zero(text))
02329       return 0;
02330    if (debug)
02331       ast_verbose("Really sending text %s on %s\n", text, ast->name);
02332    transmit_message_with_text(p, text);
02333    return 0;   
02334 }

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

References ast_channel::_state, append_history, ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_rtp_get_peer(), ast_set_flag, AST_STATE_UP, ast_test_flag, sip_pvt::capability, sip_pvt::flags, sip_pvt::jointcapability, sip_pvt::lastrtprx, sip_pvt::lastrtptx, sip_pvt::lock, LOG_DEBUG, option_debug, sip_pvt::ourip, sip_pvt::pendinginvite, sip_pvt::redircodecs, sip_pvt::redirip, SIP_ALREADYGONE, SIP_CAN_REINVITE_NAT, SIP_GOTREFER, SIP_NEEDREINVITE, SIP_NO_HISTORY, SIP_PENDINGBYE, ast_channel::tech_pvt, transmit_reinvite_with_sdp(), and sip_pvt::vredirip.

17162 {
17163    struct sip_pvt *p;
17164    int changed = 0;
17165 
17166    p = chan->tech_pvt;
17167    if (!p) 
17168       return -1;
17169 
17170    /* Disable early RTP bridge  */
17171    if (chan->_state != AST_STATE_UP && !global_directrtpsetup)    /* We are in early state */
17172       return 0;
17173 
17174    ast_mutex_lock(&p->lock);
17175    if (ast_test_flag(&p->flags[0], SIP_ALREADYGONE)) {
17176       /* If we're destroyed, don't bother */
17177       ast_mutex_unlock(&p->lock);
17178       return 0;
17179    }
17180 
17181    /* if this peer cannot handle reinvites of the media stream to devices
17182       that are known to be behind a NAT, then stop the process now
17183    */
17184    if (nat_active && !ast_test_flag(&p->flags[0], SIP_CAN_REINVITE_NAT)) {
17185       ast_mutex_unlock(&p->lock);
17186       return 0;
17187    }
17188 
17189    if (rtp) {
17190       changed |= ast_rtp_get_peer(rtp, &p->redirip);
17191    } else if (p->redirip.sin_addr.s_addr || ntohs(p->redirip.sin_port) != 0) {
17192       memset(&p->redirip, 0, sizeof(p->redirip));
17193       changed = 1;
17194    }
17195    if (vrtp) {
17196       changed |= ast_rtp_get_peer(vrtp, &p->vredirip);
17197    } else if (p->vredirip.sin_addr.s_addr || ntohs(p->vredirip.sin_port) != 0) {
17198       memset(&p->vredirip, 0, sizeof(p->vredirip));
17199       changed = 1;
17200    }
17201    if (codecs) {
17202       if ((p->redircodecs != codecs)) {
17203          p->redircodecs = codecs;
17204          changed = 1;
17205       }
17206       if ((p->capability & codecs) != p->capability) {
17207          p->jointcapability &= codecs;
17208          p->capability &= codecs;
17209          changed = 1;
17210       }
17211    }
17212    if (changed && !ast_test_flag(&p->flags[0], SIP_GOTREFER)) {
17213       if (chan->_state != AST_STATE_UP) { /* We are in early state */
17214          if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY))
17215             append_history(p, "ExtInv", "Initial invite sent with remote bridge proposal.");
17216          if (option_debug)
17217             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));
17218       } else if (!p->pendinginvite) {     /* We are up, and have no outstanding invite */
17219          if (option_debug > 2) {
17220             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));
17221          }
17222          transmit_reinvite_with_sdp(p);
17223       } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) {
17224          if (option_debug > 2) {
17225             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));
17226          }
17227          /* We have a pending Invite. Send re-invite when we're done with the invite */
17228          ast_set_flag(&p->flags[0], SIP_NEEDREINVITE);   
17229       }
17230    }
17231    /* Reset lastrtprx timer */
17232    p->lastrtprx = p->lastrtptx = time(NULL);
17233    ast_mutex_unlock(&p->lock);
17234    return 0;
17235 }

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

Definition at line 16988 of file chan_sip.c.

References ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_test_flag, ast_udptl_get_peer(), sip_pvt::flags, sip_pvt::lastrtprx, sip_pvt::lastrtptx, sip_pvt::lock, LOG_DEBUG, option_debug, sip_pvt::ourip, sip_pvt::pendinginvite, SIP_GOTREFER, SIP_NEEDREINVITE, SIP_PENDINGBYE, ast_channel::tech_pvt, transmit_reinvite_with_t38_sdp(), and sip_pvt::udptlredirip.

16989 {
16990    struct sip_pvt *p;
16991    
16992    p = chan->tech_pvt;
16993    if (!p)
16994       return -1;
16995    ast_mutex_lock(&p->lock);
16996    if (udptl)
16997       ast_udptl_get_peer(udptl, &p->udptlredirip);
16998    else
16999       memset(&p->udptlredirip, 0, sizeof(p->udptlredirip));
17000    if (!ast_test_flag(&p->flags[0], SIP_GOTREFER)) {
17001       if (!p->pendinginvite) {
17002          if (option_debug > 2) {
17003             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);
17004          }
17005          transmit_reinvite_with_t38_sdp(p);
17006       } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) {
17007          if (option_debug > 2) {
17008             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);
17009          }
17010          ast_set_flag(&p->flags[0], SIP_NEEDREINVITE);
17011       }
17012    }
17013    /* Reset lastrtprx timer */
17014    p->lastrtprx = p->lastrtptx = time(NULL);
17015    ast_mutex_unlock(&p->lock);
17016    return 0;
17017 }

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

Show details of one active dialog.

Definition at line 10748 of file chan_sip.c.

References sip_pvt::allowtransfer, ast_cli(), ast_getformatname_multiple(), ast_inet_ntoa(), ast_mutex_lock(), ast_mutex_unlock(), ast_strlen_zero(), ast_test_flag, sip_pvt::capability, dtmfmode2str(), sip_pvt::flags, sip_route::hop, cfsip_options::id, iflist, sip_pvt::jointcapability, sip_pvt::lastmsg, len, sip_pvt::maxcallbitrate, nat2str(), ast_channel::nativeformats, sip_pvt::next, sip_pvt::noncodeccapability, NONE, sip_pvt::ourip, sip_pvt::owner, sip_pvt::peercapability, sip_pvt::recv, sip_pvt::redirip, RESULT_SHOWUSAGE, RESULT_SUCCESS, sip_pvt::route, sip_pvt::sa, SIP_DTMF, SIP_NAT, SIP_NEEDDESTROY, sip_options, SIP_OUTGOING, SIP_PROMISCREDIR, sip_pvt::sipoptions, sip_pvt::subscribed, subscription_type2str(), sip_pvt::tag, text, and transfermode2str().

10749 {
10750    struct sip_pvt *cur;
10751    size_t len;
10752    int found = 0;
10753 
10754    if (argc != 4)
10755       return RESULT_SHOWUSAGE;
10756    len = strlen(argv[3]);
10757    ast_mutex_lock(&iflock);
10758    for (cur = iflist; cur; cur = cur->next) {
10759       if (!strncasecmp(cur->callid, argv[3], len)) {
10760          char formatbuf[BUFSIZ/2];
10761          ast_cli(fd,"\n");
10762          if (cur->subscribed != NONE)
10763             ast_cli(fd, "  * Subscription (type: %s)\n", subscription_type2str(cur->subscribed));
10764          else
10765             ast_cli(fd, "  * SIP Call\n");
10766          ast_cli(fd, "  Curr. trans. direction:  %s\n", ast_test_flag(&cur->flags[0], SIP_OUTGOING) ? "Outgoing" : "Incoming");
10767          ast_cli(fd, "  Call-ID:                %s\n", cur->callid);
10768          ast_cli(fd, "  Owner channel ID:       %s\n", cur->owner ? cur->owner->name : "<none>");
10769          ast_cli(fd, "  Our Codec Capability:   %d\n", cur->capability);
10770          ast_cli(fd, "  Non-Codec Capability (DTMF):   %d\n", cur->noncodeccapability);
10771          ast_cli(fd, "  Their Codec Capability:   %d\n", cur->peercapability);
10772          ast_cli(fd, "  Joint Codec Capability:   %d\n", cur->jointcapability);
10773          ast_cli(fd, "  Format:                 %s\n", ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->owner ? cur->owner->nativeformats : 0) );
10774          ast_cli(fd, "  MaxCallBR:              %d kbps\n", cur->maxcallbitrate);
10775          ast_cli(fd, "  Theoretical Address:    %s:%d\n", ast_inet_ntoa(cur->sa.sin_addr), ntohs(cur->sa.sin_port));
10776          ast_cli(fd, "  Received Address:       %s:%d\n", ast_inet_ntoa(cur->recv.sin_addr), ntohs(cur->recv.sin_port));
10777          ast_cli(fd, "  SIP Transfer mode:      %s\n", transfermode2str(cur->allowtransfer));
10778          ast_cli(fd, "  NAT Support:            %s\n", nat2str(ast_test_flag(&cur->flags[0], SIP_NAT)));
10779          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)" );
10780          ast_cli(fd, "  Our Tag:                %s\n", cur->tag);
10781          ast_cli(fd, "  Their Tag:              %s\n", cur->theirtag);
10782          ast_cli(fd, "  SIP User agent:         %s\n", cur->useragent);
10783          if (!ast_strlen_zero(cur->username))
10784             ast_cli(fd, "  Username:               %s\n", cur->username);
10785          if (!ast_strlen_zero(cur->peername))
10786             ast_cli(fd, "  Peername:               %s\n", cur->peername);
10787          if (!ast_strlen_zero(cur->uri))
10788             ast_cli(fd, "  Original uri:           %s\n", cur->uri);
10789          if (!ast_strlen_zero(cur->cid_num))
10790             ast_cli(fd, "  Caller-ID:              %s\n", cur->cid_num);
10791          ast_cli(fd, "  Need Destroy:           %d\n", ast_test_flag(&cur->flags[0], SIP_NEEDDESTROY));
10792          ast_cli(fd, "  Last Message:           %s\n", cur->lastmsg);
10793          ast_cli(fd, "  Promiscuous Redir:      %s\n", ast_test_flag(&cur->flags[0], SIP_PROMISCREDIR) ? "Yes" : "No");
10794          ast_cli(fd, "  Route:                  %s\n", cur->route ? cur->route->hop : "N/A");
10795          ast_cli(fd, "  DTMF Mode:              %s\n", dtmfmode2str(ast_test_flag(&cur->flags[0], SIP_DTMF)));
10796          ast_cli(fd, "  SIP Options:            ");
10797          if (cur->sipoptions) {
10798             int x;
10799             for (x=0 ; (x < (sizeof(sip_options) / sizeof(sip_options[0]))); x++) {
10800                if (cur->sipoptions & sip_options[x].id)
10801                   ast_cli(fd, "%s ", sip_options[x].text);
10802             }
10803          } else
10804             ast_cli(fd, "(none)\n");
10805          ast_cli(fd, "\n\n");
10806          found++;
10807       }
10808    }
10809    ast_mutex_unlock(&iflock);
10810    if (!found) 
10811       ast_cli(fd, "No such SIP Call ID starting with '%s'\n", argv[3]);
10812    return RESULT_SUCCESS;
10813 }

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

Show active SIP channels.

Definition at line 10546 of file chan_sip.c.

References __sip_show_channels().

10547 {
10548         return __sip_show_channels(fd, argc, argv, 0);
10549 }

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

CLI command to list local domains.

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

10059 {
10060    struct domain *d;
10061 #define FORMAT "%-40.40s %-20.20s %-16.16s\n"
10062 
10063    if (AST_LIST_EMPTY(&domain_list)) {
10064       ast_cli(fd, "SIP Domain support not enabled.\n\n");
10065       return RESULT_SUCCESS;
10066    } else {
10067       ast_cli(fd, FORMAT, "Our local SIP domains:", "Context", "Set by");
10068       AST_LIST_LOCK(&domain_list);
10069       AST_LIST_TRAVERSE(&domain_list, d, list)
10070          ast_cli(fd, FORMAT, d->domain, S_OR(d->context, "(default)"),
10071             domain_mode_to_text(d->mode));
10072       AST_LIST_UNLOCK(&domain_list);
10073       ast_cli(fd, "\n");
10074       return RESULT_SUCCESS;
10075    }
10076 }

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

Show history details of one dialog.

Definition at line 10816 of file chan_sip.c.

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

10817 {
10818    struct sip_pvt *cur;
10819    size_t len;
10820    int found = 0;
10821 
10822    if (argc != 4)
10823       return RESULT_SHOWUSAGE;
10824    if (!recordhistory)
10825       ast_cli(fd, "\n***Note: History recording is currently DISABLED.  Use 'sip history' to ENABLE.\n");
10826    len = strlen(argv[3]);
10827    ast_mutex_lock(&iflock);
10828    for (cur = iflist; cur; cur = cur->next) {
10829       if (!strncasecmp(cur->callid, argv[3], len)) {
10830          struct sip_history *hist;
10831          int x = 0;
10832 
10833          ast_cli(fd,"\n");
10834          if (cur->subscribed != NONE)
10835             ast_cli(fd, "  * Subscription\n");
10836          else
10837             ast_cli(fd, "  * SIP Call\n");
10838          if (cur->history)
10839             AST_LIST_TRAVERSE(cur->history, hist, list)
10840                ast_cli(fd, "%d. %s\n", ++x, hist->event);
10841          if (x == 0)
10842             ast_cli(fd, "Call '%s' has no history\n", cur->callid);
10843          found++;
10844       }
10845    }
10846    ast_mutex_unlock(&iflock);
10847    if (!found) 
10848       ast_cli(fd, "No such SIP Call ID starting with '%s'\n", argv[3]);
10849    return RESULT_SUCCESS;
10850 }

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

09484 {
09485 #define FORMAT  "%-25.25s %-15.15s %-15.15s \n"
09486 #define FORMAT2 "%-25.25s %-15.15s %-15.15s \n"
09487    char ilimits[40];
09488    char iused[40];
09489    int showall = FALSE;
09490 
09491    if (argc < 3) 
09492       return RESULT_SHOWUSAGE;
09493 
09494    if (argc == 4 && !strcmp(argv[3],"all")) 
09495          showall = TRUE;
09496    
09497    ast_cli(fd, FORMAT, "* User name", "In use", "Limit");
09498    ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do {
09499       ASTOBJ_RDLOCK(iterator);
09500       if (iterator->call_limit)
09501          snprintf(ilimits, sizeof(ilimits), "%d", iterator->call_limit);
09502       else 
09503          ast_copy_string(ilimits, "N/A", sizeof(ilimits));
09504       snprintf(iused, sizeof(iused), "%d", iterator->inUse);
09505       if (showall || iterator->call_limit)
09506          ast_cli(fd, FORMAT2, iterator->name, iused, ilimits);
09507       ASTOBJ_UNLOCK(iterator);
09508    } while (0) );
09509 
09510    ast_cli(fd, FORMAT, "* Peer name", "In use", "Limit");
09511 
09512    ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do {
09513       ASTOBJ_RDLOCK(iterator);
09514       if (iterator->call_limit)
09515          snprintf(ilimits, sizeof(ilimits), "%d", iterator->call_limit);
09516       else 
09517          ast_copy_string(ilimits, "N/A", sizeof(ilimits));
09518       snprintf(iused, sizeof(iused), "%d/%d", iterator->inUse, iterator->inRinging);
09519       if (showall || iterator->call_limit)
09520          ast_cli(fd, FORMAT2, iterator->name, iused, ilimits);
09521       ASTOBJ_UNLOCK(iterator);
09522    } while (0) );
09523 
09524    return RESULT_SUCCESS;
09525 #undef FORMAT
09526 #undef FORMAT2
09527 }

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

List all allocated SIP Objects (realtime or static).

Definition at line 9804 of file chan_sip.c.

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

09805 {
09806    char tmp[256];
09807    if (argc != 3)
09808       return RESULT_SHOWUSAGE;
09809    ast_cli(fd, "-= User objects: %d static, %d realtime =-\n\n", suserobjs, ruserobjs);
09810    ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), &userl);
09811    ast_cli(fd, "-= Peer objects: %d static, %d realtime, %d autocreate =-\n\n", speerobjs, rpeerobjs, apeerobjs);
09812    ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), &peerl);
09813    ast_cli(fd, "-= Registry objects: %d =-\n\n", regobjs);
09814    ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), &regl);
09815    return RESULT_SUCCESS;
09816 }

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

Show one peer in detail.

Definition at line 10110 of file chan_sip.c.

References _sip_show_peer().

10111 {
10112    return _sip_show_peer(0, fd, NULL, NULL, argc, (const char **) argv);
10113 }

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

CLI Show Peers command.

Definition at line 9660 of file chan_sip.c.

References _sip_show_peers().

09661 {
09662    return _sip_show_peers(fd, NULL, NULL, NULL, argc, (const char **) argv);
09663 }

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

Show SIP Registry (registrations with other SIP proxies.

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

10384 {
10385 #define FORMAT2 "%-30.30s  %-12.12s  %8.8s %-20.20s %-25.25s\n"
10386 #define FORMAT  "%-30.30s  %-12.12s  %8d %-20.20s %-25.25s\n"
10387    char host[80];
10388    char tmpdat[256];
10389    struct tm tm;
10390 
10391 
10392    if (argc != 3)
10393       return RESULT_SHOWUSAGE;
10394    ast_cli(fd, FORMAT2, "Host", "Username", "Refresh", "State", "Reg.Time");
10395    ASTOBJ_CONTAINER_TRAVERSE(&regl, 1, do {
10396       ASTOBJ_RDLOCK(iterator);
10397       snprintf(host, sizeof(host), "%s:%d", iterator->hostname, iterator->portno ? iterator->portno : STANDARD_SIP_PORT);
10398       if (iterator->regtime) {
10399          ast_localtime(&iterator->regtime, &tm, NULL);
10400          strftime(tmpdat, sizeof(tmpdat), "%a, %d %b %Y %T", &tm);
10401       } else {
10402          tmpdat[0] = 0;
10403       }
10404       ast_cli(fd, FORMAT, host, iterator->username, iterator->refresh, regstate2str(iterator->regstate), tmpdat);
10405       ASTOBJ_UNLOCK(iterator);
10406    } while(0));
10407    return RESULT_SUCCESS;
10408 #undef FORMAT
10409 #undef FORMAT2
10410 }

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

List global settings for the SIP channel.

Definition at line 10413 of file chan_sip.c.

References ast_check_realtime(), ast_cli(), ast_getformatname_multiple(), ast_inet_ntoa(), AST_LIST_EMPTY, ast_test_flag, ast_tos2str(), authl, bindaddr, default_prefs, dtmfmode2str(), nat2str(), print_codec_to_cli(), RESULT_SHOWUSAGE, RESULT_SUCCESS, S_OR, SIP_DTMF, SIP_NAT, SIP_PAGE2_ALLOWOVERLAP, SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PAGE2_IGNOREREGEXPIRE, SIP_PAGE2_RFC2833_COMPENSATE, SIP_PAGE2_RTCACHEFRIENDS, SIP_PAGE2_RTSAVE_SYSNAME, SIP_PAGE2_RTUPDATE, SIP_PAGE2_T38SUPPORT_RTP, SIP_PAGE2_T38SUPPORT_TCP, SIP_PAGE2_T38SUPPORT_UDPTL, SIP_PAGE2_VIDEOSUPPORT, SIP_PROG_INBAND, SIP_PROG_INBAND_NEVER, SIP_PROG_INBAND_NO, SIP_PROMISCREDIR, SIP_USECLIENTCODE, SIP_USEREQPHONE, and transfermode2str().

10414 {
10415    int realtimepeers;
10416    int realtimeusers;
10417    char codec_buf[BUFSIZ];
10418 
10419    realtimepeers = ast_check_realtime("sippeers");
10420    realtimeusers = ast_check_realtime("sipusers");
10421 
10422    if (argc != 3)
10423       return RESULT_SHOWUSAGE;
10424    ast_cli(fd, "\n\nGlobal Settings:\n");
10425    ast_cli(fd, "----------------\n");
10426    ast_cli(fd, "  SIP Port:               %d\n", ntohs(bindaddr.sin_port));
10427    ast_cli(fd, "  Bindaddress:            %s\n", ast_inet_ntoa(bindaddr.sin_addr));
10428    ast_cli(fd, "  Videosupport:           %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_VIDEOSUPPORT) ? "Yes" : "No");
10429    ast_cli(fd, "  AutoCreatePeer:         %s\n", autocreatepeer ? "Yes" : "No");
10430    ast_cli(fd, "  Allow unknown access:   %s\n", global_allowguest ? "Yes" : "No");
10431    ast_cli(fd, "  Allow subscriptions:    %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWSUBSCRIBE) ? "Yes" : "No");
10432    ast_cli(fd, "  Allow overlap dialing:  %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP) ? "Yes" : "No");
10433    ast_cli(fd, "  Promsic. redir:         %s\n", ast_test_flag(&global_flags[0], SIP_PROMISCREDIR) ? "Yes" : "No");
10434    ast_cli(fd, "  SIP domain support:     %s\n", AST_LIST_EMPTY(&domain_list) ? "No" : "Yes");
10435    ast_cli(fd, "  Call to non-local dom.: %s\n", allow_external_domains ? "Yes" : "No");
10436    ast_cli(fd, "  URI user is phone no:   %s\n", ast_test_flag(&global_flags[0], SIP_USEREQPHONE) ? "Yes" : "No");
10437    ast_cli(fd, "  Our auth realm          %s\n", global_realm);
10438    ast_cli(fd, "  Realm. auth:            %s\n", authl ? "Yes": "No");
10439    ast_cli(fd, "  Always auth rejects:    %s\n", global_alwaysauthreject ? "Yes" : "No");
10440    ast_cli(fd, "  Call limit peers only:  %s\n", global_limitonpeers ? "Yes" : "No");
10441    ast_cli(fd, "  Direct RTP setup:       %s\n", global_directrtpsetup ? "Yes" : "No");
10442    ast_cli(fd, "  User Agent:             %s\n", global_useragent);
10443    ast_cli(fd, "  MWI checking interval:  %d secs\n", global_mwitime);
10444    ast_cli(fd, "  Reg. context:           %s\n", S_OR(global_regcontext, "(not set)"));
10445    ast_cli(fd, "  Caller ID:              %s\n", default_callerid);
10446    ast_cli(fd, "  From: Domain:           %s\n", default_fromdomain);
10447    ast_cli(fd, "  Record SIP history:     %s\n", recordhistory ? "On" : "Off");
10448    ast_cli(fd, "  Call Events:            %s\n", global_callevents ? "On" : "Off");
10449    ast_cli(fd, "  IP ToS SIP:             %s\n", ast_tos2str(global_tos_sip));
10450    ast_cli(fd, "  IP ToS RTP audio:       %s\n", ast_tos2str(global_tos_audio));
10451    ast_cli(fd, "  IP ToS RTP video:       %s\n", ast_tos2str(global_tos_video));
10452    ast_cli(fd, "  T38 fax pt UDPTL:       %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT_UDPTL) ? "Yes" : "No");
10453 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS
10454    ast_cli(fd, "  T38 fax pt RTP:         %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT_RTP) ? "Yes" : "No");
10455    ast_cli(fd, "  T38 fax pt TCP:         %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT_TCP) ? "Yes" : "No");
10456 #endif
10457    ast_cli(fd, "  RFC2833 Compensation:   %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RFC2833_COMPENSATE) ? "Yes" : "No");
10458    if (!realtimepeers && !realtimeusers)
10459       ast_cli(fd, "  SIP realtime:           Disabled\n" );
10460    else
10461       ast_cli(fd, "  SIP realtime:           Enabled\n" );
10462 
10463    ast_cli(fd, "\nGlobal Signalling Settings:\n");
10464    ast_cli(fd, "---------------------------\n");
10465    ast_cli(fd, "  Codecs:                 ");
10466    ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, global_capability);
10467    ast_cli(fd, "%s\n", codec_buf);
10468    ast_cli(fd, "  Codec Order:            ");
10469    print_codec_to_cli(fd, &default_prefs);
10470    ast_cli(fd, "\n");
10471    ast_cli(fd, "  T1 minimum:             %d\n", global_t1min);
10472    ast_cli(fd, "  Relax DTMF:             %s\n", global_relaxdtmf ? "Yes" : "No");
10473    ast_cli(fd, "  Compact SIP headers:    %s\n", compactheaders ? "Yes" : "No");
10474    ast_cli(fd, "  RTP Keepalive:          %d %s\n", global_rtpkeepalive, global_rtpkeepalive ? "" : "(Disabled)" );
10475    ast_cli(fd, "  RTP Timeout:            %d %s\n", global_rtptimeout, global_rtptimeout ? "" : "(Disabled)" );
10476    ast_cli(fd, "  RTP Hold Timeout:       %d %s\n", global_rtpholdtimeout, global_rtpholdtimeout ? "" : "(Disabled)");
10477    ast_cli(fd, "  MWI NOTIFY mime type:   %s\n", default_notifymime);
10478    ast_cli(fd, "  DNS SRV lookup:         %s\n", srvlookup ? "Yes" : "No");
10479    ast_cli(fd, "  Pedantic SIP support:   %s\n", pedanticsipchecking ? "Yes" : "No");
10480    ast_cli(fd, "  Reg. min duration       %d secs\n", min_expiry);
10481    ast_cli(fd, "  Reg. max duration:      %d secs\n", max_expiry);
10482    ast_cli(fd, "  Reg. default duration:  %d secs\n", default_expiry);
10483    ast_cli(fd, "  Outbound reg. timeout:  %d secs\n", global_reg_timeout);
10484    ast_cli(fd, "  Outbound reg. attempts: %d\n", global_regattempts_max);
10485    ast_cli(fd, "  Notify ringing state:   %s\n", global_notifyringing ? "Yes" : "No");
10486    ast_cli(fd, "  Notify hold state:      %s\n", global_notifyhold ? "Yes" : "No");
10487    ast_cli(fd, "  SIP Transfer mode:      %s\n", transfermode2str(global_allowtransfer));
10488    ast_cli(fd, "  Max Call Bitrate:       %d kbps\r\n", default_maxcallbitrate);
10489    ast_cli(fd, "  Auto-Framing:           %s \r\n", global_autoframing ? "Yes" : "No");
10490    ast_cli(fd, "\nDefault Settings:\n");
10491    ast_cli(fd, "-----------------\n");
10492    ast_cli(fd, "  Context:                %s\n", default_context);
10493    ast_cli(fd, "  Nat:                    %s\n", nat2str(ast_test_flag(&global_flags[0], SIP_NAT)));
10494    ast_cli(fd, "  DTMF:                   %s\n", dtmfmode2str(ast_test_flag(&global_flags[0], SIP_DTMF)));
10495    ast_cli(fd, "  Qualify:                %d\n", default_qualify);
10496    ast_cli(fd, "  Use ClientCode:         %s\n", ast_test_flag(&global_flags[0], SIP_USECLIENTCODE) ? "Yes" : "No");
10497    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" );
10498    ast_cli(fd, "  Language:               %s\n", S_OR(default_language, "(Defaults to English)"));
10499    ast_cli(fd, "  MOH Interpret:          %s\n", default_mohinterpret);
10500    ast_cli(fd, "  MOH Suggest:            %s\n", default_mohsuggest);
10501    ast_cli(fd, "  Voice Mail Extension:   %s\n", default_vmexten);
10502 
10503    
10504    if (realtimepeers || realtimeusers) {
10505       ast_cli(fd, "\nRealtime SIP Settings:\n");
10506       ast_cli(fd, "----------------------\n");
10507       ast_cli(fd, "  Realtime Peers:         %s\n", realtimepeers ? "Yes" : "No");
10508       ast_cli(fd, "  Realtime Users:         %s\n", realtimeusers ? "Yes" : "No");
10509       ast_cli(fd, "  Cache Friends:          %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS) ? "Yes" : "No");
10510       ast_cli(fd, "  Update:                 %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RTUPDATE) ? "Yes" : "No");
10511       ast_cli(fd, "  Ignore Reg. Expire:     %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_IGNOREREGEXPIRE) ? "Yes" : "No");
10512       ast_cli(fd, "  Save sys. name:         %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RTSAVE_SYSNAME) ? "Yes" : "No");
10513       ast_cli(fd, "  Auto Clear:             %d\n", global_rtautoclear);
10514    }
10515    ast_cli(fd, "\n----\n");
10516    return RESULT_SUCCESS;
10517 }

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

Show active SIP subscriptions.

Definition at line 10552 of file chan_sip.c.

References __sip_show_channels().

10553 {
10554         return __sip_show_channels(fd, argc, argv, 1);
10555 }

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

Show one user in detail.

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

10329 {
10330    char cbuf[256];
10331    struct sip_user *user;
10332    struct ast_variable *v;
10333    int load_realtime;
10334 
10335    if (argc < 4)
10336       return RESULT_SHOWUSAGE;
10337 
10338    /* Load from realtime storage? */
10339    load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? TRUE : FALSE;
10340 
10341    user = find_user(argv[3], load_realtime);
10342    if (user) {
10343       ast_cli(fd,"\n\n");
10344       ast_cli(fd, "  * Name       : %s\n", user->name);
10345       ast_cli(fd, "  Secret       : %s\n", ast_strlen_zero(user->secret)?"<Not set>":"<Set>");
10346       ast_cli(fd, "  MD5Secret    : %s\n", ast_strlen_zero(user->md5secret)?"<Not set>":"<Set>");
10347       ast_cli(fd, "  Context      : %s\n", user->context);
10348       ast_cli(fd, "  Language     : %s\n", user->language);
10349       if (!ast_strlen_zero(user->accountcode))
10350          ast_cli(fd, "  Accountcode  : %s\n", user->accountcode);
10351       ast_cli(fd, "  AMA flags    : %s\n", ast_cdr_flags2str(user->amaflags));
10352       ast_cli(fd, "  Transfer mode: %s\n", transfermode2str(user->allowtransfer));
10353       ast_cli(fd, "  MaxCallBR    : %d kbps\n", user->maxcallbitrate);
10354       ast_cli(fd, "  CallingPres  : %s\n", ast_describe_caller_presentation(user->callingpres));
10355       ast_cli(fd, "  Call limit   : %d\n", user->call_limit);
10356       ast_cli(fd, "  Callgroup    : ");
10357       print_group(fd, user->callgroup, 0);
10358       ast_cli(fd, "  Pickupgroup  : ");
10359       print_group(fd, user->pickupgroup, 0);
10360       ast_cli(fd, "  Callerid     : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), user->cid_name, user->cid_num, "<unspecified>"));
10361       ast_cli(fd, "  ACL          : %s\n", (user->ha?"Yes":"No"));
10362       ast_cli(fd, "  Codec Order  : (");
10363       print_codec_to_cli(fd, &user->prefs);
10364       ast_cli(fd, ")\n");
10365 
10366       ast_cli(fd, "  Auto-Framing:  %s \n", user->autoframing ? "Yes" : "No");
10367       if (user->chanvars) {
10368          ast_cli(fd, "  Variables    :\n");
10369          for (v = user->chanvars ; v ; v = v->next)
10370             ast_cli(fd, "                 %s = %s\n", v->name, v->value);
10371       }
10372       ast_cli(fd,"\n");
10373       ASTOBJ_UNREF(user,sip_destroy_user);
10374    } else {
10375       ast_cli(fd,"User %s not found.\n", argv[3]);
10376       ast_cli(fd,"\n");
10377    }
10378 
10379    return RESULT_SUCCESS;
10380 }

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

CLI Command 'SIP Show Users'.

Definition at line 9583 of file chan_sip.c.

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

09584 {
09585    regex_t regexbuf;
09586    int havepattern = FALSE;
09587 
09588 #define FORMAT  "%-25.25s  %-15.15s  %-15.15s  %-15.15s  %-5.5s%-10.10s\n"
09589 
09590    switch (argc) {
09591    case 5:
09592       if (!strcasecmp(argv[3], "like")) {
09593          if (regcomp(&regexbuf, argv[4], REG_EXTENDED | REG_NOSUB))
09594             return RESULT_SHOWUSAGE;
09595          havepattern = TRUE;
09596       } else
09597          return RESULT_SHOWUSAGE;
09598    case 3:
09599       break;
09600    default:
09601       return RESULT_SHOWUSAGE;
09602    }
09603 
09604    ast_cli(fd, FORMAT, "Username", "Secret", "Accountcode", "Def.Context", "ACL", "NAT");
09605    ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do {
09606       ASTOBJ_RDLOCK(iterator);
09607 
09608       if (havepattern && regexec(&regexbuf, iterator->name, 0, NULL, 0)) {
09609          ASTOBJ_UNLOCK(iterator);
09610          continue;
09611       }
09612 
09613       ast_cli(fd, FORMAT, iterator->name, 
09614          iterator->secret, 
09615          iterator->accountcode,
09616          iterator->context,
09617          iterator->ha ? "Yes" : "No",
09618          nat2str(ast_test_flag(&iterator->flags[0], SIP_NAT)));
09619       ASTOBJ_UNLOCK(iterator);
09620    } while (0)
09621    );
09622 
09623    if (havepattern)
09624       regfree(&regexbuf);
09625 
09626    return RESULT_SUCCESS;
09627 #undef FORMAT
09628 }

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 17348 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(), strcasestr(), strsep(), and transmit_response_reliable().

Referenced by sip_transfer().

17349 {
17350    char *cdest;
17351    char *extension, *host, *port;
17352    char tmp[80];
17353    
17354    cdest = ast_strdupa(dest);
17355    
17356    extension = strsep(&cdest, "@");
17357    host = strsep(&cdest, ":");
17358    port = strsep(&cdest, ":");
17359    if (ast_strlen_zero(extension)) {
17360       ast_log(LOG_ERROR, "Missing mandatory argument: extension\n");
17361       return 0;
17362    }
17363 
17364    /* we'll issue the redirect message here */
17365    if (!host) {
17366       char *localtmp;
17367       ast_copy_string(tmp, get_header(&p->initreq, "To"), sizeof(tmp));
17368       if (ast_strlen_zero(tmp)) {
17369          ast_log(LOG_ERROR, "Cannot retrieve the 'To' header from the original SIP request!\n");
17370          return 0;
17371       }
17372       if ((localtmp = strcasestr(tmp, "sip:")) && (localtmp = strchr(localtmp, '@'))) {
17373          char lhost[80], lport[80];
17374          memset(lhost, 0, sizeof(lhost));
17375          memset(lport, 0, sizeof(lport));
17376          localtmp++;
17377          /* This is okey because lhost and lport are as big as tmp */
17378          sscanf(localtmp, "%[^<>:; ]:%[^<>:; ]", lhost, lport);
17379          if (ast_strlen_zero(lhost)) {
17380             ast_log(LOG_ERROR, "Can't find the host address\n");
17381             return 0;
17382          }
17383          host = ast_strdupa(lhost);
17384          if (!ast_strlen_zero(lport)) {
17385             port = ast_strdupa(lport);
17386          }
17387       }
17388    }
17389 
17390    ast_string_field_build(p, our_contact, "Transfer <sip:%s@%s%s%s>", extension, host, port ? ":" : "", port ? port : "");
17391    transmit_response_reliable(p, "302 Moved Temporarily", &p->initreq);
17392 
17393    sip_scheddestroy(p, 32000);   /* Make sure we stop send this reply. */
17394    sip_alreadygone(p);
17395    return 0;
17396 }

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

Transfer SIP call.

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

03759 {
03760    struct sip_pvt *p = ast->tech_pvt;
03761    int res;
03762 
03763    if (dest == NULL) /* functions below do not take a NULL */
03764       dest = "";
03765    ast_mutex_lock(&p->lock);
03766    if (ast->_state == AST_STATE_RING)
03767       res = sip_sipredirect(p, dest);
03768    else
03769       res = transmit_refer(p, dest);
03770    ast_mutex_unlock(&p->lock);
03771    return res;
03772 }

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

Send frame to media channel (rtp).

Definition at line 3593 of file chan_sip.c.

References ast_channel::_state, AST_FORMAT_AUDIO_MASK, AST_FRAME_IMAGE, AST_FRAME_MODEM, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_getformatname_multiple(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_rtp_write(), ast_set_flag, AST_STATE_UP, ast_test_flag, ast_udptl_write(), sip_pvt::flags, ast_frame::frametype, sip_pvt::initreq, sip_pvt::lastrtptx, sip_pvt::lock, LOG_WARNING, ast_channel::nativeformats, ast_channel::readformat, sip_pvt::rtp, SIP_OUTGOING, SIP_PROGRESS_SENT, ast_frame::subclass, ast_channel::tech_pvt, transmit_response_with_sdp(), sip_pvt::udptl, sip_pvt::vrtp, ast_channel::writeformat, and XMIT_UNRELIABLE.

03594 {
03595    struct sip_pvt *p = ast->tech_pvt;
03596    int res = 0;
03597 
03598    switch (frame->frametype) {
03599    case AST_FRAME_VOICE:
03600       if (!(frame->subclass & ast->nativeformats)) {
03601          char s1[512], s2[512], s3[512];
03602          ast_log(LOG_WARNING, "Asked to transmit frame type %d, while native formats is %s(%d) read/write = %s(%d)/%s(%d)\n",
03603             frame->subclass, 
03604             ast_getformatname_multiple(s1, sizeof(s1) - 1, ast->nativeformats & AST_FORMAT_AUDIO_MASK),
03605             ast->nativeformats & AST_FORMAT_AUDIO_MASK,
03606             ast_getformatname_multiple(s2, sizeof(s2) - 1, ast->readformat),
03607             ast->readformat,
03608             ast_getformatname_multiple(s3, sizeof(s3) - 1, ast->writeformat),
03609             ast->writeformat);
03610          return 0;
03611       }
03612       if (p) {
03613          ast_mutex_lock(&p->lock);
03614          if (p->rtp) {
03615             /* If channel is not up, activate early media session */
03616             if ((ast->_state != AST_STATE_UP) &&
03617                 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) &&
03618                 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
03619                transmit_response_with_sdp(p, "183 Session Progress", &p->initreq, XMIT_UNRELIABLE);
03620                ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT);  
03621             }
03622             p->lastrtptx = time(NULL);
03623             res = ast_rtp_write(p->rtp, frame);
03624          }
03625          ast_mutex_unlock(&p->lock);
03626       }
03627       break;
03628    case AST_FRAME_VIDEO:
03629       if (p) {
03630          ast_mutex_lock(&p->lock);
03631          if (p->vrtp) {
03632             /* Activate video early media */
03633             if ((ast->_state != AST_STATE_UP) &&
03634                 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) &&
03635                 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
03636                transmit_response_with_sdp(p, "183 Session Progress", &p->initreq, XMIT_UNRELIABLE);
03637                ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT);  
03638             }
03639             p->lastrtptx = time(NULL);
03640             res = ast_rtp_write(p->vrtp, frame);
03641          }
03642          ast_mutex_unlock(&p->lock);
03643       }
03644       break;
03645    case AST_FRAME_IMAGE:
03646       return 0;
03647       break;
03648    case AST_FRAME_MODEM:
03649       if (p) {
03650          ast_mutex_lock(&p->lock);
03651          /* UDPTL requires two-way communication, so early media is not needed here.
03652             we simply forget the frames if we get modem frames before the bridge is up.
03653             Fax will re-transmit.
03654          */
03655          if (p->udptl && ast->_state == AST_STATE_UP) 
03656             res = ast_udptl_write(p->udptl, frame);
03657          ast_mutex_unlock(&p->lock);
03658       }
03659       break;
03660    default: 
03661       ast_log(LOG_WARNING, "Can't send %d type frames with SIP write\n", frame->frametype);
03662       return 0;
03663    }
03664 
03665    return res;
03666 }

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

References append_history, ast_channel_trylock, ast_channel_unlock, ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_test_flag, ast_update_use_count(), ast_verbose(), sip_request::data, find_call(), find_sip_method(), sip_pvt::flags, get_header(), handle_request(), sip_request::headers, sip_request::len, len, sip_request::lines, sip_pvt::lock, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, LOG_WARNING, lws2sws(), sip_request::method, option_debug, sip_pvt::owner, parse_request(), sip_pvt::recv, sip_request::rlPart1, sip_request::rlPart2, S_OR, SIP_ACK, sip_debug_test_addr(), SIP_NO_HISTORY, SIP_PKT_DEBUG, sipsock, and transmit_response().

Referenced by do_monitor().

15053 {
15054    struct sip_request req;
15055    struct sockaddr_in sin = { 0, };
15056    struct sip_pvt *p;
15057    int res;
15058    socklen_t len = sizeof(sin);
15059    int nounlock;
15060    int recount = 0;
15061    int lockretry;
15062 
15063    memset(&req, 0, sizeof(req));
15064    res = recvfrom(sipsock, req.data, sizeof(req.data) - 1, 0, (struct sockaddr *)&sin, &len);
15065    if (res < 0) {
15066 #if !defined(__FreeBSD__)
15067       if (errno == EAGAIN)
15068          ast_log(LOG_NOTICE, "SIP: Received packet with bad UDP checksum\n");
15069       else 
15070 #endif
15071       if (errno != ECONNREFUSED)
15072          ast_log(LOG_WARNING, "Recv error: %s\n", strerror(errno));
15073       return 1;
15074    }
15075    if (option_debug && res == sizeof(req.data)) {
15076       ast_log(LOG_DEBUG, "Received packet exceeds buffer. Data is possibly lost\n");
15077       req.data[sizeof(req.data) - 1] = '\0';
15078    } else
15079       req.data[res] = '\0';
15080    req.len = res;
15081    if(sip_debug_test_addr(&sin)) /* Set the debug flag early on packet level */
15082       ast_set_flag(&req, SIP_PKT_DEBUG);
15083    if (pedanticsipchecking)
15084       req.len = lws2sws(req.data, req.len);  /* Fix multiline headers */
15085    if (ast_test_flag(&req, SIP_PKT_DEBUG))
15086       ast_verbose("\n<--- SIP read from %s:%d --->\n%s\n<------------->\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port), req.data);
15087 
15088    parse_request(&req);
15089    req.method = find_sip_method(req.rlPart1);
15090 
15091    if (ast_test_flag(&req, SIP_PKT_DEBUG))
15092       ast_verbose("--- (%d headers %d lines)%s ---\n", req.headers, req.lines, (req.headers + req.lines == 0) ? " Nat keepalive" : "");
15093 
15094    if (req.headers < 2) /* Must have at least two headers */
15095       return 1;
15096 
15097    /* Process request, with netlock held, and with usual deadlock avoidance */
15098    for (lockretry = 100; lockretry > 0; lockretry--) {
15099       ast_mutex_lock(&netlock);
15100 
15101       /* Find the active SIP dialog or create a new one */
15102       p = find_call(&req, &sin, req.method); /* returns p locked */
15103       if (p == NULL) {
15104          if (option_debug)
15105             ast_log(LOG_DEBUG, "Invalid SIP message - rejected , no callid, len %d\n", req.len);
15106          ast_mutex_unlock(&netlock);
15107          return 1;
15108       }
15109       /* Go ahead and lock the owner if it has one -- we may need it */
15110       /* becaues this is deadlock-prone, we need to try and unlock if failed */
15111       if (!p->owner || !ast_channel_trylock(p->owner))
15112          break;   /* locking succeeded */
15113       if (option_debug)
15114          ast_log(LOG_DEBUG, "Failed to grab owner channel lock, trying again. (SIP call %s)\n", p->callid);
15115       ast_mutex_unlock(&p->lock);
15116       ast_mutex_unlock(&netlock);
15117       /* Sleep for a very short amount of time */
15118       usleep(1);
15119    }
15120    p->recv = sin;
15121 
15122    if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) /* This is a request or response, note what it was for */
15123       append_history(p, "Rx", "%s / %s / %s", req.data, get_header(&req, "CSeq"), req.rlPart2);
15124 
15125    if (!lockretry) {
15126       if (p->owner)
15127          ast_log(LOG_ERROR, "We could NOT get the channel lock for %s! \n", S_OR(p->owner->name, "- no channel name ??? - "));
15128       ast_log(LOG_ERROR, "SIP transaction failed: %s \n", p->callid);
15129       if (req.method != SIP_ACK)
15130          transmit_response(p, "503 Server error", &req); /* We must respond according to RFC 3261 sec 12.2 */
15131       /* XXX We could add retry-after to make sure they come back */
15132       append_history(p, "LockFail", "Owner lock failed, transaction failed.");
15133       return 1;
15134    }
15135    nounlock = 0;
15136    if (handle_request(p, &req, &sin, &recount, &nounlock) == -1) {
15137       /* Request failed */
15138       if (option_debug)
15139          ast_log(LOG_DEBUG, "SIP message could not be handled, bad request: %-70.70s\n", p->callid[0] ? p->callid : "<no callid>");
15140    }
15141       
15142    if (p->owner && !nounlock)
15143       ast_channel_unlock(p->owner);
15144    ast_mutex_unlock(&p->lock);
15145    ast_mutex_unlock(&netlock);
15146    if (recount)
15147       ast_update_use_count();
15148 
15149    return 1;
15150 }

static void stop_media_flows ( struct sip_pvt p  )  [static]

Immediately stop RTP, VRTP and UDPTL as applicable.

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

12328 {
12329    /* Immediately stop RTP, VRTP and UDPTL as applicable */
12330    if (p->rtp)
12331       ast_rtp_stop(p->rtp);
12332    if (p->vrtp)
12333       ast_rtp_stop(p->vrtp);
12334    if (p->udptl)
12335       ast_udptl_stop(p->udptl);
12336 }

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

Show subscription type in string format.

Definition at line 10520 of file chan_sip.c.

References subscription_types, cfsubscription_types::text, and type.

Referenced by __sip_show_channels(), and sip_show_channel().

10521 {
10522    int i;
10523 
10524    for (i = 1; (i < (sizeof(subscription_types) / sizeof(subscription_types[0]))); i++) {
10525       if (subscription_types[i].type == subtype) {
10526          return subscription_types[i].text;
10527       }
10528    }
10529    return subscription_types[0].text;
10530 }

static int t38_get_rate ( int  t38cap  )  [static]

Get Max T.38 Transmission rate from T38 capabilities.

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

06091 {
06092    int maxrate = (t38cap & (T38FAX_RATE_14400 | T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400));
06093    
06094    if (maxrate & T38FAX_RATE_14400) {
06095       if (option_debug > 1)
06096          ast_log(LOG_DEBUG, "T38MaxFaxRate 14400 found\n");
06097       return 14400;
06098    } else if (maxrate & T38FAX_RATE_12000) {
06099       if (option_debug > 1)
06100          ast_log(LOG_DEBUG, "T38MaxFaxRate 12000 found\n");
06101       return 12000;
06102    } else if (maxrate & T38FAX_RATE_9600) {
06103       if (option_debug > 1)
06104          ast_log(LOG_DEBUG, "T38MaxFaxRate 9600 found\n");
06105       return 9600;
06106    } else if (maxrate & T38FAX_RATE_7200) {
06107       if (option_debug > 1)
06108          ast_log(LOG_DEBUG, "T38MaxFaxRate 7200 found\n");
06109       return 7200;
06110    } else if (maxrate & T38FAX_RATE_4800) {
06111       if (option_debug > 1)
06112          ast_log(LOG_DEBUG, "T38MaxFaxRate 4800 found\n");
06113       return 4800;
06114    } else if (maxrate & T38FAX_RATE_2400) {
06115       if (option_debug > 1)
06116          ast_log(LOG_DEBUG, "T38MaxFaxRate 2400 found\n");
06117       return 2400;
06118    } else {
06119       if (option_debug > 1)
06120          ast_log(LOG_DEBUG, "Strange, T38MaxFaxRate NOT found in peers T38 SDP.\n");
06121       return 0;
06122    }
06123 }

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

Create temporary peer (used in autocreatepeer mode).

Definition at line 16144 of file chan_sip.c.

References ast_calloc, ast_set_flag, ASTOBJ_INIT, default_prefs, sip_peer::flags, sip_peer::prefs, reg_source_db(), set_peer_defaults(), SIP_PAGE2_DYNAMIC, and SIP_PAGE2_SELFDESTRUCT.

Referenced by register_verify().

16145 {
16146    struct sip_peer *peer;
16147 
16148    if (!(peer = ast_calloc(1, sizeof(*peer))))
16149       return NULL;
16150 
16151    apeerobjs++;
16152    ASTOBJ_INIT(peer);
16153    set_peer_defaults(peer);
16154 
16155    ast_copy_string(peer->name, name, sizeof(peer->name));
16156 
16157    ast_set_flag(&peer->flags[1], SIP_PAGE2_SELFDESTRUCT);
16158    ast_set_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC);
16159    peer->prefs = default_prefs;
16160    reg_source_db(peer);
16161 
16162    return peer;
16163 }

static void temp_pvt_cleanup ( void *  data  )  [static]

Definition at line 5866 of file chan_sip.c.

References ast_string_field_free_pools, and free.

05867 {
05868    struct sip_pvt *p = data;
05869 
05870    ast_string_field_free_pools(p);
05871 
05872    free(data);
05873 }

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

Convert transfer mode to text string.

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

09531 {
09532    if (mode == TRANSFER_OPENFORALL)
09533       return "open";
09534    else if (mode == TRANSFER_CLOSED)
09535       return "closed";
09536    return "strict";
09537 }

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

08376 {
08377    ast_string_field_build(p, randdata, "%08lx", ast_random()); /* Create nonce for challenge */
08378    transmit_response_with_auth(p, "401 Unauthorized", req, p->randdata, reliable, "WWW-Authenticate", 0);
08379 }

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

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

Referenced by sip_senddigit_end().

07615 {
07616    struct sip_request req;
07617 
07618    reqprep(&req, p, SIP_INFO, 0, 1);
07619    add_digit(&req, digit, duration);
07620    return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
07621 }

static int transmit_info_with_vidupdate ( struct sip_pvt p  )  [static]

Send SIP INFO with video update request.

Definition at line 7624 of file chan_sip.c.

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

Referenced by sip_indicate().

07625 {
07626    struct sip_request req;
07627 
07628    reqprep(&req, p, SIP_INFO, 0, 1);
07629    add_vidupdate(&req);
07630    return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
07631 }

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 6892 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_LIST_TRAVERSE, ast_log(), ast_random(), ast_strdupa, ast_strlen_zero(), ast_udptl_offered_from_local(), ast_var_name(), ast_var_value(), sip_invite_param::auth, sip_invite_param::authheader, sip_pvt::branch, build_via(), sip_request::headers, initialize_initreq(), sip_pvt::initreq, initreqprep(), sip_pvt::lastinvite, LOG_DEBUG, LOG_WARNING, sip_request::method, sip_pvt::ocseq, option_debug, sip_pvt::options, sip_pvt::owner, sip_pvt::refer, sip_refer::refer_to, sip_refer::referred_by, sip_refer::referred_by_name, sip_invite_param::replaces, reqprep(), sip_pvt::rtp, send_request(), SIP_REFER, sipdebug, t38properties::state, SUPPORTED_EXTENSIONS, sip_pvt::t38, T38_LOCAL_DIRECT, sip_pvt::udptl, ast_channel::varshead, XMIT_CRITICAL, and XMIT_RELIABLE.

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

06893 {
06894    struct sip_request req;
06895    
06896    req.method = sipmethod;
06897    if (init) {    /* Seems like init always is 2 */
06898       /* Bump branch even on initial requests */
06899       p->branch ^= ast_random();
06900       build_via(p);
06901       if (init > 1)
06902          initreqprep(&req, p, sipmethod);
06903       else
06904          reqprep(&req, p, sipmethod, 0, 1);
06905    } else
06906       reqprep(&req, p, sipmethod, 0, 1);
06907       
06908    if (p->options && p->options->auth)
06909       add_header(&req, p->options->authheader, p->options->auth);
06910    append_date(&req);
06911    if (sipmethod == SIP_REFER) { /* Call transfer */
06912       if (p->refer) {
06913          char buf[BUFSIZ];
06914          if (!ast_strlen_zero(p->refer->refer_to))
06915             add_header(&req, "Refer-To", p->refer->refer_to);
06916          if (!ast_strlen_zero(p->refer->referred_by)) {
06917             sprintf(buf, "%s <%s>", p->refer->referred_by_name, p->refer->referred_by);
06918             add_header(&req, "Referred-By", buf);
06919          }
06920       }
06921    }
06922    /* This new INVITE is part of an attended transfer. Make sure that the
06923    other end knows and replace the current call with this new call */
06924    if (p->options && p->options->replaces && !ast_strlen_zero(p->options->replaces)) {
06925       add_header(&req, "Replaces", p->options->replaces);
06926       add_header(&req, "Require", "replaces");
06927    }
06928 
06929    add_header(&req, "Allow", ALLOWED_METHODS);
06930    add_header(&req, "Supported", SUPPORTED_EXTENSIONS);
06931    if (p->options && p->options->addsipheaders && p->owner) {
06932       struct ast_channel *ast = p->owner; /* The owner channel */
06933       struct varshead *headp = &ast->varshead;
06934 
06935          if (!headp)
06936             ast_log(LOG_WARNING,"No Headp for the channel...ooops!\n");
06937          else {
06938             const struct ast_var_t *current;
06939             AST_LIST_TRAVERSE(headp, current, entries) {  
06940                /* SIPADDHEADER: Add SIP header to outgoing call */
06941                if (!strncasecmp(ast_var_name(current), "SIPADDHEADER", strlen("SIPADDHEADER"))) {
06942                   char *content, *end;
06943                   const char *header = ast_var_value(current);
06944                   char *headdup = ast_strdupa(header);
06945 
06946                   /* Strip of the starting " (if it's there) */
06947                   if (*headdup == '"')
06948                      headdup++;
06949                   if ((content = strchr(headdup, ':'))) {
06950                      *content++ = '\0';
06951                      content = ast_skip_blanks(content); /* Skip white space */
06952                      /* Strip the ending " (if it's there) */
06953                      end = content + strlen(content) -1; 
06954                      if (*end == '"')
06955                         *end = '\0';
06956                   
06957                      add_header(&req, headdup, content);
06958                      if (sipdebug)
06959                         ast_log(LOG_DEBUG, "Adding SIP Header \"%s\" with content :%s: \n", headdup, content);
06960                   }
06961                }
06962             }
06963          }
06964    }
06965    if (sdp) {
06966       if (p->udptl && p->t38.state == T38_LOCAL_DIRECT) {
06967          ast_udptl_offered_from_local(p->udptl, 1);
06968          if (option_debug)
06969             ast_log(LOG_DEBUG, "T38 is in state %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>");
06970          add_t38_sdp(&req, p);
06971       } else if (p->rtp) 
06972          add_sdp(&req, p);
06973    } else {
06974       add_header_contentLength(&req, 0);
06975    }
06976 
06977    if (!p->initreq.headers)
06978       initialize_initreq(p, &req);
06979    p->lastinvite = p->ocseq;
06980    return send_request(p, &req, init ? XMIT_CRITICAL : XMIT_RELIABLE, p->ocseq);
06981 }

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

Transmit text with SIP MESSAGE method.

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

07523 {
07524    struct sip_request req;
07525 
07526    reqprep(&req, p, SIP_MESSAGE, 0, 1);
07527    add_text(&req, text);
07528    return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
07529 }

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

References add_header(), add_header_contentLength(), add_line(), ast_build_string(), ast_inet_ntoa(), ast_log(), ast_test_flag, sip_pvt::expiry, sip_pvt::flags, sip_request::headers, initialize_initreq(), sip_pvt::initreq, initreqprep(), LOG_WARNING, sip_pvt::ocseq, sip_pvt::ourip, S_OR, send_request(), SIP_NOTIFY, SIP_PAGE2_BUGGY_MWI, sip_pvt::subscribed, t, and XMIT_RELIABLE.

Referenced by sip_send_mwi_to_peer().

07163 {
07164    struct sip_request req;
07165    char tmp[500];
07166    char *t = tmp;
07167    size_t maxbytes = sizeof(tmp);
07168 
07169    initreqprep(&req, p, SIP_NOTIFY);
07170    add_header(&req, "Event", "message-summary");
07171    add_header(&req, "Content-Type", default_notifymime);
07172 
07173    ast_build_string(&t, &maxbytes, "Messages-Waiting: %s\r\n", newmsgs ? "yes" : "no");
07174    ast_build_string(&t, &maxbytes, "Message-Account: sip:%s@%s\r\n",
07175       S_OR(vmexten, default_vmexten), S_OR(p->fromdomain, ast_inet_ntoa(p->ourip)));
07176    /* Cisco has a bug in the SIP stack where it can't accept the
07177       (0/0) notification. This can temporarily be disabled in
07178       sip.conf with the "buggymwi" option */
07179    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)"));
07180 
07181    if (p->subscribed) {
07182       if (p->expiry)
07183          add_header(&req, "Subscription-State", "active");
07184       else  /* Expired */
07185          add_header(&req, "Subscription-State", "terminated;reason=timeout");
07186    }
07187 
07188    if (t > tmp + sizeof(tmp))
07189       ast_log(LOG_WARNING, "Buffer overflow detected!!  (Please file a bug report)\n");
07190 
07191    add_header_contentLength(&req, strlen(tmp));
07192    add_line(&req, tmp);
07193 
07194    if (!p->initreq.headers) 
07195       initialize_initreq(p, &req);
07196    return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
07197 }

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 7208 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::ocseq, reqprep(), send_request(), SIP_NOTIFY, SUPPORTED_EXTENSIONS, and XMIT_RELIABLE.

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

07209 {
07210    struct sip_request req;
07211    char tmp[BUFSIZ/2];
07212 
07213    reqprep(&req, p, SIP_NOTIFY, 0, 1);
07214    snprintf(tmp, sizeof(tmp), "refer;id=%d", cseq);
07215    add_header(&req, "Event", tmp);
07216    add_header(&req, "Subscription-state", terminate ? "terminated;reason=noresource" : "active");
07217    add_header(&req, "Content-Type", "message/sipfrag;version=2.0");
07218    add_header(&req, "Allow", ALLOWED_METHODS);
07219    add_header(&req, "Supported", SUPPORTED_EXTENSIONS);
07220 
07221    snprintf(tmp, sizeof(tmp), "SIP/2.0 %s\r\n", message);
07222    add_header_contentLength(&req, strlen(tmp));
07223    add_line(&req, tmp);
07224 
07225    if (!p->initreq.headers)
07226       initialize_initreq(p, &req);
07227 
07228    return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
07229 }

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

References add_header(), ALLOWED_METHODS, ast_log(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, DEFAULT_MAX_FORWARDS, sip_pvt::flags, get_header(), get_in_brackets(), sip_request::headers, sip_pvt::initreq, LOG_DEBUG, LOG_NOTICE, sip_pvt::ocseq, option_debug, sip_pvt::refer, REFER_SENT, sip_refer::refer_to, sip_refer::referred_by, reqprep(), send_request(), SIP_OUTGOING, SIP_REFER, sip_refer_allocate(), sipdebug, sip_refer::status, SUPPORTED_EXTENSIONS, sip_pvt::tag, and XMIT_RELIABLE.

Referenced by sip_transfer().

07544 {
07545    struct sip_request req = { 
07546       .headers = 0,  
07547    };
07548    char from[256];
07549    const char *of;
07550    char *c;
07551    char referto[256];
07552    char *ttag, *ftag;
07553    char *theirtag = ast_strdupa(p->theirtag);
07554 
07555    if (option_debug || sipdebug)
07556       ast_log(LOG_DEBUG, "SIP transfer of %s to %s\n", p->callid, dest);
07557 
07558    /* Are we transfering an inbound or outbound call ? */
07559    if (ast_test_flag(&p->flags[0], SIP_OUTGOING))  {
07560       of = get_header(&p->initreq, "To");
07561       ttag = theirtag;
07562       ftag = p->tag;
07563    } else {
07564       of = get_header(&p->initreq, "From");
07565       ftag = theirtag;
07566       ttag = p->tag;
07567    }
07568 
07569    ast_copy_string(from, of, sizeof(from));
07570    of = get_in_brackets(from);
07571    ast_string_field_set(p, from, of);
07572    if (strncasecmp(of, "sip:", 4))
07573       ast_log(LOG_NOTICE, "From address missing 'sip:', using it anyway\n");
07574    else
07575       of += 4;
07576    /* Get just the username part */
07577    if ((c = strchr(dest, '@')))
07578       c = NULL;
07579    else if ((c = strchr(of, '@')))
07580       *c++ = '\0';
07581    if (c) 
07582       snprintf(referto, sizeof(referto), "<sip:%s@%s>", dest, c);
07583    else
07584       snprintf(referto, sizeof(referto), "<sip:%s>", dest);
07585 
07586    /* save in case we get 407 challenge */
07587    sip_refer_allocate(p);
07588    ast_copy_string(p->refer->refer_to, referto, sizeof(p->refer->refer_to));
07589    ast_copy_string(p->refer->referred_by, p->our_contact, sizeof(p->refer->referred_by));
07590    p->refer->status = REFER_SENT;   /* Set refer status */
07591 
07592    reqprep(&req, p, SIP_REFER, 0, 1);
07593    add_header(&req, "Max-Forwards", DEFAULT_MAX_FORWARDS);
07594 
07595    add_header(&req, "Refer-To", referto);
07596    add_header(&req, "Allow", ALLOWED_METHODS);
07597    add_header(&req, "Supported", SUPPORTED_EXTENSIONS);
07598    if (!ast_strlen_zero(p->our_contact))
07599       add_header(&req, "Referred-By", p->our_contact);
07600 
07601    return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
07602    /* We should propably wait for a NOTIFY here until we ack the transfer */
07603    /* Maybe fork a new thread and wait for a STATUS of REFER_200OK on the refer status before returning to app_transfer */
07604 
07605    /*! \todo In theory, we should hang around and wait for a reply, before
07606    returning to the dial plan here. Don't know really how that would
07607    affect the transfer() app or the pbx, but, well, to make this
07608    useful we should have a STATUS code on transfer().
07609    */
07610 }

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

References __ourip, add_header(), add_header_contentLength(), append_history, ast_log(), ast_random(), ast_sched_add(), ast_sched_del(), ast_set_flag, ast_sip_ouraddrfor(), ast_string_field_free, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_verbose(), ASTOBJ_REF, bindaddr, sip_pvt::branch, build_callid_registry(), build_contact(), build_reply_digest(), build_via(), sip_registry::call, sip_registry::callid_valid, create_addr(), DEFAULT_MAX_FORWARDS, exten, sip_pvt::flags, sip_request::headers, init_req(), initialize_initreq(), sip_pvt::initreq, sip_request::lines, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, make_our_tag(), sip_pvt::noncecount, sip_registry::noncecount, sip_pvt::ocseq, sip_registry::ocseq, option_debug, sip_pvt::ourip, sip_registry::portno, REG_STATE_AUTHSENT, REG_STATE_REGSENT, sip_registry::regattempts, sip_pvt::registry, sip_registry::regstate, sip_pvt::sa, send_request(), sip_alloc(), sip_debug_test_pvt(), sip_destroy(), sip_methods, SIP_NO_HISTORY, SIP_OUTGOING, sip_reg_timeout(), SIP_REGISTER, sipdebug, STANDARD_SIP_PORT, sip_pvt::tag, cfsip_methods::text, sip_registry::timeout, TRUE, username, and XMIT_CRITICAL.

Referenced by __sip_do_register(), do_register_auth(), and sip_reg_timeout().

07332 {
07333    struct sip_request req;
07334    char from[256];
07335    char to[256];
07336    char tmp[80];
07337    char addr[80];
07338    struct sip_pvt *p;
07339 
07340    /* exit if we are already in process with this registrar ?*/
07341    if ( r == NULL || ((auth==NULL) && (r->regstate==REG_STATE_REGSENT || r->regstate==REG_STATE_AUTHSENT))) {
07342       ast_log(LOG_NOTICE, "Strange, trying to register %s@%s when registration already pending\n", r->username, r->hostname);
07343       return 0;
07344    }
07345 
07346    if (r->call) { /* We have a registration */
07347       if (!auth) {
07348          ast_log(LOG_WARNING, "Already have a REGISTER going on to %s@%s?? \n", r->username, r->hostname);
07349          return 0;
07350       } else {
07351          p = r->call;
07352          make_our_tag(p->tag, sizeof(p->tag));  /* create a new local tag for every register attempt */
07353          ast_string_field_free(p, theirtag); /* forget their old tag, so we don't match tags when getting response */
07354       }
07355    } else {
07356       /* Build callid for registration if we haven't registered before */
07357       if (!r->callid_valid) {
07358          build_callid_registry(r, __ourip, default_fromdomain);
07359          r->callid_valid = TRUE;
07360       }
07361       /* Allocate SIP packet for registration */
07362       if (!(p = sip_alloc( r->callid, NULL, 0, SIP_REGISTER))) {
07363          ast_log(LOG_WARNING, "Unable to allocate registration transaction (memory or socket error)\n");
07364          return 0;
07365       }
07366       if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY))
07367          append_history(p, "RegistryInit", "Account: %s@%s", r->username, r->hostname);
07368       /* Find address to hostname */
07369       if (create_addr(p, r->hostname)) {
07370          /* we have what we hope is a temporary network error,
07371           * probably DNS.  We need to reschedule a registration try */
07372          sip_destroy(p);
07373          if (r->timeout > -1) {
07374             ast_sched_del(sched, r->timeout);
07375             r->timeout = ast_sched_add(sched, global_reg_timeout*1000, sip_reg_timeout, r);
07376             ast_log(LOG_WARNING, "Still have a registration timeout for %s@%s (create_addr() error), %d\n", r->username, r->hostname, r->timeout);
07377          } else {
07378             r->timeout = ast_sched_add(sched, global_reg_timeout*1000, sip_reg_timeout, r);
07379             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);
07380          }
07381          r->regattempts++;
07382          return 0;
07383       }
07384       /* Copy back Call-ID in case create_addr changed it */
07385       ast_string_field_set(r, callid, p->callid);
07386       if (r->portno)
07387          p->sa.sin_port = htons(r->portno);
07388       else  /* Set registry port to the port set from the peer definition/srv or default */
07389          r->portno = ntohs(p->sa.sin_port);
07390       ast_set_flag(&p->flags[0], SIP_OUTGOING); /* Registration is outgoing call */
07391       r->call=p;        /* Save pointer to SIP packet */
07392       p->registry = ASTOBJ_REF(r);  /* Add pointer to registry in packet */
07393       if (!ast_strlen_zero(r->secret)) /* Secret (password) */
07394          ast_string_field_set(p, peersecret, r->secret);
07395       if (!ast_strlen_zero(r->md5secret))
07396          ast_string_field_set(p, peermd5secret, r->md5secret);
07397       /* User name in this realm  
07398       - if authuser is set, use that, otherwise use username */
07399       if (!ast_strlen_zero(r->authuser)) {   
07400          ast_string_field_set(p, peername, r->authuser);
07401          ast_string_field_set(p, authname, r->authuser);
07402       } else if (!ast_strlen_zero(r->username)) {
07403          ast_string_field_set(p, peername, r->username);
07404          ast_string_field_set(p, authname, r->username);
07405          ast_string_field_set(p, fromuser, r->username);
07406       }
07407       if (!ast_strlen_zero(r->username))
07408          ast_string_field_set(p, username, r->username);
07409       /* Save extension in packet */
07410       ast_string_field_set(p, exten, r->contact);
07411 
07412       /*
07413         check which address we should use in our contact header 
07414         based on whether the remote host is on the external or
07415         internal network so we can register through nat
07416        */
07417       if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
07418          p->ourip = bindaddr.sin_addr;
07419       build_contact(p);
07420    }
07421 
07422    /* set up a timeout */
07423    if (auth == NULL)  {
07424       if (r->timeout > -1) {
07425          ast_log(LOG_WARNING, "Still have a registration timeout, #%d - deleting it\n", r->timeout);
07426          ast_sched_del(sched, r->timeout);
07427       }
07428       r->timeout = ast_sched_add(sched, global_reg_timeout * 1000, sip_reg_timeout, r);
07429       if (option_debug)
07430          ast_log(LOG_DEBUG, "Scheduled a registration timeout for %s id  #%d \n", r->hostname, r->timeout);
07431    }
07432 
07433    if (strchr(r->username, '@')) {
07434       snprintf(from, sizeof(from), "<sip:%s>;tag=%s", r->username, p->tag);
07435       if (!ast_strlen_zero(p->theirtag))
07436          snprintf(to, sizeof(to), "<sip:%s>;tag=%s", r->username, p->theirtag);
07437       else
07438          snprintf(to, sizeof(to), "<sip:%s>", r->username);
07439    } else {
07440       snprintf(from, sizeof(from), "<sip:%s@%s>;tag=%s", r->username, p->tohost, p->tag);
07441       if (!ast_strlen_zero(p->theirtag))
07442          snprintf(to, sizeof(to), "<sip:%s@%s>;tag=%s", r->username, p->tohost, p->theirtag);
07443       else
07444          snprintf(to, sizeof(to), "<sip:%s@%s>", r->username, p->tohost);
07445    }
07446    
07447    /* Fromdomain is what we are registering to, regardless of actual
07448       host name from SRV */
07449    if (!ast_strlen_zero(p->fromdomain)) {
07450       if (r->portno && r->portno != STANDARD_SIP_PORT)
07451          snprintf(addr, sizeof(addr), "sip:%s:%d", p->fromdomain, r->portno);
07452       else
07453          snprintf(addr, sizeof(addr), "sip:%s", p->fromdomain);
07454    } else {
07455       if (r->portno && r->portno != STANDARD_SIP_PORT)
07456          snprintf(addr, sizeof(addr), "sip:%s:%d", r->hostname, r->portno);
07457       else
07458          snprintf(addr, sizeof(addr), "sip:%s", r->hostname);
07459    }
07460    ast_string_field_set(p, uri, addr);
07461 
07462    p->branch ^= ast_random();
07463 
07464    init_req(&req, sipmethod, addr);
07465 
07466    /* Add to CSEQ */
07467    snprintf(tmp, sizeof(tmp), "%u %s", ++r->ocseq, sip_methods[sipmethod].text);
07468    p->ocseq = r->ocseq;
07469 
07470    build_via(p);
07471    add_header(&req, "Via", p->via);
07472    add_header(&req, "From", from);
07473    add_header(&req, "To", to);
07474    add_header(&req, "Call-ID", p->callid);
07475    add_header(&req, "CSeq", tmp);
07476    if (!ast_strlen_zero(global_useragent))
07477       add_header(&req, "User-Agent", global_useragent);
07478    add_header(&req, "Max-Forwards", DEFAULT_MAX_FORWARDS);
07479 
07480    
07481    if (auth)   /* Add auth header */
07482       add_header(&req, authheader, auth);
07483    else if (!ast_strlen_zero(r->nonce)) {
07484       char digest[1024];
07485 
07486       /* We have auth data to reuse, build a digest header! */
07487       if (sipdebug)
07488          ast_log(LOG_DEBUG, "   >>> Re-using Auth data for %s@%s\n", r->username, r->hostname);
07489       ast_string_field_set(p, realm, r->realm);
07490       ast_string_field_set(p, nonce, r->nonce);
07491       ast_string_field_set(p, domain, r->domain);
07492       ast_string_field_set(p, opaque, r->opaque);
07493       ast_string_field_set(p, qop, r->qop);
07494       r->noncecount++;
07495       p->noncecount = r->noncecount;
07496 
07497       memset(digest,0,sizeof(digest));
07498       if(!build_reply_digest(p, sipmethod, digest, sizeof(digest)))
07499          add_header(&req, "Authorization", digest);
07500       else
07501          ast_log(LOG_NOTICE, "No authorization available for authentication of registration to %s@%s\n", r->username, r->hostname);
07502    
07503    }
07504 
07505    snprintf(tmp, sizeof(tmp), "%d", default_expiry);
07506    add_header(&req, "Expires", tmp);
07507    add_header(&req, "Contact", p->our_contact);
07508    add_header(&req, "Event", "registration");
07509    add_header_contentLength(&req, 0);
07510 
07511    initialize_initreq(p, &req);
07512    if (sip_debug_test_pvt(p))
07513       ast_verbose("REGISTER %d headers, %d lines\n", p->initreq.headers, p->initreq.lines);
07514    r->regstate = auth ? REG_STATE_AUTHSENT : REG_STATE_REGSENT;
07515    r->regattempts++; /* Another attempt */
07516    if (option_debug > 3)
07517       ast_verbose("REGISTER attempt %d to %s@%s\n", r->regattempts, r->username, r->hostname);
07518    return send_request(p, &req, XMIT_CRITICAL, p->ocseq);
07519 }

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

References add_header(), add_sdp(), ALLOWED_METHODS, append_history, ast_set_flag, ast_test_flag, sip_pvt::flags, initialize_initreq(), sip_pvt::lastinvite, sip_pvt::ocseq, reqprep(), send_request(), SIP_INVITE, SIP_NO_HISTORY, SIP_OUTGOING, SIP_REINVITE_UPDATE, SIP_UPDATE, sipdebug, SUPPORTED_EXTENSIONS, and XMIT_CRITICAL.

Referenced by check_pendings(), and sip_set_rtp_peer().

06613 {
06614    struct sip_request req;
06615 
06616    reqprep(&req, p, ast_test_flag(&p->flags[0], SIP_REINVITE_UPDATE) ?  SIP_UPDATE : SIP_INVITE, 0, 1);
06617    
06618    add_header(&req, "Allow", ALLOWED_METHODS);
06619    add_header(&req, "Supported", SUPPORTED_EXTENSIONS);
06620    if (sipdebug)
06621       add_header(&req, "X-asterisk-Info", "SIP re-invite (External RTP bridge)");
06622    if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY))
06623       append_history(p, "ReInv", "Re-invite sent");
06624    add_sdp(&req, p);
06625    /* Use this as the basis */
06626    initialize_initreq(p, &req);
06627    p->lastinvite = p->ocseq;
06628    ast_set_flag(&p->flags[0], SIP_OUTGOING);    /* Change direction of this dialog */
06629    return send_request(p, &req, XMIT_CRITICAL, p->ocseq);
06630 }

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

06637 {
06638    struct sip_request req;
06639 
06640    reqprep(&req, p, ast_test_flag(&p->flags[0], SIP_REINVITE_UPDATE) ?  SIP_UPDATE : SIP_INVITE, 0, 1);
06641    
06642    add_header(&req, "Allow", ALLOWED_METHODS);
06643    add_header(&req, "Supported", SUPPORTED_EXTENSIONS);
06644    if (sipdebug)
06645       add_header(&req, "X-asterisk-info", "SIP re-invite (T38 switchover)");
06646    ast_udptl_offered_from_local(p->udptl, 1);
06647    add_t38_sdp(&req, p);
06648    /* Use this as the basis */
06649    initialize_initreq(p, &req);
06650    ast_set_flag(&p->flags[0], SIP_OUTGOING);    /* Change direction of this dialog */
06651    p->lastinvite = p->ocseq;
06652    return send_request(p, &req, XMIT_CRITICAL, p->ocseq);
06653 }

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

07637 {
07638    struct sip_request resp;
07639 
07640    if (sipmethod == SIP_ACK)
07641       p->invitestate = INV_CONFIRMED;
07642 
07643    reqprep(&resp, p, sipmethod, seqno, newbranch);
07644    add_header_contentLength(&resp, 0);
07645    return send_request(p, &resp, reliable, seqno ? seqno : p->ocseq);
07646 }

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

References add_header(), add_header_contentLength(), ast_cause2str(), ast_log(), ast_strlen_zero(), sip_invite_param::auth_type, build_reply_digest(), ast_channel::hangupcause, LOG_WARNING, sip_pvt::ocseq, sip_pvt::options, sip_pvt::owner, PROXY_AUTH, reqprep(), send_request(), SIP_BYE, and WWW_AUTH.

Referenced by __sip_autodestruct(), check_pendings(), and sip_hangup().

07650 {
07651    struct sip_request resp;
07652 
07653    reqprep(&resp, p, sipmethod, seqno, newbranch);
07654    if (!ast_strlen_zero(p->realm)) {
07655       char digest[1024];
07656 
07657       memset(digest, 0, sizeof(digest));
07658       if(!build_reply_digest(p, sipmethod, digest, sizeof(digest))) {
07659          if (p->options && p->options->auth_type == PROXY_AUTH)
07660             add_header(&resp, "Proxy-Authorization", digest);
07661          else if (p->options && p->options->auth_type == WWW_AUTH)
07662             add_header(&resp, "Authorization", digest);
07663          else  /* Default, to be backwards compatible (maybe being too careful, but leaving it for now) */
07664             add_header(&resp, "Proxy-Authorization", digest);
07665       } else
07666          ast_log(LOG_WARNING, "No authentication available for call %s\n", p->callid);
07667    }
07668    /* If we are hanging up and know a cause for that, send it in clear text to make
07669       debugging easier. */
07670    if (sipmethod == SIP_BYE && p->owner && p->owner->hangupcause) {
07671       char buf[10];
07672 
07673       add_header(&resp, "X-Asterisk-HangupCause", ast_cause2str(p->owner->hangupcause));
07674       snprintf(buf, sizeof(buf), "%d", p->owner->hangupcause);
07675       add_header(&resp, "X-Asterisk-HangupCauseCode", buf);
07676    }
07677 
07678    add_header_contentLength(&resp, 0);
07679    return send_request(p, &resp, reliable, seqno ? seqno : p->ocseq);   
07680 }

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

Transmit response, no retransmits.

Definition at line 5926 of file chan_sip.c.

References __transmit_response(), and XMIT_UNRELIABLE.

05927 {
05928    return __transmit_response(p, msg, req, XMIT_UNRELIABLE);
05929 }

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

References __transmit_response(), and XMIT_CRITICAL.

Referenced by handle_invite_replaces(), handle_request(), handle_request_bye(), handle_request_cancel(), handle_request_invite(), handle_request_subscribe(), sip_hangup(), and sip_sipredirect().

05946 {
05947    return __transmit_response(p, msg, req, XMIT_CRITICAL);
05948 }

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 5876 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_free_all, ast_string_field_init, ast_string_field_set, ast_test_flag, sip_pvt::branch, build_via(), do_setnat(), sip_pvt::flags, INITIAL_CSEQ, LOG_NOTICE, make_our_tag(), sip_pvt::method, sip_pvt::ocseq, sip_pvt::ourip, sip_pvt::recv, sip_pvt::sa, SIP_NAT, SIP_NAT_ROUTE, SIP_NO_HISTORY, sip_pvt::tag, and XMIT_UNRELIABLE.

Referenced by find_call().

05877 {
05878    struct sip_pvt *p = NULL;
05879 
05880    if (!(p = ast_threadstorage_get(&ts_temp_pvt, sizeof(*p)))) {
05881       ast_log(LOG_NOTICE, "Failed to get temporary pvt\n");
05882       return -1;
05883    }
05884 
05885    /* if the structure was just allocated, initialize it */
05886    if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) {
05887       ast_set_flag(&p->flags[0], SIP_NO_HISTORY);
05888       if (ast_string_field_init(p, 512))
05889          return -1;
05890    }
05891 
05892    /* Initialize the bare minimum */
05893    p->method = intended_method;
05894 
05895    if (sin) {
05896       p->sa = *sin;
05897       if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
05898          p->ourip = __ourip;
05899    } else
05900       p->ourip = __ourip;
05901 
05902    p->branch = ast_random();
05903    make_our_tag(p->tag, sizeof(p->tag));
05904    p->ocseq = INITIAL_CSEQ;
05905 
05906    if (useglobal_nat && sin) {
05907       ast_copy_flags(&p->flags[0], &global_flags[0], SIP_NAT);
05908       p->recv = *sin;
05909       do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE);
05910    }
05911 
05912    ast_string_field_set(p, fromdomain, default_fromdomain);
05913    build_via(p);
05914    ast_string_field_set(p, callid, callid);
05915 
05916    /* Use this temporary pvt structure to send the message */
05917    __transmit_response(p, msg, req, XMIT_UNRELIABLE);
05918 
05919    /* Free the string fields, but not the pool space */
05920    ast_string_field_free_all(p);
05921 
05922    return 0;
05923 }

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

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

Referenced by handle_request(), and handle_request_options().

05974 {
05975    struct sip_request resp;
05976    respprep(&resp, p, msg, req);
05977    add_header(&resp, "Accept", "application/sdp");
05978    add_header_contentLength(&resp, 0);
05979    return send_response(p, &resp, reliable, 0);
05980 }

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

References add_header(), add_header_contentLength(), append_history, ast_log(), get_header(), LOG_WARNING, sip_pvt::noncecount, respprep(), and send_response().

Referenced by check_auth(), and transmit_fake_auth_response().

05984 {
05985    struct sip_request resp;
05986    char tmp[512];
05987    int seqno = 0;
05988 
05989    if (reliable && (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1)) {
05990       ast_log(LOG_WARNING, "Unable to determine sequence number from '%s'\n", get_header(req, "CSeq"));
05991       return -1;
05992    }
05993    /* Stale means that they sent us correct authentication, but 
05994       based it on an old challenge (nonce) */
05995    snprintf(tmp, sizeof(tmp), "Digest algorithm=MD5, realm=\"%s\", nonce=\"%s\"%s", global_realm, randdata, stale ? ", stale=true" : "");
05996    respprep(&resp, p, msg, req);
05997    add_header(&resp, header, tmp);
05998    add_header_contentLength(&resp, 0);
05999    append_history(p, "AuthChal", "Auth challenge sent for %s - nc %d", p->username, p->noncecount);
06000    return send_response(p, &resp, reliable, seqno);
06001 }

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

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

Referenced by register_verify().

05964 {
05965    struct sip_request resp;
05966    respprep(&resp, p, msg, req);
05967    append_date(&resp);
05968    add_header_contentLength(&resp, 0);
05969    return send_response(p, &resp, XMIT_UNRELIABLE, 0);
05970 }

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

References add_sdp(), ast_log(), ast_rtp_codec_setpref(), ast_test_flag, sip_pvt::autoframing, sip_pvt::flags, get_header(), LOG_DEBUG, LOG_ERROR, LOG_WARNING, option_debug, sip_pvt::pendinginvite, sip_pvt::prefs, respprep(), sip_pvt::rtp, send_response(), SIP_OUTGOING, and try_suggested_sip_codec().

Referenced by handle_invite_replaces(), handle_request_invite(), sip_answer(), sip_indicate(), and sip_write().

06542 {
06543    struct sip_request resp;
06544    int seqno;
06545    if (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1) {
06546       ast_log(LOG_WARNING, "Unable to get seqno from '%s'\n", get_header(req, "CSeq"));
06547       return -1;
06548    }
06549    respprep(&resp, p, msg, req);
06550    if (p->rtp) {
06551       if (!p->autoframing && !ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
06552          if (option_debug)
06553             ast_log(LOG_DEBUG, "Setting framing from config on incoming call\n");
06554          ast_rtp_codec_setpref(p->rtp, &p->prefs);
06555       }
06556       try_suggested_sip_codec(p);   
06557       add_sdp(&resp, p);
06558    } else 
06559       ast_log(LOG_ERROR, "Can't add SDP to response, since we have no RTP session allocated. Call-ID %s\n", p->callid);
06560    if (reliable && !p->pendinginvite)
06561       p->pendinginvite = seqno;     /* Buggy clients sends ACK on RINGING too */
06562    return send_response(p, &resp, reliable, seqno);
06563 }

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

References add_t38_sdp(), ast_log(), ast_udptl_offered_from_local(), get_header(), LOG_ERROR, LOG_WARNING, sip_pvt::pendinginvite, respprep(), send_response(), and sip_pvt::udptl.

Referenced by handle_request_invite(), sip_answer(), and sip_handle_t38_reinvite().

06502 {
06503    struct sip_request resp;
06504    int seqno;
06505    
06506    if (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1) {
06507       ast_log(LOG_WARNING, "Unable to get seqno from '%s'\n", get_header(req, "CSeq"));
06508       return -1;
06509    }
06510    respprep(&resp, p, msg, req);
06511    if (p->udptl) {
06512       ast_udptl_offered_from_local(p->udptl, 0);
06513       add_t38_sdp(&resp, p);
06514    } else 
06515       ast_log(LOG_ERROR, "Can't add SDP to response, since we have no UDPTL session allocated. Call-ID %s\n", p->callid);
06516    if (retrans && !p->pendinginvite)
06517       p->pendinginvite = seqno;     /* Buggy clients sends ACK on RINGING too */
06518    return send_response(p, &resp, retrans, seqno);
06519 }

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

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

Referenced by handle_request_invite().

05933 {
05934    struct sip_request resp;
05935    respprep(&resp, p, msg, req);
05936    append_date(&resp);
05937    add_header(&resp, "Unsupported", unsupported);
05938    add_header_contentLength(&resp, 0);
05939    return send_response(p, &resp, XMIT_UNRELIABLE, 0);
05940 }

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

07201 {
07202    if (!p->initreq.headers)   /* Initialize first request before sending */
07203       initialize_initreq(p, req);
07204    return send_request(p, req, XMIT_UNRELIABLE, p->ocseq);
07205 }

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

References add_header(), add_header_contentLength(), add_line(), ast_build_string(), ast_device_state(), AST_DEVICE_UNAVAILABLE, AST_EXTENSION_BUSY, AST_EXTENSION_DEACTIVATED, AST_EXTENSION_INUSE, AST_EXTENSION_NOT_INUSE, AST_EXTENSION_ONHOLD, AST_EXTENSION_REMOVED, AST_EXTENSION_RINGING, AST_EXTENSION_UNAVAILABLE, ast_get_hint(), ast_log(), AST_MAX_EXTENSION, CPIM_PIDF_XML, DIALOG_INFO_XML, sip_pvt::dialogver, cfsubscription_types::event, sip_pvt::expiry, find_subscription_type(), get_header(), get_in_brackets(), sip_pvt::initreq, LOG_WARNING, cfsubscription_types::mediatype, NONE, sip_pvt::ocseq, PIDF_XML, reqprep(), send_request(), SIP_NOTIFY, strsep(), sip_pvt::subscribed, t, XMIT_RELIABLE, and XPIDF_XML.

Referenced by __sip_autodestruct(), cb_extensionstate(), and handle_request_subscribe().

06985 {
06986    char tmp[4000], from[256], to[256];
06987    char *t = tmp, *c, *mfrom, *mto;
06988    size_t maxbytes = sizeof(tmp);
06989    struct sip_request req;
06990    char hint[AST_MAX_EXTENSION];
06991    char *statestring = "terminated";
06992    const struct cfsubscription_types *subscriptiontype;
06993    enum state { NOTIFY_OPEN, NOTIFY_INUSE, NOTIFY_CLOSED } local_state = NOTIFY_OPEN;
06994    char *pidfstate = "--";
06995    char *pidfnote= "Ready";
06996 
06997    memset(from, 0, sizeof(from));
06998    memset(to, 0, sizeof(to));
06999    memset(tmp, 0, sizeof(tmp));
07000 
07001    switch (state) {
07002    case (AST_EXTENSION_RINGING | AST_EXTENSION_INUSE):
07003       statestring = (global_notifyringing) ? "early" : "confirmed";
07004       local_state = NOTIFY_INUSE;
07005       pidfstate = "busy";
07006       pidfnote = "Ringing";
07007       break;
07008    case AST_EXTENSION_RINGING:
07009       statestring = "early";
07010       local_state = NOTIFY_INUSE;
07011       pidfstate = "busy";
07012       pidfnote = "Ringing";
07013       break;
07014    case AST_EXTENSION_INUSE:
07015       statestring = "confirmed";
07016       local_state = NOTIFY_INUSE;
07017       pidfstate = "busy";
07018       pidfnote = "On the phone";
07019       break;
07020    case AST_EXTENSION_BUSY:
07021       statestring = "confirmed";
07022       local_state = NOTIFY_CLOSED;
07023       pidfstate = "busy";
07024       pidfnote = "On the phone";
07025       break;
07026    case AST_EXTENSION_UNAVAILABLE:
07027       statestring = "terminated";
07028       local_state = NOTIFY_CLOSED;
07029       pidfstate = "away";
07030       pidfnote = "Unavailable";
07031       break;
07032    case AST_EXTENSION_ONHOLD:
07033       statestring = "confirmed";
07034       local_state = NOTIFY_INUSE;
07035       pidfstate = "busy";
07036       pidfnote = "On Hold";
07037       break;
07038    case AST_EXTENSION_NOT_INUSE:
07039    default:
07040       /* Default setting */
07041       break;
07042    }
07043 
07044    subscriptiontype = find_subscription_type(p->subscribed);
07045    
07046    /* Check which device/devices we are watching  and if they are registered */
07047    if (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, p->context, p->exten)) {
07048       char *hint2 = hint, *individual_hint = NULL;
07049       while ((individual_hint = strsep(&hint2, "&"))) {
07050          /* If they are not registered, we will override notification and show no availability */
07051          if (ast_device_state(individual_hint) == AST_DEVICE_UNAVAILABLE) {
07052             local_state = NOTIFY_CLOSED;
07053             pidfstate = "away";
07054             pidfnote = "Not online";
07055          }
07056       }
07057    }
07058 
07059    ast_copy_string(from, get_header(&p->initreq, "From"), sizeof(from));
07060    c = get_in_brackets(from);
07061    if (strncasecmp(c, "sip:", 4)) {
07062       ast_log(LOG_WARNING, "Huh?  Not a SIP header (%s)?\n", c);
07063       return -1;
07064    }
07065    mfrom = strsep(&c, ";");   /* trim ; and beyond */
07066 
07067    ast_copy_string(to, get_header(&p->initreq, "To"), sizeof(to));
07068    c = get_in_brackets(to);
07069    if (strncasecmp(c, "sip:", 4)) {
07070       ast_log(LOG_WARNING, "Huh?  Not a SIP header (%s)?\n", c);
07071       return -1;
07072    }
07073    mto = strsep(&c, ";");  /* trim ; and beyond */
07074 
07075    reqprep(&req, p, SIP_NOTIFY, 0, 1);
07076 
07077    
07078    add_header(&req, "Event", subscriptiontype->event);
07079    add_header(&req, "Content-Type", subscriptiontype->mediatype);
07080    switch(state) {
07081    case AST_EXTENSION_DEACTIVATED:
07082       if (timeout)
07083          add_header(&req, "Subscription-State", "terminated;reason=timeout");
07084       else {
07085          add_header(&req, "Subscription-State", "terminated;reason=probation");
07086          add_header(&req, "Retry-After", "60");
07087       }
07088       break;
07089    case AST_EXTENSION_REMOVED:
07090       add_header(&req, "Subscription-State", "terminated;reason=noresource");
07091       break;
07092    default:
07093       if (p->expiry)
07094          add_header(&req, "Subscription-State", "active");
07095       else  /* Expired */
07096          add_header(&req, "Subscription-State", "terminated;reason=timeout");
07097    }
07098    switch (p->subscribed) {
07099    case XPIDF_XML:
07100    case CPIM_PIDF_XML:
07101       ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\"?>\n");
07102       ast_build_string(&t, &maxbytes, "<!DOCTYPE presence PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n");
07103       ast_build_string(&t, &maxbytes, "<presence>\n");
07104       ast_build_string(&t, &maxbytes, "<presentity uri=\"%s;method=SUBSCRIBE\" />\n", mfrom);
07105       ast_build_string(&t, &maxbytes, "<atom id=\"%s\">\n", p->exten);
07106       ast_build_string(&t, &maxbytes, "<address uri=\"%s;user=ip\" priority=\"0.800000\">\n", mto);
07107       ast_build_string(&t, &maxbytes, "<status status=\"%s\" />\n", (local_state ==  NOTIFY_OPEN) ? "open" : (local_state == NOTIFY_INUSE) ? "inuse" : "closed");
07108       ast_build_string(&t, &maxbytes, "<msnsubstatus substatus=\"%s\" />\n", (local_state == NOTIFY_OPEN) ? "online" : (local_state == NOTIFY_INUSE) ? "onthephone" : "offline");
07109       ast_build_string(&t, &maxbytes, "</address>\n</atom>\n</presence>\n");
07110       break;
07111    case PIDF_XML: /* Eyebeam supports this format */
07112       ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n");
07113       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);
07114       ast_build_string(&t, &maxbytes, "<pp:person><status>\n");
07115       if (pidfstate[0] != '-')
07116          ast_build_string(&t, &maxbytes, "<ep:activities><ep:%s/></ep:activities>\n", pidfstate);
07117       ast_build_string(&t, &maxbytes, "</status></pp:person>\n");
07118       ast_build_string(&t, &maxbytes, "<note>%s</note>\n", pidfnote); /* Note */
07119       ast_build_string(&t, &maxbytes, "<tuple id=\"%s\">\n", p->exten); /* Tuple start */
07120       ast_build_string(&t, &maxbytes, "<contact priority=\"1\">%s</contact>\n", mto);
07121       if (pidfstate[0] == 'b') /* Busy? Still open ... */
07122          ast_build_string(&t, &maxbytes, "<status><basic>open</basic></status>\n");
07123       else
07124          ast_build_string(&t, &maxbytes, "<status><basic>%s</basic></status>\n", (local_state != NOTIFY_CLOSED) ? "open" : "closed");
07125       ast_build_string(&t, &maxbytes, "</tuple>\n</presence>\n");
07126       break;
07127    case DIALOG_INFO_XML: /* SNOM subscribes in this format */
07128       ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\"?>\n");
07129       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);
07130       if ((state & AST_EXTENSION_RINGING) && global_notifyringing)
07131          ast_build_string(&t, &maxbytes, "<dialog id=\"%s\" direction=\"recipient\">\n", p->exten);
07132       else
07133          ast_build_string(&t, &maxbytes, "<dialog id=\"%s\">\n", p->exten);
07134       ast_build_string(&t, &maxbytes, "<state>%s</state>\n", statestring);
07135       if (state == AST_EXTENSION_ONHOLD) {
07136          ast_build_string(&t, &maxbytes, "<local>\n<target uri=\"%s\">\n"
07137                                          "<param pname=\"+sip.rendering\" pvalue=\"no\">\n"
07138                                          "</target>\n</local>\n", mto);
07139       }
07140       ast_build_string(&t, &maxbytes, "</dialog>\n</dialog-info>\n");
07141       break;
07142    case NONE:
07143    default:
07144       break;
07145    }
07146 
07147    if (t > tmp + sizeof(tmp))
07148       ast_log(LOG_WARNING, "Buffer overflow detected!!  (Please file a bug report)\n");
07149 
07150    add_header_contentLength(&req, strlen(tmp));
07151    add_line(&req, tmp);
07152 
07153    return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
07154 }

static void try_suggested_sip_codec ( struct sip_pvt p  )  [static]

Try setting codec suggested by the SIP_CODEC channel variable.

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

03545 {
03546    int fmt;
03547    const char *codec;
03548 
03549    codec = pbx_builtin_getvar_helper(p->owner, "SIP_CODEC");
03550    if (!codec) 
03551       return;
03552 
03553    fmt = ast_getformatbyname(codec);
03554    if (fmt) {
03555       ast_log(LOG_NOTICE, "Changing codec to '%s' for this call because of ${SIP_CODEC} variable\n", codec);
03556       if (p->jointcapability & fmt) {
03557          p->jointcapability &= fmt;
03558          p->capability &= fmt;
03559       } else
03560          ast_log(LOG_NOTICE, "Ignoring ${SIP_CODEC} variable because it is not shared by both ends.\n");
03561    } else
03562       ast_log(LOG_NOTICE, "Ignoring ${SIP_CODEC} variable because of unrecognized/not configured codec (check allow/disallow in sip.conf): %s\n", codec);
03563    return;  
03564 }

static int unload_module ( void   )  [static]

PBX unload module API.

Definition at line 17699 of file chan_sip.c.

References __sip_destroy(), ast_channel_unregister(), ast_cli_unregister_multiple(), ast_custom_function_unregister(), ast_free_ha(), ast_manager_unregister(), ast_mutex_lock(), ast_mutex_unlock(), AST_PTHREADT_NULL, AST_PTHREADT_STOP, ast_rtp_proto_unregister(), ast_softhangup(), AST_SOFTHANGUP_APPUNLOAD, ast_udptl_proto_unregister(), ast_unregister_application(), ASTOBJ_CONTAINER_DESTROY, ASTOBJ_CONTAINER_DESTROYALL, authl, clear_realm_authentication(), clear_sip_domains(), iflist, localaddr, sip_pvt::next, sip_pvt::owner, peerl, regl, sched_context_destroy(), sip_destroy_peer(), sip_destroy_user(), sip_registry_destroy(), sip_rtp, sip_tech, sip_udptl, sipsock, TRUE, and userl.

17700 {
17701    struct sip_pvt *p, *pl;
17702    
17703    /* First, take us out of the channel type list */
17704    ast_channel_unregister(&sip_tech);
17705 
17706    /* Unregister dial plan functions */
17707    ast_custom_function_unregister(&sipchaninfo_function);
17708    ast_custom_function_unregister(&sippeer_function);
17709    ast_custom_function_unregister(&sip_header_function);
17710    ast_custom_function_unregister(&checksipdomain_function);
17711 
17712    /* Unregister dial plan applications */
17713    ast_unregister_application(app_dtmfmode);
17714    ast_unregister_application(app_sipaddheader);
17715 
17716    /* Unregister CLI commands */
17717    ast_cli_unregister_multiple(cli_sip, sizeof(cli_sip) / sizeof(struct ast_cli_entry));
17718 
17719    /* Disconnect from the RTP subsystem */
17720    ast_rtp_proto_unregister(&sip_rtp);
17721 
17722    /* Disconnect from UDPTL */
17723    ast_udptl_proto_unregister(&sip_udptl);
17724 
17725    /* Unregister AMI actions */
17726    ast_manager_unregister("SIPpeers");
17727    ast_manager_unregister("SIPshowpeer");
17728 
17729    ast_mutex_lock(&iflock);
17730    /* Hangup all interfaces if they have an owner */
17731    for (p = iflist; p ; p = p->next) {
17732       if (p->owner)
17733          ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD);
17734    }
17735    ast_mutex_unlock(&iflock);
17736 
17737    ast_mutex_lock(&monlock);
17738    if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP) && (monitor_thread != AST_PTHREADT_NULL)) {
17739       pthread_cancel(monitor_thread);
17740       pthread_kill(monitor_thread, SIGURG);
17741       pthread_join(monitor_thread, NULL);
17742    }
17743    monitor_thread = AST_PTHREADT_STOP;
17744    ast_mutex_unlock(&monlock);
17745 
17746    ast_mutex_lock(&iflock);
17747    /* Destroy all the interfaces and free their memory */
17748    p = iflist;
17749    while (p) {
17750       pl = p;
17751       p = p->next;
17752       __sip_destroy(pl, TRUE);
17753    }
17754    iflist = NULL;
17755    ast_mutex_unlock(&iflock);
17756 
17757    /* Free memory for local network address mask */
17758    ast_free_ha(localaddr);
17759 
17760    ASTOBJ_CONTAINER_DESTROYALL(&userl, sip_destroy_user);
17761    ASTOBJ_CONTAINER_DESTROY(&userl);
17762    ASTOBJ_CONTAINER_DESTROYALL(&peerl, sip_destroy_peer);
17763    ASTOBJ_CONTAINER_DESTROY(&peerl);
17764    ASTOBJ_CONTAINER_DESTROYALL(&regl, sip_registry_destroy);
17765    ASTOBJ_CONTAINER_DESTROY(&regl);
17766 
17767    clear_realm_authentication(authl);
17768    clear_sip_domains();
17769    close(sipsock);
17770    sched_context_destroy(sched);
17771       
17772    return 0;
17773 }

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

References ast_clear_flag, ast_device_state_changed(), ast_log(), ast_set_flag, ast_strlen_zero(), ast_test_flag, ASTOBJ_UNREF, sip_peer::call_limit, sip_user::call_limit, DEC_CALL_LIMIT, DEC_CALL_RINGING, FALSE, find_peer(), find_user(), sip_pvt::flags, INC_CALL_LIMIT, INC_CALL_RINGING, sip_peer::inRinging, sip_peer::inUse, sip_user::inUse, inuse, LOG_DEBUG, LOG_ERROR, LOG_WARNING, name, option_debug, SIP_CALL_LIMIT, sip_destroy_peer(), sip_destroy_user(), SIP_INC_COUNT, SIP_PAGE2_CALL_ONHOLD, SIP_PAGE2_INC_RINGING, SIP_PAGE2_OUTGOING_CALL, SIP_PAGE2_RTCACHEFRIENDS, sip_peer_hold(), SIP_REALTIME, and sipdebug.

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

03102 {
03103    char name[256];
03104    int *inuse = NULL, *call_limit = NULL, *inringing = NULL;
03105    int outgoing = ast_test_flag(&fup->flags[1], SIP_PAGE2_OUTGOING_CALL);
03106    struct sip_user *u = NULL;
03107    struct sip_peer *p = NULL;
03108 
03109    if (option_debug > 2)
03110       ast_log(LOG_DEBUG, "Updating call counter for %s call\n", outgoing ? "outgoing" : "incoming");
03111 
03112    /* Test if we need to check call limits, in order to avoid 
03113       realtime lookups if we do not need it */
03114    if (!ast_test_flag(&fup->flags[0], SIP_CALL_LIMIT) && !ast_test_flag(&fup->flags[1], SIP_PAGE2_CALL_ONHOLD))
03115       return 0;
03116 
03117    ast_copy_string(name, fup->username, sizeof(name));
03118 
03119    /* Check the list of users only for incoming calls */
03120    if (global_limitonpeers == FALSE && !outgoing && (u = find_user(name, 1)))  {
03121       inuse = &u->inUse;
03122       call_limit = &u->call_limit;
03123       inringing = NULL;
03124    } else if ( (p = find_peer(ast_strlen_zero(fup->peername) ? name : fup->peername, NULL, 1) ) ) { /* Try to find peer */
03125       inuse = &p->inUse;
03126       call_limit = &p->call_limit;
03127       inringing = &p->inRinging;
03128       ast_copy_string(name, fup->peername, sizeof(name));
03129    } 
03130    if (!p && !u) {
03131       if (option_debug > 1)
03132          ast_log(LOG_DEBUG, "%s is not a local device, no call limit\n", name);
03133       return 0;
03134    }
03135 
03136    switch(event) {
03137    /* incoming and outgoing affects the inUse counter */
03138    case DEC_CALL_LIMIT:
03139       if ( *inuse > 0 ) {
03140          if (ast_test_flag(&fup->flags[0], SIP_INC_COUNT)) {
03141             (*inuse)--;
03142             ast_clear_flag(&fup->flags[0], SIP_INC_COUNT);
03143          }
03144       } else {
03145          *inuse = 0;
03146       }
03147       if (inringing) {
03148          if (ast_test_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING)) {
03149             if (*inringing > 0)
03150                (*inringing)--;
03151             else if (!ast_test_flag(&fup->flags[0], SIP_REALTIME) || ast_test_flag(&fup->flags[1], SIP_PAGE2_RTCACHEFRIENDS))
03152                ast_log(LOG_WARNING, "Inringing for peer '%s' < 0?\n", fup->peername);
03153             ast_clear_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING);
03154          }
03155       }
03156       if (ast_test_flag(&fup->flags[1], SIP_PAGE2_CALL_ONHOLD) && global_notifyhold) {
03157          ast_clear_flag(&fup->flags[1], SIP_PAGE2_CALL_ONHOLD);
03158          sip_peer_hold(fup, 0);
03159       }
03160       if (option_debug > 1 || sipdebug) {
03161          ast_log(LOG_DEBUG, "Call %s %s '%s' removed from call limit %d\n", outgoing ? "to" : "from", u ? "user":"peer", name, *call_limit);
03162       }
03163       break;
03164 
03165    case INC_CALL_RINGING:
03166    case INC_CALL_LIMIT:
03167       if (*call_limit > 0 ) {
03168          if (*inuse >= *call_limit) {
03169             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);
03170             if (u)
03171                ASTOBJ_UNREF(u, sip_destroy_user);
03172             else
03173                ASTOBJ_UNREF(p, sip_destroy_peer);
03174             return -1; 
03175          }
03176       }
03177       if (inringing && (event == INC_CALL_RINGING)) {
03178          if (!ast_test_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING)) {
03179             (*inringing)++;
03180             ast_set_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING);
03181          }
03182       }
03183       /* Continue */
03184       (*inuse)++;
03185       ast_set_flag(&fup->flags[0], SIP_INC_COUNT);
03186       if (option_debug > 1 || sipdebug) {
03187          ast_log(LOG_DEBUG, "Call %s %s '%s' is %d out of %d\n", outgoing ? "to" : "from", u ? "user":"peer", name, *inuse, *call_limit);
03188       }
03189       break;
03190 
03191    case DEC_CALL_RINGING:
03192       if (inringing) {
03193          if (ast_test_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING)) {
03194             if (*inringing > 0)
03195                (*inringing)--;
03196             else if (!ast_test_flag(&fup->flags[0], SIP_REALTIME) || ast_test_flag(&fup->flags[1], SIP_PAGE2_RTCACHEFRIENDS))
03197                ast_log(LOG_WARNING, "Inringing for peer '%s' < 0?\n", p->name);
03198             ast_clear_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING);
03199          }
03200       }
03201       break;
03202 
03203    default:
03204       ast_log(LOG_ERROR, "update_call_counter(%s, %d) called with no event!\n", name, event);
03205    }
03206    if (p) {
03207       ast_device_state_changed("SIP/%s", p->name);
03208       ASTOBJ_UNREF(p, sip_destroy_peer);
03209    } else /* u must be set */
03210       ASTOBJ_UNREF(u, sip_destroy_user);
03211    return 0;
03212 }

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

Update peer data in database (if used).

Definition at line 2441 of file chan_sip.c.

References sip_peer::addr, ast_test_flag, sip_peer::flags, sip_peer::fullcontact, realtime_update_peer(), SIP_PAGE2_RTCACHEFRIENDS, SIP_PAGE2_RTUPDATE, SIP_REALTIME, and sip_peer::username.

Referenced by register_verify().

02442 {
02443    int rtcachefriends = ast_test_flag(&p->flags[1], SIP_PAGE2_RTCACHEFRIENDS);
02444    if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTUPDATE) &&
02445        (ast_test_flag(&p->flags[0], SIP_REALTIME) || rtcachefriends)) {
02446       realtime_update_peer(p->name, &p->addr, p->username, rtcachefriends ? p->fullcontact : NULL, expiry);
02447    }
02448 }


Variable Documentation

struct in_addr __ourip [static]

Definition at line 1193 of file chan_sip.c.

int allow_external_domains [static]

Accept calls to external SIP domains?

Definition at line 558 of file chan_sip.c.

int apeerobjs = 0 [static]

Autocreated peer objects

Definition at line 574 of file chan_sip.c.

char* app_dtmfmode = "SIPDtmfMode" [static]

Definition at line 17239 of file chan_sip.c.

char* app_sipaddheader = "SIPAddHeader" [static]

Definition at line 17241 of file chan_sip.c.

struct sip_auth* authl = NULL [static]

Definition at line 1182 of file chan_sip.c.

Referenced by build_reply_digest(), reload_config(), sip_do_reload(), sip_show_settings(), and unload_module().

int autocreatepeer [static]

Auto creation of peers at registration? Default off.

Definition at line 538 of file chan_sip.c.

struct sockaddr_in bindaddr = { 0, } [static]

The address we bind to

Definition at line 1187 of file chan_sip.c.

struct ast_custom_function checksipdomain_function [static]

Definition at line 11538 of file chan_sip.c.

struct ast_cli_entry cli_sip[] [static]

Definition at line 17535 of file chan_sip.c.

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

int compactheaders [static]

send compact sip headers

Definition at line 552 of file chan_sip.c.

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

Definition at line 224 of file chan_sip.c.

char debug_usage[] [static]

Definition at line 11422 of file chan_sip.c.

struct sockaddr_in debugaddr [static]

Definition at line 1196 of file chan_sip.c.

Referenced by sip_debug_test_addr(), 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 518 of file chan_sip.c.

char default_context[AST_MAX_CONTEXT] [static]

Definition at line 515 of file chan_sip.c.

int default_expiry = DEFAULT_DEFAULT_EXPIRY [static]

Definition at line 187 of file chan_sip.c.

char default_fromdomain[AST_MAX_EXTENSION] [static]

Definition at line 519 of file chan_sip.c.

struct ast_jb_conf default_jbconf [static]

Global jitterbuffer configuration - by default, jb is disabled.

Definition at line 215 of file chan_sip.c.

char default_language[MAX_LANGUAGE] [static]

Definition at line 517 of file chan_sip.c.

int default_maxcallbitrate [static]

Maximum bitrate for call

Definition at line 526 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 523 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 524 of file chan_sip.c.

char default_notifymime[AST_MAX_EXTENSION] [static]

Definition at line 520 of file chan_sip.c.

struct ast_codec_pref default_prefs [static]

Default codec prefs

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

char default_subscribecontext[AST_MAX_CONTEXT] [static]

Definition at line 516 of file chan_sip.c.

char default_vmexten[AST_MAX_EXTENSION] [static]

Definition at line 522 of file chan_sip.c.

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

Definition at line 17238 of file chan_sip.c.

char* descrip_sipaddheader [static]

Definition at line 17244 of file chan_sip.c.

int dumphistory [static]

Dump history to verbose before destroying SIP dialog

Definition at line 554 of file chan_sip.c.

int expiry = DEFAULT_EXPIRY [static]

Definition at line 188 of file chan_sip.c.

time_t externexpire = 0 [static]

Expiration counter for re-resolving external host name in dynamic DNS

Definition at line 1190 of file chan_sip.c.

Referenced by ast_sip_ouraddrfor(), and reload_config().

char externhost[MAXHOSTNAMELEN] [static]

External host name (possibly with dynamic DNS and DHCP

Definition at line 1189 of file chan_sip.c.

Referenced by ast_sip_ouraddrfor(), and reload_config().

struct sockaddr_in externip [static]

External IP address if we are behind NAT

Definition at line 1188 of file chan_sip.c.

int externrefresh = 10 [static]

Definition at line 1191 of file chan_sip.c.

Referenced by ast_sip_ouraddrfor(), and reload_config().

int global_allowguest [static]

allow unauthenticated users/peers to connect?

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

enum transfermodes global_allowtransfer [static]

SIP Refer restriction scheme

Definition at line 562 of file chan_sip.c.

int global_alwaysauthreject [static]

Send 401 Unauthorized for all failing requests

Definition at line 535 of file chan_sip.c.

int global_autoframing [static]

Turn autoframing on or off.

Definition at line 561 of file chan_sip.c.

int global_callevents [static]

Whether we send manager events or not

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

int global_directrtpsetup [static]

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

Definition at line 530 of file chan_sip.c.

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

global SIP_ flags

Definition at line 577 of file chan_sip.c.

struct ast_jb_conf global_jbconf [static]

Definition at line 222 of file chan_sip.c.

int global_limitonpeers [static]

Match call limit on peers only

Definition at line 531 of file chan_sip.c.

int global_matchexterniplocally [static]

Match externip/externhost setting against localnet setting

Definition at line 564 of file chan_sip.c.

int global_mwitime [static]

Time between MWI checks for peers

Definition at line 548 of file chan_sip.c.

int global_notifyhold [static]

Send notifications on hold

Definition at line 534 of file chan_sip.c.

int global_notifyringing [static]

Send notifications on ringing

Definition at line 533 of file chan_sip.c.

char global_realm[MAXHOSTNAMELEN] [static]

Default realm

Definition at line 555 of file chan_sip.c.

int global_reg_timeout [static]

Definition at line 543 of file chan_sip.c.

int global_regattempts_max [static]

Registration attempts before giving up

Definition at line 544 of file chan_sip.c.

char global_regcontext[AST_MAX_CONTEXT] [static]

Context for auto-extensions

Definition at line 556 of file chan_sip.c.

int global_relaxdtmf [static]

Relax DTMF

Definition at line 539 of file chan_sip.c.

int global_rtautoclear [static]

Definition at line 532 of file chan_sip.c.

int global_rtpholdtimeout [static]

Definition at line 541 of file chan_sip.c.

int global_rtpkeepalive [static]

Send RTP keepalives

Definition at line 542 of file chan_sip.c.

int global_rtptimeout [static]

Time out call if no RTP

Definition at line 540 of file chan_sip.c.

int global_t1min [static]

T1 roundtrip time minimum

Definition at line 560 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 825 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 550 of file chan_sip.c.

unsigned int global_tos_sip [static]

IP type of service for SIP packets

Definition at line 549 of file chan_sip.c.

unsigned int global_tos_video [static]

IP type of service for video RTP packets

Definition at line 551 of file chan_sip.c.

char global_useragent[AST_MAX_EXTENSION] [static]

Useragent for the SIP channel

Definition at line 557 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 11439 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 598 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 1192 of file chan_sip.c.

Referenced by ast_sip_ouraddrfor(), reload_config(), and unload_module().

char mandescr_show_peer[] [static]

Initial value:

 
"Description: Show one SIP peer with details on current status.\n"
"Variables: \n"
"  Peer: <name>           The peer name you want to check.\n"
"  ActionID: <id>   Optional action ID for this AMI transaction.\n"

Definition at line 10079 of file chan_sip.c.

Referenced by load_module().

char mandescr_show_peers[] [static]

Initial value:

 
"Description: Lists SIP peers in text format with details on current status.\n"
"Variables: \n"
"  ActionID: <id> Action ID for this transaction. Will be returned.\n"

Definition at line 9630 of file chan_sip.c.

Referenced by load_module().

int max_expiry = DEFAULT_MAX_EXPIRY [static]

Maximum accepted registration time

Definition at line 186 of file chan_sip.c.

int min_expiry = DEFAULT_MIN_EXPIRY [static]

Minimum accepted registration time

Definition at line 185 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 592 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 11431 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 11435 of file chan_sip.c.

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

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

Referenced by complete_sipnotify(), reload_config(), and sip_notify().

char notify_usage[] [static]

Initial value:

"Usage: sip notify <type> <peer> [<peer>...]\n"
"       Send a NOTIFY message to a SIP peer or peers\n"
"       Message types are defined in sip_notify.conf\n"

Definition at line 11371 of file chan_sip.c.

int ourport [static]

Definition at line 1195 of file chan_sip.c.

struct sockaddr_in outboundproxyip [static]

Definition at line 1194 of file chan_sip.c.

Referenced by reload_config().

int pedanticsipchecking [static]

Extra checking ? Default off

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

int recordhistory [static]

Record SIP history. Off by default

Definition at line 553 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(), sip_do_reload(), sip_register(), sip_send_all_registers(), sip_show_objects(), sip_show_registry(), and unload_module().

int regobjs = 0 [static]

Registry objects

Definition at line 575 of file chan_sip.c.

int rpeerobjs = 0 [static]

Realtime peers

Definition at line 573 of file chan_sip.c.

int ruserobjs = 0 [static]

Realtime users

Definition at line 571 of file chan_sip.c.

struct sched_context* sched [static]

The scheduling context

Definition at line 597 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 11395 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 11391 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 11366 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 11399 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 11386 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 11452 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 11408 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 11403 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 11418 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 11456 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 11448 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 11381 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 11376 of file chan_sip.c.

struct ast_custom_function sip_header_function [static]

Definition at line 11514 of file chan_sip.c.

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_call(), 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 11444 of file chan_sip.c.

int sip_reloading = FALSE [static]

Flag for avoiding multiple reloads at the same time

Definition at line 594 of file chan_sip.c.

enum channelreloadreason sip_reloadreason [static]

Reason for last reload/load of configuration

Definition at line 595 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 1596 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 1538 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 1564 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 1605 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 11693 of file chan_sip.c.

struct ast_custom_function sippeer_function

Structure to declare a dialplan function: SIPPEER.

Definition at line 11613 of file chan_sip.c.

int sipsock = -1 [static]

Main socket for SIP network communication

Definition at line 1186 of file chan_sip.c.

Referenced by __sip_xmit(), do_monitor(), reg_source_db(), reload_config(), sipsock_read(), and unload_module().

int* sipsock_read_id [static]

ID of IO entry for sipsock FD

Definition at line 599 of file chan_sip.c.

int speerobjs = 0 [static]

Statis peers

Definition at line 572 of file chan_sip.c.

int srvlookup [static]

SRV Lookup on or off. Default is off, RFC behavior is on

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

char* synopsis_dtmfmode = "Change the dtmfmode for a SIP call" [static]

Definition at line 17237 of file chan_sip.c.

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

Definition at line 17242 of file chan_sip.c.

struct ast_user_list userl [static]

The user list: Users and friends.


Generated on Wed Aug 15 01:24:57 2007 for Asterisk - the Open Source PBX by  doxygen 1.5.3