Fri Aug 24 02:24:03 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"

Include dependency graph for chan_sip.c:

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_HISTORY_ENTRIES   50
#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_typesfind_subscription_type (enum subscriptiontype subtype)
 Find subscription type in array.
static struct sip_userfind_user (const char *name, int realtime)
 Locate user by name Locates user by name (From: sip uri user name part) first from in-memory list (static configuration) then from realtime storage (defined in extconfig.conf).
static void free_old_route (struct sip_route *route)
 Remove route from route list.
static int func_check_sipdomain (struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
 Dial plan function to check if domain is local.
static int func_header_read (struct ast_channel *chan, char *function, char *data, char *buf, size_t len)
 Read SIP header (dialplan function).
static int function_sipchaninfo_read (struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
 ${SIPCHANINFO()} Dialplan function - reads sip channel data
static int function_sippeer (struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
 ${SIPPEER()} Dialplan function - reads peer data
static char * generate_random_string (char *buf, size_t size)
 Generate 32 byte random string for callid's etc.
static int get_also_info (struct sip_pvt *p, struct sip_request *oreq)
 Call transfer support (old way, deprecated by the IETF)--.
static char * get_body (struct sip_request *req, char *name)
 Get a specific line from the message body.
static char * get_body_by_line (const char *line, const char *name, int nameLen)
 Reads one line of SIP message body.
static char * get_calleridname (const char *input, char *output, size_t outputsize)
 Get caller id name from SIP headers.
static int get_destination (struct sip_pvt *p, struct sip_request *oreq)
 Find out who the call is for We use the INVITE uri to find out.
static const char * get_header (const struct sip_request *req, const char *name)
 Get header from SIP request.
static char * get_in_brackets (char *tmp)
 Pick out text in brackets from character string.
static int get_msg_text (char *buf, int len, struct sip_request *req)
 Get text out of a SIP MESSAGE packet.
static int get_rdnis (struct sip_pvt *p, struct sip_request *oreq)
 Get referring dnis.
static int get_refer_info (struct sip_pvt *transferer, struct sip_request *outgoing_req)
 Call transfer support (the REFER method) Extracts Refer headers into pvt dialog structure.
static int get_rpid_num (const char *input, char *output, int maxlen)
 Get caller id number from Remote-Party-ID header field Returns true if number should be restricted (privacy setting found) output is set to NULL if no number found.
static const char * get_sdp (struct sip_request *req, const char *name)
 Get a line from an SDP message body.
static const char * get_sdp_iterate (int *start, struct sip_request *req, const char *name)
 Lookup 'name' in the SDP starting at the 'start' line. Returns the matching line, and 'start' is updated with the next line number.
static struct sip_pvtget_sip_pvt_byid_locked (const char *callid, const char *totag, const char *fromtag)
 Lock interface lock and find matching pvt lock
  • 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_channelsip_new (struct sip_pvt *i, int state, const char *title)
 Initiate a call in the SIP channel called from sip_request_call (calls from the pbx ) for outbound channels and from handle_request_invite for inbound channels.
static int sip_no_debug (int fd, int argc, char *argv[])
 Disable SIP Debugging in CLI.
static int sip_no_debug_deprecated (int fd, int argc, char *argv[])
static int sip_no_history (int fd, int argc, char *argv[])
 Disable SIP History logging (CLI).
static int sip_notify (int fd, int argc, char *argv[])
 Cli command to send SIP notify to peer.
static int sip_park (struct ast_channel *chan1, struct ast_channel *chan2, struct sip_request *req, int seqno)
 Park a call using the subsystem in res_features.c This is executed in a separate thread.
static void * sip_park_thread (void *stuff)
 Park SIP call support function Starts in a new thread, then parks the call XXX Should we add a wait period after streaming audio and before hangup?? Sometimes the audio can't be heard before hangup.
static void sip_peer_hold (struct sip_pvt *p, int hold)
 Change onhold state of a peer using a pvt structure.
static void sip_poke_all_peers (void)
 Send a poke to all known peers Space them out 100 ms apart XXX We might have a cool algorithm for this or use random - any suggestions?
static int sip_poke_noanswer (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_channelsip_request_call (const char *type, int format, void *data, int *cause)
 PBX interface function -build SIP pvt structure SIP calls initiated by the PBX arrive here.
static int sip_reregister (void *data)
 Update registration with SIP Proxy.
static struct ast_framesip_rtp_read (struct ast_channel *ast, struct sip_pvt *p, int *faxdetect)
 Read RTP from network.
static void sip_scheddestroy (struct sip_pvt *p, int ms)
 Schedule destruction of SIP dialog.
static void sip_send_all_registers (void)
 Send all known registrations.
static int sip_send_mwi_to_peer (struct sip_peer *peer)
 Send message waiting indication to alert peer that they've got voicemail.
static int sip_senddigit_begin (struct ast_channel *ast, char digit)
static int sip_senddigit_end (struct ast_channel *ast, char digit, unsigned int duration)
 Send DTMF character on SIP channel within one call, we're able to transmit in many methods simultaneously.
static int sip_sendtext (struct ast_channel *ast, const char *text)
 Send SIP MESSAGE text within a call Called from PBX core sendtext() application.
static int sip_set_rtp_peer (struct ast_channel *chan, struct ast_rtp *rtp, struct ast_rtp *vrtp, int codecs, int nat_active)
 Set the RTP peer for this call.
static int sip_set_udptl_peer (struct ast_channel *chan, struct ast_udptl *udptl)
static int sip_show_channel (int fd, int argc, char *argv[])
 Show details of one active dialog.
static int sip_show_channels (int fd, int argc, char *argv[])
 Show active SIP channels.
static int sip_show_domains (int fd, int argc, char *argv[])
 CLI command to list local domains.
static int sip_show_history (int fd, int argc, char *argv[])
 Show history details of one dialog.
static int sip_show_inuse (int fd, int argc, char *argv[])
 CLI Command to show calls within limits set by call_limit.
static int sip_show_objects (int fd, int argc, char *argv[])
 List all allocated SIP Objects (realtime or static).
static int sip_show_peer (int fd, int argc, char *argv[])
 Show one peer in detail.
static int sip_show_peers (int fd, int argc, char *argv[])
 CLI Show Peers command.
static int sip_show_registry (int fd, int argc, char *argv[])
 Show SIP Registry (registrations with other SIP proxies.
static int sip_show_settings (int fd, int argc, char *argv[])
 List global settings for the SIP channel.
static int sip_show_subscriptions (int fd, int argc, char *argv[])
 Show active SIP subscriptions.
static int sip_show_user (int fd, int argc, char *argv[])
 Show one user in detail.
static int sip_show_users (int fd, int argc, char *argv[])
 CLI Command 'SIP Show Users'.
static int sip_sipredirect (struct sip_pvt *p, const char *dest)
 Transfer call before connect with a 302 redirect.
static int sip_transfer (struct ast_channel *ast, const char *dest)
 Transfer SIP call.
static int sip_write (struct ast_channel *ast, struct ast_frame *frame)
 Send frame to media channel (rtp).
static int sipsock_read (int *id, int fd, short events, void *ignore)
 Read data from SIP socket.
static void stop_media_flows (struct sip_pvt *p)
 Immediately stop RTP, VRTP and UDPTL as applicable.
static const char * subscription_type2str (enum subscriptiontype subtype)
 Show subscription type in string format.
static int t38_get_rate (int t38cap)
 Get Max T.38 Transmission rate from T38 capabilities.
static struct sip_peertemp_peer (const char *name)
 Create temporary peer (used in autocreatepeer mode).
static void temp_pvt_cleanup (void *)
static char * transfermode2str (enum transfermodes mode)
 Convert transfer mode to text string.
static void transmit_fake_auth_response (struct sip_pvt *p, struct sip_request *req, int reliable)
 Send a fake 401 Unauthorized response when the administrator wants to hide the names of local users/peers from fishers.
static int transmit_info_with_digit (struct sip_pvt *p, const char digit, unsigned int duration)
 Send SIP INFO dtmf message, see Cisco documentation on cisco.com.
static int transmit_info_with_vidupdate (struct sip_pvt *p)
 Send SIP INFO with video update request.
static int transmit_invite (struct sip_pvt *p, int sipmethod, int sdp, int init)
 Build REFER/INVITE/OPTIONS message and transmit it.
static int transmit_message_with_text (struct sip_pvt *p, const char *text)
 Transmit text with SIP MESSAGE method.
static int transmit_notify_with_mwi (struct sip_pvt *p, int newmsgs, int oldmsgs, char *vmexten)
 Notify user of messages waiting in voicemail.
static int transmit_notify_with_sipfrag (struct sip_pvt *p, int cseq, char *message, int terminate)
 Notify a transferring party of the status of transfer.
static int transmit_refer (struct sip_pvt *p, const char *dest)
 Transmit SIP REFER message (initiated by the transfer() dialplan application.
static int transmit_register (struct sip_registry *r, int sipmethod, const char *auth, const char *authheader)
 Transmit register to SIP proxy or UA.
static int transmit_reinvite_with_sdp (struct sip_pvt *p)
 Transmit reinvite with SDP.
static int transmit_reinvite_with_t38_sdp (struct sip_pvt *p)
 Transmit reinvite with T38 SDP We reinvite so that the T38 processing can take place. SIP Signalling stays with * in the path.
static int transmit_request (struct sip_pvt *p, int sipmethod, int seqno, enum xmittype reliable, int newbranch)
 Transmit generic SIP request returns XMIT_ERROR if transmit failed with a critical error (don't retry).
static int transmit_request_with_auth (struct sip_pvt *p, int sipmethod, int seqno, enum xmittype reliable, int newbranch)
 Transmit SIP request, auth added.
static int transmit_response (struct sip_pvt *p, const char *msg, const struct sip_request *req)
 Transmit response, no retransmits.
static int transmit_response_reliable (struct sip_pvt *p, const char *msg, const struct sip_request *req)
 Transmit response, Make sure you get an ACK This is only used for responses to INVITEs, where we need to make sure we get an ACK.
static int transmit_response_using_temp (ast_string_field callid, struct sockaddr_in *sin, int useglobal_nat, const int intended_method, const struct sip_request *req, const char *msg)
 Transmit response, no retransmits, using a temporary pvt structure.
static int transmit_response_with_allow (struct sip_pvt *p, const char *msg, const struct sip_request *req, enum xmittype reliable)
 Append Accept header, content length before transmitting response.
static int transmit_response_with_auth (struct sip_pvt *p, const char *msg, const struct sip_request *req, const char *randdata, enum xmittype reliable, const char *header, int stale)
 Respond with authorization request.
static int transmit_response_with_date (struct sip_pvt *p, const char *msg, const struct sip_request *req)
 Append date and content length before transmitting response.
static int transmit_response_with_sdp (struct sip_pvt *p, const char *msg, const struct sip_request *req, enum xmittype reliable)
 Used for 200 OK and 183 early media.
static int transmit_response_with_t38_sdp (struct sip_pvt *p, char *msg, struct sip_request *req, int retrans)
 Used for 200 OK and 183 early media.
static int transmit_response_with_unsupported (struct sip_pvt *p, const char *msg, const struct sip_request *req, const char *unsupported)
 Transmit response, no retransmits.
static int transmit_sip_request (struct sip_pvt *p, struct sip_request *req)
 Transmit SIP request unreliably (only used in sip_notify subsystem).
static int transmit_state_notify (struct sip_pvt *p, int state, int full, int timeout)
 Used in the SUBSCRIBE notification subsystem.
static void try_suggested_sip_codec (struct sip_pvt *p)
 Try setting codec suggested by the SIP_CODEC channel variable.
static int unload_module (void)
 PBX unload module API.
static int update_call_counter (struct sip_pvt *fup, int event)
 update_call_counter: Handle call_limit for SIP users Setting a call-limit will cause calls above the limit not to be accepted.
static void update_peer (struct sip_peer *p, int expiry)
 Update peer data in database (if used).

Variables

static struct in_addr __ourip
static int allow_external_domains
static int apeerobjs = 0
static char * app_dtmfmode = "SIPDtmfMode"
static char * app_sipaddheader = "SIPAddHeader"
static struct sip_authauthl = NULL
static int autocreatepeer
static struct sockaddr_in bindaddr = { 0, }
static struct ast_custom_function checksipdomain_function
static struct ast_cli_entry cli_sip []
static struct ast_cli_entry cli_sip_debug_deprecated
static struct ast_cli_entry cli_sip_no_debug_deprecated
static int compactheaders
static const char config [] = "sip.conf"
static char debug_usage []
static struct sockaddr_in debugaddr
static char default_callerid [AST_MAX_EXTENSION]
static char default_context [AST_MAX_CONTEXT]
static int default_expiry = DEFAULT_DEFAULT_EXPIRY
static char default_fromdomain [AST_MAX_EXTENSION]
static struct ast_jb_conf default_jbconf
 Global jitterbuffer configuration - by default, jb is disabled.
static char default_language [MAX_LANGUAGE]
static int default_maxcallbitrate
static char default_mohinterpret [MAX_MUSICCLASS]
static char default_mohsuggest [MAX_MUSICCLASS]
static char default_notifymime [AST_MAX_EXTENSION]
static struct ast_codec_pref default_prefs
static int default_qualify
static char default_subscribecontext [AST_MAX_CONTEXT]
static char default_vmexten [AST_MAX_EXTENSION]
static char * descrip_dtmfmode = "SIPDtmfMode(inband|info|rfc2833): Changes the dtmfmode for a SIP call\n"
static char * descrip_sipaddheader
static int dumphistory
static int expiry = DEFAULT_EXPIRY
static time_t externexpire = 0
static char externhost [MAXHOSTNAMELEN]
static struct sockaddr_in externip
static int externrefresh = 10
static int global_allowguest
static int global_allowsubscribe
static enum transfermodes global_allowtransfer
static int global_alwaysauthreject
static int global_autoframing
static int global_callevents
static int global_capability = AST_FORMAT_ULAW | AST_FORMAT_ALAW | AST_FORMAT_GSM | AST_FORMAT_H263
 Codecs that we support by default:.
static int global_directrtpsetup
static struct ast_flags global_flags [2] = {{0}}
static struct ast_jb_conf global_jbconf
static int global_limitonpeers
static int global_matchexterniplocally
static int global_mwitime
static int global_notifyhold
static int global_notifyringing
static char global_realm [MAXHOSTNAMELEN]
static int global_reg_timeout
static int global_regattempts_max
static char global_regcontext [AST_MAX_CONTEXT]
static int global_relaxdtmf
static int global_rtautoclear
static int global_rtpholdtimeout
static int global_rtpkeepalive
static int global_rtptimeout
static int global_t1min
static int global_t38_capability = T38FAX_VERSION_0 | T38FAX_RATE_2400 | T38FAX_RATE_4800 | T38FAX_RATE_7200 | T38FAX_RATE_9600
static unsigned int global_tos_audio
static unsigned int global_tos_sip
static unsigned int global_tos_video
static char global_useragent [AST_MAX_EXTENSION]
static char history_usage []
static struct sip_pvtiflist
 sip_pvt: PVT structures are used for each SIP dialog, ie. a call, a registration, a subscribe
static struct io_contextio
static struct ast_halocaladdr
static char mandescr_show_peer []
static char mandescr_show_peers []
static int max_expiry = DEFAULT_MAX_EXPIRY
static int min_expiry = DEFAULT_MIN_EXPIRY
static pthread_t monitor_thread = AST_PTHREADT_NULL
 This is the thread for the monitor which checks for input on the channels which are not currently in use.
static char no_debug_usage []
static char no_history_usage []
static const char notify_config [] = "sip_notify.conf"
static struct ast_confignotify_types
static char notify_usage []
static int ourport
static struct sockaddr_in outboundproxyip
static int pedanticsipchecking
static struct ast_peer_list peerl
 The peer list: Peers and Friends.
static char prune_realtime_usage []
static int recordhistory
static struct c_referstatusstring referstatusstrings []
static struct ast_register_list regl
 The register list: Other SIP proxys we register with and place calls to.
static int regobjs = 0
static int rpeerobjs = 0
static int ruserobjs = 0
static struct sched_contextsched
static char show_channel_usage []
static char show_channels_usage []
static char show_domains_usage []
static char show_history_usage []
static char show_inuse_usage []
static char show_objects_usage []
static char show_peer_usage []
static char show_peers_usage []
static char show_reg_usage []
static char show_settings_usage []
static char show_subscriptions_usage []
static char show_user_usage []
static char show_users_usage []
static struct ast_custom_function sip_header_function
static struct cfsip_methods sip_methods []
static struct cfsip_options sip_options []
 List of well-known SIP options. If we get this in a require, we should check the list and answer accordingly.
static char sip_reload_usage []
static int sip_reloading = FALSE
static enum channelreloadreason sip_reloadreason
static struct ast_rtp_protocol sip_rtp
 Interface structure with callbacks used to connect to RTP module.
static struct ast_channel_tech sip_tech
 Definition of this channel for PBX channel registration.
static struct ast_channel_tech sip_tech_info
 This version of the sip channel tech has no send_digit_begin callback. This is for use with channels using SIP INFO DTMF so that the core knows that the channel doesn't want DTMF BEGIN frames.
static struct ast_udptl_protocol sip_udptl
 Interface structure with callbacks used to connect to UDPTL module.
static struct ast_custom_function sipchaninfo_function
 Structure to declare a dialplan function: SIPCHANINFO.
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 1831 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.

#define CAN_CREATE_DIALOG_UNSUPPORTED_METHOD   2

Definition at line 362 of file chan_sip.c.

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

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

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

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

Referenced by __sip_reliable_xmit(), and retrans_pkt().

#define FLAG_RESPONSE   (1 << 0)

Definition at line 1015 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_HISTORY_ENTRIES   50

Max entires in the history list for a sip_pvt

Definition at line 1013 of file chan_sip.c.

Referenced by append_history_va().

#define MAX_RETRANS   6

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

Definition at line 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 6274 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(), handle_common_options(), reload_config(), sip_get_rtp_peer(), sip_get_udptl_peer(), sip_get_vrtp_peer(), and sip_handle_t38_reinvite().

#define SIP_CAN_REINVITE_NAT   (2 << 20)

allow media reinvite when new peer is behind NAT

Definition at line 738 of file chan_sip.c.

Referenced by handle_common_options(), sip_get_rtp_peer(), and sip_set_rtp_peer().

#define SIP_DEFER_BYE_ON_TRANSFER   (1 << 15)

Do not hangup at first ast_hangup

Definition at line 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 append_history_full(), do_register_auth(), handle_request_bye(), handle_request_invite(), send_request(), send_response(), sip_alloc(), sip_hangup(), sip_new(), sip_reregister(), sip_scheddestroy(), sip_set_rtp_peer(), sipsock_read(), transmit_register(), transmit_reinvite_with_sdp(), and transmit_response_using_temp().

#define SIP_NOVIDEO   (1 << 2)

Didn't get video in invite, don't offer

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

#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(), 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(), 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(), 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 handle_common_options(), transmit_reinvite_with_sdp(), and transmit_reinvite_with_t38_sdp().

#define SIP_RINGING   (1 << 3)

Have sent 180 ringing

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

#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(), 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 1592 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 4144 of file chan_sip.c.

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

04145 {
04146    int pass;
04147 
04148    /*
04149     * Technically you can place arbitrary whitespace both before and after the ':' in
04150     * a header, although RFC3261 clearly says you shouldn't before, and place just
04151     * one afterwards.  If you shouldn't do it, what absolute idiot decided it was 
04152     * a good idea to say you can do it, and if you can do it, why in the hell would.
04153     * you say you shouldn't.
04154     * Anyways, pedanticsipchecking controls whether we allow spaces before ':',
04155     * and we always allow spaces after that for compatibility.
04156     */
04157    for (pass = 0; name && pass < 2;pass++) {
04158       int x, len = strlen(name);
04159       for (x=*start; x<req->headers; x++) {
04160          if (!strncasecmp(req->header[x], name, len)) {
04161             char *r = req->header[x] + len;  /* skip name */
04162             if (pedanticsipchecking)
04163                r = ast_skip_blanks(r);
04164 
04165             if (*r == ':') {
04166                *start = x+1;
04167                return ast_skip_blanks(r+1);
04168             }
04169          }
04170       }
04171       if (pass == 0) /* Try aliases */
04172          name = find_alias(name, NULL);
04173    }
04174 
04175    /* Don't return NULL, so get_header is always a valid pointer */
04176    return "";
04177 }

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

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

02124 {
02125    struct sip_pkt *cur, *prev = NULL;
02126 
02127    /* Just in case... */
02128    char *msg;
02129    int res = FALSE;
02130 
02131    msg = sip_methods[sipmethod].text;
02132 
02133    ast_mutex_lock(&p->lock);
02134    for (cur = p->packets; cur; prev = cur, cur = cur->next) {
02135       if ((cur->seqno == seqno) && ((ast_test_flag(cur, FLAG_RESPONSE)) == resp) &&
02136          ((ast_test_flag(cur, FLAG_RESPONSE)) || 
02137           (!strncasecmp(msg, cur->data, strlen(msg)) && (cur->data[strlen(msg)] < 33)))) {
02138          if (!resp && (seqno == p->pendinginvite)) {
02139             if (option_debug)
02140                ast_log(LOG_DEBUG, "Acked pending invite %d\n", p->pendinginvite);
02141             p->pendinginvite = 0;
02142          }
02143          /* this is our baby */
02144          res = TRUE;
02145          UNLINK(cur, p->packets, prev);
02146          if (cur->retransid > -1) {
02147             if (sipdebug && option_debug > 3)
02148                ast_log(LOG_DEBUG, "** SIP TIMER: Cancelling retransmit of packet (reply received) Retransid #%d\n", cur->retransid);
02149             ast_sched_del(sched, cur->retransid);
02150             cur->retransid = -1;
02151          }
02152          free(cur);
02153          break;
02154       }
02155    }
02156    ast_mutex_unlock(&p->lock);
02157    if (option_debug)
02158       ast_log(LOG_DEBUG, "Stopping retransmission on '%s' of %s %d: Match %s\n", p->callid, resp ? "Response" : "Request", seqno, res ? "Not Found" : "Found");
02159 }

static int __sip_autodestruct ( void *  data  )  [static]

Kill a SIP dialog (called by scheduler).

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

02058 {
02059    struct sip_pvt *p = data;
02060 
02061    /* If this is a subscription, tell the phone that we got a timeout */
02062    if (p->subscribed) {
02063       transmit_state_notify(p, AST_EXTENSION_DEACTIVATED, 1, TRUE);  /* Send last notification */
02064       p->subscribed = NONE;
02065       append_history(p, "Subscribestatus", "timeout");
02066       if (option_debug > 2)
02067          ast_log(LOG_DEBUG, "Re-scheduled destruction of SIP subsription %s\n", p->callid ? p->callid : "<unknown>");
02068       return 10000;  /* Reschedule this destruction so that we know that it's gone */
02069    }
02070 
02071    /* If we're destroying a subscription, dereference peer object too */
02072    if (p->subscribed == MWI_NOTIFICATION && p->relatedpeer)
02073       ASTOBJ_UNREF(p->relatedpeer,sip_destroy_peer);
02074 
02075    /* Reset schedule ID */
02076    p->autokillid = -1;
02077 
02078    if (option_debug)
02079       ast_log(LOG_DEBUG, "Auto destroying SIP dialog '%s'\n", p->callid);
02080    append_history(p, "AutoDestroy", "%s", p->callid);
02081    if (p->owner) {
02082       ast_log(LOG_WARNING, "Autodestruct on dialog '%s' with owner in place (Method: %s)\n", p->callid, sip_methods[p->method].text);
02083       ast_queue_hangup(p->owner);
02084    } else if (p->refer) {
02085       if (option_debug > 2)
02086          ast_log(LOG_DEBUG, "Finally hanging up channel after transfer: %s\n", p->callid);
02087       transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, 1);
02088       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
02089    } else
02090       sip_destroy(p);
02091    return 0;
02092 }

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

Execute destruction of SIP dialog structure, release memory.

Definition at line 3011 of file chan_sip.c.

References ast_channel_lock, ast_channel_unlock, ast_extension_state_del(), AST_LIST_REMOVE_HEAD, ast_log(), ast_rtp_destroy(), ast_sched_del(), ast_test_flag, ast_udptl_destroy(), ast_verbose(), ASTOBJ_UNREF, DEC_CALL_LIMIT, sip_pvt::flags, free, free_old_route(), iflist, LOG_DEBUG, sip_pvt::method, sip_peer::mwipvt, sip_pvt::next, option_debug, sip_pvt::relatedpeer, sip_pkt::retransid, sched, sip_debug_test_pvt(), sip_dump_history(), SIP_INC_COUNT, sip_methods, SIP_PAGE2_CALL_ONHOLD, sip_registry_destroy(), cfsip_methods::text, UNLINK, and update_call_counter().

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

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

static int __sip_do_register ( struct sip_registry r  )  [static]

Register with SIP proxy.

Definition at line 7311 of file chan_sip.c.

References SIP_REGISTER, and transmit_register().

Referenced by sip_reregister().

07312 {
07313    int res;
07314 
07315    res = transmit_register(r, SIP_REGISTER, NULL, NULL);
07316    return res;
07317 }

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

02164 {
02165    struct sip_pkt *cur = NULL;
02166 
02167    while (p->packets) {
02168       int method;
02169       if (cur == p->packets) {
02170          ast_log(LOG_WARNING, "Have a packet that doesn't want to give up! %s\n", sip_methods[cur->method].text);
02171          return;
02172       }
02173       cur = p->packets;
02174       method = (cur->method) ? cur->method : find_sip_method(cur->data);
02175       __sip_ack(p, cur->seqno, ast_test_flag(cur, FLAG_RESPONSE), method);
02176    }
02177 }

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

Referenced by send_request(), and send_response().

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

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

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

Referenced by handle_response().

02181 {
02182    struct sip_pkt *cur;
02183    int res = -1;
02184 
02185    for (cur = p->packets; cur; cur = cur->next) {
02186       if (cur->seqno == seqno && ast_test_flag(cur, FLAG_RESPONSE) == resp &&
02187          (ast_test_flag(cur, FLAG_RESPONSE) || method_match(sipmethod, cur->data))) {
02188          /* this is our baby */
02189          if (cur->retransid > -1) {
02190             if (option_debug > 3 && sipdebug)
02191                ast_log(LOG_DEBUG, "*** SIP TIMER: Cancelling retransmission #%d - %s (got response)\n", cur->retransid, sip_methods[sipmethod].text);
02192             ast_sched_del(sched, cur->retransid);
02193             cur->retransid = -1;
02194          }
02195          res = 0;
02196          break;
02197       }
02198    }
02199    if (option_debug)
02200       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");
02201    return res;
02202 }

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

SIP show channels CLI (main function).

Definition at line 10595 of file chan_sip.c.

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

Referenced by sip_show_channels(), and sip_show_subscriptions().

10596 {
10597 #define FORMAT3 "%-15.15s  %-10.10s  %-11.11s  %-15.15s  %-13.13s  %-15.15s %-10.10s\n"
10598 #define FORMAT2 "%-15.15s  %-10.10s  %-11.11s  %-11.11s  %-4.4s  %-7.7s  %-15.15s\n"
10599 #define FORMAT  "%-15.15s  %-10.10s  %-11.11s  %5.5d/%5.5d  %-4.4s  %-3.3s %-3.3s  %-15.15s %-10.10s\n"
10600    struct sip_pvt *cur;
10601    int numchans = 0;
10602    char *referstatus = NULL;
10603 
10604    if (argc != 3)
10605       return RESULT_SHOWUSAGE;
10606    ast_mutex_lock(&iflock);
10607    cur = iflist;
10608    if (!subscriptions)
10609       ast_cli(fd, FORMAT2, "Peer", "User/ANR", "Call ID", "Seq (Tx/Rx)", "Format", "Hold", "Last Message");
10610    else 
10611       ast_cli(fd, FORMAT3, "Peer", "User", "Call ID", "Extension", "Last state", "Type", "Mailbox");
10612    for (; cur; cur = cur->next) {
10613       referstatus = "";
10614       if (cur->refer) { /* SIP transfer in progress */
10615          referstatus = referstatus2str(cur->refer->status);
10616       }
10617       if (cur->subscribed == NONE && !subscriptions) {
10618          ast_cli(fd, FORMAT, ast_inet_ntoa(cur->sa.sin_addr), 
10619             S_OR(cur->username, S_OR(cur->cid_num, "(None)")),
10620             cur->callid, 
10621             cur->ocseq, cur->icseq, 
10622             ast_getformatname(cur->owner ? cur->owner->nativeformats : 0), 
10623             ast_test_flag(&cur->flags[1], SIP_PAGE2_CALL_ONHOLD) ? "Yes" : "No",
10624             ast_test_flag(&cur->flags[0], SIP_NEEDDESTROY) ? "(d)" : "",
10625             cur->lastmsg ,
10626             referstatus
10627          );
10628          numchans++;
10629       }
10630       if (cur->subscribed != NONE && subscriptions) {
10631          ast_cli(fd, FORMAT3, ast_inet_ntoa(cur->sa.sin_addr),
10632             S_OR(cur->username, S_OR(cur->cid_num, "(None)")), 
10633                cur->callid,
10634             /* the 'complete' exten/context is hidden in the refer_to field for subscriptions */
10635             cur->subscribed == MWI_NOTIFICATION ? "--" : cur->subscribeuri,
10636             cur->subscribed == MWI_NOTIFICATION ? "<none>" : ast_extension_state2str(cur->laststate), 
10637             subscription_type2str(cur->subscribed),
10638             cur->subscribed == MWI_NOTIFICATION ? (cur->relatedpeer ? cur->relatedpeer->mailbox : "<none>") : "<none>"
10639 );
10640          numchans++;
10641       }
10642    }
10643    ast_mutex_unlock(&iflock);
10644    if (!subscriptions)
10645       ast_cli(fd, "%d active SIP channel%s\n", numchans, (numchans != 1) ? "s" : "");
10646    else
10647       ast_cli(fd, "%d active SIP subscription%s\n", numchans, (numchans != 1) ? "s" : "");
10648    return RESULT_SUCCESS;
10649 #undef FORMAT
10650 #undef FORMAT2
10651 #undef FORMAT3
10652 }

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

Transmit SIP message.

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

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

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

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

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

05875 {
05876    struct sip_request resp;
05877    int seqno = 0;
05878 
05879    if (reliable && (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1)) {
05880       ast_log(LOG_WARNING, "Unable to determine sequence number from '%s'\n", get_header(req, "CSeq"));
05881       return -1;
05882    }
05883    respprep(&resp, p, msg, req);
05884    add_header_contentLength(&resp, 0);
05885    /* If we are cancelling an incoming invite for some reason, add information
05886       about the reason why we are doing this in clear text */
05887    if (p->method == SIP_INVITE && msg[0] != '1' && p->owner && p->owner->hangupcause) {
05888       char buf[10];
05889 
05890       add_header(&resp, "X-Asterisk-HangupCause", ast_cause2str(p->owner->hangupcause));
05891       snprintf(buf, sizeof(buf), "%d", p->owner->hangupcause);
05892       add_header(&resp, "X-Asterisk-HangupCauseCode", buf);
05893    }
05894    return send_response(p, &resp, reliable, seqno);
05895 }

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

References sip_peer::accountcode, sip_peer::addr, sip_peer::allowtransfer, sip_peer::amaflags, ast_callerid_merge(), ast_cdr_flags2str(), ast_check_realtime(), ast_cli(), ast_codec_pref_index(), ast_describe_caller_presentation(), ast_getformatname(), ast_getformatname_multiple(), ast_inet_ntoa(), ast_print_group(), ast_sched_when(), ast_strlen_zero(), ast_test_flag, astman_append(), astman_get_header(), astman_send_error(), ASTOBJ_UNREF, sip_peer::auth, sip_peer::autoframing, sip_peer::call_limit, sip_peer::callgroup, sip_peer::callingpres, sip_peer::capability, sip_peer::chanvars, sip_peer::cid_name, sip_peer::cid_num, sip_peer::context, sip_peer::defaddr, dtmfmode2str(), sip_peer::expire, FALSE, find_peer(), sip_peer::flags, sip_peer::fromdomain, sip_peer::fromuser, sip_peer::fullcontact, sip_peer::ha, insecure2str(), sip_peer::language, sip_peer::lastmsg, sip_peer::lastmsgssent, sip_peer::mailbox, sip_peer::maxcallbitrate, sip_auth::md5secret, sip_peer::md5secret, ast_variable::name, nat2str(), ast_variable::next, sip_auth::next, peer_status(), sip_peer::pickupgroup, sip_peer::prefs, print_codec_to_cli(), print_group(), sip_auth::realm, sip_peer::regexten, RESULT_SHOWUSAGE, RESULT_SUCCESS, s, S_OR, sched, sip_auth::secret, sip_peer::secret, SIP_CAN_REINVITE, sip_destroy_peer(), SIP_DTMF, SIP_INSECURE_INVITE, SIP_INSECURE_PORT, SIP_NAT, sip_options, SIP_PAGE2_ALLOWOVERLAP, SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PAGE2_DYNAMIC, SIP_PAGE2_T38SUPPORT_RTP, SIP_PAGE2_T38SUPPORT_TCP, SIP_PAGE2_T38SUPPORT_UDPTL, SIP_PAGE2_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().

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

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

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

Referenced by manager_sip_show_peers(), and sip_show_peers().

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

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

Definition at line 14376 of file chan_sip.c.

References AST_APP_ARG, AST_DECLARE_APP_ARGS, ast_log(), ast_rtp_get_quality(), AST_STANDARD_APP_ARGS, ast_strdupa, ast_strlen_zero(), LOG_ERROR, parse(), sip_pvt::rtp, sip_tech, sip_tech_info, ast_channel::tech, ast_channel::tech_pvt, type, and sip_pvt::vrtp.

14377 {
14378    struct ast_rtp_quality qos;
14379    struct sip_pvt *p = chan->tech_pvt;
14380    char *all = "", *parse = ast_strdupa(preparse);
14381    AST_DECLARE_APP_ARGS(args,
14382       AST_APP_ARG(param);
14383       AST_APP_ARG(type);
14384       AST_APP_ARG(field);
14385    );
14386    AST_STANDARD_APP_ARGS(args, parse);
14387 
14388    /* Sanity check */
14389    if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) {
14390       ast_log(LOG_ERROR, "Cannot call %s on a non-SIP channel\n", funcname);
14391       return 0;
14392    }
14393 
14394    if (strcasecmp(args.param, "rtpqos"))
14395       return 0;
14396 
14397    /* Default arguments of audio,all */
14398    if (ast_strlen_zero(args.type))
14399       args.type = "audio";
14400    if (ast_strlen_zero(args.field))
14401       args.field = "all";
14402 
14403    memset(buf, 0, buflen);
14404    memset(&qos, 0, sizeof(qos));
14405 
14406    if (strcasecmp(args.type, "AUDIO") == 0) {
14407       all = ast_rtp_get_quality(p->rtp, &qos);
14408    } else if (strcasecmp(args.type, "VIDEO") == 0) {
14409       all = ast_rtp_get_quality(p->vrtp, &qos);
14410    }
14411 
14412    if (strcasecmp(args.field, "local_ssrc") == 0)
14413       snprintf(buf, buflen, "%u", qos.local_ssrc);
14414    else if (strcasecmp(args.field, "local_lostpackets") == 0)
14415       snprintf(buf, buflen, "%u", qos.local_lostpackets);
14416    else if (strcasecmp(args.field, "local_jitter") == 0)
14417       snprintf(buf, buflen, "%.0lf", qos.local_jitter * 1000.0);
14418    else if (strcasecmp(args.field, "local_count") == 0)
14419       snprintf(buf, buflen, "%u", qos.local_count);
14420    else if (strcasecmp(args.field, "remote_ssrc") == 0)
14421       snprintf(buf, buflen, "%u", qos.remote_ssrc);
14422    else if (strcasecmp(args.field, "remote_lostpackets") == 0)
14423       snprintf(buf, buflen, "%u", qos.remote_lostpackets);
14424    else if (strcasecmp(args.field, "remote_jitter") == 0)
14425       snprintf(buf, buflen, "%.0lf", qos.remote_jitter * 1000.0);
14426    else if (strcasecmp(args.field, "remote_count") == 0)
14427       snprintf(buf, buflen, "%u", qos.remote_count);
14428    else if (strcasecmp(args.field, "rtt") == 0)
14429       snprintf(buf, buflen, "%.0lf", qos.rtt * 1000.0);
14430    else if (strcasecmp(args.field, "all") == 0)
14431       ast_copy_string(buf, all, buflen);
14432    else {
14433       ast_log(LOG_WARNING, "Unrecognized argument '%s' to %s\n", preparse, funcname);
14434       return -1;
14435    }
14436    return 0;
14437 }

static void add_blank ( struct sip_request req  )  [static]

add a blank line if no body

Definition at line 2215 of file chan_sip.c.

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

Referenced by send_request(), and send_response().

02216 {
02217    if (!req->lines) {
02218       /* Add extra empty return. add_header() reserves 4 bytes so cannot be truncated */
02219       snprintf(req->data + req->len, sizeof(req->data) - req->len, "\r\n");
02220       req->len += strlen(req->data + req->len);
02221    }
02222 }

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

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

Referenced by add_sdp().

06081 {
06082    int rtp_code;
06083    struct ast_format_list fmt;
06084 
06085 
06086    if (debug)
06087       ast_verbose("Adding codec 0x%x (%s) to SDP\n", codec, ast_getformatname(codec));
06088    if ((rtp_code = ast_rtp_lookup_code(p->rtp, 1, codec)) == -1)
06089       return;
06090 
06091    if (p->rtp) {
06092       struct ast_codec_pref *pref = ast_rtp_codec_getpref(p->rtp);
06093       fmt = ast_codec_pref_getsize(pref, codec);
06094    } 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 */
06095       return;
06096    ast_build_string(m_buf, m_size, " %d", rtp_code);
06097    ast_build_string(a_buf, a_size, "a=rtpmap:%d %s/%d\r\n", rtp_code,
06098           ast_rtp_lookup_mime_subtype(1, codec,
06099                        ast_test_flag(&p->flags[0], SIP_G726_NONSTANDARD) ? AST_RTP_OPT_G726_NONSTANDARD : 0),
06100           sample_rate);
06101    if (codec == AST_FORMAT_G729A) {
06102       /* Indicate that we don't support VAD (G.729 annex B) */
06103       ast_build_string(a_buf, a_size, "a=fmtp:%d annexb=no\r\n", rtp_code);
06104    } else if (codec == AST_FORMAT_G723_1) {
06105       /* Indicate that we don't support VAD (G.723.1 annex A) */
06106       ast_build_string(a_buf, a_size, "a=fmtp:%d annexa=no\r\n", rtp_code);
06107    } else if (codec == AST_FORMAT_ILBC) {
06108       /* Add information about us using only 20/30 ms packetization */
06109       ast_build_string(a_buf, a_size, "a=fmtp:%d mode=%d\r\n", rtp_code, fmt.cur_ms);
06110    }
06111 
06112    if (fmt.cur_ms && (fmt.cur_ms < *min_packet_size))
06113       *min_packet_size = fmt.cur_ms;
06114 
06115    /* Our first codec packetization processed cannot be less than zero */
06116    if ((*min_packet_size) == 0  && fmt.cur_ms)
06117       *min_packet_size = fmt.cur_ms;
06118 }

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

Add DTMF INFO tone to sip message.

Definition at line 6046 of file chan_sip.c.

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

Referenced by transmit_info_with_digit().

06047 {
06048    char tmp[256];
06049 
06050    snprintf(tmp, sizeof(tmp), "Signal=%c\r\nDuration=%u\r\n", digit, duration);
06051    add_header(req, "Content-Type", "application/dtmf-relay");
06052    add_header_contentLength(req, strlen(tmp));
06053    add_line(req, tmp);
06054    return 0;
06055 }

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

Add header to SIP message.

Definition at line 5437 of file chan_sip.c.

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

05438 {
05439    int maxlen = sizeof(req->data) - 4 - req->len; /* 4 bytes are for two \r\n ? */
05440 
05441    if (req->headers == SIP_MAX_HEADERS) {
05442       ast_log(LOG_WARNING, "Out of SIP header space\n");
05443       return -1;
05444    }
05445 
05446    if (req->lines) {
05447       ast_log(LOG_WARNING, "Can't add more headers when lines have been added\n");
05448       return -1;
05449    }
05450 
05451    if (maxlen <= 0) {
05452       ast_log(LOG_WARNING, "Out of space, can't add anymore (%s:%s)\n", var, value);
05453       return -1;
05454    }
05455 
05456    req->header[req->headers] = req->data + req->len;
05457 
05458    if (compactheaders)
05459       var = find_alias(var, var);
05460 
05461    snprintf(req->header[req->headers], maxlen, "%s: %s\r\n", var, value);
05462    req->len += strlen(req->header[req->headers]);
05463    req->headers++;
05464    if (req->headers < SIP_MAX_HEADERS)
05465       req->headers++;
05466    else
05467       ast_log(LOG_WARNING, "Out of SIP header space... Will generate broken SIP message\n");
05468 
05469    return 0;   
05470 }

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

Add 'Content-Length' header to SIP message.

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

05474 {
05475    char clen[10];
05476 
05477    snprintf(clen, sizeof(clen), "%d", len);
05478    return add_header(req, "Content-Length", clen);
05479 }

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

Add content (not header) to SIP message.

Definition at line 5482 of file chan_sip.c.

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

05483 {
05484    if (req->lines == SIP_MAX_LINES)  {
05485       ast_log(LOG_WARNING, "Out of SIP line space\n");
05486       return -1;
05487    }
05488    if (!req->lines) {
05489       /* Add extra empty return */
05490       snprintf(req->data + req->len, sizeof(req->data) - req->len, "\r\n");
05491       req->len += strlen(req->data + req->len);
05492    }
05493    if (req->len >= sizeof(req->data) - 4) {
05494       ast_log(LOG_WARNING, "Out of space, can't add anymore\n");
05495       return -1;
05496    }
05497    req->line[req->lines] = req->data + req->len;
05498    snprintf(req->line[req->lines], sizeof(req->data) - req->len, "%s", line);
05499    req->len += strlen(req->line[req->lines]);
05500    req->lines++;
05501    return 0;   
05502 }

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

06257 {
06258    int rtp_code;
06259 
06260    if (debug)
06261       ast_verbose("Adding non-codec 0x%x (%s) to SDP\n", format, ast_rtp_lookup_mime_subtype(0, format, 0));
06262    if ((rtp_code = ast_rtp_lookup_code(p->rtp, 0, format)) == -1)
06263       return;
06264 
06265    ast_build_string(m_buf, m_size, " %d", rtp_code);
06266    ast_build_string(a_buf, a_size, "a=rtpmap:%d %s/%d\r\n", rtp_code,
06267           ast_rtp_lookup_mime_subtype(0, format, 0),
06268           sample_rate);
06269    if (format == AST_RTP_DTMF)
06270       /* Indicate we support DTMF and FLASH... */
06271       ast_build_string(a_buf, a_size, "a=fmtp:%d 0-16\r\n", rtp_code);
06272 }

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

Add realm authentication in list.

Definition at line 15953 of file chan_sip.c.

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

Referenced by build_peer().

15954 {
15955    char authcopy[256];
15956    char *username=NULL, *realm=NULL, *secret=NULL, *md5secret=NULL;
15957    char *stringp;
15958    struct sip_auth *a, *b, *auth;
15959 
15960    if (ast_strlen_zero(configuration))
15961       return authlist;
15962 
15963    if (option_debug)
15964       ast_log(LOG_DEBUG, "Auth config ::  %s\n", configuration);
15965 
15966    ast_copy_string(authcopy, configuration, sizeof(authcopy));
15967    stringp = authcopy;
15968 
15969    username = stringp;
15970    realm = strrchr(stringp, '@');
15971    if (realm)
15972       *realm++ = '\0';
15973    if (ast_strlen_zero(username) || ast_strlen_zero(realm)) {
15974       ast_log(LOG_WARNING, "Format for authentication entry is user[:secret]@realm at line %d\n", lineno);
15975       return authlist;
15976    }
15977    stringp = username;
15978    username = strsep(&stringp, ":");
15979    if (username) {
15980       secret = strsep(&stringp, ":");
15981       if (!secret) {
15982          stringp = username;
15983          md5secret = strsep(&stringp,"#");
15984       }
15985    }
15986    if (!(auth = ast_calloc(1, sizeof(*auth))))
15987       return authlist;
15988 
15989    ast_copy_string(auth->realm, realm, sizeof(auth->realm));
15990    ast_copy_string(auth->username, username, sizeof(auth->username));
15991    if (secret)
15992       ast_copy_string(auth->secret, secret, sizeof(auth->secret));
15993    if (md5secret)
15994       ast_copy_string(auth->md5secret, md5secret, sizeof(auth->md5secret));
15995 
15996    /* find the end of the list */
15997    for (b = NULL, a = authlist; a ; b = a, a = a->next)
15998       ;
15999    if (b)
16000       b->next = auth;   /* Add structure add end of list */
16001    else
16002       authlist = auth;
16003 
16004    if (option_verbose > 2)
16005       ast_verbose("Added authentication for realm %s\n", realm);
16006 
16007    return authlist;
16008 
16009 }

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

Add route header into request per learned route.

Definition at line 5603 of file chan_sip.c.

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

Referenced by reqprep().

05604 {
05605    char r[BUFSIZ*2], *p;
05606    int n, rem = sizeof(r);
05607 
05608    if (!route)
05609       return;
05610 
05611    p = r;
05612    for (;route ; route = route->next) {
05613       n = strlen(route->hop);
05614       if (rem < n+3) /* we need room for ",<route>" */
05615          break;
05616       if (p != r) {  /* add a separator after fist route */
05617          *p++ = ',';
05618          --rem;
05619       }
05620       *p++ = '<';
05621       ast_copy_string(p, route->hop, rem); /* cannot fail */
05622       p += n;
05623       *p++ = '>';
05624       rem -= (n+2);
05625    }
05626    *p = '\0';
05627    add_header(req, "Route", r);
05628 }

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

Add Session Description Protocol message.

Definition at line 6277 of file chan_sip.c.

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

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

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

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

15890 {
15891    struct domain *d;
15892 
15893    if (ast_strlen_zero(domain)) {
15894       ast_log(LOG_WARNING, "Zero length domain.\n");
15895       return 1;
15896    }
15897 
15898    if (!(d = ast_calloc(1, sizeof(*d))))
15899       return 0;
15900 
15901    ast_copy_string(d->domain, domain, sizeof(d->domain));
15902 
15903    if (!ast_strlen_zero(context))
15904       ast_copy_string(d->context, context, sizeof(d->context));
15905 
15906    d->mode = mode;
15907 
15908    AST_LIST_LOCK(&domain_list);
15909    AST_LIST_INSERT_TAIL(&domain_list, d, list);
15910    AST_LIST_UNLOCK(&domain_list);
15911 
15912    if (sipdebug)  
15913       ast_log(LOG_DEBUG, "Added local SIP domain '%s'\n", domain);
15914 
15915    return 1;
15916 }

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

Add T.38 Session Description Protocol message.

Definition at line 6157 of file chan_sip.c.

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

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

06158 {
06159    int len = 0;
06160    int x = 0;
06161    struct sockaddr_in udptlsin;
06162    char v[256] = "";
06163    char s[256] = "";
06164    char o[256] = "";
06165    char c[256] = "";
06166    char t[256] = "";
06167    char m_modem[256];
06168    char a_modem[1024];
06169    char *m_modem_next = m_modem;
06170    size_t m_modem_left = sizeof(m_modem);
06171    char *a_modem_next = a_modem;
06172    size_t a_modem_left = sizeof(a_modem);
06173    struct sockaddr_in udptldest = { 0, };
06174    int debug;
06175    
06176    debug = sip_debug_test_pvt(p);
06177    len = 0;
06178    if (!p->udptl) {
06179       ast_log(LOG_WARNING, "No way to add SDP without an UDPTL structure\n");
06180       return -1;
06181    }
06182    
06183    if (!p->sessionid) {
06184       p->sessionid = getpid();
06185       p->sessionversion = p->sessionid;
06186    } else
06187       p->sessionversion++;
06188    
06189    /* Our T.38 end is */
06190    ast_udptl_get_us(p->udptl, &udptlsin);
06191    
06192    /* Determine T.38 UDPTL destination */
06193    if (p->udptlredirip.sin_addr.s_addr) {
06194       udptldest.sin_port = p->udptlredirip.sin_port;
06195       udptldest.sin_addr = p->udptlredirip.sin_addr;
06196    } else {
06197       udptldest.sin_addr = p->ourip;
06198       udptldest.sin_port = udptlsin.sin_port;
06199    }
06200    
06201    if (debug) 
06202       ast_log(LOG_DEBUG, "T.38 UDPTL is at %s port %d\n", ast_inet_ntoa(p->ourip), ntohs(udptlsin.sin_port));
06203    
06204    /* We break with the "recommendation" and send our IP, in order that our
06205       peer doesn't have to ast_gethostbyname() us */
06206    
06207    if (debug) {
06208       ast_log(LOG_DEBUG, "Our T38 capability (%d), peer T38 capability (%d), joint capability (%d)\n",
06209          p->t38.capability,
06210          p->t38.peercapability,
06211          p->t38.jointcapability);
06212    }
06213    snprintf(v, sizeof(v), "v=0\r\n");
06214    snprintf(o, sizeof(o), "o=root %d %d IN IP4 %s\r\n", p->sessionid, p->sessionversion, ast_inet_ntoa(udptldest.sin_addr));
06215    snprintf(s, sizeof(s), "s=session\r\n");
06216    snprintf(c, sizeof(c), "c=IN IP4 %s\r\n", ast_inet_ntoa(udptldest.sin_addr));
06217    snprintf(t, sizeof(t), "t=0 0\r\n");
06218    ast_build_string(&m_modem_next, &m_modem_left, "m=image %d udptl t38\r\n", ntohs(udptldest.sin_port));
06219    
06220    if ((p->t38.jointcapability & T38FAX_VERSION) == T38FAX_VERSION_0)
06221       ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxVersion:0\r\n");
06222    if ((p->t38.jointcapability & T38FAX_VERSION) == T38FAX_VERSION_1)
06223       ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxVersion:1\r\n");
06224    if ((x = t38_get_rate(p->t38.jointcapability)))
06225       ast_build_string(&a_modem_next, &a_modem_left, "a=T38MaxBitRate:%d\r\n",x);
06226    ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxFillBitRemoval:%d\r\n", (p->t38.jointcapability & T38FAX_FILL_BIT_REMOVAL) ? 1 : 0);
06227    ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxTranscodingMMR:%d\r\n", (p->t38.jointcapability & T38FAX_TRANSCODING_MMR) ? 1 : 0);
06228    ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxTranscodingJBIG:%d\r\n", (p->t38.jointcapability & T38FAX_TRANSCODING_JBIG) ? 1 : 0);
06229    ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxRateManagement:%s\r\n", (p->t38.jointcapability & T38FAX_RATE_MANAGEMENT_LOCAL_TCF) ? "localTCF" : "transferredTCF");
06230    x = ast_udptl_get_local_max_datagram(p->udptl);
06231    ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxMaxBuffer:%d\r\n",x);
06232    ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxMaxDatagram:%d\r\n",x);
06233    if (p->t38.jointcapability != T38FAX_UDP_EC_NONE)
06234       ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxUdpEC:%s\r\n", (p->t38.jointcapability & T38FAX_UDP_EC_REDUNDANCY) ? "t38UDPRedundancy" : "t38UDPFEC");
06235    len = strlen(v) + strlen(s) + strlen(o) + strlen(c) + strlen(t) + strlen(m_modem) + strlen(a_modem);
06236    add_header(resp, "Content-Type", "application/sdp");
06237    add_header_contentLength(resp, len);
06238    add_line(resp, v);
06239    add_line(resp, o);
06240    add_line(resp, s);
06241    add_line(resp, c);
06242    add_line(resp, t);
06243    add_line(resp, m_modem);
06244    add_line(resp, a_modem);
06245    
06246    /* Update lastrtprx when we send our SDP */
06247    p->lastrtprx = p->lastrtptx = time(NULL);
06248    
06249    return 0;
06250 }

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

Add text body to SIP message.

Definition at line 6035 of file chan_sip.c.

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

Referenced by transmit_message_with_text().

06036 {
06037    /* XXX Convert \n's to \r\n's XXX */
06038    add_header(req, "Content-Type", "text/plain");
06039    add_header_contentLength(req, strlen(text));
06040    add_line(req, text);
06041    return 0;
06042 }

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

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

Referenced by transmit_info_with_vidupdate().

06060 {
06061    const char *xml_is_a_huge_waste_of_space =
06062       "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\r\n"
06063       " <media_control>\r\n"
06064       "  <vc_primitive>\r\n"
06065       "   <to_encoder>\r\n"
06066       "    <picture_fast_update>\r\n"
06067       "    </picture_fast_update>\r\n"
06068       "   </to_encoder>\r\n"
06069       "  </vc_primitive>\r\n"
06070       " </media_control>\r\n";
06071    add_header(req, "Content-Type", "application/media_control+xml");
06072    add_header_contentLength(req, strlen(xml_is_a_huge_waste_of_space));
06073    add_line(req, xml_is_a_huge_waste_of_space);
06074    return 0;
06075 }

static void append_date ( struct sip_request req  )  [static]

Append date to SIP message.

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

05983 {
05984    char tmpdat[256];
05985    struct tm tm;
05986    time_t t = time(NULL);
05987 
05988    gmtime_r(&t, &tm);
05989    strftime(tmpdat, sizeof(tmpdat), "%a, %d %b %Y %T GMT", &tm);
05990    add_header(req, "Date", tmpdat);
05991 }

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

Append to SIP dialog history with arg list.

Definition at line 1864 of file chan_sip.c.

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

01865 {
01866    va_list ap;
01867 
01868    if (!p)
01869       return;
01870 
01871    if (ast_test_flag(&p->flags[0], SIP_NO_HISTORY) 
01872       && !recordhistory && !dumphistory) {
01873       return;
01874    }
01875 
01876    va_start(ap, fmt);
01877    append_history_va(p, fmt, ap);
01878    va_end(ap);
01879 
01880    return;
01881 }

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

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

Referenced by append_history_full().

01838 {
01839    char buf[80], *c = buf; /* max history length */
01840    struct sip_history *hist;
01841    int l;
01842 
01843    vsnprintf(buf, sizeof(buf), fmt, ap);
01844    strsep(&c, "\r\n"); /* Trim up everything after \r or \n */
01845    l = strlen(buf) + 1;
01846    if (!(hist = ast_calloc(1, sizeof(*hist) + l)))
01847       return;
01848    if (!p->history && !(p->history = ast_calloc(1, sizeof(*p->history)))) {
01849       free(hist);
01850       return;
01851    }
01852    memcpy(hist->event, buf, l);
01853    if (p->history_entries == MAX_HISTORY_ENTRIES) {
01854       struct sip_history *oldest;
01855       oldest = AST_LIST_REMOVE_HEAD(p->history, list);
01856       p->history_entries--;
01857       free(oldest);
01858    }
01859    AST_LIST_INSERT_TAIL(p->history, hist, list);
01860    p->history_entries++;
01861 }

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

12947 {
12948    if (chan && chan->_state == AST_STATE_UP) {
12949       if (chan->generatordata)
12950          ast_deactivate_generator(chan);
12951    }
12952 }

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

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

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

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

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 12956 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(), sip_dual::chan1, sip_dual::chan2, LOG_DEBUG, LOG_NOTICE, and option_debug.

12957 {
12958    int res = 0;
12959    struct ast_channel *peera = NULL,   
12960       *peerb = NULL,
12961       *peerc = NULL,
12962       *peerd = NULL;
12963 
12964 
12965    /* We will try to connect the transferee with the target and hangup
12966       all channels to the transferer */   
12967    if (option_debug > 3) {
12968       ast_log(LOG_DEBUG, "Sip transfer:--------------------\n");
12969       if (transferer->chan1)
12970          ast_log(LOG_DEBUG, "-- Transferer to PBX channel: %s State %s\n", transferer->chan1->name, ast_state2str(transferer->chan1->_state));
12971       else
12972          ast_log(LOG_DEBUG, "-- No transferer first channel - odd??? \n");
12973       if (target->chan1)
12974          ast_log(LOG_DEBUG, "-- Transferer to PBX second channel (target): %s State %s\n", target->chan1->name, ast_state2str(target->chan1->_state));
12975       else
12976          ast_log(LOG_DEBUG, "-- No target first channel ---\n");
12977       if (transferer->chan2)
12978          ast_log(LOG_DEBUG, "-- Bridged call to transferee: %s State %s\n", transferer->chan2->name, ast_state2str(transferer->chan2->_state));
12979       else
12980          ast_log(LOG_DEBUG, "-- No bridged call to transferee\n");
12981       if (target->chan2)
12982          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)");
12983       else
12984          ast_log(LOG_DEBUG, "-- No target second channel ---\n");
12985       ast_log(LOG_DEBUG, "-- END Sip transfer:--------------------\n");
12986    }
12987    if (transferer->chan2) { /* We have a bridge on the transferer's channel */
12988       peera = transferer->chan1; /* Transferer - PBX -> transferee channel * the one we hangup */
12989       peerb = target->chan1;     /* Transferer - PBX -> target channel - This will get lost in masq */
12990       peerc = transferer->chan2; /* Asterisk to Transferee */
12991       peerd = target->chan2;     /* Asterisk to Target */
12992       if (option_debug > 2)
12993          ast_log(LOG_DEBUG, "SIP transfer: Four channels to handle\n");
12994    } else if (target->chan2) {   /* Transferer has no bridge (IVR), but transferee */
12995       peera = target->chan1;     /* Transferer to PBX -> target channel */
12996       peerb = transferer->chan1; /* Transferer to IVR*/
12997       peerc = target->chan2;     /* Asterisk to Target */
12998       peerd = transferer->chan2; /* Nothing */
12999       if (option_debug > 2)
13000          ast_log(LOG_DEBUG, "SIP transfer: Three channels to handle\n");
13001    }
13002 
13003    if (peera && peerb && peerc && (peerb != peerc)) {
13004       ast_quiet_chan(peera);     /* Stop generators */
13005       ast_quiet_chan(peerb);  
13006       ast_quiet_chan(peerc);
13007       if (peerd)
13008          ast_quiet_chan(peerd);
13009 
13010       /* Fix CDRs so they're attached to the remaining channel */
13011       if (peera->cdr && peerb->cdr)
13012          peerb->cdr = ast_cdr_append(peerb->cdr, peera->cdr);
13013       else if (peera->cdr) 
13014          peerb->cdr = peera->cdr;
13015       peera->cdr = NULL;
13016 
13017       if (peerb->cdr && peerc->cdr) 
13018          peerb->cdr = ast_cdr_append(peerb->cdr, peerc->cdr);
13019       else if (peerc->cdr)
13020          peerb->cdr = peerc->cdr;
13021       peerc->cdr = NULL;
13022    
13023       if (option_debug > 3)
13024          ast_log(LOG_DEBUG, "SIP transfer: trying to masquerade %s into %s\n", peerc->name, peerb->name);
13025       if (ast_channel_masquerade(peerb, peerc)) {
13026          ast_log(LOG_WARNING, "Failed to masquerade %s into %s\n", peerb->name, peerc->name);
13027          res = -1;
13028       } else
13029          ast_log(LOG_DEBUG, "SIP transfer: Succeeded to masquerade channels.\n");
13030       return res;
13031    } else {
13032       ast_log(LOG_NOTICE, "SIP Transfer attempted with no appropriate bridged calls to transfer\n");
13033       if (transferer->chan1)
13034          ast_softhangup_nolock(transferer->chan1, AST_SOFTHANGUP_DEV);
13035       if (target->chan1)
13036          ast_softhangup_nolock(target->chan1, AST_SOFTHANGUP_DEV);
13037       return -2;
13038    }
13039    return 0;
13040 }

static int auto_congest ( void *  nothing  )  [static]

Scheduled congestion on a call.

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

02872 {
02873    struct sip_pvt *p = nothing;
02874 
02875    ast_mutex_lock(&p->lock);
02876    p->initid = -1;
02877    if (p->owner) {
02878       /* XXX fails on possible deadlock */
02879       if (!ast_channel_trylock(p->owner)) {
02880          ast_log(LOG_NOTICE, "Auto-congesting %s\n", p->owner->name);
02881          append_history(p, "Cong", "Auto-congesting (timer)");
02882          ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
02883          ast_channel_unlock(p->owner);
02884       }
02885    }
02886    ast_mutex_unlock(&p->lock);
02887    return 0;
02888 }

static void build_callid_pvt ( struct sip_pvt pvt  )  [static]

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

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

04314 {
04315    char buf[33];
04316 
04317    const char *host = S_OR(pvt->fromdomain, ast_inet_ntoa(pvt->ourip));
04318    
04319    ast_string_field_build(pvt, callid, "%s@%s", generate_random_string(buf, sizeof(buf)), host);
04320 
04321 }

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

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

Referenced by transmit_register().

04325 {
04326    char buf[33];
04327 
04328    const char *host = S_OR(fromdomain, ast_inet_ntoa(ourip));
04329 
04330    ast_string_field_build(reg, callid, "%s@%s", generate_random_string(buf, sizeof(buf)), host);
04331 }

static void build_contact ( struct sip_pvt p  )  [static]

Build contact header - the contact header we send out.

Definition at line 6700 of file chan_sip.c.

References ast_inet_ntoa(), ast_string_field_build, ast_strlen_zero(), ourport, and STANDARD_SIP_PORT.

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

06701 {
06702    /* Construct Contact: header */
06703    if (ourport != STANDARD_SIP_PORT)
06704       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);
06705    else
06706       ast_string_field_build(p, our_contact, "<sip:%s%s%s>", p->exten, ast_strlen_zero(p->exten) ? "" : "@", ast_inet_ntoa(p->ourip));
06707 }

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

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

Definition at line 16219 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, format, sip_peer::fromdomain, sip_peer::fromuser, sip_peer::fullcontact, global_flags, sip_peer::ha, handle_common_options(), sip_peer::language, sip_peer::lastmsgssent, ast_variable::lineno, LOG_DEBUG, sip_peer::mailbox, sip_peer::maxcallbitrate, sip_peer::maxms, sip_peer::md5secret, sip_peer::mohinterpret, sip_peer::mohsuggest, ast_variable::name, ast_variable::next, option_debug, peerl, sip_peer::pickupgroup, sip_peer::prefs, reg_source_db(), sip_peer::regexten, sip_peer::rtpholdtimeout, sip_peer::rtpkeepalive, sip_peer::rtptimeout, sched, sip_peer::secret, set_peer_defaults(), sip_destroy_peer(), SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PAGE2_DYNAMIC, SIP_PAGE2_IGNOREREGEXPIRE, SIP_PAGE2_RT_FROMCONTACT, SIP_PAGE2_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.

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

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

References append_history, ast_inet_ntoa(), ast_log(), ast_md5_hash(), ast_random(), ast_strlen_zero(), authl, find_realm_authentication(), LOG_DEBUG, sip_auth::md5secret, sip_pvt::noncecount, sip_pvt::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().

11336 {
11337    char a1[256];
11338    char a2[256];
11339    char a1_hash[256];
11340    char a2_hash[256];
11341    char resp[256];
11342    char resp_hash[256];
11343    char uri[256];
11344    char cnonce[80];
11345    const char *username;
11346    const char *secret;
11347    const char *md5secret;
11348    struct sip_auth *auth = NULL; /* Realm authentication */
11349 
11350    if (!ast_strlen_zero(p->domain))
11351       ast_copy_string(uri, p->domain, sizeof(uri));
11352    else if (!ast_strlen_zero(p->uri))
11353       ast_copy_string(uri, p->uri, sizeof(uri));
11354    else
11355       snprintf(uri, sizeof(uri), "sip:%s@%s",p->username, ast_inet_ntoa(p->sa.sin_addr));
11356 
11357    snprintf(cnonce, sizeof(cnonce), "%08lx", ast_random());
11358 
11359    /* Check if we have separate auth credentials */
11360    if ((auth = find_realm_authentication(authl, p->realm))) {
11361       ast_log(LOG_WARNING, "use realm [%s] from peer [%s][%s]\n",
11362          auth->username, p->peername, p->username);
11363       username = auth->username;
11364       secret = auth->secret;
11365       md5secret = auth->md5secret;
11366       if (sipdebug)
11367          ast_log(LOG_DEBUG,"Using realm %s authentication for call %s\n", p->realm, p->callid);
11368    } else {
11369       /* No authentication, use peer or register= config */
11370       username = p->authname;
11371       secret =  p->peersecret;
11372       md5secret = p->peermd5secret;
11373    }
11374    if (ast_strlen_zero(username))   /* We have no authentication */
11375       return -1;
11376 
11377    /* Calculate SIP digest response */
11378    snprintf(a1,sizeof(a1),"%s:%s:%s", username, p->realm, secret);
11379    snprintf(a2,sizeof(a2),"%s:%s", sip_methods[method].text, uri);
11380    if (!ast_strlen_zero(md5secret))
11381       ast_copy_string(a1_hash, md5secret, sizeof(a1_hash));
11382    else
11383       ast_md5_hash(a1_hash,a1);
11384    ast_md5_hash(a2_hash,a2);
11385 
11386    p->noncecount++;
11387    if (!ast_strlen_zero(p->qop))
11388       snprintf(resp,sizeof(resp),"%s:%s:%08x:%s:%s:%s", a1_hash, p->nonce, p->noncecount, cnonce, "auth", a2_hash);
11389    else
11390       snprintf(resp,sizeof(resp),"%s:%s:%s", a1_hash, p->nonce, a2_hash);
11391    ast_md5_hash(resp_hash, resp);
11392    /* XXX We hard code our qop to "auth" for now.  XXX */
11393    if (!ast_strlen_zero(p->qop))
11394       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);
11395    else
11396       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);
11397 
11398    append_history(p, "AuthResp", "Auth response sent for %s in realm %s - nc %d", username, p->realm, p->noncecount);
11399 
11400    return 0;
11401 }

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

08080 {
08081    struct sip_route *thishop, *head, *tail;
08082    int start = 0;
08083    int len;
08084    const char *rr, *contact, *c;
08085 
08086    /* Once a persistant route is set, don't fool with it */
08087    if (p->route && p->route_persistant) {
08088       if (option_debug)
08089          ast_log(LOG_DEBUG, "build_route: Retaining previous route: <%s>\n", p->route->hop);
08090       return;
08091    }
08092 
08093    if (p->route) {
08094       free_old_route(p->route);
08095       p->route = NULL;
08096    }
08097    
08098    p->route_persistant = backwards;
08099    
08100    /* Build a tailq, then assign it to p->route when done.
08101     * If backwards, we add entries from the head so they end up
08102     * in reverse order. However, we do need to maintain a correct
08103     * tail pointer because the contact is always at the end.
08104     */
08105    head = NULL;
08106    tail = head;
08107    /* 1st we pass through all the hops in any Record-Route headers */
08108    for (;;) {
08109       /* Each Record-Route header */
08110       rr = __get_header(req, "Record-Route", &start);
08111       if (*rr == '\0')
08112          break;
08113       for (; (rr = strchr(rr, '<')) ; rr += len) { /* Each route entry */
08114          ++rr;
08115          len = strcspn(rr, ">") + 1;
08116          /* Make a struct route */
08117          if ((thishop = ast_malloc(sizeof(*thishop) + len))) {
08118             /* ast_calloc is not needed because all fields are initialized in this block */
08119             ast_copy_string(thishop->hop, rr, len);
08120             if (option_debug > 1)
08121                ast_log(LOG_DEBUG, "build_route: Record-Route hop: <%s>\n", thishop->hop);
08122             /* Link in */
08123             if (backwards) {
08124                /* Link in at head so they end up in reverse order */
08125                thishop->next = head;
08126                head = thishop;
08127                /* If this was the first then it'll be the tail */
08128                if (!tail)
08129                   tail = thishop;
08130             } else {
08131                thishop->next = NULL;
08132                /* Link in at the end */
08133                if (tail)
08134                   tail->next = thishop;
08135                else
08136                   head = thishop;
08137                tail = thishop;
08138             }
08139          }
08140       }
08141    }
08142 
08143    /* Only append the contact if we are dealing with a strict router */
08144    if (!head || (!ast_strlen_zero(head->hop) && strstr(head->hop,";lr") == NULL) ) {
08145       /* 2nd append the Contact: if there is one */
08146       /* Can be multiple Contact headers, comma separated values - we just take the first */
08147       contact = get_header(req, "Contact");
08148       if (!ast_strlen_zero(contact)) {
08149          if (option_debug > 1)
08150             ast_log(LOG_DEBUG, "build_route: Contact hop: %s\n", contact);
08151          /* Look for <: delimited address */
08152          c = strchr(contact, '<');
08153          if (c) {
08154             /* Take to > */
08155             ++c;
08156             len = strcspn(c, ">") + 1;
08157          } else {
08158             /* No <> - just take the lot */
08159             c = contact;
08160             len = strlen(contact) + 1;
08161          }
08162          if ((thishop = ast_malloc(sizeof(*thishop) + len))) {
08163             /* ast_calloc is not needed because all fields are initialized in this block */
08164             ast_copy_string(thishop->hop, c, len);
08165             thishop->next = NULL;
08166             /* Goes at the end */
08167             if (tail)
08168                tail->next = thishop;
08169             else
08170                head = thishop;
08171          }
08172       }
08173    }
08174 
08175    /* Store as new route */
08176    p->route = head;
08177 
08178    /* For debugging dump what we ended up with */
08179    if (sip_debug_test_pvt(p))
08180       list_route(p->route);
08181 }

static void build_rpid ( struct sip_pvt p  )  [static]

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

Definition at line 6710 of file chan_sip.c.

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

Referenced by initreqprep().

06711 {
06712    int send_pres_tags = TRUE;
06713    const char *privacy=NULL;
06714    const char *screen=NULL;
06715    char buf[256];
06716    const char *clid = default_callerid;
06717    const char *clin = NULL;
06718    const char *fromdomain;
06719 
06720    if (!ast_strlen_zero(p->rpid) || !ast_strlen_zero(p->rpid_from))  
06721       return;
06722 
06723    if (p->owner && p->owner->cid.cid_num)
06724       clid = p->owner->cid.cid_num;
06725    if (p->owner && p->owner->cid.cid_name)
06726       clin = p->owner->cid.cid_name;
06727    if (ast_strlen_zero(clin))
06728       clin = clid;
06729 
06730    switch (p->callingpres) {
06731    case AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED:
06732       privacy = "off";
06733       screen = "no";
06734       break;
06735    case AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN:
06736       privacy = "off";
06737       screen = "yes";
06738       break;
06739    case AST_PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN:
06740       privacy = "off";
06741       screen = "no";
06742       break;
06743    case AST_PRES_ALLOWED_NETWORK_NUMBER:
06744       privacy = "off";
06745       screen = "yes";
06746       break;
06747    case AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED:
06748       privacy = "full";
06749       screen = "no";
06750       break;
06751    case AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN:
06752       privacy = "full";
06753       screen = "yes";
06754       break;
06755    case AST_PRES_PROHIB_USER_NUMBER_FAILED_SCREEN:
06756       privacy = "full";
06757       screen = "no";
06758       break;
06759    case AST_PRES_PROHIB_NETWORK_NUMBER:
06760       privacy = "full";
06761       screen = "yes";
06762       break;
06763    case AST_PRES_NUMBER_NOT_AVAILABLE:
06764       send_pres_tags = FALSE;
06765       break;
06766    default:
06767       ast_log(LOG_WARNING, "Unsupported callingpres (%d)\n", p->callingpres);
06768       if ((p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED)
06769          privacy = "full";
06770       else
06771          privacy = "off";
06772       screen = "no";
06773       break;
06774    }
06775    
06776    fromdomain = S_OR(p->fromdomain, ast_inet_ntoa(p->ourip));
06777 
06778    snprintf(buf, sizeof(buf), "\"%s\" <sip:%s@%s>", clin, clid, fromdomain);
06779    if (send_pres_tags)
06780       snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), ";privacy=%s;screen=%s", privacy, screen);
06781    ast_string_field_set(p, rpid, buf);
06782 
06783    ast_string_field_build(p, rpid_from, "\"%s\" <sip:%s@%s>;tag=%s", clin,
06784                 S_OR(p->fromuser, clid),
06785                 fromdomain, p->tag);
06786 }

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

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

Definition at line 16040 of file chan_sip.c.

References sip_user::allowtransfer, ast_append_ha(), ast_calloc, ast_copy_flags, ast_strdupa, ast_true(), ast_variable_new(), ASTOBJ_INIT, sip_user::chanvars, default_prefs, format, global_flags, sip_user::ha, handle_common_options(), ast_variable::name, ast_variable::next, sip_user::secret, SIP_FLAGS_TO_COPY, SIP_PAGE2_FLAGS_TO_COPY, TRANSFER_CLOSED, TRANSFER_OPENFORALL, and ast_variable::value.

16041 {
16042    struct sip_user *user;
16043    int format;
16044    struct ast_ha *oldha = NULL;
16045    char *varname = NULL, *varval = NULL;
16046    struct ast_variable *tmpvar = NULL;
16047    struct ast_flags userflags[2] = {{(0)}};
16048    struct ast_flags mask[2] = {{(0)}};
16049 
16050 
16051    if (!(user = ast_calloc(1, sizeof(*user))))
16052       return NULL;
16053       
16054    suserobjs++;
16055    ASTOBJ_INIT(user);
16056    ast_copy_string(user->name, name, sizeof(user->name));
16057    oldha = user->ha;
16058    user->ha = NULL;
16059    ast_copy_flags(&user->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY);
16060    ast_copy_flags(&user->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY);
16061    user->capability = global_capability;
16062    user->allowtransfer = global_allowtransfer;
16063    user->maxcallbitrate = default_maxcallbitrate;
16064    user->autoframing = global_autoframing;
16065    user->prefs = default_prefs;
16066    /* set default context */
16067    strcpy(user->context, default_context);
16068    strcpy(user->language, default_language);
16069    strcpy(user->mohinterpret, default_mohinterpret);
16070    strcpy(user->mohsuggest, default_mohsuggest);
16071    for (; v; v = v->next) {
16072       if (handle_common_options(&userflags[0], &mask[0], v))
16073          continue;
16074 
16075       if (!strcasecmp(v->name, "context")) {
16076          ast_copy_string(user->context, v->value, sizeof(user->context));
16077       } else if (!strcasecmp(v->name, "subscribecontext")) {
16078          ast_copy_string(user->subscribecontext, v->value, sizeof(user->subscribecontext));
16079       } else if (!strcasecmp(v->name, "setvar")) {
16080          varname = ast_strdupa(v->value);
16081          if ((varval = strchr(varname,'='))) {
16082             *varval++ = '\0';
16083             if ((tmpvar = ast_variable_new(varname, varval))) {
16084                tmpvar->next = user->chanvars;
16085                user->chanvars = tmpvar;
16086             }
16087          }
16088       } else if (!strcasecmp(v->name, "permit") ||
16089                !strcasecmp(v->name, "deny")) {
16090          user->ha = ast_append_ha(v->name, v->value, user->ha);
16091       } else if (!strcasecmp(v->name, "allowtransfer")) {
16092          user->allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED;
16093       } else if (!strcasecmp(v->name, "secret")) {
16094          ast_copy_string(user->secret, v->value, sizeof(user->secret)); 
16095       } else if (!strcasecmp(v->name, "md5secret")) {
16096          ast_copy_string(user->md5secret, v->value, sizeof(user->md5secret));
16097       } else if (!strcasecmp(v->name, "callerid")) {
16098          ast_callerid_split(v->value, user->cid_name, sizeof(user->cid_name), user->cid_num, sizeof(user->cid_num));
16099       } else if (!strcasecmp(v->name, "fullname")) {
16100          ast_copy_string(user->cid_name, v->value, sizeof(user->cid_name));
16101       } else if (!strcasecmp(v->name, "cid_number")) {
16102          ast_copy_string(user->cid_num, v->value, sizeof(user->cid_num));
16103       } else if (!strcasecmp(v->name, "callgroup")) {
16104          user->callgroup = ast_get_group(v->value);
16105       } else if (!strcasecmp(v->name, "pickupgroup")) {
16106          user->pickupgroup = ast_get_group(v->value);
16107       } else if (!strcasecmp(v->name, "language")) {
16108          ast_copy_string(user->language, v->value, sizeof(user->language));
16109       } else if (!strcasecmp(v->name, "mohinterpret") 
16110          || !strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) {
16111          ast_copy_string(user->mohinterpret, v->value, sizeof(user->mohinterpret));
16112       } else if (!strcasecmp(v->name, "mohsuggest")) {
16113          ast_copy_string(user->mohsuggest, v->value, sizeof(user->mohsuggest));
16114       } else if (!strcasecmp(v->name, "accountcode")) {
16115          ast_copy_string(user->accountcode, v->value, sizeof(user->accountcode));
16116       } else if (!strcasecmp(v->name, "call-limit")) {
16117          user->call_limit = atoi(v->value);
16118          if (user->call_limit < 0)
16119             user->call_limit = 0;
16120       } else if (!strcasecmp(v->name, "amaflags")) {
16121          format = ast_cdr_amaflags2int(v->value);
16122          if (format < 0) {
16123             ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
16124          } else {
16125             user->amaflags = format;
16126          }
16127       } else if (!strcasecmp(v->name, "allow")) {
16128          ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1);
16129       } else if (!strcasecmp(v->name, "disallow")) {
16130          ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 0);
16131       } else if (!strcasecmp(v->name, "autoframing")) {
16132          user->autoframing = ast_true(v->value);
16133       } else if (!strcasecmp(v->name, "callingpres")) {
16134          user->callingpres = ast_parse_caller_presentation(v->value);
16135          if (user->callingpres == -1)
16136             user->callingpres = atoi(v->value);
16137       } else if (!strcasecmp(v->name, "maxcallbitrate")) {
16138          user->maxcallbitrate = atoi(v->value);
16139          if (user->maxcallbitrate < 0)
16140             user->maxcallbitrate = default_maxcallbitrate;
16141       }
16142       /* We can't just report unknown options here because this may be a
16143        * type=friend entry.  All user options are valid for a peer, but not
16144        * the other way around.  */
16145    }
16146    ast_copy_flags(&user->flags[0], &userflags[0], mask[0].flags);
16147    ast_copy_flags(&user->flags[1], &userflags[1], mask[1].flags);
16148    if (ast_test_flag(&user->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE))
16149       global_allowsubscribe = TRUE; /* No global ban any more */
16150    ast_free_ha(oldha);
16151    return user;
16152 }

static void build_via ( struct sip_pvt p  )  [static]

Build a Via header for a request.

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

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

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

08372 {
08373    struct sip_pvt *p = data;
08374 
08375    ast_mutex_lock(&p->lock);
08376 
08377    switch(state) {
08378    case AST_EXTENSION_DEACTIVATED:  /* Retry after a while */
08379    case AST_EXTENSION_REMOVED:   /* Extension is gone */
08380       if (p->autokillid > -1)
08381          sip_cancel_destroy(p);  /* Remove subscription expiry for renewals */
08382       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);  /* Delete subscription in 32 secs */
08383       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);
08384       p->stateid = -1;
08385       p->subscribed = NONE;
08386       append_history(p, "Subscribestatus", "%s", state == AST_EXTENSION_REMOVED ? "HintRemoved" : "Deactivated");
08387       break;
08388    default: /* Tell user */
08389       p->laststate = state;
08390       break;
08391    }
08392    if (p->subscribed != NONE) /* Only send state NOTIFY if we know the format */
08393       transmit_state_notify(p, state, 1, FALSE);
08394 
08395    if (option_verbose > 1)
08396       ast_verbose(VERBOSE_PREFIX_1 "Extension Changed %s new state %s for Notify User %s\n", exten, ast_extension_state2str(state), p->username);
08397    
08398    ast_mutex_unlock(&p->lock);
08399 
08400    return 0;
08401 }

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

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

Referenced by handle_request_invite(), and process_sdp().

04855 {
04856    if (global_notifyhold)
04857       sip_peer_hold(dialog, holdstate);
04858    if (global_callevents)
04859       manager_event(EVENT_FLAG_CALL, holdstate ? "Hold" : "Unhold",
04860                "Channel: %s\r\n"
04861                "Uniqueid: %s\r\n",
04862                dialog->owner->name, 
04863                dialog->owner->uniqueid);
04864    append_history(dialog, holdstate ? "Hold" : "Unhold", "%s", req->data);
04865    if (!holdstate) {    /* Put off remote hold */
04866       ast_clear_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD);   /* Clear both flags */
04867       return;
04868    }
04869    /* No address for RTP, we're on hold */
04870 
04871    if (sendonly == 1)   /* One directional hold (sendonly/recvonly) */
04872       ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_ONEDIR);
04873    else if (sendonly == 2) /* Inactive stream */
04874       ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_INACTIVE);
04875    else
04876       ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_ACTIVE);
04877    return;
04878 }

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

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

static void check_pendings ( struct sip_pvt p  )  [static]

Check pending actions on SIP call.

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

11797 {
11798    if (ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) {
11799       /* if we can't BYE, then this is really a pending CANCEL */
11800       if (p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA)
11801          transmit_request(p, SIP_CANCEL, p->ocseq, XMIT_RELIABLE, FALSE);
11802          /* Actually don't destroy us yet, wait for the 487 on our original 
11803             INVITE, but do set an autodestruct just in case we never get it. */
11804       else 
11805          transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, TRUE);
11806       ast_clear_flag(&p->flags[0], SIP_PENDINGBYE);   
11807       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
11808    } else if (ast_test_flag(&p->flags[0], SIP_NEEDREINVITE)) {
11809       if (option_debug)
11810          ast_log(LOG_DEBUG, "Sending pending reinvite on '%s'\n", p->callid);
11811       /* Didn't get to reinvite yet, so do it now */
11812       transmit_reinvite_with_sdp(p);
11813       ast_clear_flag(&p->flags[0], SIP_NEEDREINVITE); 
11814    }
11815 }

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

References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_strlen_zero(), domain::context, domain::domain, and result.

Referenced by func_check_sipdomain(), get_destination(), handle_request_refer(), and register_verify().

15920 {
15921    struct domain *d;
15922    int result = 0;
15923 
15924    AST_LIST_LOCK(&domain_list);
15925    AST_LIST_TRAVERSE(&domain_list, d, list) {
15926       if (strcasecmp(d->domain, domain))
15927          continue;
15928 
15929       if (len && !ast_strlen_zero(d->context))
15930          ast_copy_string(context, d->context, len);
15931       
15932       result = 1;
15933       break;
15934    }
15935    AST_LIST_UNLOCK(&domain_list);
15936 
15937    return result;
15938 }

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

References check_user_full().

Referenced by handle_request_invite().

09446 {
09447    return check_user_full(p, req, sipmethod, uri, reliable, sin, NULL);
09448 }

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

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

Referenced by check_user(), and handle_request_subscribe().

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

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

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

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

08993 {
08994    char via[256];
08995    char *c, *pt;
08996    struct hostent *hp;
08997    struct ast_hostent ahp;
08998 
08999    ast_copy_string(via, get_header(req, "Via"), sizeof(via));
09000 
09001    /* Work on the leftmost value of the topmost Via header */
09002    c = strchr(via, ',');
09003    if (c)
09004       *c = '\0';
09005 
09006    /* Check for rport */
09007    c = strstr(via, ";rport");
09008    if (c && (c[6] != '=')) /* rport query, not answer */
09009       ast_set_flag(&p->flags[0], SIP_NAT_ROUTE);
09010 
09011    c = strchr(via, ';');
09012    if (c) 
09013       *c = '\0';
09014 
09015    c = strchr(via, ' ');
09016    if (c) {
09017       *c = '\0';
09018       c = ast_skip_blanks(c+1);
09019       if (strcasecmp(via, "SIP/2.0/UDP")) {
09020          ast_log(LOG_WARNING, "Don't know how to respond via '%s'\n", via);
09021          return;
09022       }
09023       pt = strchr(c, ':');
09024       if (pt)
09025          *pt++ = '\0';  /* remember port pointer */
09026       hp = ast_gethostbyname(c, &ahp);
09027       if (!hp) {
09028          ast_log(LOG_WARNING, "'%s' is not a valid host\n", c);
09029          return;
09030       }
09031       memset(&p->sa, 0, sizeof(p->sa));
09032       p->sa.sin_family = AF_INET;
09033       memcpy(&p->sa.sin_addr, hp->h_addr, sizeof(p->sa.sin_addr));
09034       p->sa.sin_port = htons(pt ? atoi(pt) : STANDARD_SIP_PORT);
09035 
09036       if (sip_debug_test_pvt(p)) {
09037          const struct sockaddr_in *dst = sip_real_dst(p);
09038          ast_verbose("Sending to %s : %d (%s)\n", ast_inet_ntoa(dst->sin_addr), ntohs(dst->sin_port), sip_nat_mode(p));
09039       }
09040    }
09041 }

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

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

09888 {
09889    char *oldcontext, *newcontext, *stalecontext, *stringp, newlist[AST_MAX_CONTEXT];
09890 
09891    while ((oldcontext = strsep(&old, "&"))) {
09892       stalecontext = '\0';
09893       ast_copy_string(newlist, new, sizeof(newlist));
09894       stringp = newlist;
09895       while ((newcontext = strsep(&stringp, "&"))) {
09896          if (strcmp(newcontext, oldcontext) == 0) {
09897             /* This is not the context you're looking for */
09898             stalecontext = '\0';
09899             break;
09900          } else if (strcmp(newcontext, oldcontext)) {
09901             stalecontext = oldcontext;
09902          }
09903          
09904       }
09905       if (stalecontext)
09906          ast_context_destroy(ast_context_find(stalecontext), "SIP");
09907    }
09908 }

static int clear_realm_authentication ( struct sip_auth authlist  )  [static]

Clear realm authentication list (at reload).

Definition at line 16012 of file chan_sip.c.

References free, and sip_auth::next.

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

16013 {
16014    struct sip_auth *a = authlist;
16015    struct sip_auth *b;
16016 
16017    while (a) {
16018       b = a;
16019       a = a->next;
16020       free(b);
16021    }
16022 
16023    return 1;
16024 }

static void clear_sip_domains ( void   )  [static]

Clear our domain list (at reload).

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

15942 {
15943    struct domain *d;
15944 
15945    AST_LIST_LOCK(&domain_list);
15946    while ((d = AST_LIST_REMOVE_HEAD(&domain_list, list)))
15947       free(d);
15948    AST_LIST_UNLOCK(&domain_list);
15949 }

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

References complete_sip_peer().

10701 {
10702    if (pos == 3)
10703       return complete_sip_peer(word, state, 0);
10704 
10705    return NULL;
10706 }

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

Do completion on peer name.

Definition at line 10674 of file chan_sip.c.

References ast_strdup, ast_test_flag, ASTOBJ_CONTAINER_TRAVERSE, peerl, and result.

Referenced by complete_sip_debug_peer(), complete_sip_prune_realtime_peer(), complete_sip_show_peer(), and complete_sipnotify().

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

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

References complete_sip_peer(), and SIP_PAGE2_RTCACHEFRIENDS.

10769 {
10770    if (pos == 4)
10771       return complete_sip_peer(word, state, SIP_PAGE2_RTCACHEFRIENDS);
10772    return NULL;
10773 }

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

References complete_sip_user(), and SIP_PAGE2_RTCACHEFRIENDS.

10777 {
10778    if (pos == 4)
10779       return complete_sip_user(word, state, SIP_PAGE2_RTCACHEFRIENDS);
10780 
10781    return NULL;
10782 }

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

References complete_sip_peer().

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

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

References complete_sip_user().

10730 {
10731    if (pos == 3)
10732       return complete_sip_user(word, state, 0);
10733 
10734    return NULL;
10735 }

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

Do completion on user name.

Definition at line 10709 of file chan_sip.c.

References ast_strdup, ast_test_flag, ASTOBJ_CONTAINER_TRAVERSE, result, and userl.

Referenced by complete_sip_prune_realtime_user(), and complete_sip_show_user().

10710 {
10711    char *result = NULL;
10712    int wordlen = strlen(word);
10713    int which = 0;
10714 
10715    ASTOBJ_CONTAINER_TRAVERSE(&userl, !result, do {
10716       /* locking of the object is not required because only the name and flags are being compared */
10717       if (!strncasecmp(word, iterator->name, wordlen)) {
10718          if (flags2 && !ast_test_flag(&iterator->flags[1], flags2))
10719             continue;
10720          if (++which > state) {
10721             result = ast_strdup(iterator->name);
10722          }
10723       }
10724    } while(0) );
10725    return result;
10726 }

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

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

10656 {
10657    int which=0;
10658    struct sip_pvt *cur;
10659    char *c = NULL;
10660    int wordlen = strlen(word);
10661 
10662    ast_mutex_lock(&iflock);
10663    for (cur = iflist; cur; cur = cur->next) {
10664       if (!strncasecmp(word, cur->callid, wordlen) && ++which > state) {
10665          c = ast_strdup(cur->callid);
10666          break;
10667       }
10668    }
10669    ast_mutex_unlock(&iflock);
10670    return c;
10671 }

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

Support routine for 'sip notify' CLI.

Definition at line 10738 of file chan_sip.c.

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

10739 {
10740    char *c = NULL;
10741 
10742    if (pos == 2) {
10743       int which = 0;
10744       char *cat = NULL;
10745       int wordlen = strlen(word);
10746 
10747       /* do completion for notify type */
10748 
10749       if (!notify_types)
10750          return NULL;
10751       
10752       while ( (cat = ast_category_browse(notify_types, cat)) ) {
10753          if (!strncasecmp(word, cat, wordlen) && ++which > state) {
10754             c = ast_strdup(cat);
10755             break;
10756          }
10757       }
10758       return c;
10759    }
10760 
10761    if (pos > 2)
10762       return complete_sip_peer(word, state, 0);
10763 
10764    return NULL;
10765 }

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

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

Referenced by respprep().

05517 {
05518    int start = 0;
05519    int copied = 0;
05520    for (;;) {
05521       const char *tmp = __get_header(orig, field, &start);
05522 
05523       if (ast_strlen_zero(tmp))
05524          break;
05525       /* Add what we're responding to */
05526       add_header(req, field, tmp);
05527       copied++;
05528    }
05529    return copied ? 0 : -1;
05530 }

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

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

Referenced by reqprep(), and respprep().

05506 {
05507    const char *tmp = get_header(orig, field);
05508 
05509    if (!ast_strlen_zero(tmp)) /* Add what we're responding to */
05510       return add_header(req, field, tmp);
05511    ast_log(LOG_NOTICE, "No field '%s' present to copy\n", field);
05512    return -1;
05513 }

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

References offset.

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

06554 {
06555    long offset;
06556    int x;
06557    offset = ((void *)dst) - ((void *)src);
06558    /* First copy stuff */
06559    memcpy(dst, src, sizeof(*dst));
06560    /* Now fix pointer arithmetic */
06561    for (x=0; x < src->headers; x++)
06562       dst->header[x] += offset;
06563    for (x=0; x < src->lines; x++)
06564       dst->line[x] += offset;
06565    dst->rlPart1 += offset;
06566    dst->rlPart2 += offset;
06567 }

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

05539 {
05540    int copied = 0;
05541    int start = 0;
05542 
05543    for (;;) {
05544       char new[256];
05545       const char *oh = __get_header(orig, field, &start);
05546 
05547       if (ast_strlen_zero(oh))
05548          break;
05549 
05550       if (!copied) { /* Only check for empty rport in topmost via header */
05551          char leftmost[256], *others, *rport;
05552 
05553          /* Only work on leftmost value */
05554          ast_copy_string(leftmost, oh, sizeof(leftmost));
05555          others = strchr(leftmost, ',');
05556          if (others)
05557              *others++ = '\0';
05558 
05559          /* Find ;rport;  (empty request) */
05560          rport = strstr(leftmost, ";rport");
05561          if (rport && *(rport+6) == '=') 
05562             rport = NULL;     /* We already have a parameter to rport */
05563 
05564          /* Check rport if NAT=yes or NAT=rfc3581 (which is the default setting)  */
05565          if (rport && ((ast_test_flag(&p->flags[0], SIP_NAT) == SIP_NAT_ALWAYS) || (ast_test_flag(&p->flags[0], SIP_NAT) == SIP_NAT_RFC3581))) {
05566             /* We need to add received port - rport */
05567             char *end;
05568 
05569             rport = strstr(leftmost, ";rport");
05570 
05571             if (rport) {
05572                end = strchr(rport + 1, ';');
05573                if (end)
05574                   memmove(rport, end, strlen(end) + 1);
05575                else
05576                   *rport = '\0';
05577             }
05578 
05579             /* Add rport to first VIA header if requested */
05580             snprintf(new, sizeof(new), "%s;received=%s;rport=%d%s%s",
05581                leftmost, ast_inet_ntoa(p->recv.sin_addr),
05582                ntohs(p->recv.sin_port),
05583                others ? "," : "", others ? others : "");
05584          } else {
05585             /* We should *always* add a received to the topmost via */
05586             snprintf(new, sizeof(new), "%s;received=%s%s%s",
05587                leftmost, ast_inet_ntoa(p->recv.sin_addr),
05588                others ? "," : "", others ? others : "");
05589          }
05590          oh = new;   /* the header to copy */
05591       }  /* else add the following via headers untouched */
05592       add_header(req, field, oh);
05593       copied++;
05594    }
05595    if (!copied) {
05596       ast_log(LOG_NOTICE, "No header field '%s' present to copy\n", field);
05597       return -1;
05598    }
05599    return 0;
05600 }

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

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

02822 {
02823    struct hostent *hp;
02824    struct ast_hostent ahp;
02825    struct sip_peer *p;
02826    char *port;
02827    int portno;
02828    char host[MAXHOSTNAMELEN], *hostn;
02829    char peer[256];
02830 
02831    ast_copy_string(peer, opeer, sizeof(peer));
02832    port = strchr(peer, ':');
02833    if (port)
02834       *port++ = '\0';
02835    dialog->sa.sin_family = AF_INET;
02836    dialog->timer_t1 = 500; /* Default SIP retransmission timer T1 (RFC 3261) */
02837    p = find_peer(peer, NULL, 1);
02838 
02839    if (p) {
02840       int res = create_addr_from_peer(dialog, p);
02841       ASTOBJ_UNREF(p, sip_destroy_peer);
02842       return res;
02843    }
02844    hostn = peer;
02845    portno = port ? atoi(port) : STANDARD_SIP_PORT;
02846    if (srvlookup) {
02847       char service[MAXHOSTNAMELEN];
02848       int tportno;
02849       int ret;
02850 
02851       snprintf(service, sizeof(service), "_sip._udp.%s", peer);
02852       ret = ast_get_srv(NULL, host, sizeof(host), &tportno, service);
02853       if (ret > 0) {
02854          hostn = host;
02855          portno = tportno;
02856       }
02857    }
02858    hp = ast_gethostbyname(hostn, &ahp);
02859    if (!hp) {
02860       ast_log(LOG_WARNING, "No such host: %s\n", peer);
02861       return -1;
02862    }
02863    ast_string_field_set(dialog, tohost, peer);
02864    memcpy(&dialog->sa.sin_addr, hp->h_addr, sizeof(dialog->sa.sin_addr));
02865    dialog->sa.sin_port = htons(portno);
02866    dialog->recv = dialog->sa;
02867    return 0;
02868 }

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

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

static void destroy_association ( struct sip_peer peer  )  [static]

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

Definition at line 7714 of file chan_sip.c.

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

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

07715 {
07716    if (!ast_test_flag(&global_flags[1], SIP_PAGE2_IGNOREREGEXPIRE)) {
07717       if (ast_test_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT))
07718          ast_update_realtime("sippeers", "name", peer->name, "fullcontact", "", "ipaddr", "", "port", "", "regseconds", "0", "username", "", "regserver", "", NULL);
07719       else 
07720          ast_db_del("SIP/Registry", peer->name);
07721    }
07722 }

static int determine_firstline_parts ( struct sip_request req  )  [static]

Parse first line of incoming SIP request.

Definition at line 6597 of file chan_sip.c.

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

Referenced by parse_request().

06598 {
06599    char *e = ast_skip_blanks(req->header[0]);   /* there shouldn't be any */
06600 
06601    if (!*e)
06602       return -1;
06603    req->rlPart1 = e; /* method or protocol */
06604    e = ast_skip_nonblanks(e);
06605    if (*e)
06606       *e++ = '\0';
06607    /* Get URI or status code */
06608    e = ast_skip_blanks(e);
06609    if ( !*e )
06610       return -1;
06611    ast_trim_blanks(e);
06612 
06613    if (!strcasecmp(req->rlPart1, "SIP/2.0") ) { /* We have a response */
06614       if (strlen(e) < 3)   /* status code is 3 digits */
06615          return -1;
06616       req->rlPart2 = e;
06617    } else { /* We have a request */
06618       if ( *e == '<' ) { /* XXX the spec says it must not be in <> ! */
06619          ast_log(LOG_WARNING, "bogus uri in <> %s\n", e);
06620          e++;
06621          if (!*e)
06622             return -1; 
06623       }
06624       req->rlPart2 = e; /* URI */
06625       e = ast_skip_nonblanks(e);
06626       if (*e)
06627          *e++ = '\0';
06628       e = ast_skip_blanks(e);
06629       if (strcasecmp(e, "SIP/2.0") ) {
06630          ast_log(LOG_WARNING, "Bad request protocol %s\n", e);
06631          return -1;
06632       }
06633    }
06634    return 1;
06635 }

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

References __sip_destroy(), ast_channel_trylock, ast_channel_unlock, ast_io_add(), ast_io_change(), AST_IO_IN, 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_SOFTHANGUP_DEV, ast_softhangup_nolock(), AST_STATE_UP, ast_test_flag, ast_verbose(), FALSE, sip_pvt::flags, iflist, io, sip_pvt::lock, LOG_NOTICE, sip_pvt::next, option_verbose, sip_pvt::owner, sip_pvt::packets, sip_do_reload(), SIP_NEEDDESTROY, sipsock, sipsock_read(), t, T38_ENABLED, and VERBOSE_PREFIX_1.

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

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

11237 {
11238    char digest[1024];
11239 
11240    if (!p->options && !(p->options = ast_calloc(1, sizeof(*p->options))))
11241       return -2;
11242 
11243    p->authtries++;
11244    if (option_debug > 1)
11245       ast_log(LOG_DEBUG, "Auth attempt %d on %s\n", p->authtries, sip_methods[sipmethod].text);
11246    memset(digest, 0, sizeof(digest));
11247    if (reply_digest(p, req, header, sipmethod, digest, sizeof(digest) )) {
11248       /* No way to authenticate */
11249       return -1;
11250    }
11251    /* Now we have a reply digest */
11252    p->options->auth = digest;
11253    p->options->authheader = respheader;
11254    return transmit_invite(p, sipmethod, sipmethod == SIP_INVITE, init); 
11255 }

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

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

Referenced by handle_response_register().

11216 {
11217    char digest[1024];
11218    p->authtries++;
11219    memset(digest,0,sizeof(digest));
11220    if (reply_digest(p, req, header, SIP_REGISTER, digest, sizeof(digest))) {
11221       /* There's nothing to use for authentication */
11222       /* No digest challenge in request */
11223       if (sip_debug_test_pvt(p) && p->registry)
11224          ast_verbose("No authentication challenge, sending blank registration to domain/host name %s\n", p->registry->hostname);
11225          /* No old challenge */
11226       return -1;
11227    }
11228    if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY))
11229       append_history(p, "RegistryAuth", "Try: %d", p->authtries);
11230    if (sip_debug_test_pvt(p) && p->registry)
11231       ast_verbose("Responding to challenge, registration to domain/host name %s\n", p->registry->hostname);
11232    return transmit_register(p->registry, SIP_REGISTER, digest, respheader); 
11233 }

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

Set nat mode on the various data sockets.

Definition at line 2689 of file chan_sip.c.

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

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

02690 {
02691    const char *mode = natflags ? "On" : "Off";
02692 
02693    if (p->rtp) {
02694       if (option_debug)
02695          ast_log(LOG_DEBUG, "Setting NAT on RTP to %s\n", mode);
02696       ast_rtp_setnat(p->rtp, natflags);
02697    }
02698    if (p->vrtp) {
02699       if (option_debug)
02700          ast_log(LOG_DEBUG, "Setting NAT on VRTP to %s\n", mode);
02701       ast_rtp_setnat(p->vrtp, natflags);
02702    }
02703    if (p->udptl) {
02704       if (option_debug)
02705          ast_log(LOG_DEBUG, "Setting NAT on UDPTL to %s\n", mode);
02706       ast_udptl_setnat(p->udptl, natflags);
02707    }
02708 }

static int does_peer_need_mwi ( struct sip_peer peer  )  [static]

Check whether peer needs a new MWI notification check.

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

15243 {
15244    time_t t = time(NULL);
15245 
15246    if (ast_test_flag(&peer->flags[1], SIP_PAGE2_SUBSCRIBEMWIONLY) &&
15247        !peer->mwipvt) { /* We don't have a subscription */
15248       peer->lastmsgcheck = t; /* Reset timer */
15249       return FALSE;
15250    }
15251 
15252    if (!ast_strlen_zero(peer->mailbox) && (t - peer->lastmsgcheck) > global_mwitime)
15253       return TRUE;
15254 
15255    return FALSE;
15256 }

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

Print domain mode to cli.

Definition at line 10076 of file chan_sip.c.

References SIP_DOMAIN_AUTO, and SIP_DOMAIN_CONFIG.

Referenced by sip_show_domains().

10077 {
10078    switch (mode) {
10079    case SIP_DOMAIN_AUTO:
10080       return "[Automatic]";
10081    case SIP_DOMAIN_CONFIG:
10082       return "[Configured]";
10083    }
10084 
10085    return "";
10086 }

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

Convert DTMF mode to printable string.

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

09857 {
09858    switch (mode) {
09859    case SIP_DTMF_RFC2833:
09860       return "rfc2833";
09861    case SIP_DTMF_INFO:
09862       return "info";
09863    case SIP_DTMF_INBAND:
09864       return "inband";
09865    case SIP_DTMF_AUTO:
09866       return "auto";
09867    }
09868    return "<error>";
09869 }

static int expire_register ( void *  data  )  [static]

Expire registration of SIP peer.

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

07726 {
07727    struct sip_peer *peer = data;
07728    
07729    if (!peer)     /* Hmmm. We have no peer. Weird. */
07730       return 0;
07731 
07732    memset(&peer->addr, 0, sizeof(peer->addr));
07733 
07734    destroy_association(peer); /* remove registration data from storage */
07735    
07736    manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name);
07737    register_peer_exten(peer, FALSE);   /* Remove regexten */
07738    peer->expire = -1;
07739    ast_device_state_changed("SIP/%s", peer->name);
07740 
07741    /* Do we need to release this peer from memory? 
07742       Only for realtime peers and autocreated peers
07743    */
07744    if (ast_test_flag(&peer->flags[1], SIP_PAGE2_SELFDESTRUCT) ||
07745        ast_test_flag(&peer->flags[1], SIP_PAGE2_RTAUTOCLEAR)) {
07746       peer = ASTOBJ_CONTAINER_UNLINK(&peerl, peer);   /* Remove from peer list */
07747       ASTOBJ_UNREF(peer, sip_destroy_peer);     /* Remove from memory */
07748    }
07749 
07750    return 0;
07751 }

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

Check Contact: URI of SIP message.

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

06688 {
06689    char stripped[BUFSIZ];
06690    char *c;
06691 
06692    ast_copy_string(stripped, get_header(req, "Contact"), sizeof(stripped));
06693    c = get_in_brackets(stripped);
06694    c = strsep(&c, ";"); /* trim ; and beyond */
06695    if (!ast_strlen_zero(c))
06696       ast_string_field_set(p, uri, c);
06697 }

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

References aliases.

04108 {
04109    /*! \brief Structure for conversion between compressed SIP and "normal" SIP */
04110    static const struct cfalias {
04111       char * const fullname;
04112       char * const shortname;
04113    } aliases[] = {
04114       { "Content-Type",  "c" },
04115       { "Content-Encoding",    "e" },
04116       { "From",       "f" },
04117       { "Call-ID",       "i" },
04118       { "Contact",       "m" },
04119       { "Content-Length",   "l" },
04120       { "Subject",       "s" },
04121       { "To",         "t" },
04122       { "Supported",     "k" },
04123       { "Refer-To",      "r" },
04124       { "Referred-By",   "b" },
04125       { "Allow-Events",  "u" },
04126       { "Event",      "o" },
04127       { "Via",     "v" },
04128       { "Accept-Contact",      "a" },
04129       { "Reject-Contact",      "j" },
04130       { "Request-Disposition", "d" },
04131       { "Session-Expires",     "x" },
04132       { "Identity",            "y" },
04133       { "Identity-Info",       "n" },
04134    };
04135    int x;
04136 
04137    for (x=0; x<sizeof(aliases) / sizeof(aliases[0]); x++) 
04138       if (!strcasecmp(aliases[x].fullname, name))
04139          return aliases[x].shortname;
04140 
04141    return _default;
04142 }

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

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

Definition at line 4466 of file chan_sip.c.

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

Referenced by sipsock_read().

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

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

References s.

Referenced by get_in_brackets().

02280 {
02281         char last_char = '\0';
02282         const char *s;
02283         for (s = start; *s && s != lim; last_char = *s++) {
02284                 if (*s == '"' && last_char != '\\')
02285                         break;
02286         }
02287         return s;
02288 }

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

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

Definition at line 2601 of file chan_sip.c.

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

02602 {
02603    struct sip_peer *p = NULL;
02604 
02605    if (peer)
02606       p = ASTOBJ_CONTAINER_FIND(&peerl, peer);
02607    else
02608       p = ASTOBJ_CONTAINER_FIND_FULL(&peerl, sin, name, sip_addr_hashfunc, 1, sip_addrcmp);
02609 
02610    if (!p && realtime)
02611       p = realtime_peer(peer, sin);
02612 
02613    return p;
02614 }

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

Find authentication for a specific realm.

Definition at line 16027 of file chan_sip.c.

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

Referenced by build_reply_digest().

16028 {
16029    struct sip_auth *a;
16030 
16031    for (a = authlist; a; a = a->next) {
16032       if (!strcasecmp(a->realm, realm))
16033          break;
16034    }
16035 
16036    return a;
16037 }

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

04788 {
04789    const char *content_type;
04790    const char *search;
04791    char *boundary;
04792    unsigned int x;
04793    int boundaryisquoted = FALSE;
04794 
04795    content_type = get_header(req, "Content-Type");
04796 
04797    /* if the body contains only SDP, this is easy */
04798    if (!strcasecmp(content_type, "application/sdp")) {
04799       req->sdp_start = 0;
04800       req->sdp_end = req->lines;
04801       return req->lines ? 1 : 0;
04802    }
04803 
04804    /* if it's not multipart/mixed, there cannot be an SDP */
04805    if (strncasecmp(content_type, "multipart/mixed", 15))
04806       return 0;
04807 
04808    /* if there is no boundary marker, it's invalid */
04809    if (!(search = strcasestr(content_type, ";boundary=")))
04810       return 0;
04811 
04812    search += 10;
04813    if (ast_strlen_zero(search))
04814       return 0;
04815 
04816    /* If the boundary is quoted with ", remove quote */
04817    if (*search == '\"')  {
04818       search++;
04819       boundaryisquoted = TRUE;
04820    }
04821 
04822    /* make a duplicate of the string, with two extra characters
04823       at the beginning */
04824    boundary = ast_strdupa(search - 2);
04825    boundary[0] = boundary[1] = '-';
04826 
04827    /* Remove final quote */
04828    if (boundaryisquoted)
04829       boundary[strlen(boundary) - 1] = '\0';
04830 
04831    /* search for the boundary marker, but stop when there are not enough
04832       lines left for it, the Content-Type header and at least one line of
04833       body */
04834    for (x = 0; x < (req->lines - 2); x++) {
04835       if (!strncasecmp(req->line[x], boundary, strlen(boundary)) &&
04836           !strcasecmp(req->line[x + 1], "Content-Type: application/sdp")) {
04837          x += 2;
04838          req->sdp_start = x;
04839 
04840          /* search for the end of the body part */
04841          for ( ; x < req->lines; x++) {
04842             if (!strncasecmp(req->line[x], boundary, strlen(boundary)))
04843                break;
04844          }
04845          req->sdp_end = x;
04846          return 1;
04847       }
04848    }
04849 
04850    return 0;
04851 }

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

find_sip_method: Find SIP method from header

Definition at line 1667 of file chan_sip.c.

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

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

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

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

Find subscription type in array.

Definition at line 10570 of file chan_sip.c.

References subscription_types, and type.

Referenced by transmit_state_notify().

10571 {
10572    int i;
10573 
10574    for (i = 1; (i < (sizeof(subscription_types) / sizeof(subscription_types[0]))); i++) {
10575       if (subscription_types[i].type == subtype) {
10576          return &subscription_types[i];
10577       }
10578    }
10579    return &subscription_types[0];
10580 }

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

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

Definition at line 2680 of file chan_sip.c.

References ASTOBJ_CONTAINER_FIND, realtime_user(), and userl.

02681 {
02682    struct sip_user *u = ASTOBJ_CONTAINER_FIND(&userl, name);
02683    if (!u && realtime)
02684       u = realtime_user(name);
02685    return u;
02686 }

static void free_old_route ( struct sip_route route  )  [static]

Remove route from route list.

Definition at line 8056 of file chan_sip.c.

References free, and sip_route::next.

Referenced by __sip_destroy(), and build_route().

08057 {
08058    struct sip_route *next;
08059 
08060    while (route) {
08061       next = route->next;
08062       free(route);
08063       route = next;
08064    }
08065 }

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

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

11563 {
11564    if (ast_strlen_zero(data)) {
11565       ast_log(LOG_WARNING, "CHECKSIPDOMAIN requires an argument - A domain name\n");
11566       return -1;
11567    }
11568    if (check_sip_domain(data, NULL, 0))
11569       ast_copy_string(buf, data, len);
11570    else
11571       buf[0] = '\0';
11572    return 0;
11573 }

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

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

11499 {
11500    struct sip_pvt *p;
11501    const char *content = NULL;
11502    AST_DECLARE_APP_ARGS(args,
11503       AST_APP_ARG(header);
11504       AST_APP_ARG(number);
11505    );
11506    int i, number, start = 0;
11507 
11508    if (ast_strlen_zero(data)) {
11509       ast_log(LOG_WARNING, "This function requires a header name.\n");
11510       return -1;
11511    }
11512 
11513    ast_channel_lock(chan);
11514    if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) {
11515       ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n");
11516       ast_channel_unlock(chan);
11517       return -1;
11518    }
11519 
11520    AST_STANDARD_APP_ARGS(args, data);
11521    if (!args.number) {
11522       number = 1;
11523    } else {
11524       sscanf(args.number, "%d", &number);
11525       if (number < 1)
11526          number = 1;
11527    }
11528 
11529    p = chan->tech_pvt;
11530 
11531    /* If there is no private structure, this channel is no longer alive */
11532    if (!p) {
11533       ast_channel_unlock(chan);
11534       return -1;
11535    }
11536 
11537    for (i = 0; i < number; i++)
11538       content = __get_header(&p->initreq, args.header, &start);
11539 
11540    if (ast_strlen_zero(content)) {
11541       ast_channel_unlock(chan);
11542       return -1;
11543    }
11544 
11545    ast_copy_string(buf, content, len);
11546    ast_channel_unlock(chan);
11547 
11548    return 0;
11549 }

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

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

11678 {
11679    struct sip_pvt *p;
11680 
11681    *buf = 0;
11682    
11683    if (!data) {
11684       ast_log(LOG_WARNING, "This function requires a parameter name.\n");
11685       return -1;
11686    }
11687 
11688    ast_channel_lock(chan);
11689    if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) {
11690       ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n");
11691       ast_channel_unlock(chan);
11692       return -1;
11693    }
11694 
11695    p = chan->tech_pvt;
11696 
11697    /* If there is no private structure, this channel is no longer alive */
11698    if (!p) {
11699       ast_channel_unlock(chan);
11700       return -1;
11701    }
11702 
11703    if (!strcasecmp(data, "peerip")) {
11704       ast_copy_string(buf, p->sa.sin_addr.s_addr ? ast_inet_ntoa(p->sa.sin_addr) : "", len);
11705    } else  if (!strcasecmp(data, "recvip")) {
11706       ast_copy_string(buf, p->recv.sin_addr.s_addr ? ast_inet_ntoa(p->recv.sin_addr) : "", len);
11707    } else  if (!strcasecmp(data, "from")) {
11708       ast_copy_string(buf, p->from, len);
11709    } else  if (!strcasecmp(data, "uri")) {
11710       ast_copy_string(buf, p->uri, len);
11711    } else  if (!strcasecmp(data, "useragent")) {
11712       ast_copy_string(buf, p->useragent, len);
11713    } else  if (!strcasecmp(data, "peername")) {
11714       ast_copy_string(buf, p->peername, len);
11715    } else if (!strcasecmp(data, "t38passthrough")) {
11716       if (p->t38.state == T38_DISABLED)
11717          ast_copy_string(buf, "0", sizeof("0"));
11718       else    /* T38 is offered or enabled in this call */
11719          ast_copy_string(buf, "1", sizeof("1"));
11720    } else {
11721       ast_channel_unlock(chan);
11722       return -1;
11723    }
11724    ast_channel_unlock(chan);
11725 
11726    return 0;
11727 }

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

11588 {
11589    struct sip_peer *peer;
11590    char *colname;
11591 
11592    if ((colname = strchr(data, ':')))  /*! \todo Will be deprecated after 1.4 */
11593       *colname++ = '\0';
11594    else if ((colname = strchr(data, '|')))
11595       *colname++ = '\0';
11596    else
11597       colname = "ip";
11598 
11599    if (!(peer = find_peer(data, NULL, 1)))
11600       return -1;
11601 
11602    if (!strcasecmp(colname, "ip")) {
11603       ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "", len);
11604    } else  if (!strcasecmp(colname, "status")) {
11605       peer_status(peer, buf, len);
11606    } else  if (!strcasecmp(colname, "language")) {
11607       ast_copy_string(buf, peer->language, len);
11608    } else  if (!strcasecmp(colname, "regexten")) {
11609       ast_copy_string(buf, peer->regexten, len);
11610    } else  if (!strcasecmp(colname, "limit")) {
11611       snprintf(buf, len, "%d", peer->call_limit);
11612    } else  if (!strcasecmp(colname, "curcalls")) {
11613       snprintf(buf, len, "%d", peer->inUse);
11614    } else  if (!strcasecmp(colname, "accountcode")) {
11615       ast_copy_string(buf, peer->accountcode, len);
11616    } else  if (!strcasecmp(colname, "useragent")) {
11617       ast_copy_string(buf, peer->useragent, len);
11618    } else  if (!strcasecmp(colname, "mailbox")) {
11619       ast_copy_string(buf, peer->mailbox, len);
11620    } else  if (!strcasecmp(colname, "context")) {
11621       ast_copy_string(buf, peer->context, len);
11622    } else  if (!strcasecmp(colname, "expire")) {
11623       snprintf(buf, len, "%d", peer->expire);
11624    } else  if (!strcasecmp(colname, "dynamic")) {
11625       ast_copy_string(buf, (ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC) ? "yes" : "no"), len);
11626    } else  if (!strcasecmp(colname, "callerid_name")) {
11627       ast_copy_string(buf, peer->cid_name, len);
11628    } else  if (!strcasecmp(colname, "callerid_num")) {
11629       ast_copy_string(buf, peer->cid_num, len);
11630    } else  if (!strcasecmp(colname, "codecs")) {
11631       ast_getformatname_multiple(buf, len -1, peer->capability);
11632    } else  if (!strncasecmp(colname, "codec[", 6)) {
11633       char *codecnum;
11634       int index = 0, codec = 0;
11635       
11636       codecnum = colname + 6; /* move past the '[' */
11637       codecnum = strsep(&codecnum, "]"); /* trim trailing ']' if any */
11638       index = atoi(codecnum);
11639       if((codec = ast_codec_pref_index(&peer->prefs, index))) {
11640          ast_copy_string(buf, ast_getformatname(codec), len);
11641       }
11642    }
11643 
11644    ASTOBJ_UNREF(peer, sip_destroy_peer);
11645 
11646    return 0;
11647 }

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

Generate 32 byte random string for callid's etc.

Definition at line 4300 of file chan_sip.c.

References ast_random().

Referenced by build_callid_pvt(), and build_callid_registry().

04301 {
04302    long val[4];
04303    int x;
04304 
04305    for (x=0; x<4; x++)
04306       val[x] = ast_random();
04307    snprintf(buf, size, "%08lx%08lx%08lx%08lx", val[0], val[1], val[2], val[3]);
04308 
04309    return buf;
04310 }

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

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

Referenced by handle_request_bye().

08938 {
08939    char tmp[256] = "", *c, *a;
08940    struct sip_request *req = oreq ? oreq : &p->initreq;
08941    struct sip_refer *referdata = p->refer;
08942    const char *transfer_context = NULL;
08943    
08944    ast_copy_string(tmp, get_header(req, "Also"), sizeof(tmp));
08945    c = get_in_brackets(tmp);
08946 
08947    if (pedanticsipchecking)
08948       ast_uri_decode(c);
08949    
08950    if (strncasecmp(c, "sip:", 4)) {
08951       ast_log(LOG_WARNING, "Huh?  Not a SIP header in Also: transfer (%s)?\n", c);
08952       return -1;
08953    }
08954    c += 4;
08955    if ((a = strchr(c, ';')))  /* Remove arguments */
08956       *a = '\0';
08957    
08958    if ((a = strchr(c, '@'))) {   /* Separate Domain */
08959       *a++ = '\0';
08960       ast_copy_string(referdata->refer_to_domain, a, sizeof(referdata->refer_to_domain));
08961    }
08962    
08963    if (sip_debug_test_pvt(p))
08964       ast_verbose("Looking for %s in %s\n", c, p->context);
08965 
08966    if (p->owner)  /* Mimic behaviour in res_features.c */
08967       transfer_context = pbx_builtin_getvar_helper(p->owner, "TRANSFER_CONTEXT");
08968 
08969    /* By default, use the context in the channel sending the REFER */
08970    if (ast_strlen_zero(transfer_context)) {
08971       transfer_context = S_OR(p->owner->macrocontext,
08972                S_OR(p->context, default_context));
08973    }
08974    if (ast_exists_extension(NULL, transfer_context, c, 1, NULL)) {
08975       /* This is a blind transfer */
08976       if (option_debug)
08977          ast_log(LOG_DEBUG,"SIP Bye-also transfer to Extension %s@%s \n", c, transfer_context);
08978       ast_copy_string(referdata->refer_to, c, sizeof(referdata->refer_to));
08979       ast_copy_string(referdata->referred_by, "", sizeof(referdata->referred_by));
08980       ast_copy_string(referdata->refer_contact, "", sizeof(referdata->refer_contact));
08981       referdata->refer_call = NULL;
08982       /* Set new context */
08983       ast_string_field_set(p, context, transfer_context);
08984       return 0;
08985    } else if (ast_canmatch_extension(NULL, p->context, c, 1, NULL)) {
08986       return 1;
08987    }
08988 
08989    return -1;
08990 }

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

Get a specific line from the message body.

Definition at line 4091 of file chan_sip.c.

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

Referenced by handle_request_info().

04092 {
04093    int x;
04094    int len = strlen(name);
04095    char *r;
04096 
04097    for (x = 0; x < req->lines; x++) {
04098       r = get_body_by_line(req->line[x], name, len);
04099       if (r[0] != '\0')
04100          return r;
04101    }
04102 
04103    return "";
04104 }

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

Referenced by get_body(), and get_sdp_iterate().

04058 {
04059    if (strncasecmp(line, name, nameLen) == 0 && line[nameLen] == '=')
04060       return ast_skip_blanks(line + nameLen + 1);
04061 
04062    return "";
04063 }

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

Get caller id name from SIP headers.

Definition at line 9044 of file chan_sip.c.

Referenced by check_user_full().

09045 {
09046    const char *end = strchr(input,'<');   /* first_bracket */
09047    const char *tmp = strchr(input,'"');   /* first quote */
09048    int bytes = 0;
09049    int maxbytes = outputsize - 1;
09050 
09051    if (!end || end == input)  /* we require a part in brackets */
09052       return NULL;
09053 
09054    end--; /* move just before "<" */
09055 
09056    if (tmp && tmp <= end) {
09057       /* The quote (tmp) precedes the bracket (end+1).
09058        * Find the matching quote and return the content.
09059        */
09060       end = strchr(tmp+1, '"');
09061       if (!end)
09062          return NULL;
09063       bytes = (int) (end - tmp);
09064       /* protect the output buffer */
09065       if (bytes > maxbytes)
09066          bytes = maxbytes;
09067       ast_copy_string(output, tmp + 1, bytes);
09068    } else {
09069       /* No quoted string, or it is inside brackets. */
09070       /* clear the empty characters in the begining*/
09071       input = ast_skip_blanks(input);
09072       /* clear the empty characters in the end */
09073       while(*end && *end < 33 && end > input)
09074          end--;
09075       if (end >= input) {
09076          bytes = (int) (end - input) + 2;
09077          /* protect the output buffer */
09078          if (bytes > maxbytes)
09079             bytes = maxbytes;
09080          ast_copy_string(output, input, bytes);
09081       } else
09082          return NULL;
09083    }
09084    return output;
09085 }

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

08612 {
08613    char tmp[256] = "", *uri, *a;
08614    char tmpf[256] = "", *from;
08615    struct sip_request *req;
08616    char *colon;
08617    
08618    req = oreq;
08619    if (!req)
08620       req = &p->initreq;
08621 
08622    /* Find the request URI */
08623    if (req->rlPart2)
08624       ast_copy_string(tmp, req->rlPart2, sizeof(tmp));
08625    
08626    if (pedanticsipchecking)
08627       ast_uri_decode(tmp);
08628 
08629    uri = get_in_brackets(tmp);
08630 
08631    if (strncasecmp(uri, "sip:", 4)) {
08632       ast_log(LOG_WARNING, "Huh?  Not a SIP header (%s)?\n", uri);
08633       return -1;
08634    }
08635    uri += 4;
08636 
08637    /* Now find the From: caller ID and name */
08638    ast_copy_string(tmpf, get_header(req, "From"), sizeof(tmpf));
08639    if (!ast_strlen_zero(tmpf)) {
08640       if (pedanticsipchecking)
08641          ast_uri_decode(tmpf);
08642       from = get_in_brackets(tmpf);
08643    } else {
08644       from = NULL;
08645    }
08646    
08647    if (!ast_strlen_zero(from)) {
08648       if (strncasecmp(from, "sip:", 4)) {
08649          ast_log(LOG_WARNING, "Huh?  Not a SIP header (%s)?\n", from);
08650          return -1;
08651       }
08652       from += 4;
08653       if ((a = strchr(from, '@')))
08654          *a++ = '\0';
08655       else
08656          a = from;   /* just a domain */
08657       from = strsep(&from, ";"); /* Remove userinfo options */
08658       a = strsep(&a, ";");    /* Remove URI options */
08659       ast_string_field_set(p, fromdomain, a);
08660    }
08661 
08662    /* Skip any options and find the domain */
08663 
08664    /* Get the target domain */
08665    if ((a = strchr(uri, '@'))) {
08666       *a++ = '\0';
08667    } else { /* No username part */
08668       a = uri;
08669       uri = "s";  /* Set extension to "s" */
08670    }
08671    colon = strchr(a, ':'); /* Remove :port */
08672    if (colon)
08673       *colon = '\0';
08674 
08675    uri = strsep(&uri, ";");   /* Remove userinfo options */
08676    a = strsep(&a, ";");    /* Remove URI options */
08677 
08678    ast_string_field_set(p, domain, a);
08679 
08680    if (!AST_LIST_EMPTY(&domain_list)) {
08681       char domain_context[AST_MAX_EXTENSION];
08682 
08683       domain_context[0] = '\0';
08684       if (!check_sip_domain(p->domain, domain_context, sizeof(domain_context))) {
08685          if (!allow_external_domains && (req->method == SIP_INVITE || req->method == SIP_REFER)) {
08686             if (option_debug)
08687                ast_log(LOG_DEBUG, "Got SIP %s to non-local domain '%s'; refusing request.\n", sip_methods[req->method].text, p->domain);
08688             return -2;
08689          }
08690       }
08691       /* If we have a context defined, overwrite the original context */
08692       if (!ast_strlen_zero(domain_context))
08693          ast_string_field_set(p, context, domain_context);
08694    }
08695 
08696    if (sip_debug_test_pvt(p))
08697       ast_verbose("Looking for %s in %s (domain %s)\n", uri, p->context, p->domain);
08698 
08699    /* Check the dialplan for the username part of the request URI,
08700       the domain will be stored in the SIPDOMAIN variable
08701       Return 0 if we have a matching extension */
08702    if (ast_exists_extension(NULL, p->context, uri, 1, from) ||
08703       !strcmp(uri, ast_pickup_ext())) {
08704       if (!oreq)
08705          ast_string_field_set(p, exten, uri);
08706       return 0;
08707    }
08708 
08709    /* Return 1 for pickup extension or overlap dialling support (if we support it) */
08710    if((ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP) && 
08711        ast_canmatch_extension(NULL, p->context, uri, 1, from)) ||
08712        !strncmp(uri, ast_pickup_ext(), strlen(uri))) {
08713       return 1;
08714    }
08715    
08716    return -1;
08717 }

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

Get header from SIP request.

Definition at line 4180 of file chan_sip.c.

References __get_header().

04181 {
04182    int start = 0;
04183    return __get_header(req, name, &start);
04184 }

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

02302 {
02303    const char *parse = tmp;
02304    char *first_bracket;
02305 
02306    /*
02307     * Skip any quoted text until we find the part in brackets.
02308          * On any error give up and return the full string.
02309          */
02310         while ( (first_bracket = strchr(parse, '<')) ) {
02311                 char *first_quote = strchr(parse, '"');
02312 
02313       if (!first_quote || first_quote > first_bracket)
02314          break; /* no need to look at quoted part */
02315       /* the bracket is within quotes, so ignore it */
02316       parse = find_closing_quote(first_quote + 1, NULL);
02317       if (!*parse) { /* not found, return full string ? */
02318          /* XXX or be robust and return in-bracket part ? */
02319          ast_log(LOG_WARNING, "No closing quote found in '%s'\n", tmp);
02320          break;
02321       }
02322       parse++;
02323    }
02324    if (first_bracket) {
02325       char *second_bracket = strchr(first_bracket + 1, '>');
02326       if (second_bracket) {
02327          *second_bracket = '\0';
02328          tmp = first_bracket + 1;
02329       } else {
02330          ast_log(LOG_WARNING, "No closing bracket found in '%s'\n", tmp);
02331       }
02332    }
02333    return tmp;
02334 }

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

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

Referenced by handle_request_notify(), and receive_message().

09452 {
09453    int x;
09454    int y;
09455 
09456    buf[0] = '\0';
09457    y = len - strlen(buf) - 5;
09458    if (y < 0)
09459       y = 0;
09460    for (x=0;x<req->lines;x++) {
09461       strncat(buf, req->line[x], y); /* safe */
09462       y -= strlen(req->line[x]) + 1;
09463       if (y < 0)
09464          y = 0;
09465       if (y != 0)
09466          strcat(buf, "\n"); /* safe */
09467    }
09468    return 0;
09469 }

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

Get referring dnis.

Definition at line 8582 of file chan_sip.c.

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

Referenced by handle_request_invite().

08583 {
08584    char tmp[256], *c, *a;
08585    struct sip_request *req;
08586    
08587    req = oreq;
08588    if (!req)
08589       req = &p->initreq;
08590    ast_copy_string(tmp, get_header(req, "Diversion"), sizeof(tmp));
08591    if (ast_strlen_zero(tmp))
08592       return 0;
08593    c = get_in_brackets(tmp);
08594    if (strncasecmp(c, "sip:", 4)) {
08595       ast_log(LOG_WARNING, "Huh?  Not an RDNIS SIP header (%s)?\n", c);
08596       return -1;
08597    }
08598    c += 4;
08599    a = c;
08600    strsep(&a, "@;"); /* trim anything after @ or ; */
08601    if (sip_debug_test_pvt(p))
08602       ast_verbose("RDNIS is %s\n", c);
08603    ast_string_field_set(p, rdnis, c);
08604 
08605    return 0;
08606 }

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

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

Referenced by handle_request_refer().

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

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

References AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED.

Referenced by check_user_full().

09092 {
09093    char *start;
09094    char *end;
09095 
09096    start = strchr(input,':');
09097    if (!start) {
09098       output[0] = '\0';
09099       return 0;
09100    }
09101    start++;
09102 
09103    /* we found "number" */
09104    ast_copy_string(output,start,maxlen);
09105    output[maxlen-1] = '\0';
09106 
09107    end = strchr(output,'@');
09108    if (end)
09109       *end = '\0';
09110    else
09111       output[0] = '\0';
09112    if (strstr(input,"privacy=full") || strstr(input,"privacy=uri"))
09113       return AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED;
09114 
09115    return 0;
09116 }

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

Get a line from an SDP message body.

Definition at line 4083 of file chan_sip.c.

References get_sdp_iterate().

04084 {
04085    int dummy = 0;
04086 
04087    return get_sdp_iterate(&dummy, req, name);
04088 }

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

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

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

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

Lock interface lock and find matching pvt lock

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

08725 {
08726    struct sip_pvt *sip_pvt_ptr;
08727 
08728    ast_mutex_lock(&iflock);
08729 
08730    if (option_debug > 3 && totag)
08731       ast_log(LOG_DEBUG, "Looking for callid %s (fromtag %s totag %s)\n", callid, fromtag ? fromtag : "<no fromtag>", totag ? totag : "<no totag>");
08732 
08733    /* Search interfaces and find the match */
08734    for (sip_pvt_ptr = iflist; sip_pvt_ptr; sip_pvt_ptr = sip_pvt_ptr->next) {
08735       if (!strcmp(sip_pvt_ptr->callid, callid)) {
08736          int match = 1;
08737          char *ourtag = sip_pvt_ptr->tag;
08738 
08739          /* Go ahead and lock it (and its owner) before returning */
08740          ast_mutex_lock(&sip_pvt_ptr->lock);
08741 
08742          /* Check if tags match. If not, this is not the call we want
08743             (With a forking SIP proxy, several call legs share the
08744             call id, but have different tags)
08745          */
08746          if (pedanticsipchecking && (strcmp(fromtag, sip_pvt_ptr->theirtag) || (!ast_strlen_zero(totag) && strcmp(totag, ourtag))))
08747             match = 0;
08748 
08749          if (!match) {
08750             ast_mutex_unlock(&sip_pvt_ptr->lock);
08751             continue;
08752          }
08753 
08754          if (option_debug > 3 && totag)             
08755             ast_log(LOG_DEBUG, "Matched %s call - their tag is %s Our tag is %s\n",
08756                ast_test_flag(&sip_pvt_ptr->flags[0], SIP_OUTGOING) ? "OUTGOING": "INCOMING",
08757                sip_pvt_ptr->theirtag, sip_pvt_ptr->tag);
08758 
08759          /* deadlock avoidance... */
08760          while (sip_pvt_ptr->owner && ast_channel_trylock(sip_pvt_ptr->owner)) {
08761             ast_mutex_unlock(&sip_pvt_ptr->lock);
08762             usleep(1);
08763             ast_mutex_lock(&sip_pvt_ptr->lock);
08764          }
08765          break;
08766       }
08767    }
08768    ast_mutex_unlock(&iflock);
08769    if (option_debug > 3 && !sip_pvt_ptr)
08770       ast_log(LOG_DEBUG, "Found no match for callid %s to-tag %s from-tag %s\n", callid, totag, fromtag);
08771    return sip_pvt_ptr;
08772 }

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

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

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

13048 {
13049    const char *thetag;
13050 
13051    if (!tagbuf)
13052       return NULL;
13053    tagbuf[0] = '\0';    /* reset the buffer */
13054    thetag = get_header(req, header);
13055    thetag = strcasestr(thetag, ";tag=");
13056    if (thetag) {
13057       thetag += 5;
13058       ast_copy_string(tagbuf, thetag, tagbufsize);
13059       return strsep(&tagbuf, ";");
13060    }
13061    return NULL;
13062 }

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

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

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

15780 {
15781    int res = 1;
15782 
15783    if (!strcasecmp(v->name, "trustrpid")) {
15784       ast_set_flag(&mask[0], SIP_TRUSTRPID);
15785       ast_set2_flag(&flags[0], ast_true(v->value), SIP_TRUSTRPID);
15786    } else if (!strcasecmp(v->name, "sendrpid")) {
15787       ast_set_flag(&mask[0], SIP_SENDRPID);
15788       ast_set2_flag(&flags[0], ast_true(v->value), SIP_SENDRPID);
15789    } else if (!strcasecmp(v->name, "g726nonstandard")) {
15790       ast_set_flag(&mask[0], SIP_G726_NONSTANDARD);
15791       ast_set2_flag(&flags[0], ast_true(v->value), SIP_G726_NONSTANDARD);
15792    } else if (!strcasecmp(v->name, "useclientcode")) {
15793       ast_set_flag(&mask[0], SIP_USECLIENTCODE);
15794       ast_set2_flag(&flags[0], ast_true(v->value), SIP_USECLIENTCODE);
15795    } else if (!strcasecmp(v->name, "dtmfmode")) {
15796       ast_set_flag(&mask[0], SIP_DTMF);
15797       ast_clear_flag(&flags[0], SIP_DTMF);
15798       if (!strcasecmp(v->value, "inband"))
15799          ast_set_flag(&flags[0], SIP_DTMF_INBAND);
15800       else if (!strcasecmp(v->value, "rfc2833"))
15801          ast_set_flag(&flags[0], SIP_DTMF_RFC2833);
15802       else if (!strcasecmp(v->value, "info"))
15803          ast_set_flag(&flags[0], SIP_DTMF_INFO);
15804       else if (!strcasecmp(v->value, "auto"))
15805          ast_set_flag(&flags[0], SIP_DTMF_AUTO);
15806       else {
15807          ast_log(LOG_WARNING, "Unknown dtmf mode '%s' on line %d, using rfc2833\n", v->value, v->lineno);
15808          ast_set_flag(&flags[0], SIP_DTMF_RFC2833);
15809       }
15810    } else if (!strcasecmp(v->name, "nat")) {
15811       ast_set_flag(&mask[0], SIP_NAT);
15812       ast_clear_flag(&flags[0], SIP_NAT);
15813       if (!strcasecmp(v->value, "never"))
15814          ast_set_flag(&flags[0], SIP_NAT_NEVER);
15815       else if (!strcasecmp(v->value, "route"))
15816          ast_set_flag(&flags[0], SIP_NAT_ROUTE);
15817       else if (ast_true(v->value))
15818          ast_set_flag(&flags[0], SIP_NAT_ALWAYS);
15819       else
15820          ast_set_flag(&flags[0], SIP_NAT_RFC3581);
15821    } else if (!strcasecmp(v->name, "canreinvite")) {
15822       ast_set_flag(&mask[0], SIP_REINVITE);
15823       ast_clear_flag(&flags[0], SIP_REINVITE);
15824       if(ast_true(v->value)) {
15825          ast_set_flag(&flags[0], SIP_CAN_REINVITE | SIP_CAN_REINVITE_NAT);
15826       } else if (!ast_false(v->value)) {
15827          char buf[64];
15828          char *word, *next = buf;
15829 
15830          ast_copy_string(buf, v->value, sizeof(buf));
15831          while ((word = strsep(&next, ","))) {
15832             if(!strcasecmp(word, "update")) {
15833                ast_set_flag(&flags[0], SIP_REINVITE_UPDATE | SIP_CAN_REINVITE);
15834             } else if(!strcasecmp(word, "nonat")) {
15835                ast_set_flag(&flags[0], SIP_CAN_REINVITE);
15836                ast_clear_flag(&flags[0], SIP_CAN_REINVITE_NAT);
15837             } else {
15838                ast_log(LOG_WARNING, "Unknown canreinvite mode '%s' on line %d\n", v->value, v->lineno);
15839             }
15840          }
15841       }
15842    } else if (!strcasecmp(v->name, "insecure")) {
15843       ast_set_flag(&mask[0], SIP_INSECURE_PORT | SIP_INSECURE_INVITE);
15844       ast_clear_flag(&flags[0], SIP_INSECURE_PORT | SIP_INSECURE_INVITE);
15845       set_insecure_flags(flags, v->value, v->lineno);
15846    } else if (!strcasecmp(v->name, "progressinband")) {
15847       ast_set_flag(&mask[0], SIP_PROG_INBAND);
15848       ast_clear_flag(&flags[0], SIP_PROG_INBAND);
15849       if (ast_true(v->value))
15850          ast_set_flag(&flags[0], SIP_PROG_INBAND_YES);
15851       else if (strcasecmp(v->value, "never"))
15852          ast_set_flag(&flags[0], SIP_PROG_INBAND_NO);
15853    } else if (!strcasecmp(v->name, "promiscredir")) {
15854       ast_set_flag(&mask[0], SIP_PROMISCREDIR);
15855       ast_set2_flag(&flags[0], ast_true(v->value), SIP_PROMISCREDIR);
15856    } else if (!strcasecmp(v->name, "videosupport")) {
15857       ast_set_flag(&mask[1], SIP_PAGE2_VIDEOSUPPORT);
15858       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_VIDEOSUPPORT);
15859    } else if (!strcasecmp(v->name, "allowoverlap")) {
15860       ast_set_flag(&mask[1], SIP_PAGE2_ALLOWOVERLAP);
15861       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_ALLOWOVERLAP);
15862    } else if (!strcasecmp(v->name, "allowsubscribe")) {
15863       ast_set_flag(&mask[1], SIP_PAGE2_ALLOWSUBSCRIBE);
15864       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_ALLOWSUBSCRIBE);
15865    } else if (!strcasecmp(v->name, "t38pt_udptl")) {
15866       ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT_UDPTL);
15867       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_T38SUPPORT_UDPTL);
15868 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS
15869    } else if (!strcasecmp(v->name, "t38pt_rtp")) {
15870       ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT_RTP);
15871       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_T38SUPPORT_RTP);
15872    } else if (!strcasecmp(v->name, "t38pt_tcp")) {
15873       ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT_TCP);
15874       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_T38SUPPORT_TCP);
15875 #endif
15876    } else if (!strcasecmp(v->name, "rfc2833compensate")) {
15877       ast_set_flag(&mask[1], SIP_PAGE2_RFC2833_COMPENSATE);
15878       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_RFC2833_COMPENSATE);
15879    } else if (!strcasecmp(v->name, "buggymwi")) {
15880       ast_set_flag(&mask[1], SIP_PAGE2_BUGGY_MWI);
15881       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_BUGGY_MWI);
15882    } else
15883       res = 0;
15884 
15885    return res;
15886 }

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

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

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 14873 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, cfsip_methods::id, sip_pvt::initreq, INV_TERMINATED, len, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, sip_request::method, option_debug, process_sdp(), sip_request::rlPart1, sip_request::rlPart2, SIP_ACK, SIP_ALREADYGONE, SIP_BYE, SIP_CANCEL, sip_debug_test_pvt(), SIP_INFO, SIP_INVITE, SIP_MESSAGE, sip_methods, SIP_NEEDDESTROY, SIP_NOTIFY, SIP_OPTIONS, SIP_PKT_DEBUG, SIP_PKT_IGNORE, SIP_PKT_IGNORE_REQ, SIP_PKT_IGNORE_RESP, SIP_PKT_WITH_TOTAG, SIP_REFER, SIP_REGISTER, SIP_RESPONSE, sip_scheddestroy(), SIP_SUBSCRIBE, sip_pvt::tag, cfsip_methods::text, transmit_response(), transmit_response_reliable(), transmit_response_with_allow(), and TRUE.

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

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

Handle incoming BYE request.

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

14441 {
14442    struct ast_channel *c=NULL;
14443    int res;
14444    struct ast_channel *bridged_to;
14445    
14446    /* If we have an INCOMING invite that we haven't answered, terminate that transaction */
14447    if (p->pendinginvite && !ast_test_flag(&p->flags[0], SIP_OUTGOING) && !ast_test_flag(req, SIP_PKT_IGNORE) && !p->owner) 
14448       transmit_response_reliable(p, "487 Request Terminated", &p->initreq);
14449 
14450    p->invitestate = INV_TERMINATED;
14451 
14452    copy_request(&p->initreq, req);
14453    check_via(p, req);
14454    sip_alreadygone(p);
14455 
14456    /* Get RTCP quality before end of call */
14457    if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY) || p->owner) {
14458       char *audioqos, *videoqos;
14459       if (p->rtp) {
14460          audioqos = ast_rtp_get_quality(p->rtp, NULL);
14461          if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY))
14462             append_history(p, "RTCPaudio", "Quality:%s", audioqos);
14463          if (p->owner)
14464             pbx_builtin_setvar_helper(p->owner, "RTPAUDIOQOS", audioqos);
14465       }
14466       if (p->vrtp) {
14467          videoqos = ast_rtp_get_quality(p->vrtp, NULL);
14468          if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY))
14469             append_history(p, "RTCPvideo", "Quality:%s", videoqos);
14470          if (p->owner)
14471             pbx_builtin_setvar_helper(p->owner, "RTPVIDEOQOS", videoqos);
14472       }
14473    }
14474 
14475    stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */
14476 
14477    if (!ast_strlen_zero(get_header(req, "Also"))) {
14478       ast_log(LOG_NOTICE, "Client '%s' using deprecated BYE/Also transfer method.  Ask vendor to support REFER instead\n",
14479          ast_inet_ntoa(p->recv.sin_addr));
14480       if (ast_strlen_zero(p->context))
14481          ast_string_field_set(p, context, default_context);
14482       res = get_also_info(p, req);
14483       if (!res) {
14484          c = p->owner;
14485          if (c) {
14486             bridged_to = ast_bridged_channel(c);
14487             if (bridged_to) {
14488                /* Don't actually hangup here... */
14489                ast_queue_control(c, AST_CONTROL_UNHOLD);
14490                ast_async_goto(bridged_to, p->context, p->refer->refer_to,1);
14491             } else
14492                ast_queue_hangup(p->owner);
14493          }
14494       } else {
14495          ast_log(LOG_WARNING, "Invalid transfer information from '%s'\n", ast_inet_ntoa(p->recv.sin_addr));
14496          if (p->owner)
14497             ast_queue_hangup(p->owner);
14498       }
14499    } else if (p->owner) {
14500       ast_queue_hangup(p->owner);
14501       if (option_debug > 2)
14502          ast_log(LOG_DEBUG, "Received bye, issuing owner hangup\n");
14503    } else {
14504       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
14505       if (option_debug > 2)
14506          ast_log(LOG_DEBUG, "Received bye, no owner, selfdestruct soon.\n");
14507    }
14508    transmit_response(p, "200 OK", req);
14509 
14510    return 1;
14511 }

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

Handle incoming CANCEL request.

Definition at line 14342 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, INV_CANCELLED, sip_pvt::invitestate, LOG_DEBUG, option_debug, sip_pvt::owner, sip_dual::req, sip_alreadygone(), SIP_INC_COUNT, SIP_PAGE2_CALL_ONHOLD, sip_scheddestroy(), stop_media_flows(), transmit_response(), transmit_response_reliable(), and update_call_counter().

Referenced by handle_request().

14343 {
14344       
14345    check_via(p, req);
14346    sip_alreadygone(p);
14347    p->invitestate = INV_CANCELLED;
14348    
14349    if (p->owner && p->owner->_state == AST_STATE_UP) {
14350       /* This call is up, cancel is ignored, we need a bye */
14351       transmit_response(p, "200 OK", req);
14352       if (option_debug)
14353          ast_log(LOG_DEBUG, "Got CANCEL on an answered call. Ignoring... \n");
14354       return 0;
14355    }
14356 
14357    if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) 
14358       update_call_counter(p, DEC_CALL_LIMIT);
14359 
14360    stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */
14361 
14362    if (p->owner)
14363       ast_queue_hangup(p->owner);
14364    else
14365       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
14366    if (p->initreq.len > 0) {
14367       transmit_response_reliable(p, "487 Request Terminated", &p->initreq);
14368       transmit_response(p, "200 OK", req);
14369       return 1;
14370    } else {
14371       transmit_response(p, "481 Call Leg Does Not Exist", req);
14372       return 0;
14373    }
14374 }

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

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

Referenced by handle_request().

10924 {
10925    char buf[1024];
10926    unsigned int event;
10927    const char *c = get_header(req, "Content-Type");
10928 
10929    /* Need to check the media/type */
10930    if (!strcasecmp(c, "application/dtmf-relay") ||
10931        !strcasecmp(c, "application/vnd.nortelnetworks.digits")) {
10932       unsigned int duration = 0;
10933 
10934       /* Try getting the "signal=" part */
10935       if (ast_strlen_zero(c = get_body(req, "Signal")) && ast_strlen_zero(c = get_body(req, "d"))) {
10936          ast_log(LOG_WARNING, "Unable to retrieve DTMF signal from INFO message from %s\n", p->callid);
10937          transmit_response(p, "200 OK", req); /* Should return error */
10938          return;
10939       } else {
10940          ast_copy_string(buf, c, sizeof(buf));
10941       }
10942 
10943       if (!ast_strlen_zero((c = get_body(req, "Duration"))))
10944          duration = atoi(c);
10945       if (!duration)
10946          duration = 100; /* 100 ms */
10947 
10948       if (!p->owner) {  /* not a PBX call */
10949          transmit_response(p, "481 Call leg/transaction does not exist", req);
10950          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
10951          return;
10952       }
10953 
10954       if (ast_strlen_zero(buf)) {
10955          transmit_response(p, "200 OK", req);
10956          return;
10957       }
10958 
10959       if (buf[0] == '*')
10960          event = 10;
10961       else if (buf[0] == '#')
10962          event = 11;
10963       else if ((buf[0] >= 'A') && (buf[0] <= 'D'))
10964          event = 12 + buf[0] - 'A';
10965       else
10966          event = atoi(buf);
10967       if (event == 16) {
10968          /* send a FLASH event */
10969          struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_FLASH, };
10970          ast_queue_frame(p->owner, &f);
10971          if (sipdebug)
10972             ast_verbose("* DTMF-relay event received: FLASH\n");
10973       } else {
10974          /* send a DTMF event */
10975          struct ast_frame f = { AST_FRAME_DTMF, };
10976          if (event < 10) {
10977             f.subclass = '0' + event;
10978          } else if (event < 11) {
10979             f.subclass = '*';
10980          } else if (event < 12) {
10981             f.subclass = '#';
10982          } else if (event < 16) {
10983             f.subclass = 'A' + (event - 12);
10984          }
10985          f.len = duration;
10986          ast_queue_frame(p->owner, &f);
10987          if (sipdebug)
10988             ast_verbose("* DTMF-relay event received: %c\n", f.subclass);
10989       }
10990       transmit_response(p, "200 OK", req);
10991       return;
10992    } else if (!strcasecmp(c, "application/media_control+xml")) {
10993       /* Eh, we'll just assume it's a fast picture update for now */
10994       if (p->owner)
10995          ast_queue_control(p->owner, AST_CONTROL_VIDUPDATE);
10996       transmit_response(p, "200 OK", req);
10997       return;
10998    } else if (!ast_strlen_zero(c = get_header(req, "X-ClientCode"))) {
10999       /* Client code (from SNOM phone) */
11000       if (ast_test_flag(&p->flags[0], SIP_USECLIENTCODE)) {
11001          if (p->owner && p->owner->cdr)
11002             ast_cdr_setuserfield(p->owner, c);
11003          if (p->owner && ast_bridged_channel(p->owner) && ast_bridged_channel(p->owner)->cdr)
11004             ast_cdr_setuserfield(ast_bridged_channel(p->owner), c);
11005          transmit_response(p, "200 OK", req);
11006       } else {
11007          transmit_response(p, "403 Unauthorized", req);
11008       }
11009       return;
11010    }
11011    /* Other type of INFO message, not really understood by Asterisk */
11012    /* if (get_msg_text(buf, sizeof(buf), req)) { */
11013 
11014    ast_log(LOG_WARNING, "Unable to parse INFO message from %s. Content %s\n", p->callid, buf);
11015    transmit_response(p, "415 Unsupported media type", req);
11016    return;
11017 }

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 13383 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, sip_pvt::lock, ast_channel::lock, LOG_DEBUG, LOG_NOTICE, 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().

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

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

Handle incoming MESSAGE request.

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

14515 {
14516    if (!ast_test_flag(req, SIP_PKT_IGNORE)) {
14517       if (ast_test_flag(req, SIP_PKT_DEBUG))
14518          ast_verbose("Receiving message!\n");
14519       receive_message(p, req);
14520    } else
14521       transmit_response(p, "202 Accepted", req);
14522    return 1;
14523 }

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

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

Referenced by handle_request().

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

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

Handle incoming OPTIONS request.

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

13198 {
13199    int res;
13200 
13201    res = get_destination(p, req);
13202    build_contact(p);
13203    /* XXX Should we authenticate OPTIONS? XXX */
13204    if (ast_strlen_zero(p->context))
13205       ast_string_field_set(p, context, default_context);
13206    if (res < 0)
13207       transmit_response_with_allow(p, "404 Not Found", req, 0);
13208    else 
13209       transmit_response_with_allow(p, "200 OK", req, 0);
13210    /* Destroy if this OPTIONS was the opening request, but not if
13211       it's in the middle of a normal call flow. */
13212    if (!p->lastinvite)
13213       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
13214 
13215    return res;
13216 }

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

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

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

14821 {
14822    enum check_auth_result res;
14823 
14824    /* Use this as the basis */
14825    if (ast_test_flag(req, SIP_PKT_DEBUG))
14826       ast_verbose("Using latest REGISTER request as basis request\n");
14827    copy_request(&p->initreq, req);
14828    check_via(p, req);
14829    if ((res = register_verify(p, sin, req, e)) < 0) {
14830       const char *reason;
14831 
14832       switch (res) {
14833       case AUTH_SECRET_FAILED:
14834          reason = "Wrong password";
14835          break;
14836       case AUTH_USERNAME_MISMATCH:
14837          reason = "Username/auth name mismatch";
14838          break;
14839       case AUTH_NOT_FOUND:
14840          reason = "No matching peer found";
14841          break;
14842       case AUTH_UNKNOWN_DOMAIN:
14843          reason = "Not a local domain";
14844          break;
14845       case AUTH_PEER_NOT_DYNAMIC:
14846          reason = "Peer is not supposed to register";
14847          break;
14848       case AUTH_ACL_FAILED:
14849          reason = "Device does not match ACL";
14850          break;
14851       default:
14852          reason = "Unknown failure";
14853          break;
14854       }
14855       ast_log(LOG_NOTICE, "Registration from '%s' failed for '%s' - %s\n",
14856          get_header(req, "To"), ast_inet_ntoa(sin->sin_addr),
14857          reason);
14858       append_history(p, "RegRequest", "Failed : Account %s : %s", get_header(req, "To"), reason);
14859    } else
14860       append_history(p, "RegRequest", "Succeeded : Account %s", get_header(req, "To"));
14861 
14862    if (res < 1) {
14863       /* Destroy the session, but keep us around for just a bit in case they don't
14864          get our 200 OK */
14865       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
14866    }
14867    return res;
14868 }

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 14526 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, sip_peer::mailbox, make_our_tag(), sip_request::method, sip_peer::mwipvt, sip_pvt::next, NONE, option_debug, parse_ok_contact(), PIDF_XML, sip_pvt::relatedpeer, sip_pvt::sa, sip_cancel_destroy(), sip_destroy(), sip_destroy_peer(), sip_methods, SIP_NEEDDESTROY, SIP_PAGE2_ALLOWSUBSCRIBE, SIP_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().

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

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 12379 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(), 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, LOG_DEBUG, LOG_NOTICE, MAX_AUTHTRIES, sip_pvt::method, NONE, option_debug, option_verbose, sip_pvt::owner, parse_moved_contact(), process_sdp(), sip_pvt::refer, sip_pvt::relatedpeer, SIP_ACK, sip_alreadygone(), SIP_BYE, SIP_CANCEL, sip_cancel_destroy(), SIP_INFO, SIP_INVITE, SIP_MESSAGE, sip_methods, SIP_NEEDDESTROY, SIP_NOTIFY, SIP_OPTIONS, SIP_OUTGOING, SIP_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.

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

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 11818 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, authenticate(), 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, INV_CALLING, INV_COMPLETED, INV_EARLY_MEDIA, INV_PROCEEDING, INV_TERMINATED, sip_pvt::invitestate, sip_pvt::lock, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, MAX_AUTHTRIES, option_debug, sip_pvt::owner, parse_ok_contact(), process_sdp(), PROXY_AUTH, sched, set_address_from_contact(), SIP_ACK, sip_alreadygone(), SIP_ALREADYGONE, sip_cancel_destroy(), sip_handle_t38_reinvite(), SIP_INVITE, SIP_NEEDDESTROY, SIP_OUTGOING, SIP_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(), WWW_AUTH, XMIT_ERROR, and XMIT_UNRELIABLE.

Referenced by handle_response().

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

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

Handle qualification responses (OPTIONS).

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

Referenced by handle_response().

12320 {
12321    struct sip_peer *peer = p->relatedpeer;
12322    int statechanged, is_reachable, was_reachable;
12323    int pingtime = ast_tvdiff_ms(ast_tvnow(), peer->ps);
12324 
12325    /*
12326     * Compute the response time to a ping (goes in peer->lastms.)
12327     * -1 means did not respond, 0 means unknown,
12328     * 1..maxms is a valid response, >maxms means late response.
12329     */
12330    if (pingtime < 1) /* zero = unknown, so round up to 1 */
12331       pingtime = 1;
12332 
12333    /* Now determine new state and whether it has changed.
12334     * Use some helper variables to simplify the writing
12335     * of the expressions.
12336     */
12337    was_reachable = peer->lastms > 0 && peer->lastms <= peer->maxms;
12338    is_reachable = pingtime <= peer->maxms;
12339    statechanged = peer->lastms == 0 /* yes, unknown before */
12340       || was_reachable != is_reachable;
12341 
12342    peer->lastms = pingtime;
12343    peer->call = NULL;
12344    if (statechanged) {
12345       const char *s = is_reachable ? "Reachable" : "Lagged";
12346 
12347       ast_log(LOG_NOTICE, "Peer '%s' is now %s. (%dms / %dms)\n",
12348          peer->name, s, pingtime, peer->maxms);
12349       ast_device_state_changed("SIP/%s", peer->name);
12350       manager_event(EVENT_FLAG_SYSTEM, "PeerStatus",
12351          "Peer: SIP/%s\r\nPeerStatus: %s\r\nTime: %d\r\n",
12352          peer->name, s, pingtime);
12353    }
12354 
12355    if (peer->pokeexpire > -1)
12356       ast_sched_del(sched, peer->pokeexpire);
12357    ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12358 
12359    /* Try again eventually */
12360    peer->pokeexpire = ast_sched_add(sched,
12361       is_reachable ? DEFAULT_FREQ_OK : DEFAULT_FREQ_NOTOK,
12362       sip_poke_peer_s, peer);
12363 }

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

Definition at line 12120 of file chan_sip.c.

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

Referenced by handle_response().

12121 {
12122    char *auth = "Proxy-Authenticate";
12123    char *auth2 = "Proxy-Authorization";
12124 
12125    /* If no refer structure exists, then do nothing */
12126    if (!p->refer)
12127       return;
12128 
12129    switch (resp) {
12130    case 202:   /* Transfer accepted */
12131       /* We need  to do something here */
12132       /* The transferee is now sending INVITE to target */
12133       p->refer->status = REFER_ACCEPTED;
12134       /* Now wait for next message */
12135       if (option_debug > 2)
12136          ast_log(LOG_DEBUG, "Got 202 accepted on transfer\n");
12137       /* We should hang along, waiting for NOTIFY's here */
12138       break;
12139 
12140    case 401:   /* Not www-authorized on SIP method */
12141    case 407:   /* Proxy auth */
12142       if (ast_strlen_zero(p->authname)) {
12143          ast_log(LOG_WARNING, "Asked to authenticate REFER to %s:%d but we have no matching peer or realm auth!\n",
12144             ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port));
12145          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
12146       }
12147       if (resp == 401) {
12148          auth = "WWW-Authenticate";
12149          auth2 = "Authorization";
12150       }
12151       if ((p->authtries > 1) || do_proxy_auth(p, req, auth, auth2, SIP_REFER, 0)) {
12152          ast_log(LOG_NOTICE, "Failed to authenticate on REFER to '%s'\n", get_header(&p->initreq, "From"));
12153          p->refer->status = REFER_NOAUTH;
12154          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
12155       }
12156       break;
12157    case 481: /* Call leg does not exist */
12158 
12159       /* A transfer with Replaces did not work */
12160       /* OEJ: We should Set flag, cancel the REFER, go back
12161       to original call - but right now we can't */
12162       ast_log(LOG_WARNING, "Remote host can't match REFER request to call '%s'. Giving up.\n", p->callid);
12163       if (p->owner)
12164          ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
12165       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
12166       break;
12167 
12168    case 500:   /* Server error */
12169    case 501:   /* Method not implemented */
12170       /* Return to the current call onhold */
12171       /* Status flag needed to be reset */
12172       ast_log(LOG_NOTICE, "SIP transfer to %s failed, call miserably fails. \n", p->refer->refer_to);
12173       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
12174       p->refer->status = REFER_FAILED;
12175       break;
12176    case 603:   /* Transfer declined */
12177       ast_log(LOG_NOTICE, "SIP transfer to %s declined, call miserably fails. \n", p->refer->refer_to);
12178       p->refer->status = REFER_FAILED;
12179       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
12180       break;
12181    }
12182 }

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

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

Referenced by handle_response().

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

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

03361 {
03362    switch (cause) {
03363       case AST_CAUSE_UNALLOCATED:      /* 1 */
03364       case AST_CAUSE_NO_ROUTE_DESTINATION:   /* 3 IAX2: Can't find extension in context */
03365       case AST_CAUSE_NO_ROUTE_TRANSIT_NET:   /* 2 */
03366          return "404 Not Found";
03367       case AST_CAUSE_CONGESTION:    /* 34 */
03368       case AST_CAUSE_SWITCH_CONGESTION:   /* 42 */
03369          return "503 Service Unavailable";
03370       case AST_CAUSE_NO_USER_RESPONSE: /* 18 */
03371          return "408 Request Timeout";
03372       case AST_CAUSE_NO_ANSWER:     /* 19 */
03373          return "480 Temporarily unavailable";
03374       case AST_CAUSE_CALL_REJECTED:    /* 21 */
03375          return "403 Forbidden";
03376       case AST_CAUSE_NUMBER_CHANGED:      /* 22 */
03377          return "410 Gone";
03378       case AST_CAUSE_NORMAL_UNSPECIFIED:  /* 31 */
03379          return "480 Temporarily unavailable";
03380       case AST_CAUSE_INVALID_NUMBER_FORMAT:
03381          return "484 Address incomplete";
03382       case AST_CAUSE_USER_BUSY:
03383          return "486 Busy here";
03384       case AST_CAUSE_FAILURE:
03385          return "500 Server internal failure";
03386       case AST_CAUSE_FACILITY_REJECTED:   /* 29 */
03387          return "501 Not Implemented";
03388       case AST_CAUSE_CHAN_NOT_IMPLEMENTED:
03389          return "503 Service Unavailable";
03390       /* Used in chan_iax2 */
03391       case AST_CAUSE_DESTINATION_OUT_OF_ORDER:
03392          return "502 Bad Gateway";
03393       case AST_CAUSE_BEARERCAPABILITY_NOTAVAIL: /* Can't find codec to connect to host */
03394          return "488 Not Acceptable Here";
03395          
03396       case AST_CAUSE_NOTDEFINED:
03397       default:
03398          if (option_debug)
03399             ast_log(LOG_DEBUG, "AST hangup cause %d (no match found in SIP)\n", cause);
03400          return NULL;
03401    }
03402 
03403    /* Never reached */
03404    return 0;
03405 }

static int hangup_sip2cause ( int  cause  )  [static]

Convert SIP hangup causes to Asterisk hangup causes.

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

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

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

Initialize SIP request.

Definition at line 5708 of file chan_sip.c.

References sip_methods, and cfsip_methods::text.

05709 {
05710    /* Initialize a request */
05711    memset(req, 0, sizeof(*req));
05712         req->method = sipmethod;
05713    req->header[0] = req->data;
05714    snprintf(req->header[0], sizeof(req->data), "%s %s SIP/2.0\r\n", sip_methods[sipmethod].text, recip);
05715    req->len = strlen(req->header[0]);
05716    req->headers++;
05717    return 0;
05718 }

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

Initialize SIP response, based on SIP request.

Definition at line 5695 of file chan_sip.c.

References SIP_RESPONSE.

05696 {
05697    /* Initialize a response */
05698    memset(resp, 0, sizeof(*resp));
05699    resp->method = SIP_RESPONSE;
05700    resp->header[0] = resp->data;
05701    snprintf(resp->header[0], sizeof(resp->data), "SIP/2.0 %s\r\n", msg);
05702    resp->len = strlen(resp->header[0]);
05703    resp->headers++;
05704    return 0;
05705 }

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

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

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

Initiate new SIP request to peer/user.

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

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

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

Convert Insecure setting to printable string.

Definition at line 9872 of file chan_sip.c.

Referenced by _sip_show_peer().

09873 {
09874    if (port && invite)
09875       return "port,invite";
09876    else if (port)
09877       return "port";
09878    else if (invite)
09879       return "invite";
09880    else
09881       return "no";
09882 }

static void list_route ( struct sip_route route  )  [static]

List all routes - mostly for debugging.

Definition at line 8068 of file chan_sip.c.

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

Referenced by build_route().

08069 {
08070    if (!route)
08071       ast_verbose("list_route: no route\n");
08072    else {
08073       for (;route; route = route->next)
08074          ast_verbose("list_route: hop: <%s>\n", route->hop);
08075    }
08076 }

static int load_module ( void   )  [static]

PBX load module - initialization.

Definition at line 17688 of file chan_sip.c.

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

17689 {
17690    ASTOBJ_CONTAINER_INIT(&userl);   /* User object list */
17691    ASTOBJ_CONTAINER_INIT(&peerl);   /* Peer object list */
17692    ASTOBJ_CONTAINER_INIT(&regl); /* Registry object list */
17693 
17694    if (!(sched = sched_context_create())) {
17695       ast_log(LOG_ERROR, "Unable to create scheduler context\n");
17696       return AST_MODULE_LOAD_FAILURE;
17697    }
17698 
17699    if (!(io = io_context_create())) {
17700       ast_log(LOG_ERROR, "Unable to create I/O context\n");
17701       sched_context_destroy(sched);
17702       return AST_MODULE_LOAD_FAILURE;
17703    }
17704 
17705    sip_reloadreason = CHANNEL_MODULE_LOAD;
17706 
17707    if(reload_config(sip_reloadreason)) /* Load the configuration from sip.conf */
17708       return AST_MODULE_LOAD_DECLINE;
17709 
17710    /* Make sure we can register our sip channel type */
17711    if (ast_channel_register(&sip_tech)) {
17712       ast_log(LOG_ERROR, "Unable to register channel type 'SIP'\n");
17713       io_context_destroy(io);
17714       sched_context_destroy(sched);
17715       return AST_MODULE_LOAD_FAILURE;
17716    }
17717 
17718    /* Register all CLI functions for SIP */
17719    ast_cli_register_multiple(cli_sip, sizeof(cli_sip)/ sizeof(struct ast_cli_entry));
17720 
17721    /* Tell the RTP subdriver that we're here */
17722    ast_rtp_proto_register(&sip_rtp);
17723 
17724    /* Tell the UDPTL subdriver that we're here */
17725    ast_udptl_proto_register(&sip_udptl);
17726 
17727    /* Register dialplan applications */
17728    ast_register_application(app_dtmfmode, sip_dtmfmode, synopsis_dtmfmode, descrip_dtmfmode);
17729    ast_register_application(app_sipaddheader, sip_addheader, synopsis_sipaddheader, descrip_sipaddheader);
17730 
17731    /* Register dialplan functions */
17732    ast_custom_function_register(&sip_header_function);
17733    ast_custom_function_register(&sippeer_function);
17734    ast_custom_function_register(&sipchaninfo_function);
17735    ast_custom_function_register(&checksipdomain_function);
17736 
17737    /* Register manager commands */
17738    ast_manager_register2("SIPpeers", EVENT_FLAG_SYSTEM, manager_sip_show_peers,
17739          "List SIP peers (text format)", mandescr_show_peers);
17740    ast_manager_register2("SIPshowpeer", EVENT_FLAG_SYSTEM, manager_sip_show_peer,
17741          "Show SIP peer (text format)", mandescr_show_peer);
17742 
17743    sip_poke_all_peers();   
17744    sip_send_all_registers();
17745    
17746    /* And start the monitor for the first time */
17747    restart_monitor();
17748 
17749    return AST_MODULE_LOAD_SUCCESS;
17750 }

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

13907 {
13908    struct sip_dual target;    /* Chan 1: Call from tranferer to Asterisk */
13909                /* Chan 2: Call from Asterisk to target */
13910    int res = 0;
13911    struct sip_pvt *targetcall_pvt;
13912 
13913    /* Check if the call ID of the replaces header does exist locally */
13914    if (!(targetcall_pvt = get_sip_pvt_byid_locked(transferer->refer->replaces_callid, transferer->refer->replaces_callid_totag, 
13915       transferer->refer->replaces_callid_fromtag))) {
13916       if (transferer->refer->localtransfer) {
13917          /* We did not find the refered call. Sorry, can't accept then */
13918          transmit_response(transferer, "202 Accepted", req);
13919          /* Let's fake a response from someone else in order
13920             to follow the standard */
13921          transmit_notify_with_sipfrag(transferer, seqno, "481 Call leg/transaction does not exist", TRUE);
13922          append_history(transferer, "Xfer", "Refer failed");
13923          ast_clear_flag(&transferer->flags[0], SIP_GOTREFER);  
13924          transferer->refer->status = REFER_FAILED;
13925          return -1;
13926       }
13927       /* Fall through for remote transfers that we did not find locally */
13928       if (option_debug > 2)
13929          ast_log(LOG_DEBUG, "SIP attended transfer: Not our call - generating INVITE with replaces\n");
13930       return 0;
13931    }
13932 
13933    /* Ok, we can accept this transfer */
13934    transmit_response(transferer, "202 Accepted", req);
13935    append_history(transferer, "Xfer", "Refer accepted");
13936    if (!targetcall_pvt->owner) { /* No active channel */
13937       if (option_debug > 3)
13938          ast_log(LOG_DEBUG, "SIP attended transfer: Error: No owner of target call\n");
13939       /* Cancel transfer */
13940       transmit_notify_with_sipfrag(transferer, seqno, "503 Service Unavailable", TRUE);
13941       append_history(transferer, "Xfer", "Refer failed");
13942       ast_clear_flag(&transferer->flags[0], SIP_GOTREFER);
13943       transferer->refer->status = REFER_FAILED;
13944       ast_mutex_unlock(&targetcall_pvt->lock);
13945       ast_channel_unlock(current->chan1);
13946       return -1;
13947    }
13948 
13949    /* We have a channel, find the bridge */
13950    target.chan1 = targetcall_pvt->owner;           /* Transferer to Asterisk */
13951    target.chan2 = ast_bridged_channel(targetcall_pvt->owner);  /* Asterisk to target */
13952 
13953    if (!target.chan2 || !(target.chan2->_state == AST_STATE_UP || target.chan2->_state == AST_STATE_RINGING) ) {
13954       /* Wrong state of new channel */
13955       if (option_debug > 3) {
13956          if (target.chan2) 
13957             ast_log(LOG_DEBUG, "SIP attended transfer: Error: Wrong state of target call: %s\n", ast_state2str(target.chan2->_state));
13958          else if (target.chan1->_state != AST_STATE_RING)
13959             ast_log(LOG_DEBUG, "SIP attended transfer: Error: No target channel\n");
13960          else
13961             ast_log(LOG_DEBUG, "SIP attended transfer: Attempting transfer in ringing state\n");
13962       }
13963    }
13964 
13965    /* Transfer */
13966    if (option_debug > 3 && sipdebug) {
13967       if (current->chan2)  /* We have two bridges */
13968          ast_log(LOG_DEBUG, "SIP attended transfer: trying to bridge %s and %s\n", target.chan1->name, current->chan2->name);
13969       else        /* One bridge, propably transfer of IVR/voicemail etc */
13970          ast_log(LOG_DEBUG, "SIP attended transfer: trying to make %s take over (masq) %s\n", target.chan1->name, current->chan1->name);
13971    }
13972 
13973    ast_set_flag(&transferer->flags[0], SIP_DEFER_BYE_ON_TRANSFER);   /* Delay hangup */
13974 
13975    /* Perform the transfer */
13976    res = attempt_transfer(current, &target);
13977    ast_mutex_unlock(&targetcall_pvt->lock);
13978    if (res) {
13979       /* Failed transfer */
13980       transmit_notify_with_sipfrag(transferer, seqno, "486 Busy Here", TRUE);
13981       append_history(transferer, "Xfer", "Refer failed");
13982       transferer->refer->status = REFER_FAILED;
13983       if (targetcall_pvt->owner)
13984          ast_channel_unlock(targetcall_pvt->owner);
13985       /* Right now, we have to hangup, sorry. Bridge is destroyed */
13986       if (res != -2)
13987          ast_hangup(transferer->owner);
13988       else
13989          ast_clear_flag(&transferer->flags[0], SIP_DEFER_BYE_ON_TRANSFER);
13990    } else {
13991       /* Transfer succeeded! */
13992 
13993       /* Tell transferer that we're done. */
13994       transmit_notify_with_sipfrag(transferer, seqno, "200 OK", TRUE);
13995       append_history(transferer, "Xfer", "Refer succeeded");
13996       transferer->refer->status = REFER_200OK;
13997       if (targetcall_pvt->owner) {
13998          if (option_debug)
13999             ast_log(LOG_DEBUG, "SIP attended transfer: Unlocking channel %s\n", targetcall_pvt->owner->name);
14000          ast_channel_unlock(targetcall_pvt->owner);
14001       }
14002    }
14003    return 1;
14004 }

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

References t.

Referenced by sipsock_read().

04663 {
04664    int h = 0, t = 0; 
04665    int lws = 0; 
04666 
04667    for (; h < len;) { 
04668       /* Eliminate all CRs */ 
04669       if (msgbuf[h] == '\r') { 
04670          h++; 
04671          continue; 
04672       } 
04673       /* Check for end-of-line */ 
04674       if (msgbuf[h] == '\n') { 
04675          /* Check for end-of-message */ 
04676          if (h + 1 == len) 
04677             break; 
04678          /* Check for a continuation line */ 
04679          if (msgbuf[h + 1] == ' ' || msgbuf[h + 1] == '\t') { 
04680             /* Merge continuation line */ 
04681             h++; 
04682             continue; 
04683          } 
04684          /* Propagate LF and start new line */ 
04685          msgbuf[t++] = msgbuf[h++]; 
04686          lws = 0;
04687          continue; 
04688       } 
04689       if (msgbuf[h] == ' ' || msgbuf[h] == '\t') { 
04690          if (lws) { 
04691             h++; 
04692             continue; 
04693          } 
04694          msgbuf[t++] = msgbuf[h++]; 
04695          lws = 1; 
04696          continue; 
04697       } 
04698       msgbuf[t++] = msgbuf[h++]; 
04699       if (lws) 
04700          lws = 0; 
04701    } 
04702    msgbuf[t] = '\0'; 
04703    return t; 
04704 }

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

Make our SIP dialog tag.

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

04335 {
04336    snprintf(tagbuf, len, "as%08lx", ast_random());
04337 }

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

Show SIP peers in the manager API.

Definition at line 10117 of file chan_sip.c.

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

Referenced by load_module().

10118 {
10119    const char *a[4];
10120    const char *peer;
10121    int ret;
10122 
10123    peer = astman_get_header(m,"Peer");
10124    if (ast_strlen_zero(peer)) {
10125       astman_send_error(s, m, "Peer: <name> missing.\n");
10126       return 0;
10127    }
10128    a[0] = "sip";
10129    a[1] = "show";
10130    a[2] = "peer";
10131    a[3] = peer;
10132 
10133    ret = _sip_show_peer(1, -1, s, m, 4, a);
10134    astman_append(s, "\r\n\r\n" );
10135    return ret;
10136 }

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

Show SIP peers in the manager API.

Definition at line 9668 of file chan_sip.c.

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

Referenced by load_module().

09669 {
09670    const char *id = astman_get_header(m,"ActionID");
09671    const char *a[] = {"sip", "show", "peers"};
09672    char idtext[256] = "";
09673    int total = 0;
09674 
09675    if (!ast_strlen_zero(id))
09676       snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
09677 
09678    astman_send_ack(s, m, "Peer status list will follow");
09679    /* List the peers in separate manager events */
09680    _sip_show_peers(-1, &total, s, m, 3, a);
09681    /* Send final confirmation */
09682    astman_append(s,
09683    "Event: PeerlistComplete\r\n"
09684    "ListItems: %d\r\n"
09685    "%s"
09686    "\r\n", total, idtext);
09687    return 0;
09688 }

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

References len, sip_methods, and text.

Referenced by __sip_semi_ack(), and find_sip_method().

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

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

Convert NAT setting to text string.

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

09572 {
09573    switch(nat) {
09574    case SIP_NAT_NEVER:
09575       return "No";
09576    case SIP_NAT_ROUTE:
09577       return "Route";
09578    case SIP_NAT_ALWAYS:
09579       return "Always";
09580    case SIP_NAT_RFC3581:
09581       return "RFC3581";
09582    default:
09583       return "Unknown";
09584    }
09585 }

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

Copy SIP request, parse it.

Definition at line 2206 of file chan_sip.c.

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

Referenced by send_request(), and send_response().

02207 {
02208    memset(dst, 0, sizeof(*dst));
02209    memcpy(dst->data, src->data, sizeof(dst->data));
02210    dst->len = src->len;
02211    parse_request(dst);
02212 }

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

Parse 302 Moved temporalily response.

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

11747 {
11748    char tmp[BUFSIZ];
11749    char *s, *e, *uri, *t;
11750    char *domain;
11751 
11752    ast_copy_string(tmp, get_header(req, "Contact"), sizeof(tmp));
11753    if ((t = strchr(tmp, ',')))
11754       *t = '\0';
11755    s = get_in_brackets(tmp);
11756    uri = ast_strdupa(s);
11757    if (ast_test_flag(&p->flags[0], SIP_PROMISCREDIR)) {
11758       if (!strncasecmp(s, "sip:", 4))
11759          s += 4;
11760       e = strchr(s, ';');
11761       if (e)
11762          *e = '\0';
11763       if (option_debug)
11764          ast_log(LOG_DEBUG, "Found promiscuous redirection to 'SIP/%s'\n", s);
11765       if (p->owner)
11766          ast_string_field_build(p->owner, call_forward, "SIP/%s", s);
11767    } else {
11768       e = strchr(tmp, '@');
11769       if (e) {
11770          *e++ = '\0';
11771          domain = e;
11772       } else {
11773          /* No username part */
11774          domain = tmp;
11775       }
11776       e = strchr(s, ';');  /* Strip of parameters in the username part */
11777       if (e)
11778          *e = '\0';
11779       e = strchr(domain, ';');   /* Strip of parameters in the domain part */
11780       if (e)
11781          *e = '\0';
11782    
11783       if (!strncasecmp(s, "sip:", 4))
11784          s += 4;
11785       if (option_debug > 1)
11786          ast_log(LOG_DEBUG, "Received 302 Redirect to extension '%s' (domain %s)\n", s, domain);
11787       if (p->owner) {
11788          pbx_builtin_setvar_helper(p->owner, "SIPREDIRECTURI", uri);
11789          pbx_builtin_setvar_helper(p->owner, "SIPDOMAIN", domain);
11790          ast_string_field_set(p->owner, call_forward, s);
11791       }
11792    }
11793 }

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

07825 {
07826    char contact[BUFSIZ]; 
07827    char *c;
07828 
07829    /* Look for brackets */
07830    ast_copy_string(contact, get_header(req, "Contact"), sizeof(contact));
07831    c = get_in_brackets(contact);
07832 
07833    /* Save full contact to call pvt for later bye or re-invite */
07834    ast_string_field_set(pvt, fullcontact, c);
07835 
07836    /* Save URI for later ACKs, BYE or RE-invites */
07837    ast_string_field_set(pvt, okcontacturi, c);
07838 
07839    /* We should return false for URI:s we can't handle,
07840       like sips:, tel:, mailto:,ldap: etc */
07841    return TRUE;      
07842 }

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

References sip_peer::addr, ahp, ast_db_put(), ast_gethostbyname(), ast_inet_ntoa(), ast_log(), ast_sched_add(), ast_sched_del(), ast_sched_when(), ast_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, manager_event(), option_verbose, PARSE_REGISTER_FAILED, PARSE_REGISTER_QUERY, PARSE_REGISTER_UPDATE, sip_pvt::recv, register_peer_exten(), sched, 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().

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

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

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

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

04710 {
04711    /* Divide fields by NULL's */
04712    char *c;
04713    int f = 0;
04714 
04715    c = req->data;
04716 
04717    /* First header starts immediately */
04718    req->header[f] = c;
04719    while(*c) {
04720       if (*c == '\n') {
04721          /* We've got a new header */
04722          *c = 0;
04723 
04724          if (sipdebug && option_debug > 3)
04725             ast_log(LOG_DEBUG, "Header %d: %s (%d)\n", f, req->header[f], (int) strlen(req->header[f]));
04726          if (ast_strlen_zero(req->header[f])) {
04727             /* Line by itself means we're now in content */
04728             c++;
04729             break;
04730          }
04731          if (f >= SIP_MAX_HEADERS - 1) {
04732             ast_log(LOG_WARNING, "Too many SIP headers. Ignoring.\n");
04733          } else
04734             f++;
04735          req->header[f] = c + 1;
04736       } else if (*c == '\r') {
04737          /* Ignore but eliminate \r's */
04738          *c = 0;
04739       }
04740       c++;
04741    }
04742    /* Check for last header */
04743    if (!ast_strlen_zero(req->header[f])) {
04744       if (sipdebug && option_debug > 3)
04745          ast_log(LOG_DEBUG, "Header %d: %s (%d)\n", f, req->header[f], (int) strlen(req->header[f]));
04746       f++;
04747    }
04748    req->headers = f;
04749    /* Now we process any mime content */
04750    f = 0;
04751    req->line[f] = c;
04752    while(*c) {
04753       if (*c == '\n') {
04754          /* We've got a new line */
04755          *c = 0;
04756          if (sipdebug && option_debug > 3)
04757             ast_log(LOG_DEBUG, "Line: %s (%d)\n", req->line[f], (int) strlen(req->line[f]));
04758          if (f >= SIP_MAX_LINES - 1) {
04759             ast_log(LOG_WARNING, "Too many SDP lines. Ignoring.\n");
04760          } else
04761             f++;
04762          req->line[f] = c + 1;
04763       } else if (*c == '\r') {
04764          /* Ignore and eliminate \r's */
04765          *c = 0;
04766       }
04767       c++;
04768    }
04769    /* Check for last line */
04770    if (!ast_strlen_zero(req->line[f])) 
04771       f++;
04772    req->lines = f;
04773    if (*c) 
04774       ast_log(LOG_WARNING, "Odd content, extra stuff left over ('%s')\n", c);
04775    /* Split up the first line parts */
04776    determine_firstline_parts(req);
04777 }

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

Parse supported header in incoming packet.

Definition at line 1681 of file chan_sip.c.

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

Referenced by handle_request_invite().

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

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

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

09591 {
09592    int res = 0;
09593    if (peer->maxms) {
09594       if (peer->lastms < 0) {
09595          ast_copy_string(status, "UNREACHABLE", statuslen);
09596       } else if (peer->lastms > peer->maxms) {
09597          snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms);
09598          res = 1;
09599       } else if (peer->lastms) {
09600          snprintf(status, statuslen, "OK (%d ms)", peer->lastms);
09601          res = 1;
09602       } else {
09603          ast_copy_string(status, "UNKNOWN", statuslen);
09604       }
09605    } else { 
09606       ast_copy_string(status, "Unmonitored", statuslen);
09607       /* Checking if port is 0 */
09608       res = -1;
09609    }
09610    return res;
09611 }

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

10059 {
10060    int x, codec;
10061 
10062    for(x = 0; x < 32 ; x++) {
10063       codec = ast_codec_pref_index(pref, x);
10064       if (!codec)
10065          break;
10066       ast_cli(fd, "%s", ast_getformatname(codec));
10067       ast_cli(fd, ":%d", pref->framing[x]);
10068       if (x < 31 && ast_codec_pref_index(pref, x + 1))
10069          ast_cli(fd, ",");
10070    }
10071    if (!x)
10072       ast_cli(fd, "none");
10073 }

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

Print call group and pickup group.

Definition at line 9849 of file chan_sip.c.

References ast_cli(), and ast_print_group().

Referenced by _sip_show_peer(), and sip_show_user().

09850 {
09851    char buf[256];
09852    ast_cli(fd, crlf ? "%s\r\n" : "%s\n", ast_print_group(buf, sizeof(buf), group) );
09853 }

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

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

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

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

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

Definition at line 2475 of file chan_sip.c.

References ast_category_browse(), ast_category_root(), ast_config_destroy(), ast_inet_ntoa(), ast_load_realtime(), ast_load_realtime_multientry(), ast_test_flag, ast_variable_retrieve(), ast_variables_destroy(), ast_flags::flags, ast_variable::name, ast_variable::next, set_insecure_flags(), SIP_INSECURE_PORT, ast_variable::value, and var.

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

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

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

02361 {
02362    char port[10];
02363    char ipaddr[INET_ADDRSTRLEN];
02364    char regseconds[20];
02365 
02366    char *sysname = ast_config_AST_SYSTEM_NAME;
02367    char *syslabel = NULL;
02368 
02369    time_t nowtime = time(NULL) + expirey;
02370    const char *fc = fullcontact ? "fullcontact" : NULL;
02371    
02372    snprintf(regseconds, sizeof(regseconds), "%d", (int)nowtime);  /* Expiration time */
02373    ast_copy_string(ipaddr, ast_inet_ntoa(sin->sin_addr), sizeof(ipaddr));
02374    snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port));
02375    
02376    if (ast_strlen_zero(sysname)) /* No system name, disable this */
02377       sysname = NULL;
02378    else if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTSAVE_SYSNAME))
02379       syslabel = "regserver";
02380 
02381    if (fc)
02382       ast_update_realtime("sippeers", "name", peername, "ipaddr", ipaddr,
02383          "port", port, "regseconds", regseconds,
02384          "username", username, fc, fullcontact, syslabel, sysname, NULL); /* note fc and syslabel _can_ be NULL */
02385    else
02386       ast_update_realtime("sippeers", "name", peername, "ipaddr", ipaddr,
02387          "port", port, "regseconds", regseconds,
02388          "username", username, syslabel, sysname, NULL); /* note syslabel _can_ be NULL */
02389 }

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

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

Definition at line 2636 of file chan_sip.c.

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

02637 {
02638    struct ast_variable *var;
02639    struct ast_variable *tmp;
02640    struct sip_user *user = NULL;
02641 
02642    var = ast_load_realtime("sipusers", "name", username, NULL);
02643 
02644    if (!var)
02645       return NULL;
02646 
02647    for (tmp = var; tmp; tmp = tmp->next) {
02648       if (!strcasecmp(tmp->name, "type") &&
02649          !strcasecmp(tmp->value, "peer")) {
02650          ast_variables_destroy(var);
02651          return NULL;
02652       }
02653    }
02654 
02655    user = build_user(username, var, !ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS));
02656    
02657    if (!user) {   /* No user found */
02658       ast_variables_destroy(var);
02659       return NULL;
02660    }
02661 
02662    if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) {
02663       ast_set_flag(&user->flags[1], SIP_PAGE2_RTCACHEFRIENDS);
02664       suserobjs++;
02665       ASTOBJ_CONTAINER_LINK(&userl,user);
02666    } else {
02667       /* Move counter from s to r... */
02668       suserobjs--;
02669       ruserobjs++;
02670       ast_set_flag(&user->flags[0], SIP_REALTIME);
02671    }
02672    ast_variables_destroy(var);
02673    return user;
02674 }

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

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

Referenced by handle_request_message().

09476 {
09477    char buf[1024];
09478    struct ast_frame f;
09479    const char *content_type = get_header(req, "Content-Type");
09480 
09481    if (strcmp(content_type, "text/plain")) { /* No text/plain attachment */
09482       transmit_response(p, "415 Unsupported Media Type", req); /* Good enough, or? */
09483       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
09484       return;
09485    }
09486 
09487    if (get_msg_text(buf, sizeof(buf), req)) {
09488       ast_log(LOG_WARNING, "Unable to retrieve text from %s\n", p->callid);
09489       transmit_response(p, "202 Accepted", req);
09490       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
09491       return;
09492    }
09493 
09494    if (p->owner) {
09495       if (sip_debug_test_pvt(p))
09496          ast_verbose("Message received: '%s'\n", buf);
09497       memset(&f, 0, sizeof(f));
09498       f.frametype = AST_FRAME_TEXT;
09499       f.subclass = 0;
09500       f.offset = 0;
09501       f.data = buf;
09502       f.datalen = strlen(buf);
09503       ast_queue_frame(p->owner, &f);
09504       transmit_response(p, "202 Accepted", req); /* We respond 202 accepted, since we relay the message */
09505    } else { /* Message outside of a call, we do not support that */
09506       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);
09507       transmit_response(p, "405 Method Not Allowed", req); /* Good enough, or? */
09508    }
09509    sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
09510    return;
09511 }

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

Convert transfer status to string.

Definition at line 1616 of file chan_sip.c.

References referstatusstrings, and text.

Referenced by __sip_show_channels().

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

static void reg_source_db ( struct sip_peer peer  )  [static]

Get registration details from Asterisk DB.

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

07765 {
07766    char data[256];
07767    struct in_addr in;
07768    int expiry;
07769    int port;
07770    char *scan, *addr, *port_str, *expiry_str, *username, *contact;
07771 
07772    if (ast_test_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT)) 
07773       return;
07774    if (ast_db_get("SIP/Registry", peer->name, data, sizeof(data)))
07775       return;
07776 
07777    scan = data;
07778    addr = strsep(&scan, ":");
07779    port_str = strsep(&scan, ":");
07780    expiry_str = strsep(&scan, ":");
07781    username = strsep(&scan, ":");
07782    contact = scan;   /* Contact include sip: and has to be the last part of the database entry as long as we use : as a separator */
07783 
07784    if (!inet_aton(addr, &in))
07785       return;
07786 
07787    if (port_str)
07788       port = atoi(port_str);
07789    else
07790       return;
07791 
07792    if (expiry_str)
07793       expiry = atoi(expiry_str);
07794    else
07795       return;
07796 
07797    if (username)
07798       ast_copy_string(peer->username, username, sizeof(peer->username));
07799    if (contact)
07800       ast_copy_string(peer->fullcontact, contact, sizeof(peer->fullcontact));
07801 
07802    if (option_debug > 1)
07803       ast_log(LOG_DEBUG, "SIP Seeding peer from astdb: '%s' at %s@%s:%d for %d\n",
07804              peer->name, peer->username, ast_inet_ntoa(in), port, expiry);
07805 
07806    memset(&peer->addr, 0, sizeof(peer->addr));
07807    peer->addr.sin_family = AF_INET;
07808    peer->addr.sin_addr = in;
07809    peer->addr.sin_port = htons(port);
07810    if (sipsock < 0) {
07811       /* SIP isn't up yet, so schedule a poke only, pretty soon */
07812       if (peer->pokeexpire > -1)
07813          ast_sched_del(sched, peer->pokeexpire);
07814       peer->pokeexpire = ast_sched_add(sched, ast_random() % 5000 + 1, sip_poke_peer_s, peer);
07815    } else
07816       sip_poke_peer(peer);
07817    if (peer->expire > -1)
07818       ast_sched_del(sched, peer->expire);
07819    peer->expire = ast_sched_add(sched, (expiry + 10) * 1000, expire_register, peer);
07820    register_peer_exten(peer, TRUE);
07821 }

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

Automatically add peer extension to dial plan.

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

02393 {
02394    char multi[256];
02395    char *stringp, *ext, *context;
02396 
02397    /* XXX note that global_regcontext is both a global 'enable' flag and
02398     * the name of the global regexten context, if not specified
02399     * individually.
02400     */
02401    if (ast_strlen_zero(global_regcontext))
02402       return;
02403 
02404    ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi));
02405    stringp = multi;
02406    while ((ext = strsep(&stringp, "&"))) {
02407       if ((context = strchr(ext, '@'))) {
02408          *context++ = '\0';   /* split ext@context */
02409          if (!ast_context_find(context)) {
02410             ast_log(LOG_WARNING, "Context %s must exist in regcontext= in sip.conf!\n", context);
02411             continue;
02412          }
02413       } else {
02414          context = global_regcontext;
02415       }
02416       if (onoff)
02417          ast_add_extension(context, 1, ext, 1, NULL, NULL, "Noop",
02418              ast_strdup(peer->name), ast_free, "SIP");
02419       else
02420          ast_context_remove_extension(context, ext, 1, NULL);
02421    }
02422 }

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

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

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

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

Convert registration state status to string.

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

07264 {
07265    switch(regstate) {
07266    case REG_STATE_FAILED:
07267       return "Failed";
07268    case REG_STATE_UNREGISTERED:
07269       return "Unregistered";
07270    case REG_STATE_REGSENT:
07271       return "Request Sent";
07272    case REG_STATE_AUTHSENT:
07273       return "Auth. Sent";
07274    case REG_STATE_REGISTERED:
07275       return "Registered";
07276    case REG_STATE_REJECTED:
07277       return "Rejected";
07278    case REG_STATE_TIMEOUT:
07279       return "Timeout";
07280    case REG_STATE_NOAUTH:
07281       return "No Authentication";
07282    default:
07283       return "Unknown";
07284    }
07285 }

static int reload ( void   )  [static]

Part of Asterisk module interface.

Definition at line 17574 of file chan_sip.c.

References sip_reload().

17575 {
17576    return sip_reload(0, 0, NULL);
17577 }

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

References ahp, ast_clear_flag, ast_config_AST_SYSTEM_NAME, ast_config_load(), ast_copy_flags, AST_FLAGS_ALL, ast_free_ha(), ast_jb_read_conf(), ast_log(), AST_MAX_CONTEXT, ast_set_flag, ast_strlen_zero(), ast_true(), ast_variable_browse(), bindaddr, context, DEFAULT_ALLOW_EXT_DOM, DEFAULT_ALLOWGUEST, DEFAULT_AUTOCREATEPEER, DEFAULT_CALLERID, DEFAULT_COMPACTHEADERS, DEFAULT_CONTEXT, DEFAULT_EXPIRY, default_jbconf, DEFAULT_MAX_CALL_BITRATE, 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, externexpire, externhost, externip, externrefresh, FALSE, global_flags, global_jbconf, handle_common_options(), hp, localaddr, LOG_NOTICE, ast_variable::name, ast_variable::next, ourport, outboundproxyip, SIP_CAN_REINVITE, SIP_DTMF_RFC2833, SIP_NAT_RFC3581, SIP_PAGE2_ALLOWOVERLAP, SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PAGE2_DEBUG_CONFIG, SIP_PAGE2_DEBUG_CONSOLE, SIP_PAGE2_RTUPDATE, SIP_PAGE2_VIDEOSUPPORT, STANDARD_SIP_PORT, TRANSFER_OPENFORALL, and ast_variable::value.

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

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

Referenced by do_proxy_auth(), and do_register_auth().

11262 {
11263    char tmp[512];
11264    char *c;
11265    char oldnonce[256];
11266 
11267    /* table of recognised keywords, and places where they should be copied */
11268    const struct x {
11269       const char *key;
11270       int field_index;
11271    } *i, keys[] = {
11272       { "realm=", ast_string_field_index(p, realm) },
11273       { "nonce=", ast_string_field_index(p, nonce) },
11274       { "opaque=", ast_string_field_index(p, opaque) },
11275       { "qop=", ast_string_field_index(p, qop) },
11276       { "domain=", ast_string_field_index(p, domain) },
11277       { NULL, 0 },
11278    };
11279 
11280    ast_copy_string(tmp, get_header(req, header), sizeof(tmp));
11281    if (ast_strlen_zero(tmp)) 
11282       return -1;
11283    if (strncasecmp(tmp, "Digest ", strlen("Digest "))) {
11284       ast_log(LOG_WARNING, "missing Digest.\n");
11285       return -1;
11286    }
11287    c = tmp + strlen("Digest ");
11288    ast_copy_string(oldnonce, p->nonce, sizeof(oldnonce));
11289    while (c && *(c = ast_skip_blanks(c))) {  /* lookup for keys */
11290       for (i = keys; i->key != NULL; i++) {
11291          char *src, *separator;
11292          if (strncasecmp(c, i->key, strlen(i->key)) != 0)
11293             continue;
11294          /* Found. Skip keyword, take text in quotes or up to the separator. */
11295          c += strlen(i->key);
11296          if (*c == '"') {
11297             src = ++c;
11298             separator = "\"";
11299          } else {
11300             src = c;
11301             separator = ",";
11302          }
11303          strsep(&c, separator); /* clear separator and move ptr */
11304          ast_string_field_index_set(p, i->field_index, src);
11305          break;
11306       }
11307       if (i->key == NULL) /* not found, try ',' */
11308          strsep(&c, ",");
11309    }
11310    /* Reset nonce count */
11311    if (strcmp(p->nonce, oldnonce)) 
11312       p->noncecount = 0;
11313 
11314    /* Save auth data for following registrations */
11315    if (p->registry) {
11316       struct sip_registry *r = p->registry;
11317 
11318       if (strcmp(r->nonce, p->nonce)) {
11319          ast_string_field_set(r, realm, p->realm);
11320          ast_string_field_set(r, nonce, p->nonce);
11321          ast_string_field_set(r, domain, p->domain);
11322          ast_string_field_set(r, opaque, p->opaque);
11323          ast_string_field_set(r, qop, p->qop);
11324          r->noncecount = 0;
11325       }
11326    }
11327    return build_reply_digest(p, sipmethod, digest, digest_len); 
11328 }

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

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

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

05723 {
05724    char newto[256];
05725    const char *ot;
05726 
05727    init_resp(resp, msg);
05728    copy_via_headers(p, resp, req, "Via");
05729    if (msg[0] == '2')
05730       copy_all_header(resp, req, "Record-Route");
05731    copy_header(resp, req, "From");
05732    ot = get_header(req, "To");
05733    if (!strcasestr(ot, "tag=") && strncmp(msg, "100", 3)) {
05734       /* Add the proper tag if we don't have it already.  If they have specified
05735          their tag, use it.  Otherwise, use our own tag */
05736       if (!ast_strlen_zero(p->theirtag) && ast_test_flag(&p->flags[0], SIP_OUTGOING))
05737          snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->theirtag);
05738       else if (p->tag && !ast_test_flag(&p->flags[0], SIP_OUTGOING))
05739          snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->tag);
05740       else
05741          ast_copy_string(newto, ot, sizeof(newto));
05742       ot = newto;
05743    }
05744    add_header(resp, "To", ot);
05745    copy_header(resp, req, "Call-ID");
05746    copy_header(resp, req, "CSeq");
05747    if (!ast_strlen_zero(global_useragent))
05748       add_header(resp, "User-Agent", global_useragent);
05749    add_header(resp, "Allow", ALLOWED_METHODS);
05750    add_header(resp, "Supported", SUPPORTED_EXTENSIONS);
05751    if (msg[0] == '2' && (p->method == SIP_SUBSCRIBE || p->method == SIP_REGISTER)) {
05752       /* For registration responses, we also need expiry and
05753          contact info */
05754       char tmp[256];
05755 
05756       snprintf(tmp, sizeof(tmp), "%d", p->expiry);
05757       add_header(resp, "Expires", tmp);
05758       if (p->expiry) {  /* Only add contact if we have an expiry time */
05759          char contact[BUFSIZ];
05760          snprintf(contact, sizeof(contact), "%s;expires=%d", p->our_contact, p->expiry);
05761          add_header(resp, "Contact", contact);  /* Not when we unregister */
05762       }
05763    } else if (msg[0] != '4' && p->our_contact[0]) {
05764       add_header(resp, "Contact", p->our_contact);
05765    }
05766    return 0;
05767 }

static int restart_monitor ( void   )  [static]

Start the channel monitor thread.

Definition at line 15424 of file chan_sip.c.

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

15425 {
15426    /* If we're supposed to be stopped -- stay stopped */
15427    if (monitor_thread == AST_PTHREADT_STOP)
15428       return 0;
15429    ast_mutex_lock(&monlock);
15430    if (monitor_thread == pthread_self()) {
15431       ast_mutex_unlock(&monlock);
15432       ast_log(LOG_WARNING, "Cannot kill myself\n");
15433       return -1;
15434    }
15435    if (monitor_thread != AST_PTHREADT_NULL) {
15436       /* Wake up the thread */
15437       pthread_kill(monitor_thread, SIGURG);
15438    } else {
15439       /* Start a new monitor */
15440       if (ast_pthread_create_background(&monitor_thread, NULL, do_monitor, NULL) < 0) {
15441          ast_mutex_unlock(&monlock);
15442          ast_log(LOG_ERROR, "Unable to start monitor thread.\n");
15443          return -1;
15444       }
15445    }
15446    ast_mutex_unlock(&monlock);
15447    return 0;
15448 }

static int retrans_pkt ( void *  data  )  [static]

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

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

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

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

02254 {
02255    int res;
02256 
02257    add_blank(req);
02258    if (sip_debug_test_pvt(p)) {
02259       if (ast_test_flag(&p->flags[0], SIP_NAT_ROUTE))
02260          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);
02261       else
02262          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);
02263    }
02264    if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) {
02265       struct sip_request tmp;
02266       parse_copy(&tmp, req);
02267       append_history(p, reliable ? "TxReqRel" : "TxReq", "%s / %s - %s", tmp.data, get_header(&tmp, "CSeq"), sip_methods[tmp.method].text);
02268    }
02269    res = (reliable) ?
02270       __sip_reliable_xmit(p, seqno, 0, req->data, req->len, (reliable == XMIT_CRITICAL), req->method) :
02271       __sip_xmit(p, req->data, req->len);
02272    return res;
02273 }

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

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

02226 {
02227    int res;
02228 
02229    add_blank(req);
02230    if (sip_debug_test_pvt(p)) {
02231       const struct sockaddr_in *dst = sip_real_dst(p);
02232 
02233       ast_verbose("\n<--- %sTransmitting (%s) to %s:%d --->\n%s\n<------------>\n",
02234          reliable ? "Reliably " : "", sip_nat_mode(p),
02235          ast_inet_ntoa(dst->sin_addr),
02236          ntohs(dst->sin_port), req->data);
02237    }
02238    if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) {
02239       struct sip_request tmp;
02240       parse_copy(&tmp, req);
02241       append_history(p, reliable ? "TxRespRel" : "TxResp", "%s / %s - %s", tmp.data, get_header(&tmp, "CSeq"), 
02242          (tmp.method == SIP_RESPONSE || tmp.method == SIP_UNKNOWN) ? tmp.rlPart2 : sip_methods[tmp.method].text);
02243    }
02244    res = (reliable) ?
02245        __sip_reliable_xmit(p, seqno, 1, req->data, req->len, (reliable == XMIT_CRITICAL), req->method) :
02246       __sip_xmit(p, req->data, req->len);
02247    if (res > 0)
02248       return 0;
02249    return res;
02250 }

static int set_address_from_contact ( struct sip_pvt pvt  )  [static]

Change the other partys IP address based on given contact.

Definition at line 7845 of file chan_sip.c.

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

Referenced by handle_response_invite().

07846 {
07847    struct hostent *hp;
07848    struct ast_hostent ahp;
07849    int port;
07850    char *c, *host, *pt;
07851    char *contact;
07852 
07853 
07854    if (ast_test_flag(&pvt->flags[0], SIP_NAT_ROUTE)) {
07855       /* NAT: Don't trust the contact field.  Just use what they came to us
07856          with. */
07857       pvt->sa = pvt->recv;
07858       return 0;
07859    }
07860 
07861 
07862    /* Work on a copy */
07863    contact = ast_strdupa(pvt->fullcontact);
07864 
07865    /* Make sure it's a SIP URL */
07866    if (strncasecmp(contact, "sip:", 4)) {
07867       ast_log(LOG_NOTICE, "'%s' is not a valid SIP contact (missing sip:) trying to use anyway\n", contact);
07868    } else
07869       contact += 4;
07870 
07871    /* Ditch arguments */
07872    /* XXX this code is replicated also shortly below */
07873 
07874    /* Grab host */
07875    host = strchr(contact, '@');
07876    if (!host) {   /* No username part */
07877       host = contact;
07878       c = NULL;
07879    } else {
07880       *host++ = '\0';
07881    }
07882    pt = strchr(host, ':');
07883    if (pt) {
07884       *pt++ = '\0';
07885       port = atoi(pt);
07886    } else
07887       port = STANDARD_SIP_PORT;
07888 
07889    contact = strsep(&contact, ";"); /* trim ; and beyond in username part */
07890    host = strsep(&host, ";");    /* trim ; and beyond in host/domain part */
07891 
07892    /* XXX This could block for a long time XXX */
07893    /* We should only do this if it's a name, not an IP */
07894    hp = ast_gethostbyname(host, &ahp);
07895    if (!hp)  {
07896       ast_log(LOG_WARNING, "Invalid host name in Contact: (can't resolve in DNS) : '%s'\n", host);
07897       return -1;
07898    }
07899    pvt->sa.sin_family = AF_INET;
07900    memcpy(&pvt->sa.sin_addr, hp->h_addr, sizeof(pvt->sa.sin_addr));
07901    pvt->sa.sin_port = htons(port);
07902 
07903    return 0;
07904 }

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

Set destination from SIP URI.

Definition at line 5631 of file chan_sip.c.

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

Referenced by reqprep().

05632 {
05633    char *h, *maddr, hostname[256];
05634    int port, hn;
05635    struct hostent *hp;
05636    struct ast_hostent ahp;
05637    int debug=sip_debug_test_pvt(p);
05638 
05639    /* Parse uri to h (host) and port - uri is already just the part inside the <> */
05640    /* general form we are expecting is sip[s]:username[:password]@host[:port][;...] */
05641 
05642    if (debug)
05643       ast_verbose("set_destination: Parsing <%s> for address/port to send to\n", uri);
05644 
05645    /* Find and parse hostname */
05646    h = strchr(uri, '@');
05647    if (h)
05648       ++h;
05649    else {
05650       h = uri;
05651       if (strncasecmp(h, "sip:", 4) == 0)
05652          h += 4;
05653       else if (strncasecmp(h, "sips:", 5) == 0)
05654          h += 5;
05655    }
05656    hn = strcspn(h, ":;>") + 1;
05657    if (hn > sizeof(hostname)) 
05658       hn = sizeof(hostname);
05659    ast_copy_string(hostname, h, hn);
05660    /* XXX bug here if string has been trimmed to sizeof(hostname) */
05661    h += hn - 1;
05662 
05663    /* Is "port" present? if not default to STANDARD_SIP_PORT */
05664    if (*h == ':') {
05665       /* Parse port */
05666       ++h;
05667       port = strtol(h, &h, 10);
05668    }
05669    else
05670       port = STANDARD_SIP_PORT;
05671 
05672    /* Got the hostname:port - but maybe there's a "maddr=" to override address? */
05673    maddr = strstr(h, "maddr=");
05674    if (maddr) {
05675       maddr += 6;
05676       hn = strspn(maddr, "0123456789.") + 1;
05677       if (hn > sizeof(hostname))
05678          hn = sizeof(hostname);
05679       ast_copy_string(hostname, maddr, hn);
05680    }
05681    
05682    hp = ast_gethostbyname(hostname, &ahp);
05683    if (hp == NULL)  {
05684       ast_log(LOG_WARNING, "Can't find address for host '%s'\n", hostname);
05685       return;
05686    }
05687    p->sa.sin_family = AF_INET;
05688    memcpy(&p->sa.sin_addr, hp->h_addr, sizeof(p->sa.sin_addr));
05689    p->sa.sin_port = htons(port);
05690    if (debug)
05691       ast_verbose("set_destination: set destination to %s, port %d\n", ast_inet_ntoa(p->sa.sin_addr), port);
05692 }

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

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

Referenced by handle_common_options(), and realtime_peer().

15729 {
15730    static int dep_insecure_very = 0;
15731    static int dep_insecure_yes = 0;
15732 
15733    if (ast_strlen_zero(value))
15734       return;
15735 
15736    if (!strcasecmp(value, "very")) {
15737       ast_set_flag(flags, SIP_INSECURE_PORT | SIP_INSECURE_INVITE);
15738       if(!dep_insecure_very) {
15739          if(lineno != -1)
15740             ast_log(LOG_WARNING, "insecure=very at line %d is deprecated; use insecure=port,invite instead\n", lineno);
15741          else
15742             ast_log(LOG_WARNING, "insecure=very is deprecated; use insecure=port,invite instead\n");
15743          dep_insecure_very = 1;
15744       }
15745    }
15746    else if (ast_true(value)) {
15747       ast_set_flag(flags, SIP_INSECURE_PORT);
15748       if(!dep_insecure_yes) {
15749          if(lineno != -1)
15750             ast_log(LOG_WARNING, "insecure=%s at line %d is deprecated; use insecure=port instead\n", value, lineno);
15751          else
15752             ast_log(LOG_WARNING, "insecure=%s is deprecated; use insecure=port instead\n", value);
15753          dep_insecure_yes = 1;
15754       }
15755    }
15756    else if (!ast_false(value)) {
15757       char buf[64];
15758       char *word, *next;
15759       ast_copy_string(buf, value, sizeof(buf));
15760       next = buf;
15761       while ((word = strsep(&next, ","))) {
15762          if (!strcasecmp(word, "port"))
15763             ast_set_flag(flags, SIP_INSECURE_PORT);
15764          else if (!strcasecmp(word, "invite"))
15765             ast_set_flag(flags, SIP_INSECURE_INVITE);
15766          else
15767             ast_log(LOG_WARNING, "Unknown insecure mode '%s' on line %d\n", value, lineno);
15768       }
15769    }
15770 }

static void set_peer_defaults ( struct sip_peer peer  )  [static]

Set peer defaults before configuring specific configurations.

Definition at line 16155 of file chan_sip.c.

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

Referenced by build_peer(), and temp_peer().

16156 {
16157    if (peer->expire == 0) {
16158       /* Don't reset expire or port time during reload 
16159          if we have an active registration 
16160       */
16161       peer->expire = -1;
16162       peer->pokeexpire = -1;
16163       peer->addr.sin_port = htons(STANDARD_SIP_PORT);
16164    }
16165    ast_copy_flags(&peer->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY);
16166    ast_copy_flags(&peer->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY);
16167    strcpy(peer->context, default_context);
16168    strcpy(peer->subscribecontext, default_subscribecontext);
16169    strcpy(peer->language, default_language);
16170    strcpy(peer->mohinterpret, default_mohinterpret);
16171    strcpy(peer->mohsuggest, default_mohsuggest);
16172    peer->addr.sin_family = AF_INET;
16173    peer->defaddr.sin_family = AF_INET;
16174    peer->capability = global_capability;
16175    peer->maxcallbitrate = default_maxcallbitrate;
16176    peer->rtptimeout = global_rtptimeout;
16177    peer->rtpholdtimeout = global_rtpholdtimeout;
16178    peer->rtpkeepalive = global_rtpkeepalive;
16179    peer->allowtransfer = global_allowtransfer;
16180    peer->autoframing = global_autoframing;
16181    strcpy(peer->vmexten, default_vmexten);
16182    peer->secret[0] = '\0';
16183    peer->md5secret[0] = '\0';
16184    peer->cid_num[0] = '\0';
16185    peer->cid_name[0] = '\0';
16186    peer->fromdomain[0] = '\0';
16187    peer->fromuser[0] = '\0';
16188    peer->regexten[0] = '\0';
16189    peer->mailbox[0] = '\0';
16190    peer->callgroup = 0;
16191    peer->pickupgroup = 0;
16192    peer->maxms = default_qualify;
16193    peer->prefs = default_prefs;
16194 }

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

Add a SIP header to an outbound INVITE.

Definition at line 17362 of file chan_sip.c.

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

Referenced by load_module().

17363 {
17364    int no = 0;
17365    int ok = FALSE;
17366    char varbuf[30];
17367    char *inbuf = (char *) data;
17368    
17369    if (ast_strlen_zero(inbuf)) {
17370       ast_log(LOG_WARNING, "This application requires the argument: Header\n");
17371       return 0;
17372    }
17373    ast_channel_lock(chan);
17374 
17375    /* Check for headers */
17376    while (!ok && no <= 50) {
17377       no++;
17378       snprintf(varbuf, sizeof(varbuf), "_SIPADDHEADER%.2d", no);
17379 
17380       /* Compare without the leading underscore */
17381       if( (pbx_builtin_getvar_helper(chan, (const char *) varbuf + 1) == (const char *) NULL) )
17382          ok = TRUE;
17383    }
17384    if (ok) {
17385       pbx_builtin_setvar_helper (chan, varbuf, inbuf);
17386       if (sipdebug)
17387          ast_log(LOG_DEBUG,"SIP Header added \"%s\" as %s\n", inbuf, varbuf);
17388    } else {
17389       ast_log(LOG_WARNING, "Too many SIP headers added, max 50\n");
17390    }
17391    ast_channel_unlock(chan);
17392    return 0;
17393 }

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

Support routine for find_peer.

Definition at line 2589 of file chan_sip.c.

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

Referenced by find_peer().

02590 {
02591    /* We know name is the first field, so we can cast */
02592    struct sip_peer *p = (struct sip_peer *) name;
02593    return   !(!inaddrcmp(&p->addr, sin) || 
02594                (ast_test_flag(&p->flags[0], SIP_INSECURE_PORT) &&
02595                (p->addr.sin_addr.s_addr == sin->sin_addr.s_addr)));
02596 }

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

Allocate SIP_PVT structure and set defaults.

Definition at line 4340 of file chan_sip.c.

References __ourip, ast_calloc, ast_copy_flags, ast_log(), ast_mutex_destroy(), ast_mutex_init(), ast_mutex_lock(), ast_mutex_unlock(), ast_random(), AST_RTP_DTMF, ast_rtp_new_with_bindaddr(), ast_rtp_set_rtpholdtimeout(), ast_rtp_set_rtpkeepalive(), ast_rtp_set_rtptimeout(), ast_rtp_setdtmf(), ast_rtp_setdtmfcompensate(), ast_rtp_settos(), ast_set2_flag, ast_sip_ouraddrfor(), ast_string_field_init, ast_string_field_set, ast_test_flag, ast_udptl_get_error_correction_scheme(), ast_udptl_new_with_bindaddr(), ast_udptl_settos(), ast_variables_destroy(), bindaddr, build_callid_pvt(), build_via(), context, default_prefs, do_setnat(), free, global_flags, global_t38_capability, iflist, INITIAL_CSEQ, io, LOG_DEBUG, make_our_tag(), mohinterpret, mohsuggest, NONE, option_debug, sched, SIP_DTMF, SIP_DTMF_AUTO, SIP_DTMF_RFC2833, SIP_FLAGS_TO_COPY, sip_methods, SIP_NAT, SIP_NAT_ROUTE, SIP_NO_HISTORY, SIP_OPTIONS, SIP_PAGE2_FLAGS_TO_COPY, SIP_PAGE2_RFC2833_COMPENSATE, SIP_PAGE2_T38SUPPORT, SIP_PAGE2_VIDEOSUPPORT, SIP_REGISTER, T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF, T38FAX_UDP_EC_FEC, T38FAX_UDP_EC_NONE, T38FAX_UDP_EC_REDUNDANCY, text, UDPTL_ERROR_CORRECTION_FEC, UDPTL_ERROR_CORRECTION_NONE, and UDPTL_ERROR_CORRECTION_REDUNDANCY.

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

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

static void sip_alreadygone ( struct sip_pvt dialog  )  [static]

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

01644 {
01645    if (option_debug > 2)
01646       ast_log(LOG_DEBUG, "Setting SIP_ALREADYGONE on dialog %s\n", dialog->callid);
01647    ast_set_flag(&dialog->flags[0], SIP_ALREADYGONE);
01648 }

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

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

03592 {
03593    int res = 0;
03594    struct sip_pvt *p = ast->tech_pvt;
03595 
03596    ast_mutex_lock(&p->lock);
03597    if (ast->_state != AST_STATE_UP) {
03598       try_suggested_sip_codec(p);   
03599 
03600       ast_setstate(ast, AST_STATE_UP);
03601       if (option_debug)
03602          ast_log(LOG_DEBUG, "SIP answering channel: %s\n", ast->name);
03603       if (p->t38.state == T38_PEER_DIRECT) {
03604          p->t38.state = T38_ENABLED;
03605          if (option_debug > 1)
03606             ast_log(LOG_DEBUG,"T38State change to %d on channel %s\n", p->t38.state, ast->name);
03607          res = transmit_response_with_t38_sdp(p, "200 OK", &p->initreq, XMIT_CRITICAL);
03608       } else 
03609          res = transmit_response_with_sdp(p, "200 OK", &p->initreq, XMIT_CRITICAL);
03610    }
03611    ast_mutex_unlock(&p->lock);
03612    return res;
03613 }

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

References ast_channel::_state, sip_invite_param::addsipheaders, AST_FORMAT_AUDIO_MASK, AST_LIST_TRAVERSE, ast_log(), ast_sched_add(), ast_sched_del(), ast_set_flag, AST_STATE_DOWN, AST_STATE_RESERVED, ast_string_field_set, ast_translate_available_formats(), ast_var_name(), ast_var_value(), auto_congest(), sip_pvt::callingpres, t38properties::capability, sip_pvt::capability, ast_channel::cid, cid_name, ast_callerid::cid_pres, sip_invite_param::distinctive_ring, sip_pvt::flags, INC_CALL_RINGING, sip_pvt::initid, INV_CALLING, sip_pvt::invitestate, t38properties::jointcapability, sip_pvt::jointcapability, sip_pvt::jointnoncodeccapability, LOG_DEBUG, sip_pvt::maxtime, sip_pvt::noncodeccapability, option_debug, sip_pvt::options, sip_pvt::prefcodec, sip_invite_param::replaces, sched, SIP_INVITE, SIP_OUTGOING, SIP_TRANS_TIMEOUT, 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.

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

static void sip_cancel_destroy ( struct sip_pvt p  )  [static]

Cancel destruction of SIP dialog.

Definition at line 2113 of file chan_sip.c.

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

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

02114 {
02115    if (p->autokillid > -1) {
02116       ast_sched_del(sched, p->autokillid);
02117       append_history(p, "CancelDestroy", "");
02118       p->autokillid = -1;
02119    }
02120 }

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

See if we pass debug IP filter.

Definition at line 1725 of file chan_sip.c.

References sipdebug.

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

01726 {
01727    if (!sipdebug)
01728       return 0;
01729    if (debugaddr.sin_addr.s_addr) {
01730       if (((ntohs(debugaddr.sin_port) != 0)
01731          && (debugaddr.sin_port != addr->sin_port))
01732          || (debugaddr.sin_addr.s_addr != addr->sin_addr.s_addr))
01733          return 0;
01734    }
01735    return 1;
01736 }

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

Test PVT for debugging output.

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

01752 {
01753    if (!sipdebug)
01754       return 0;
01755    return sip_debug_test_addr(sip_real_dst(p));
01756 }

static void sip_destroy ( struct sip_pvt p  )  [static]

Destroy SIP call structure.

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

03239 {
03240    ast_mutex_lock(&iflock);
03241    if (option_debug > 2)
03242       ast_log(LOG_DEBUG, "Destroying SIP dialog %s\n", p->callid);
03243    __sip_destroy(p, 1);
03244    ast_mutex_unlock(&iflock);
03245 }

static void sip_destroy_peer ( struct sip_peer peer  )  [static]

Destroy peer object from memory.

Definition at line 2425 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(), sched, sip_destroy(), SIP_PAGE2_SELFDESTRUCT, and SIP_REALTIME.

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

02426 {
02427    if (option_debug > 2)
02428       ast_log(LOG_DEBUG, "Destroying SIP peer %s\n", peer->name);
02429 
02430    /* Delete it, it needs to disappear */
02431    if (peer->call)
02432       sip_destroy(peer->call);
02433 
02434    if (peer->mwipvt)    /* We have an active subscription, delete it */
02435       sip_destroy(peer->mwipvt);
02436 
02437    if (peer->chanvars) {
02438       ast_variables_destroy(peer->chanvars);
02439       peer->chanvars = NULL;
02440    }
02441    if (peer->expire > -1)
02442       ast_sched_del(sched, peer->expire);
02443 
02444    if (peer->pokeexpire > -1)
02445       ast_sched_del(sched, peer->pokeexpire);
02446    register_peer_exten(peer, FALSE);
02447    ast_free_ha(peer->ha);
02448    if (ast_test_flag(&peer->flags[1], SIP_PAGE2_SELFDESTRUCT))
02449       apeerobjs--;
02450    else if (ast_test_flag(&peer->flags[0], SIP_REALTIME))
02451       rpeerobjs--;
02452    else
02453       speerobjs--;
02454    clear_realm_authentication(peer->auth);
02455    peer->auth = NULL;
02456    free(peer);
02457 }

static void sip_destroy_user ( struct sip_user user  )  [static]

Remove user object from in-memory storage.

Definition at line 2617 of file chan_sip.c.

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

Referenced by check_user_full(), sip_show_user(), unload_module(), and update_call_counter().

02618 {
02619    if (option_debug > 2)
02620       ast_log(LOG_DEBUG, "Destroying user object from memory: %s\n", user->name);
02621    ast_free_ha(user->ha);
02622    if (user->chanvars) {
02623       ast_variables_destroy(user->chanvars);
02624       user->chanvars = NULL;
02625    }
02626    if (ast_test_flag(&user->flags[0], SIP_REALTIME))
02627       ruserobjs--;
02628    else
02629       suserobjs--;
02630    free(user);
02631 }

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

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

15574 {
15575    char *host;
15576    char *tmp;
15577 
15578    struct hostent *hp;
15579    struct ast_hostent ahp;
15580    struct sip_peer *p;
15581 
15582    int res = AST_DEVICE_INVALID;
15583 
15584    /* make sure data is not null. Maybe unnecessary, but better be safe */
15585    host = ast_strdupa(data ? data : "");
15586    if ((tmp = strchr(host, '@')))
15587       host = tmp + 1;
15588 
15589    if (option_debug > 2) 
15590       ast_log(LOG_DEBUG, "Checking device state for peer %s\n", host);
15591 
15592    if ((p = find_peer(host, NULL, 1))) {
15593       if (p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) {
15594          /* we have an address for the peer */
15595       
15596          /* Check status in this order
15597             - Hold
15598             - Ringing
15599             - Busy (enforced only by call limit)
15600             - Inuse (we have a call)
15601             - Unreachable (qualify)
15602             If we don't find any of these state, report AST_DEVICE_NOT_INUSE
15603             for registered devices */
15604 
15605          if (p->onHold)
15606             /* First check for hold or ring states */
15607             res = AST_DEVICE_ONHOLD;
15608          else if (p->inRinging) {
15609             if (p->inRinging == p->inUse)
15610                res = AST_DEVICE_RINGING;
15611             else
15612                res = AST_DEVICE_RINGINUSE;
15613          } else if (p->call_limit && (p->inUse == p->call_limit))
15614             /* check call limit */
15615             res = AST_DEVICE_BUSY;
15616          else if (p->call_limit && p->inUse)
15617             /* Not busy, but we do have a call */
15618             res = AST_DEVICE_INUSE;
15619          else if (p->maxms && (p->lastms > p->maxms)) 
15620             /* We don't have a call. Are we reachable at all? Requires qualify= */
15621             res = AST_DEVICE_UNAVAILABLE;
15622          else  /* Default reply if we're registered and have no other data */
15623             res = AST_DEVICE_NOT_INUSE;
15624       } else {
15625          /* there is no address, it's unavailable */
15626          res = AST_DEVICE_UNAVAILABLE;
15627       }
15628       ASTOBJ_UNREF(p,sip_destroy_peer);
15629    } else {
15630       hp = ast_gethostbyname(host, &ahp);
15631       if (hp)
15632          res = AST_DEVICE_UNKNOWN;
15633    }
15634 
15635    return res;
15636 }

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

Turn on SIP debugging (CLI command).

Definition at line 11074 of file chan_sip.c.

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

11075 {
11076    int oldsipdebug = sipdebug_console;
11077    if (argc != 3) {
11078       if (argc != 5) 
11079          return RESULT_SHOWUSAGE;
11080       else if (strcmp(argv[3], "ip") == 0)
11081          return sip_do_debug_ip(fd, argc, argv);
11082       else if (strcmp(argv[3], "peer") == 0)
11083          return sip_do_debug_peer(fd, argc, argv);
11084       else
11085          return RESULT_SHOWUSAGE;
11086    }
11087    ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE);
11088    memset(&debugaddr, 0, sizeof(debugaddr));
11089    ast_cli(fd, "SIP Debugging %senabled\n", oldsipdebug ? "re-" : "");
11090    return RESULT_SUCCESS;
11091 }

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

Definition at line 11093 of file chan_sip.c.

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

11094 {
11095    int oldsipdebug = sipdebug_console;
11096    char *newargv[6] = { "sip", "set", "debug", NULL };
11097    if (argc != 2) {
11098       if (argc != 4) 
11099          return RESULT_SHOWUSAGE;
11100       else if (strcmp(argv[2], "ip") == 0) {
11101          newargv[3] = argv[2];
11102          newargv[4] = argv[3];
11103          return sip_do_debug_ip(fd, argc + 1, newargv);
11104       } else if (strcmp(argv[2], "peer") == 0) {
11105          newargv[3] = argv[2];
11106          newargv[4] = argv[3];
11107          return sip_do_debug_peer(fd, argc + 1, newargv);
11108       } else
11109          return RESULT_SHOWUSAGE;
11110    }
11111    ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE);
11112    memset(&debugaddr, 0, sizeof(debugaddr));
11113    ast_cli(fd, "SIP Debugging %senabled\n", oldsipdebug ? "re-" : "");
11114    return RESULT_SUCCESS;
11115 }

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

Enable SIP Debugging in CLI.

Definition at line 11020 of file chan_sip.c.

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

Referenced by sip_do_debug(), and sip_do_debug_deprecated().

11021 {
11022    struct hostent *hp;
11023    struct ast_hostent ahp;
11024    int port = 0;
11025    char *p, *arg;
11026 
11027    /* sip set debug ip <ip> */
11028    if (argc != 5)
11029       return RESULT_SHOWUSAGE;
11030    p = arg = argv[4];
11031    strsep(&p, ":");
11032    if (p)
11033       port = atoi(p);
11034    hp = ast_gethostbyname(arg, &ahp);
11035    if (hp == NULL)
11036       return RESULT_SHOWUSAGE;
11037 
11038    debugaddr.sin_family = AF_INET;
11039    memcpy(&debugaddr.sin_addr, hp->h_addr, sizeof(debugaddr.sin_addr));
11040    debugaddr.sin_port = htons(port);
11041    if (port == 0)
11042       ast_cli(fd, "SIP Debugging Enabled for IP: %s\n", ast_inet_ntoa(debugaddr.sin_addr));
11043    else
11044       ast_cli(fd, "SIP Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(debugaddr.sin_addr), port);
11045 
11046    ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE);
11047 
11048    return RESULT_SUCCESS;
11049 }

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

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

Referenced by sip_do_debug(), and sip_do_debug_deprecated().

11053 {
11054    struct sip_peer *peer;
11055    if (argc != 5)
11056       return RESULT_SHOWUSAGE;
11057    peer = find_peer(argv[4], NULL, 1);
11058    if (peer) {
11059       if (peer->addr.sin_addr.s_addr) {
11060          debugaddr.sin_family = AF_INET;
11061          debugaddr.sin_addr = peer->addr.sin_addr;
11062          debugaddr.sin_port = peer->addr.sin_port;
11063          ast_cli(fd, "SIP Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(debugaddr.sin_addr), ntohs(debugaddr.sin_port));
11064          ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE);
11065       } else
11066          ast_cli(fd, "Unable to get IP address of peer '%s'\n", argv[4]);
11067       ASTOBJ_UNREF(peer,sip_destroy_peer);
11068    } else
11069       ast_cli(fd, "No such peer '%s'\n", argv[4]);
11070    return RESULT_SUCCESS;
11071 }

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

Enable SIP History logging (CLI).

Definition at line 11193 of file chan_sip.c.

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

11194 {
11195    if (argc != 2) {
11196       return RESULT_SHOWUSAGE;
11197    }
11198    recordhistory = TRUE;
11199    ast_cli(fd, "SIP History Recording Enabled (use 'sip show history')\n");
11200    return RESULT_SUCCESS;
11201 }

static int sip_do_reload ( enum channelreloadreason  reason  )  [static]

Reload module.

Definition at line 17504 of file chan_sip.c.

References ast_log(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, authl, clear_realm_authentication(), clear_sip_domains(), LOG_DEBUG, regl, and sip_destroy().

Referenced by do_monitor().

17505 {
17506    if (option_debug > 3)
17507       ast_log(LOG_DEBUG, "--------------- SIP reload started\n");
17508 
17509    clear_realm_authentication(authl);
17510    clear_sip_domains();
17511    authl = NULL;
17512 
17513    /* First, destroy all outstanding registry calls */
17514    /* This is needed, since otherwise active registry entries will not be destroyed */
17515    ASTOBJ_CONTAINER_TRAVERSE(&regl, 1, do {
17516       ASTOBJ_RDLOCK(iterator);
17517       if (iterator->call) {
17518          if (option_debug > 2)
17519             ast_log(LOG_DEBUG, "Destroying active SIP dialog for registry %s@%s\n", iterator->username, iterator->hostname);
17520          /* This will also remove references to the registry */
17521          sip_destroy(iterator->call);
17522       }
17523       ASTOBJ_UNLOCK(iterator);
17524    
17525    } while(0));
17526 
17527    /* Then, actually destroy users and registry */
17528    ASTOBJ_CONTAINER_DESTROYALL(&userl, sip_destroy_user);
17529    if (option_debug > 3)
17530       ast_log(LOG_DEBUG, "--------------- Done destroying user list\n");
17531    ASTOBJ_CONTAINER_DESTROYALL(&regl, sip_registry_destroy);
17532    if (option_debug > 3)
17533       ast_log(LOG_DEBUG, "--------------- Done destroying registry list\n");
17534    ASTOBJ_CONTAINER_MARKALL(&peerl);
17535    reload_config(reason);
17536 
17537    /* Prune peers who still are supposed to be deleted */
17538    ASTOBJ_CONTAINER_PRUNE_MARKED(&peerl, sip_destroy_peer);
17539    if (option_debug > 3)
17540       ast_log(LOG_DEBUG, "--------------- Done destroying pruned peers\n");
17541 
17542    /* Send qualify (OPTIONS) to all peers */
17543    sip_poke_all_peers();
17544 
17545    /* Register with all services */
17546    sip_send_all_registers();
17547 
17548    if (option_debug > 3)
17549       ast_log(LOG_DEBUG, "--------------- SIP reload done\n");
17550 
17551    return 0;
17552 }

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

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

Definition at line 17307 of file chan_sip.c.

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

Referenced by load_module().

17308 {
17309    struct sip_pvt *p;
17310    char *mode;
17311    if (data)
17312       mode = (char *)data;
17313    else {
17314       ast_log(LOG_WARNING, "This application requires the argument: info, inband, rfc2833\n");
17315       return 0;
17316    }
17317    ast_channel_lock(chan);
17318    if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) {
17319       ast_log(LOG_WARNING, "Call this application only on SIP incoming calls\n");
17320       ast_channel_unlock(chan);
17321       return 0;
17322    }
17323    p = chan->tech_pvt;
17324    if (!p) {
17325       ast_channel_unlock(chan);
17326       return 0;
17327    }
17328    ast_mutex_lock(&p->lock);
17329    if (!strcasecmp(mode,"info")) {
17330       ast_clear_flag(&p->flags[0], SIP_DTMF);
17331       ast_set_flag(&p->flags[0], SIP_DTMF_INFO);
17332       p->jointnoncodeccapability &= ~AST_RTP_DTMF;
17333    } else if (!strcasecmp(mode,"rfc2833")) {
17334       ast_clear_flag(&p->flags[0], SIP_DTMF);
17335       ast_set_flag(&p->flags[0], SIP_DTMF_RFC2833);
17336       p->jointnoncodeccapability |= AST_RTP_DTMF;
17337    } else if (!strcasecmp(mode,"inband")) { 
17338       ast_clear_flag(&p->flags[0], SIP_DTMF);
17339       ast_set_flag(&p->flags[0], SIP_DTMF_INBAND);
17340       p->jointnoncodeccapability &= ~AST_RTP_DTMF;
17341    } else
17342       ast_log(LOG_WARNING, "I don't know about this dtmf mode: %s\n",mode);
17343    if (p->rtp)
17344       ast_rtp_setdtmf(p->rtp, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833);
17345    if (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) {
17346       if (!p->vad) {
17347          p->vad = ast_dsp_new();
17348          ast_dsp_set_features(p->vad, DSP_FEATURE_DTMF_DETECT);
17349       }
17350    } else {
17351       if (p->vad) {
17352          ast_dsp_free(p->vad);
17353          p->vad = NULL;
17354       }
17355    }
17356    ast_mutex_unlock(&p->lock);
17357    ast_channel_unlock(chan);
17358    return 0;
17359 }

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

10891 {
10892    int x = 0;
10893    struct sip_history *hist;
10894    static int errmsg = 0;
10895 
10896    if (!dialog)
10897       return;
10898 
10899    if (!option_debug && !sipdebug) {
10900       if (!errmsg) {
10901          ast_log(LOG_NOTICE, "You must have debugging enabled (SIP or Asterisk) in order to dump SIP history.\n");
10902          errmsg = 1;
10903       }
10904       return;
10905    }
10906 
10907    ast_log(LOG_DEBUG, "\n---------- SIP HISTORY for '%s' \n", dialog->callid);
10908    if (dialog->subscribed)
10909       ast_log(LOG_DEBUG, "  * Subscription\n");
10910    else
10911       ast_log(LOG_DEBUG, "  * SIP Call\n");
10912    if (dialog->history)
10913       AST_LIST_TRAVERSE(dialog->history, hist, list)
10914          ast_log(LOG_DEBUG, "  %-3.3d. %s\n", ++x, hist->event);
10915    if (!x)
10916       ast_log(LOG_DEBUG, "Call '%s' has no history\n", dialog->callid);
10917    ast_log(LOG_DEBUG, "\n---------- END SIP HISTORY for '%s' \n", dialog->callid);
10918 }

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

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

03696 {
03697    int ret = -1;
03698    struct sip_pvt *p;
03699 
03700    if (newchan && ast_test_flag(newchan, AST_FLAG_ZOMBIE) && option_debug)
03701       ast_log(LOG_DEBUG, "New channel is zombie\n");
03702    if (oldchan && ast_test_flag(oldchan, AST_FLAG_ZOMBIE) && option_debug)
03703       ast_log(LOG_DEBUG, "Old channel is zombie\n");
03704 
03705    if (!newchan || !newchan->tech_pvt) {
03706       if (!newchan)
03707          ast_log(LOG_WARNING, "No new channel! Fixup of %s failed.\n", oldchan->name);
03708       else
03709          ast_log(LOG_WARNING, "No SIP tech_pvt! Fixup of %s failed.\n", oldchan->name);
03710       return -1;
03711    }
03712    p = newchan->tech_pvt;
03713 
03714    if (!p) {
03715       ast_log(LOG_WARNING, "No pvt after masquerade. Strange things may happen\n");
03716       return -1;
03717    }
03718 
03719    ast_mutex_lock(&p->lock);
03720    append_history(p, "Masq", "Old channel: %s\n", oldchan->name);
03721    append_history(p, "Masq (cont)", "...new owner: %s\n", newchan->name);
03722    if (p->owner != oldchan)
03723       ast_log(LOG_WARNING, "old channel wasn't %p but was %p\n", oldchan, p->owner);
03724    else {
03725       p->owner = newchan;
03726       ret = 0;
03727    }
03728    if (option_debug > 2)
03729       ast_log(LOG_DEBUG, "SIP Fixup: New owner for dialogue %s: %s (Old parent: %s)\n", p->callid, p->owner->name, oldchan->name);
03730 
03731    ast_mutex_unlock(&p->lock);
03732    return ret;
03733 }

static int sip_get_codec ( struct ast_channel chan  )  [static]

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

Definition at line 17453 of file chan_sip.c.

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

17454 {
17455    struct sip_pvt *p = chan->tech_pvt;
17456    return p->peercapability ? p->peercapability : p->capability;  
17457 }

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

17161 {
17162    struct sip_pvt *p = NULL;
17163    enum ast_rtp_get_result res = AST_RTP_TRY_PARTIAL;
17164 
17165    if (!(p = chan->tech_pvt))
17166       return AST_RTP_GET_FAILED;
17167 
17168    ast_mutex_lock(&p->lock);
17169    if (!(p->rtp)) {
17170       ast_mutex_unlock(&p->lock);
17171       return AST_RTP_GET_FAILED;
17172    }
17173 
17174    *rtp = p->rtp;
17175 
17176    if (ast_rtp_getnat(*rtp) && !ast_test_flag(&p->flags[0], SIP_CAN_REINVITE_NAT))
17177       res = AST_RTP_TRY_PARTIAL;
17178    else if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE))
17179       res = AST_RTP_TRY_NATIVE;
17180    else if (ast_test_flag(&global_jbconf, AST_JB_FORCED))
17181       res = AST_RTP_GET_FAILED;
17182 
17183    ast_mutex_unlock(&p->lock);
17184 
17185    return res;
17186 }

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

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

17026 {
17027    struct sip_pvt *p;
17028    struct ast_udptl *udptl = NULL;
17029    
17030    p = chan->tech_pvt;
17031    if (!p)
17032       return NULL;
17033    
17034    ast_mutex_lock(&p->lock);
17035    if (p->udptl && ast_test_flag(&p->flags[0], SIP_CAN_REINVITE))
17036       udptl = p->udptl;
17037    ast_mutex_unlock(&p->lock);
17038    return udptl;
17039 }

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

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

17190 {
17191    struct sip_pvt *p = NULL;
17192    enum ast_rtp_get_result res = AST_RTP_TRY_PARTIAL;
17193    
17194    if (!(p = chan->tech_pvt))
17195       return AST_RTP_GET_FAILED;
17196 
17197    ast_mutex_lock(&p->lock);
17198    if (!(p->vrtp)) {
17199       ast_mutex_unlock(&p->lock);
17200       return AST_RTP_GET_FAILED;
17201    }
17202 
17203    *rtp = p->vrtp;
17204 
17205    if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE))
17206       res = AST_RTP_TRY_NATIVE;
17207 
17208    ast_mutex_unlock(&p->lock);
17209 
17210    return res;
17211 }

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

Handle T38 reinvite.

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

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

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

Definition at line 17077 of file chan_sip.c.

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

Referenced by handle_request_invite(), and handle_response_invite().

17078 {
17079    struct sip_pvt *p;
17080    int flag = 0;
17081    
17082    p = chan->tech_pvt;
17083    if (!p || !pvt->udptl)
17084       return -1;
17085    
17086    /* Setup everything on the other side like offered/responded from first side */
17087    ast_mutex_lock(&p->lock);
17088 
17089    /*! \todo check if this is not set earlier when setting up the PVT. If not
17090       maybe it should move there. */
17091    p->t38.jointcapability = p->t38.peercapability = pvt->t38.jointcapability;
17092 
17093    ast_udptl_set_far_max_datagram(p->udptl, ast_udptl_get_local_max_datagram(pvt->udptl));
17094    ast_udptl_set_local_max_datagram(p->udptl, ast_udptl_get_local_max_datagram(pvt->udptl));
17095    ast_udptl_set_error_correction_scheme(p->udptl, ast_udptl_get_error_correction_scheme(pvt->udptl));
17096    
17097    if (reinvite) {      /* If we are handling sending re-invite to the other side of the bridge */
17098       /*! \note The SIP_CAN_REINVITE flag is for RTP media redirects,
17099          not really T38 re-invites which are different. In this
17100          case it's used properly, to see if we can reinvite over
17101          NAT 
17102       */
17103       if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE) && ast_test_flag(&pvt->flags[0], SIP_CAN_REINVITE)) {
17104          ast_udptl_get_peer(pvt->udptl, &p->udptlredirip);
17105          flag =1;
17106       } else {
17107          memset(&p->udptlredirip, 0, sizeof(p->udptlredirip));
17108       }
17109       if (!ast_test_flag(&p->flags[0], SIP_GOTREFER)) {
17110          if (!p->pendinginvite) {
17111             if (option_debug > 2) {
17112                if (flag)
17113                   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));
17114                else
17115                   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));
17116             }
17117             transmit_reinvite_with_t38_sdp(p);
17118          } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) {
17119             if (option_debug > 2) {
17120                if (flag)
17121                   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));
17122                else
17123                   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));
17124             }
17125             ast_set_flag(&p->flags[0], SIP_NEEDREINVITE);
17126          }
17127       }
17128       /* Reset lastrtprx timer */
17129       p->lastrtprx = p->lastrtptx = time(NULL);
17130       ast_mutex_unlock(&p->lock);
17131       return 0;
17132    } else { /* If we are handling sending 200 OK to the other side of the bridge */
17133       if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE) && ast_test_flag(&pvt->flags[0], SIP_CAN_REINVITE)) {
17134          ast_udptl_get_peer(pvt->udptl, &p->udptlredirip);
17135          flag = 1;
17136       } else {
17137          memset(&p->udptlredirip, 0, sizeof(p->udptlredirip));
17138       }
17139       if (option_debug > 2) {
17140          if (flag)
17141             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));
17142          else
17143             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));
17144       }
17145       pvt->t38.state = T38_ENABLED;
17146       p->t38.state = T38_ENABLED;
17147       if (option_debug > 1) {
17148          ast_log(LOG_DEBUG, "T38 changed state to %d on channel %s\n", pvt->t38.state, pvt->owner ? pvt->owner->name : "<none>");
17149          ast_log(LOG_DEBUG, "T38 changed state to %d on channel %s\n", p->t38.state, chan ? chan->name : "<none>");
17150       }
17151       transmit_response_with_t38_sdp(p, "200 OK", &p->initreq, XMIT_CRITICAL);
17152       p->lastrtprx = p->lastrtptx = time(NULL);
17153       ast_mutex_unlock(&p->lock);
17154       return 0;
17155    }
17156 }

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 3410 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, DEC_CALL_LIMIT, DEFAULT_TRANS_TIMEOUT, FALSE, sip_pvt::flags, hangup_cause2sip(), ast_channel::hangupcause, INC_CALL_LIMIT, INV_CALLING, INV_COMPLETED, sip_pvt::invitestate, sip_pvt::lock, LOG_DEBUG, option_debug, sip_pvt::owner, pbx_builtin_setvar_helper(), sip_pvt::refer, SIP_ALREADYGONE, SIP_BYE, SIP_CANCEL, sip_cancel_destroy(), SIP_DEFER_BYE_ON_TRANSFER, SIP_INC_COUNT, SIP_NEEDDESTROY, SIP_NEEDREINVITE, SIP_NO_HISTORY, SIP_OUTGOING, SIP_PAGE2_CALL_ONHOLD, SIP_PENDINGBYE, sip_scheddestroy(), sipdebug, stop_media_flows(), ast_channel::tech_pvt, transmit_request(), transmit_request_with_auth(), transmit_response_reliable(), TRUE, update_call_counter(), sip_pvt::vad, and XMIT_RELIABLE.

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

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

03805 {
03806    struct sip_pvt *p = ast->tech_pvt;
03807    int res = 0;
03808 
03809    ast_mutex_lock(&p->lock);
03810    switch(condition) {
03811    case AST_CONTROL_RINGING:
03812       if (ast->_state == AST_STATE_RING) {
03813          p->invitestate = INV_EARLY_MEDIA;
03814          if (!ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) ||
03815              (ast_test_flag(&p->flags[0], SIP_PROG_INBAND) == SIP_PROG_INBAND_NEVER)) {            
03816             /* Send 180 ringing if out-of-band seems reasonable */
03817             transmit_response(p, "180 Ringing", &p->initreq);
03818             ast_set_flag(&p->flags[0], SIP_RINGING);
03819             if (ast_test_flag(&p->flags[0], SIP_PROG_INBAND) != SIP_PROG_INBAND_YES)
03820                break;
03821          } else {
03822             /* Well, if it's not reasonable, just send in-band */
03823          }
03824       }
03825       res = -1;
03826       break;
03827    case AST_CONTROL_BUSY:
03828       if (ast->_state != AST_STATE_UP) {
03829          transmit_response(p, "486 Busy Here", &p->initreq);
03830          p->invitestate = INV_COMPLETED;
03831          sip_alreadygone(p);
03832          ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV);
03833          break;
03834       }
03835       res = -1;
03836       break;
03837    case AST_CONTROL_CONGESTION:
03838       if (ast->_state != AST_STATE_UP) {
03839          transmit_response(p, "503 Service Unavailable", &p->initreq);
03840          p->invitestate = INV_COMPLETED;
03841          sip_alreadygone(p);
03842          ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV);
03843          break;
03844       }
03845       res = -1;
03846       break;
03847    case AST_CONTROL_PROCEEDING:
03848       if ((ast->_state != AST_STATE_UP) &&
03849           !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) &&
03850           !ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
03851          transmit_response(p, "100 Trying", &p->initreq);
03852          p->invitestate = INV_PROCEEDING;  
03853          break;
03854       }
03855       res = -1;
03856       break;
03857    case AST_CONTROL_PROGRESS:
03858       if ((ast->_state != AST_STATE_UP) &&
03859           !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) &&
03860           !ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
03861          p->invitestate = INV_EARLY_MEDIA;
03862          transmit_response_with_sdp(p, "183 Session Progress", &p->initreq, XMIT_UNRELIABLE);
03863          ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT);  
03864          break;
03865       }
03866       res = -1;
03867       break;
03868    case AST_CONTROL_HOLD:
03869       ast_moh_start(ast, data, p->mohinterpret);
03870       break;
03871    case AST_CONTROL_UNHOLD:
03872       ast_moh_stop(ast);
03873       break;
03874    case AST_CONTROL_VIDUPDATE:   /* Request a video frame update */
03875       if (p->vrtp && !ast_test_flag(&p->flags[0], SIP_NOVIDEO)) {
03876          transmit_info_with_vidupdate(p);
03877          /* ast_rtcp_send_h261fur(p->vrtp); */
03878       } else
03879          res = -1;
03880       break;
03881    case -1:
03882       res = -1;
03883       break;
03884    default:
03885       ast_log(LOG_WARNING, "Don't know how to indicate condition %d\n", condition);
03886       res = -1;
03887       break;
03888    }
03889    ast_mutex_unlock(&p->lock);
03890    return res;
03891 }

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

Display SIP nat mode.

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

01746 {
01747    return ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE ? "NAT" : "no NAT";
01748 }

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

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

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

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

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

Disable SIP Debugging in CLI.

Definition at line 11174 of file chan_sip.c.

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

11175 {
11176    if (argc != 4)
11177       return RESULT_SHOWUSAGE;
11178    ast_clear_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE);
11179    ast_cli(fd, "SIP Debugging Disabled\n");
11180    return RESULT_SUCCESS;
11181 }

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

Definition at line 11183 of file chan_sip.c.

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

11184 {
11185    if (argc != 3)
11186       return RESULT_SHOWUSAGE;
11187    ast_clear_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE);
11188    ast_cli(fd, "SIP Debugging Disabled\n");
11189    return RESULT_SUCCESS;
11190 }

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

Disable SIP History logging (CLI).

Definition at line 11204 of file chan_sip.c.

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

11205 {
11206    if (argc != 3) {
11207       return RESULT_SHOWUSAGE;
11208    }
11209    recordhistory = FALSE;
11210    ast_cli(fd, "SIP History Recording Disabled\n");
11211    return RESULT_SUCCESS;
11212 }

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

Cli command to send SIP notify to peer.

Definition at line 11118 of file chan_sip.c.

References __ourip, add_header(), ast_cli(), ast_log(), ast_sip_ouraddrfor(), ast_unescape_semicolon(), ast_variable_browse(), build_callid_pvt(), build_via(), create_addr(), DEFAULT_TRANS_TIMEOUT, initreqprep(), notify_types, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, sip_alloc(), sip_destroy(), SIP_NOTIFY, sip_scheddestroy(), transmit_sip_request(), and var.

11119 {
11120    struct ast_variable *varlist;
11121    int i;
11122 
11123    if (argc < 4)
11124       return RESULT_SHOWUSAGE;
11125 
11126    if (!notify_types) {
11127       ast_cli(fd, "No %s file found, or no types listed there\n", notify_config);
11128       return RESULT_FAILURE;
11129    }
11130 
11131    varlist = ast_variable_browse(notify_types, argv[2]);
11132 
11133    if (!varlist) {
11134       ast_cli(fd, "Unable to find notify type '%s'\n", argv[2]);
11135       return RESULT_FAILURE;
11136    }
11137 
11138    for (i = 3; i < argc; i++) {
11139       struct sip_pvt *p;
11140       struct sip_request req;
11141       struct ast_variable *var;
11142 
11143       if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY))) {
11144          ast_log(LOG_WARNING, "Unable to build sip pvt data for notify (memory/socket error)\n");
11145          return RESULT_FAILURE;
11146       }
11147 
11148       if (create_addr(p, argv[i])) {
11149          /* Maybe they're not registered, etc. */
11150          sip_destroy(p);
11151          ast_cli(fd, "Could not create address for '%s'\n", argv[i]);
11152          continue;
11153       }
11154 
11155       initreqprep(&req, p, SIP_NOTIFY);
11156 
11157       for (var = varlist; var; var = var->next)
11158          add_header(&req, var->name, ast_unescape_semicolon(var->value));
11159 
11160       /* Recalculate our side, and recalculate Call ID */
11161       if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
11162          p->ourip = __ourip;
11163       build_via(p);
11164       build_callid_pvt(p);
11165       ast_cli(fd, "Sending NOTIFY of type '%s' to '%s'\n", argv[2], argv[i]);
11166       transmit_sip_request(p, &req);
11167       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
11168    }
11169 
11170    return RESULT_SUCCESS;
11171 }

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

Referenced by handle_request_refer().

12853 {
12854    struct sip_dual *d;
12855    struct ast_channel *transferee, *transferer;
12856       /* Chan2m: The transferer, chan1m: The transferee */
12857    pthread_t th;
12858 
12859    transferee = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan1->accountcode, chan1->exten, chan1->context, chan1->amaflags, "Parking/%s", chan1->name);
12860    transferer = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->amaflags, "SIPPeer/%s", chan2->name);
12861    if ((!transferer) || (!transferee)) {
12862       if (transferee) {
12863          transferee->hangupcause = AST_CAUSE_SWITCH_CONGESTION;
12864          ast_hangup(transferee);
12865       }
12866       if (transferer) {
12867          transferer->hangupcause = AST_CAUSE_SWITCH_CONGESTION;
12868          ast_hangup(transferer);
12869       }
12870       return -1;
12871    }
12872 
12873    /* Make formats okay */
12874    transferee->readformat = chan1->readformat;
12875    transferee->writeformat = chan1->writeformat;
12876 
12877    /* Prepare for taking over the channel */
12878    ast_channel_masquerade(transferee, chan1);
12879 
12880    /* Setup the extensions and such */
12881    ast_copy_string(transferee->context, chan1->context, sizeof(transferee->context));
12882    ast_copy_string(transferee->exten, chan1->exten, sizeof(transferee->exten));
12883    transferee->priority = chan1->priority;
12884       
12885    /* We make a clone of the peer channel too, so we can play
12886       back the announcement */
12887 
12888    /* Make formats okay */
12889    transferer->readformat = chan2->readformat;
12890    transferer->writeformat = chan2->writeformat;
12891 
12892    /* Prepare for taking over the channel */
12893    ast_channel_masquerade(transferer, chan2);
12894 
12895    /* Setup the extensions and such */
12896    ast_copy_string(transferer->context, chan2->context, sizeof(transferer->context));
12897    ast_copy_string(transferer->exten, chan2->exten, sizeof(transferer->exten));
12898    transferer->priority = chan2->priority;
12899 
12900    ast_channel_lock(transferer);
12901    if (ast_do_masquerade(transferer)) {
12902       ast_log(LOG_WARNING, "Masquerade failed :(\n");
12903       ast_channel_unlock(transferer);
12904       transferer->hangupcause = AST_CAUSE_SWITCH_CONGESTION;
12905       ast_hangup(transferer);
12906       return -1;
12907    }
12908    ast_channel_unlock(transferer);
12909    if (!transferer || !transferee) {
12910       if (!transferer) { 
12911          if (option_debug)
12912             ast_log(LOG_DEBUG, "No transferer channel, giving up parking\n");
12913       }
12914       if (!transferee) {
12915          if (option_debug)
12916             ast_log(LOG_DEBUG, "No transferee channel, giving up parking\n");
12917       }
12918       return -1;
12919    }
12920    if ((d = ast_calloc(1, sizeof(*d)))) {
12921       pthread_attr_t attr;
12922 
12923       pthread_attr_init(&attr);
12924       pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);   
12925 
12926       /* Save original request for followup */
12927       copy_request(&d->req, req);
12928       d->chan1 = transferee;  /* Transferee */
12929       d->chan2 = transferer;  /* Transferer */
12930       d->seqno = seqno;
12931       if (ast_pthread_create_background(&th, &attr, sip_park_thread, d) < 0) {
12932          /* Could not start thread */
12933          free(d); /* We don't need it anymore. If thread is created, d will be free'd
12934                   by sip_park_thread() */
12935          pthread_attr_destroy(&attr);
12936          return 0;
12937       }
12938       pthread_attr_destroy(&attr);
12939    } 
12940    return -1;
12941 }

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

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

Referenced by sip_park().

12786 {
12787    struct ast_channel *transferee, *transferer; /* Chan1: The transferee, Chan2: The transferer */
12788    struct sip_dual *d;
12789    struct sip_request req;
12790    int ext;
12791    int res;
12792 
12793    d = stuff;
12794    transferee = d->chan1;
12795    transferer = d->chan2;
12796    copy_request(&req, &d->req);
12797    free(d);
12798 
12799    if (!transferee || !transferer) {
12800       ast_log(LOG_ERROR, "Missing channels for parking! Transferer %s Transferee %s\n", transferer ? "<available>" : "<missing>", transferee ? "<available>" : "<missing>" );
12801       return NULL;
12802    }
12803    if (option_debug > 3) 
12804       ast_log(LOG_DEBUG, "SIP Park: Transferer channel %s, Transferee %s\n", transferer->name, transferee->name);
12805 
12806    ast_channel_lock(transferee);
12807    if (ast_do_masquerade(transferee)) {
12808       ast_log(LOG_WARNING, "Masquerade failed.\n");
12809       transmit_response(transferer->tech_pvt, "503 Internal error", &req);
12810       ast_channel_unlock(transferee);
12811       return NULL;
12812    } 
12813    ast_channel_unlock(transferee);
12814 
12815    res = ast_park_call(transferee, transferer, 0, &ext);
12816    
12817 
12818 #ifdef WHEN_WE_KNOW_THAT_THE_CLIENT_SUPPORTS_MESSAGE
12819    if (!res) {
12820       transmit_message_with_text(transferer->tech_pvt, "Unable to park call.\n");
12821    } else {
12822       /* Then tell the transferer what happened */
12823       sprintf(buf, "Call parked on extension '%d'", ext);
12824       transmit_message_with_text(transferer->tech_pvt, buf);
12825    }
12826 #endif
12827 
12828    /* Any way back to the current call??? */
12829    /* Transmit response to the REFER request */
12830    transmit_response(transferer->tech_pvt, "202 Accepted", &req);
12831    if (!res)   {
12832       /* Transfer succeeded */
12833       append_history(transferer->tech_pvt, "SIPpark","Parked call on %d", ext);
12834       transmit_notify_with_sipfrag(transferer->tech_pvt, d->seqno, "200 OK", TRUE);
12835       transferer->hangupcause = AST_CAUSE_NORMAL_CLEARING;
12836       ast_hangup(transferer); /* This will cause a BYE */
12837       if (option_debug)
12838          ast_log(LOG_DEBUG, "SIP Call parked on extension '%d'\n", ext);
12839    } else {
12840       transmit_notify_with_sipfrag(transferer->tech_pvt, d->seqno, "503 Service Unavailable", TRUE);
12841       append_history(transferer->tech_pvt, "SIPpark","Parking failed\n");
12842       if (option_debug)
12843          ast_log(LOG_DEBUG, "SIP Call parked failed \n");
12844       /* Do not hangup call */
12845    }
12846    return NULL;
12847 }

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

08350 {
08351    struct sip_peer *peer = find_peer(p->peername, NULL, 1);
08352 
08353    if (!peer)
08354       return;
08355 
08356    /* If they put someone on hold, increment the value... otherwise decrement it */
08357    if (hold)
08358       peer->onHold++;
08359    else
08360       peer->onHold--;
08361 
08362    /* Request device state update */
08363    ast_device_state_changed("SIP/%s", peer->name);
08364 
08365    return;
08366 }

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

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

Referenced by load_module().

17464 {
17465    int ms = 0;
17466    
17467    if (!speerobjs)   /* No peers, just give up */
17468       return;
17469 
17470    ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do {
17471       ASTOBJ_WRLOCK(iterator);
17472       if (iterator->pokeexpire > -1)
17473          ast_sched_del(sched, iterator->pokeexpire);
17474       ms += 100;
17475       iterator->pokeexpire = ast_sched_add(sched, ms, sip_poke_peer_s, iterator);
17476       ASTOBJ_UNLOCK(iterator);
17477    } while (0)
17478    );
17479 }

static int sip_poke_noanswer ( void *  data  )  [static]

React to lack of answer to Qualify poke.

Definition at line 15451 of file chan_sip.c.

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

Referenced by sip_poke_peer().

15452 {
15453    struct sip_peer *peer = data;
15454    
15455    peer->pokeexpire = -1;
15456    if (peer->lastms > -1) {
15457       ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE!  Last qualify: %d\n", peer->name, peer->lastms);
15458       manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, -1);
15459    }
15460    if (peer->call)
15461       sip_destroy(peer->call);
15462    peer->call = NULL;
15463    peer->lastms = -1;
15464    ast_device_state_changed("SIP/%s", peer->name);
15465    /* Try again quickly */
15466    if (peer->pokeexpire > -1)
15467       ast_sched_del(sched, peer->pokeexpire);
15468    peer->pokeexpire = ast_sched_add(sched, DEFAULT_FREQ_NOTOK, sip_poke_peer_s, peer);
15469    return 0;
15470 }

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

15476 {
15477    struct sip_pvt *p;
15478    int xmitres = 0;
15479 
15480    if (!peer->maxms || !peer->addr.sin_addr.s_addr) {
15481       /* IF we have no IP, or this isn't to be monitored, return
15482         imeediately after clearing things out */
15483       if (peer->pokeexpire > -1)
15484          ast_sched_del(sched, peer->pokeexpire);
15485       peer->lastms = 0;
15486       peer->pokeexpire = -1;
15487       peer->call = NULL;
15488       return 0;
15489    }
15490    if (peer->call) {
15491       if (sipdebug)
15492          ast_log(LOG_NOTICE, "Still have a QUALIFY dialog active, deleting\n");
15493       sip_destroy(peer->call);
15494    }
15495    if (!(p = peer->call = sip_alloc(NULL, NULL, 0, SIP_OPTIONS)))
15496       return -1;
15497    
15498    p->sa = peer->addr;
15499    p->recv = peer->addr;
15500    ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY);
15501    ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY);
15502 
15503    /* Send OPTIONs to peer's fullcontact */
15504    if (!ast_strlen_zero(peer->fullcontact))
15505       ast_string_field_set(p, fullcontact, peer->fullcontact);
15506 
15507    if (!ast_strlen_zero(peer->tohost))
15508       ast_string_field_set(p, tohost, peer->tohost);
15509    else
15510       ast_string_field_set(p, tohost, ast_inet_ntoa(peer->addr.sin_addr));
15511 
15512    /* Recalculate our side, and recalculate Call ID */
15513    if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
15514       p->ourip = __ourip;
15515    build_via(p);
15516    build_callid_pvt(p);
15517 
15518    if (peer->pokeexpire > -1)
15519       ast_sched_del(sched, peer->pokeexpire);
15520    p->relatedpeer = peer;
15521    ast_set_flag(&p->flags[0], SIP_OUTGOING);
15522 #ifdef VOCAL_DATA_HACK
15523    ast_copy_string(p->username, "__VOCAL_DATA_SHOULD_READ_THE_SIP_SPEC__", sizeof(p->username));
15524    xmitres = transmit_invite(p, SIP_INVITE, 0, 2);
15525 #else
15526    xmitres = transmit_invite(p, SIP_OPTIONS, 0, 2);
15527 #endif
15528    gettimeofday(&peer->ps, NULL);
15529    if (xmitres == XMIT_ERROR)
15530       sip_poke_noanswer(peer);   /* Immediately unreachable, network problems */
15531    else {
15532       if (peer->pokeexpire > -1)
15533          ast_sched_del(sched, peer->pokeexpire);
15534       peer->pokeexpire = ast_sched_add(sched, DEFAULT_MAXMS * 2, sip_poke_noanswer, peer);
15535    }
15536 
15537    return 0;
15538 }

static int sip_poke_peer_s ( void *  data  )  [static]

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

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

07755 {
07756    struct sip_peer *peer = data;
07757 
07758    peer->pokeexpire = -1;
07759    sip_poke_peer(peer);
07760    return 0;
07761 }

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

Remove temporary realtime objects from memory (CLI).

Definition at line 9911 of file chan_sip.c.

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

09912 {
09913    struct sip_peer *peer;
09914    struct sip_user *user;
09915    int pruneuser = FALSE;
09916    int prunepeer = FALSE;
09917    int multi = FALSE;
09918    char *name = NULL;
09919    regex_t regexbuf;
09920 
09921    switch (argc) {
09922    case 4:
09923       if (!strcasecmp(argv[3], "user"))
09924          return RESULT_SHOWUSAGE;
09925       if (!strcasecmp(argv[3], "peer"))
09926          return RESULT_SHOWUSAGE;
09927       if (!strcasecmp(argv[3], "like"))
09928          return RESULT_SHOWUSAGE;
09929       if (!strcasecmp(argv[3], "all")) {
09930          multi = TRUE;
09931          pruneuser = prunepeer = TRUE;
09932       } else {
09933          pruneuser = prunepeer = TRUE;
09934          name = argv[3];
09935       }
09936       break;
09937    case 5:
09938       if (!strcasecmp(argv[4], "like"))
09939          return RESULT_SHOWUSAGE;
09940       if (!strcasecmp(argv[3], "all"))
09941          return RESULT_SHOWUSAGE;
09942       if (!strcasecmp(argv[3], "like")) {
09943          multi = TRUE;
09944          name = argv[4];
09945          pruneuser = prunepeer = TRUE;
09946       } else if (!strcasecmp(argv[3], "user")) {
09947          pruneuser = TRUE;
09948          if (!strcasecmp(argv[4], "all"))
09949             multi = TRUE;
09950          else
09951             name = argv[4];
09952       } else if (!strcasecmp(argv[3], "peer")) {
09953          prunepeer = TRUE;
09954          if (!strcasecmp(argv[4], "all"))
09955             multi = TRUE;
09956          else
09957             name = argv[4];
09958       } else
09959          return RESULT_SHOWUSAGE;
09960       break;
09961    case 6:
09962       if (strcasecmp(argv[4], "like"))
09963          return RESULT_SHOWUSAGE;
09964       if (!strcasecmp(argv[3], "user")) {
09965          pruneuser = TRUE;
09966          name = argv[5];
09967       } else if (!strcasecmp(argv[3], "peer")) {
09968          prunepeer = TRUE;
09969          name = argv[5];
09970       } else
09971          return RESULT_SHOWUSAGE;
09972       break;
09973    default:
09974       return RESULT_SHOWUSAGE;
09975    }
09976 
09977    if (multi && name) {
09978       if (regcomp(&regexbuf, name, REG_EXTENDED | REG_NOSUB))
09979          return RESULT_SHOWUSAGE;
09980    }
09981 
09982    if (multi) {
09983       if (prunepeer) {
09984          int pruned = 0;
09985 
09986          ASTOBJ_CONTAINER_WRLOCK(&peerl);
09987          ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do {
09988             ASTOBJ_RDLOCK(iterator);
09989             if (name && regexec(&regexbuf, iterator->name, 0, NULL, 0)) {
09990                ASTOBJ_UNLOCK(iterator);
09991                continue;
09992             };
09993             if (ast_test_flag(&iterator->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) {
09994                ASTOBJ_MARK(iterator);
09995                pruned++;
09996             }
09997             ASTOBJ_UNLOCK(iterator);
09998          } while (0) );
09999          if (pruned) {
10000             ASTOBJ_CONTAINER_PRUNE_MARKED(&peerl, sip_destroy_peer);
10001             ast_cli(fd, "%d peers pruned.\n", pruned);
10002          } else
10003             ast_cli(fd, "No peers found to prune.\n");
10004          ASTOBJ_CONTAINER_UNLOCK(&peerl);
10005       }
10006       if (pruneuser) {
10007          int pruned = 0;
10008 
10009          ASTOBJ_CONTAINER_WRLOCK(&userl);
10010          ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do {
10011             ASTOBJ_RDLOCK(iterator);
10012             if (name && regexec(&regexbuf, iterator->name, 0, NULL, 0)) {
10013                ASTOBJ_UNLOCK(iterator);
10014                continue;
10015             };
10016             if (ast_test_flag(&iterator->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) {
10017                ASTOBJ_MARK(iterator);
10018                pruned++;
10019             }
10020             ASTOBJ_UNLOCK(iterator);
10021          } while (0) );
10022          if (pruned) {
10023             ASTOBJ_CONTAINER_PRUNE_MARKED(&userl, sip_destroy_user);
10024             ast_cli(fd, "%d users pruned.\n", pruned);
10025          } else
10026             ast_cli(fd, "No users found to prune.\n");
10027          ASTOBJ_CONTAINER_UNLOCK(&userl);
10028       }
10029    } else {
10030       if (prunepeer) {
10031          if ((peer = ASTOBJ_CONTAINER_FIND_UNLINK(&peerl, name))) {
10032             if (!ast_test_flag(&peer->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) {
10033                ast_cli(fd, "Peer '%s' is not a Realtime peer, cannot be pruned.\n", name);
10034                ASTOBJ_CONTAINER_LINK(&peerl, peer);
10035             } else
10036                ast_cli(fd, "Peer '%s' pruned.\n", name);
10037             ASTOBJ_UNREF(peer, sip_destroy_peer);
10038          } else
10039             ast_cli(fd, "Peer '%s' not found.\n", name);
10040       }
10041       if (pruneuser) {
10042          if ((user = ASTOBJ_CONTAINER_FIND_UNLINK(&userl, name))) {
10043             if (!ast_test_flag(&user->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) {
10044                ast_cli(fd, "User '%s' is not a Realtime user, cannot be pruned.\n", name);
10045                ASTOBJ_CONTAINER_LINK(&userl, user);
10046             } else
10047                ast_cli(fd, "User '%s' pruned.\n", name);
10048             ASTOBJ_UNREF(user, sip_destroy_user);
10049          } else
10050             ast_cli(fd, "User '%s' not found.\n", name);
10051       }
10052    }
10053 
10054    return RESULT_SUCCESS;
10055 }

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

Read SIP RTP from channel.

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

04258 {
04259    struct ast_frame *fr;
04260    struct sip_pvt *p;
04261    
04262    if( ast == NULL )
04263        return NULL;
04264    
04265    p = ast->tech_pvt;
04266    int faxdetected = FALSE;
04267 
04268    if( p == NULL )
04269        return NULL;  
04270 
04271    ast_mutex_lock(&p->lock);
04272    fr = sip_rtp_read(ast, p, &faxdetected);
04273    p->lastrtprx = time(NULL);
04274 
04275    /* If we are NOT bridged to another channel, and we have detected fax tone we issue T38 re-invite to a peer */
04276    /* 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 */
04277    if (faxdetected && ast_test_flag(&p->t38.t38support, SIP_PAGE2_T38SUPPORT_UDPTL) && (p->t38.state == T38_DISABLED) && !(ast_bridged_channel(ast))) {
04278       if (!ast_test_flag(&p->flags[0], SIP_GOTREFER)) {
04279          if (!p->pendinginvite) {
04280             if (option_debug > 2)
04281                ast_log(LOG_DEBUG, "Sending reinvite on SIP (%s) for T.38 negotiation.\n",ast->name);
04282             p->t38.state = T38_LOCAL_REINVITE;
04283             transmit_reinvite_with_t38_sdp(p);
04284             if (option_debug > 1)
04285                ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, ast->name);
04286          }
04287       } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) {
04288          if (option_debug > 2)
04289             ast_log(LOG_DEBUG, "Deferring reinvite on SIP (%s) - it will be re-negotiated for T.38\n", ast->name);
04290          ast_set_flag(&p->flags[0], SIP_NEEDREINVITE);
04291       }
04292    }
04293 
04294    ast_mutex_unlock(&p->lock);
04295    return fr;
04296 }

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

The real destination address for a write.

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

01740 {
01741    return ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE ? &p->recv : &p->sa;
01742 }

static int sip_refer_allocate ( struct sip_pvt p  )  [static]

Allocate SIP refer structure.

Definition at line 7563 of file chan_sip.c.

References ast_calloc, and sip_pvt::refer.

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

07564 {
07565    p->refer = ast_calloc(1, sizeof(struct sip_refer)); 
07566    return p->refer ? 1 : 0;
07567 }

static int sip_reg_timeout ( void *  data  )  [static]

Registration timeout, register again.

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

07321 {
07322 
07323    /* if we are here, our registration timed out, so we'll just do it over */
07324    struct sip_registry *r = ASTOBJ_REF((struct sip_registry *) data);
07325    struct sip_pvt *p;
07326    int res;
07327 
07328    /* if we couldn't get a reference to the registry object, punt */
07329    if (!r)
07330       return 0;
07331 
07332    ast_log(LOG_NOTICE, "   -- Registration for '%s@%s' timed out, trying again (Attempt #%d)\n", r->username, r->hostname, r->regattempts); 
07333    if (r->call) {
07334       /* Unlink us, destroy old call.  Locking is not relevant here because all this happens
07335          in the single SIP manager thread. */
07336       p = r->call;
07337       if (p->registry)
07338          ASTOBJ_UNREF(p->registry, sip_registry_destroy);
07339       r->call = NULL;
07340       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
07341       /* Pretend to ACK anything just in case */
07342       __sip_pretend_ack(p); /* XXX we need p locked, not sure we have */
07343    }
07344    /* If we have a limit, stop registration and give up */
07345    if (global_regattempts_max && (r->regattempts > global_regattempts_max)) {
07346       /* Ok, enough is enough. Don't try any more */
07347       /* We could add an external notification here... 
07348          steal it from app_voicemail :-) */
07349       ast_log(LOG_NOTICE, "   -- Giving up forever trying to register '%s@%s'\n", r->username, r->hostname);
07350       r->regstate = REG_STATE_FAILED;
07351    } else {
07352       r->regstate = REG_STATE_UNREGISTERED;
07353       r->timeout = -1;
07354       res=transmit_register(r, SIP_REGISTER, NULL, NULL);
07355    }
07356    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));
07357    ASTOBJ_UNREF(r, sip_registry_destroy);
07358    return 0;
07359 }

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

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

Definition at line 4584 of file chan_sip.c.

References ast_calloc, ast_log(), ast_string_field_init, ast_string_field_set, ast_strlen_zero(), ASTOBJ_CONTAINER_LINK, ASTOBJ_INIT, ASTOBJ_UNREF, FALSE, free, hostname, INITIAL_CSEQ, LOG_ERROR, regl, secret, sip_registry_destroy(), and username.

04585 {
04586    struct sip_registry *reg;
04587    int portnum = 0;
04588    char username[256] = "";
04589    char *hostname=NULL, *secret=NULL, *authuser=NULL;
04590    char *porta=NULL;
04591    char *contact=NULL;
04592 
04593    if (!value)
04594       return -1;
04595    ast_copy_string(username, value, sizeof(username));
04596    /* First split around the last '@' then parse the two components. */
04597    hostname = strrchr(username, '@'); /* allow @ in the first part */
04598    if (hostname)
04599       *hostname++ = '\0';
04600    if (ast_strlen_zero(username) || ast_strlen_zero(hostname)) {
04601       ast_log(LOG_WARNING, "Format for registration is user[:secret[:authuser]]@host[:port][/contact] at line %d\n", lineno);
04602       return -1;
04603    }
04604    /* split user[:secret[:authuser]] */
04605    secret = strchr(username, ':');
04606    if (secret) {
04607       *secret++ = '\0';
04608       authuser = strchr(secret, ':');
04609       if (authuser)
04610          *authuser++ = '\0';
04611    }
04612    /* split host[:port][/contact] */
04613    contact = strchr(hostname, '/');
04614    if (contact)
04615       *contact++ = '\0';
04616    if (ast_strlen_zero(contact))
04617       contact = "s";
04618    porta = strchr(hostname, ':');
04619    if (porta) {
04620       *porta++ = '\0';
04621       portnum = atoi(porta);
04622       if (portnum == 0) {
04623          ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno);
04624          return -1;
04625       }
04626    }
04627    if (!(reg = ast_calloc(1, sizeof(*reg)))) {
04628       ast_log(LOG_ERROR, "Out of memory. Can't allocate SIP registry entry\n");
04629       return -1;
04630    }
04631 
04632    if (ast_string_field_init(reg, 256)) {
04633       ast_log(LOG_ERROR, "Out of memory. Can't allocate SIP registry strings\n");
04634       free(reg);
04635       return -1;
04636    }
04637 
04638    regobjs++;
04639    ASTOBJ_INIT(reg);
04640    ast_string_field_set(reg, contact, contact);
04641    if (!ast_strlen_zero(username))
04642       ast_string_field_set(reg, username, username);
04643    if (hostname)
04644       ast_string_field_set(reg, hostname, hostname);
04645    if (authuser)
04646       ast_string_field_set(reg, authuser, authuser);
04647    if (secret)
04648       ast_string_field_set(reg, secret, secret);
04649    reg->expire = -1;
04650    reg->timeout =  -1;
04651    reg->refresh = default_expiry;
04652    reg->portno = portnum;
04653    reg->callid_valid = FALSE;
04654    reg->ocseq = INITIAL_CSEQ;
04655    ASTOBJ_CONTAINER_LINK(&regl, reg);  /* Add the new registry entry to the list */
04656    ASTOBJ_UNREF(reg,sip_registry_destroy);
04657    return 0;
04658 }

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

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

02987 {
02988    /* Really delete */
02989    if (option_debug > 2)
02990       ast_log(LOG_DEBUG, "Destroying registry entry for %s@%s\n", reg->username, reg->hostname);
02991 
02992    if (reg->call) {
02993       /* Clear registry before destroying to ensure
02994          we don't get reentered trying to grab the registry lock */
02995       reg->call->registry = NULL;
02996       if (option_debug > 2)
02997          ast_log(LOG_DEBUG, "Destroying active SIP dialog for registry %s@%s\n", reg->username, reg->hostname);
02998       sip_destroy(reg->call);
02999    }
03000    if (reg->expire > -1)
03001       ast_sched_del(sched, reg->expire);
03002    if (reg->timeout > -1)
03003       ast_sched_del(sched, reg->timeout);
03004    ast_string_field_free_pools(reg);
03005    regobjs--;
03006    free(reg);
03007    
03008 }

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

Force reload of module from cli.

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

17556 {
17557    ast_mutex_lock(&sip_reload_lock);
17558    if (sip_reloading) 
17559       ast_verbose("Previous SIP reload not yet done\n");
17560    else {
17561       sip_reloading = TRUE;
17562       if (fd)
17563          sip_reloadreason = CHANNEL_CLI_RELOAD;
17564       else
17565          sip_reloadreason = CHANNEL_MODULE_RELOAD;
17566    }
17567    ast_mutex_unlock(&sip_reload_lock);
17568    restart_monitor();
17569 
17570    return 0;
17571 }

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

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

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

Definition at line 15640 of file chan_sip.c.

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

15641 {
15642    int oldformat;
15643    struct sip_pvt *p;
15644    struct ast_channel *tmpc = NULL;
15645    char *ext, *host;
15646    char tmp[256];
15647    char *dest = data;
15648 
15649    oldformat = format;
15650    if (!(format &= ((AST_FORMAT_MAX_AUDIO << 1) - 1))) {
15651       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));
15652       *cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;   /* Can't find codec to connect to host */
15653       return NULL;
15654    }
15655    if (option_debug)
15656       ast_log(LOG_DEBUG, "Asked to create a SIP channel with formats: %s\n", ast_getformatname_multiple(tmp, sizeof(tmp), oldformat));
15657 
15658    if (!(p = sip_alloc(NULL, NULL, 0, SIP_INVITE))) {
15659       ast_log(LOG_ERROR, "Unable to build sip pvt data for '%s' (Out of memory or socket error)\n", (char *)data);
15660       *cause = AST_CAUSE_SWITCH_CONGESTION;
15661       return NULL;
15662    }
15663 
15664    ast_set_flag(&p->flags[1], SIP_PAGE2_OUTGOING_CALL);
15665 
15666    if (!(p->options = ast_calloc(1, sizeof(*p->options)))) {
15667       sip_destroy(p);
15668       ast_log(LOG_ERROR, "Unable to build option SIP data structure - Out of memory\n");
15669       *cause = AST_CAUSE_SWITCH_CONGESTION;
15670       return NULL;
15671    }
15672 
15673    ast_copy_string(tmp, dest, sizeof(tmp));
15674    host = strchr(tmp, '@');
15675    if (host) {
15676       *host++ = '\0';
15677       ext = tmp;
15678    } else {
15679       ext = strchr(tmp, '/');
15680       if (ext) 
15681          *ext++ = '\0';
15682       host = tmp;
15683    }
15684 
15685    if (create_addr(p, host)) {
15686       *cause = AST_CAUSE_UNREGISTERED;
15687       if (option_debug > 2)
15688          ast_log(LOG_DEBUG, "Cant create SIP call - target device not registred\n");
15689       sip_destroy(p);
15690       return NULL;
15691    }
15692    if (ast_strlen_zero(p->peername) && ext)
15693       ast_string_field_set(p, peername, ext);
15694    /* Recalculate our side, and recalculate Call ID */
15695    if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
15696       p->ourip = __ourip;
15697    build_via(p);
15698    build_callid_pvt(p);
15699    
15700    /* We have an extension to call, don't use the full contact here */
15701    /* This to enable dialing registered peers with extension dialling,
15702       like SIP/peername/extension   
15703       SIP/peername will still use the full contact */
15704    if (ext) {
15705       ast_string_field_set(p, username, ext);
15706       ast_string_field_free(p, fullcontact);
15707    }
15708 #if 0
15709    printf("Setting up to call extension '%s' at '%s'\n", ext ? ext : "<none>", host);
15710 #endif
15711    p->prefcodec = oldformat;           /* Format for this call */
15712    ast_mutex_lock(&p->lock);
15713    tmpc = sip_new(p, AST_STATE_DOWN, host);  /* Place the call */
15714    ast_mutex_unlock(&p->lock);
15715    if (!tmpc)
15716       sip_destroy(p);
15717    ast_update_use_count();
15718    restart_monitor();
15719    return tmpc;
15720 }

static int sip_reregister ( void *  data  )  [static]

Update registration with SIP Proxy.

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

07289 {
07290    /* if we are here, we know that we need to reregister. */
07291    struct sip_registry *r= ASTOBJ_REF((struct sip_registry *) data);
07292 
07293    /* if we couldn't get a reference to the registry object, punt */
07294    if (!r)
07295       return 0;
07296 
07297    if (r->call && !ast_test_flag(&r->call->flags[0], SIP_NO_HISTORY))
07298       append_history(r->call, "RegistryRenew", "Account: %s@%s", r->username, r->hostname);
07299    /* Since registry's are only added/removed by the the monitor thread, this
07300       may be overkill to reference/dereference at all here */
07301    if (sipdebug)
07302       ast_log(LOG_NOTICE, "   -- Re-registration for  %s@%s\n", r->username, r->hostname);
07303 
07304    r->expire = -1;
07305    __sip_do_register(r);
07306    ASTOBJ_UNREF(r, sip_registry_destroy);
07307    return 0;
07308 }

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

Read RTP from network.

Definition at line 4187 of file chan_sip.c.

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

Referenced by sip_read().

04188 {
04189    /* Retrieve audio/etc from channel.  Assumes p->lock is already held. */
04190    struct ast_frame *f;
04191    
04192    if (!p->rtp) {
04193       /* We have no RTP allocated for this channel */
04194       return &ast_null_frame;
04195    }
04196 
04197    switch(ast->fdno) {
04198    case 0:
04199       f = ast_rtp_read(p->rtp);  /* RTP Audio */
04200       break;
04201    case 1:
04202       f = ast_rtcp_read(p->rtp); /* RTCP Control Channel */
04203       break;
04204    case 2:
04205       f = ast_rtp_read(p->vrtp); /* RTP Video */
04206       break;
04207    case 3:
04208       f = ast_rtcp_read(p->vrtp);   /* RTCP Control Channel for video */
04209       break;
04210    case 5:
04211       f = ast_udptl_read(p->udptl); /* UDPTL for T.38 */
04212       break;
04213    default:
04214       f = &ast_null_frame;
04215    }
04216    /* Don't forward RFC2833 if we're not supposed to */
04217    if (f && (f->frametype == AST_FRAME_DTMF) &&
04218        (ast_test_flag(&p->flags[0], SIP_DTMF) != SIP_DTMF_RFC2833))
04219       return &ast_null_frame;
04220 
04221       /* We already hold the channel lock */
04222    if (!p->owner || (f && f->frametype != AST_FRAME_VOICE))
04223       return f;
04224 
04225    if (f && f->subclass != (p->owner->nativeformats & AST_FORMAT_AUDIO_MASK)) {
04226       if (!(f->subclass & p->jointcapability)) {
04227          if (option_debug) {
04228             ast_log(LOG_DEBUG, "Bogus frame of format '%s' received from '%s'!\n",
04229                ast_getformatname(f->subclass), p->owner->name);
04230          }
04231          return &ast_null_frame;
04232       }
04233       if (option_debug)
04234          ast_log(LOG_DEBUG, "Oooh, format changed to %d\n", f->subclass);
04235       p->owner->nativeformats = (p->owner->nativeformats & AST_FORMAT_VIDEO_MASK) | f->subclass;
04236       ast_set_read_format(p->owner, p->owner->readformat);
04237       ast_set_write_format(p->owner, p->owner->writeformat);
04238    }
04239 
04240    if (f && (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) && p->vad) {
04241       f = ast_dsp_process(p->owner, p->vad, f);
04242       if (f && f->frametype == AST_FRAME_DTMF) {
04243          if (ast_test_flag(&p->t38.t38support, SIP_PAGE2_T38SUPPORT_UDPTL) && f->subclass == 'f') {
04244             if (option_debug)
04245                ast_log(LOG_DEBUG, "Fax CNG detected on %s\n", ast->name);
04246             *faxdetect = 1;
04247          } else if (option_debug) {
04248             ast_log(LOG_DEBUG, "* Detected inband DTMF '%c'\n", f->subclass);
04249          }
04250       }
04251    }
04252    
04253    return f;
04254 }

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

Schedule destruction of SIP dialog.

Definition at line 2095 of file chan_sip.c.

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

02096 {
02097    if (ms < 0) {
02098       if (p->timer_t1 == 0)
02099          p->timer_t1 = 500;   /* Set timer T1 if not set (RFC 3261) */
02100       ms = p->timer_t1 * 64;
02101    }
02102    if (sip_debug_test_pvt(p))
02103       ast_verbose("Scheduling destruction of SIP dialog '%s' in %d ms (Method: %s)\n", p->callid, ms, sip_methods[p->method].text);
02104    if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY))
02105       append_history(p, "SchedDestroy", "%d ms", ms);
02106 
02107    if (p->autokillid > -1)
02108       ast_sched_del(sched, p->autokillid);
02109    p->autokillid = ast_sched_add(sched, ms, __sip_autodestruct, p);
02110 }

static void sip_send_all_registers ( void   )  [static]

Send all known registrations.

Definition at line 17482 of file chan_sip.c.

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

Referenced by load_module().

17483 {
17484    int ms;
17485    int regspacing;
17486    if (!regobjs)
17487       return;
17488    regspacing = default_expiry * 1000/regobjs;
17489    if (regspacing > 100)
17490       regspacing = 100;
17491    ms = regspacing;
17492    ASTOBJ_CONTAINER_TRAVERSE(&regl, 1, do {
17493       ASTOBJ_WRLOCK(iterator);
17494       if (iterator->expire > -1)
17495          ast_sched_del(sched, iterator->expire);
17496       ms += regspacing;
17497       iterator->expire = ast_sched_add(sched, ms, sip_reregister, iterator);
17498       ASTOBJ_UNLOCK(iterator);
17499    } while (0)
17500    );
17501 }

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

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

Referenced by handle_request_subscribe().

15193 {
15194    /* Called with peerl lock, but releases it */
15195    struct sip_pvt *p;
15196    int newmsgs, oldmsgs;
15197 
15198    /* Do we have an IP address? If not, skip this peer */
15199    if (!peer->addr.sin_addr.s_addr && !peer->defaddr.sin_addr.s_addr) 
15200       return 0;
15201 
15202    /* Check for messages */
15203    ast_app_inboxcount(peer->mailbox, &newmsgs, &oldmsgs);
15204    
15205    peer->lastmsgcheck = time(NULL);
15206    
15207    /* Return now if it's the same thing we told them last time */
15208    if (((newmsgs > 0x7fff ? 0x7fff0000 : (newmsgs << 16)) | (oldmsgs > 0xffff ? 0xffff : oldmsgs)) == peer->lastmsgssent) {
15209       return 0;
15210    }
15211    
15212    
15213    peer->lastmsgssent = ((newmsgs > 0x7fff ? 0x7fff0000 : (newmsgs << 16)) | (oldmsgs > 0xffff ? 0xffff : oldmsgs));
15214 
15215    if (peer->mwipvt) {
15216       /* Base message on subscription */
15217       p = peer->mwipvt;
15218    } else {
15219       /* Build temporary dialog for this message */
15220       if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY))) 
15221          return -1;
15222       if (create_addr_from_peer(p, peer)) {
15223          /* Maybe they're not registered, etc. */
15224          sip_destroy(p);
15225          return 0;
15226       }
15227       /* Recalculate our side, and recalculate Call ID */
15228       if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
15229          p->ourip = __ourip;
15230       build_via(p);
15231       build_callid_pvt(p);
15232       /* Destroy this session after 32 secs */
15233       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
15234    }
15235    /* Send MWI */
15236    ast_set_flag(&p->flags[0], SIP_OUTGOING);
15237    transmit_notify_with_mwi(p, newmsgs, oldmsgs, peer->vmexten);
15238    return 0;
15239 }

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

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

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

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

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

03760 {
03761    struct sip_pvt *p = ast->tech_pvt;
03762    int res = 0;
03763 
03764    ast_mutex_lock(&p->lock);
03765    switch (ast_test_flag(&p->flags[0], SIP_DTMF)) {
03766    case SIP_DTMF_INFO:
03767       transmit_info_with_digit(p, digit, duration);
03768       break;
03769    case SIP_DTMF_RFC2833:
03770       if (p->rtp)
03771          ast_rtp_senddigit_end(p->rtp, digit);
03772       break;
03773    case SIP_DTMF_INBAND:
03774       res = -1; /* Tell Asterisk to stop inband indications */
03775       break;
03776    }
03777    ast_mutex_unlock(&p->lock);
03778 
03779    return res;
03780 }

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

02339 {
02340    struct sip_pvt *p = ast->tech_pvt;
02341    int debug = sip_debug_test_pvt(p);
02342 
02343    if (debug)
02344       ast_verbose("Sending text %s on %s\n", text, ast->name);
02345    if (!p)
02346       return -1;
02347    if (ast_strlen_zero(text))
02348       return 0;
02349    if (debug)
02350       ast_verbose("Really sending text %s on %s\n", text, ast->name);
02351    transmit_message_with_text(p, text);
02352    return 0;   
02353 }

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

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

17215 {
17216    struct sip_pvt *p;
17217    int changed = 0;
17218 
17219    p = chan->tech_pvt;
17220    if (!p) 
17221       return -1;
17222 
17223    /* Disable early RTP bridge  */
17224    if (chan->_state != AST_STATE_UP && !global_directrtpsetup)    /* We are in early state */
17225       return 0;
17226 
17227    ast_mutex_lock(&p->lock);
17228    if (ast_test_flag(&p->flags[0], SIP_ALREADYGONE)) {
17229       /* If we're destroyed, don't bother */
17230       ast_mutex_unlock(&p->lock);
17231       return 0;
17232    }
17233 
17234    /* if this peer cannot handle reinvites of the media stream to devices
17235       that are known to be behind a NAT, then stop the process now
17236    */
17237    if (nat_active && !ast_test_flag(&p->flags[0], SIP_CAN_REINVITE_NAT)) {
17238       ast_mutex_unlock(&p->lock);
17239       return 0;
17240    }
17241 
17242    if (rtp) {
17243       changed |= ast_rtp_get_peer(rtp, &p->redirip);
17244    } else if (p->redirip.sin_addr.s_addr || ntohs(p->redirip.sin_port) != 0) {
17245       memset(&p->redirip, 0, sizeof(p->redirip));
17246       changed = 1;
17247    }
17248    if (vrtp) {
17249       changed |= ast_rtp_get_peer(vrtp, &p->vredirip);
17250    } else if (p->vredirip.sin_addr.s_addr || ntohs(p->vredirip.sin_port) != 0) {
17251       memset(&p->vredirip, 0, sizeof(p->vredirip));
17252       changed = 1;
17253    }
17254    if (codecs) {
17255       if ((p->redircodecs != codecs)) {
17256          p->redircodecs = codecs;
17257          changed = 1;
17258       }
17259       if ((p->capability & codecs) != p->capability) {
17260          p->jointcapability &= codecs;
17261          p->capability &= codecs;
17262          changed = 1;
17263       }
17264    }
17265    if (changed && !ast_test_flag(&p->flags[0], SIP_GOTREFER)) {
17266       if (chan->_state != AST_STATE_UP) { /* We are in early state */
17267          if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY))
17268             append_history(p, "ExtInv", "Initial invite sent with remote bridge proposal.");
17269          if (option_debug)
17270             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));
17271       } else if (!p->pendinginvite) {     /* We are up, and have no outstanding invite */
17272          if (option_debug > 2) {
17273             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));
17274          }
17275          transmit_reinvite_with_sdp(p);
17276       } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) {
17277          if (option_debug > 2) {
17278             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));
17279          }
17280          /* We have a pending Invite. Send re-invite when we're done with the invite */
17281          ast_set_flag(&p->flags[0], SIP_NEEDREINVITE);   
17282       }
17283    }
17284    /* Reset lastrtprx timer */
17285    p->lastrtprx = p->lastrtptx = time(NULL);
17286    ast_mutex_unlock(&p->lock);
17287    return 0;
17288 }

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

Definition at line 17041 of file chan_sip.c.

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

17042 {
17043    struct sip_pvt *p;
17044    
17045    p = chan->tech_pvt;
17046    if (!p)
17047       return -1;
17048    ast_mutex_lock(&p->lock);
17049    if (udptl)
17050       ast_udptl_get_peer(udptl, &p->udptlredirip);
17051    else
17052       memset(&p->udptlredirip, 0, sizeof(p->udptlredirip));
17053    if (!ast_test_flag(&p->flags[0], SIP_GOTREFER)) {
17054       if (!p->pendinginvite) {
17055          if (option_debug > 2) {
17056             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);
17057          }
17058          transmit_reinvite_with_t38_sdp(p);
17059       } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) {
17060          if (option_debug > 2) {
17061             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);
17062          }
17063          ast_set_flag(&p->flags[0], SIP_NEEDREINVITE);
17064       }
17065    }
17066    /* Reset lastrtprx timer */
17067    p->lastrtprx = p->lastrtptx = time(NULL);
17068    ast_mutex_unlock(&p->lock);
17069    return 0;
17070 }

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

Show details of one active dialog.

Definition at line 10785 of file chan_sip.c.

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

10786 {
10787    struct sip_pvt *cur;
10788    size_t len;
10789    int found = 0;
10790 
10791    if (argc != 4)
10792       return RESULT_SHOWUSAGE;
10793    len = strlen(argv[3]);
10794    ast_mutex_lock(&iflock);
10795    for (cur = iflist; cur; cur = cur->next) {
10796       if (!strncasecmp(cur->callid, argv[3], len)) {
10797          char formatbuf[BUFSIZ/2];
10798          ast_cli(fd,"\n");
10799          if (cur->subscribed != NONE)
10800             ast_cli(fd, "  * Subscription (type: %s)\n", subscription_type2str(cur->subscribed));
10801          else
10802             ast_cli(fd, "  * SIP Call\n");
10803          ast_cli(fd, "  Curr. trans. direction:  %s\n", ast_test_flag(&cur->flags[0], SIP_OUTGOING) ? "Outgoing" : "Incoming");
10804          ast_cli(fd, "  Call-ID:                %s\n", cur->callid);
10805          ast_cli(fd, "  Owner channel ID:       %s\n", cur->owner ? cur->owner->name : "<none>");
10806          ast_cli(fd, "  Our Codec Capability:   %d\n", cur->capability);
10807          ast_cli(fd, "  Non-Codec Capability (DTMF):   %d\n", cur->noncodeccapability);
10808          ast_cli(fd, "  Their Codec Capability:   %d\n", cur->peercapability);
10809          ast_cli(fd, "  Joint Codec Capability:   %d\n", cur->jointcapability);
10810          ast_cli(fd, "  Format:                 %s\n", ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->owner ? cur->owner->nativeformats : 0) );
10811          ast_cli(fd, "  MaxCallBR:              %d kbps\n", cur->maxcallbitrate);
10812          ast_cli(fd, "  Theoretical Address:    %s:%d\n", ast_inet_ntoa(cur->sa.sin_addr), ntohs(cur->sa.sin_port));
10813          ast_cli(fd, "  Received Address:       %s:%d\n", ast_inet_ntoa(cur->recv.sin_addr), ntohs(cur->recv.sin_port));
10814          ast_cli(fd, "  SIP Transfer mode:      %s\n", transfermode2str(cur->allowtransfer));
10815          ast_cli(fd, "  NAT Support:            %s\n", nat2str(ast_test_flag(&cur->flags[0], SIP_NAT)));
10816          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)" );
10817          ast_cli(fd, "  Our Tag:                %s\n", cur->tag);
10818          ast_cli(fd, "  Their Tag:              %s\n", cur->theirtag);
10819          ast_cli(fd, "  SIP User agent:         %s\n", cur->useragent);
10820          if (!ast_strlen_zero(cur->username))
10821             ast_cli(fd, "  Username:               %s\n", cur->username);
10822          if (!ast_strlen_zero(cur->peername))
10823             ast_cli(fd, "  Peername:               %s\n", cur->peername);
10824          if (!ast_strlen_zero(cur->uri))
10825             ast_cli(fd, "  Original uri:           %s\n", cur->uri);
10826          if (!ast_strlen_zero(cur->cid_num))
10827             ast_cli(fd, "  Caller-ID:              %s\n", cur->cid_num);
10828          ast_cli(fd, "  Need Destroy:           %d\n", ast_test_flag(&cur->flags[0], SIP_NEEDDESTROY));
10829          ast_cli(fd, "  Last Message:           %s\n", cur->lastmsg);
10830          ast_cli(fd, "  Promiscuous Redir:      %s\n", ast_test_flag(&cur->flags[0], SIP_PROMISCREDIR) ? "Yes" : "No");
10831          ast_cli(fd, "  Route:                  %s\n", cur->route ? cur->route->hop : "N/A");
10832          ast_cli(fd, "  DTMF Mode:              %s\n", dtmfmode2str(ast_test_flag(&cur->flags[0], SIP_DTMF)));
10833          ast_cli(fd, "  SIP Options:            ");
10834          if (cur->sipoptions) {
10835             int x;
10836             for (x=0 ; (x < (sizeof(sip_options) / sizeof(sip_options[0]))); x++) {
10837                if (cur->sipoptions & sip_options[x].id)
10838                   ast_cli(fd, "%s ", sip_options[x].text);
10839             }
10840          } else
10841             ast_cli(fd, "(none)\n");
10842          ast_cli(fd, "\n\n");
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_channels ( int  fd,
int  argc,
char *  argv[] 
) [static]

Show active SIP channels.

Definition at line 10583 of file chan_sip.c.

References __sip_show_channels().

10584 {
10585         return __sip_show_channels(fd, argc, argv, 0);
10586 }

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

CLI command to list local domains.

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

10090 {
10091    struct domain *d;
10092 #define FORMAT "%-40.40s %-20.20s %-16.16s\n"
10093 
10094    if (AST_LIST_EMPTY(&domain_list)) {
10095       ast_cli(fd, "SIP Domain support not enabled.\n\n");
10096       return RESULT_SUCCESS;
10097    } else {
10098       ast_cli(fd, FORMAT, "Our local SIP domains:", "Context", "Set by");
10099       AST_LIST_LOCK(&domain_list);
10100       AST_LIST_TRAVERSE(&domain_list, d, list)
10101          ast_cli(fd, FORMAT, d->domain, S_OR(d->context, "(default)"),
10102             domain_mode_to_text(d->mode));
10103       AST_LIST_UNLOCK(&domain_list);
10104       ast_cli(fd, "\n");
10105       return RESULT_SUCCESS;
10106    }
10107 }

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

Show history details of one dialog.

Definition at line 10853 of file chan_sip.c.

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

10854 {
10855    struct sip_pvt *cur;
10856    size_t len;
10857    int found = 0;
10858 
10859    if (argc != 4)
10860       return RESULT_SHOWUSAGE;
10861    if (!recordhistory)
10862       ast_cli(fd, "\n***Note: History recording is currently DISABLED.  Use 'sip history' to ENABLE.\n");
10863    len = strlen(argv[3]);
10864    ast_mutex_lock(&iflock);
10865    for (cur = iflist; cur; cur = cur->next) {
10866       if (!strncasecmp(cur->callid, argv[3], len)) {
10867          struct sip_history *hist;
10868          int x = 0;
10869 
10870          ast_cli(fd,"\n");
10871          if (cur->subscribed != NONE)
10872             ast_cli(fd, "  * Subscription\n");
10873          else
10874             ast_cli(fd, "  * SIP Call\n");
10875          if (cur->history)
10876             AST_LIST_TRAVERSE(cur->history, hist, list)
10877                ast_cli(fd, "%d. %s\n", ++x, hist->event);
10878          if (x == 0)
10879             ast_cli(fd, "Call '%s' has no history\n", cur->callid);
10880          found++;
10881       }
10882    }
10883    ast_mutex_unlock(&iflock);
10884    if (!found) 
10885       ast_cli(fd, "No such SIP Call ID starting with '%s'\n", argv[3]);
10886    return RESULT_SUCCESS;
10887 }

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

09515 {
09516 #define FORMAT  "%-25.25s %-15.15s %-15.15s \n"
09517 #define FORMAT2 "%-25.25s %-15.15s %-15.15s \n"
09518    char ilimits[40];
09519    char iused[40];
09520    int showall = FALSE;
09521 
09522    if (argc < 3) 
09523       return RESULT_SHOWUSAGE;
09524 
09525    if (argc == 4 && !strcmp(argv[3],"all")) 
09526          showall = TRUE;
09527    
09528    ast_cli(fd, FORMAT, "* User name", "In use", "Limit");
09529    ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do {
09530       ASTOBJ_RDLOCK(iterator);
09531       if (iterator->call_limit)
09532          snprintf(ilimits, sizeof(ilimits), "%d", iterator->call_limit);
09533       else 
09534          ast_copy_string(ilimits, "N/A", sizeof(ilimits));
09535       snprintf(iused, sizeof(iused), "%d", iterator->inUse);
09536       if (showall || iterator->call_limit)
09537          ast_cli(fd, FORMAT2, iterator->name, iused, ilimits);
09538       ASTOBJ_UNLOCK(iterator);
09539    } while (0) );
09540 
09541    ast_cli(fd, FORMAT, "* Peer name", "In use", "Limit");
09542 
09543    ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do {
09544       ASTOBJ_RDLOCK(iterator);
09545       if (iterator->call_limit)
09546          snprintf(ilimits, sizeof(ilimits), "%d", iterator->call_limit);
09547       else 
09548          ast_copy_string(ilimits, "N/A", sizeof(ilimits));
09549       snprintf(iused, sizeof(iused), "%d/%d", iterator->inUse, iterator->inRinging);
09550       if (showall || iterator->call_limit)
09551          ast_cli(fd, FORMAT2, iterator->name, iused, ilimits);
09552       ASTOBJ_UNLOCK(iterator);
09553    } while (0) );
09554 
09555    return RESULT_SUCCESS;
09556 #undef FORMAT
09557 #undef FORMAT2
09558 }

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

List all allocated SIP Objects (realtime or static).

Definition at line 9835 of file chan_sip.c.

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

09836 {
09837    char tmp[256];
09838    if (argc != 3)
09839       return RESULT_SHOWUSAGE;
09840    ast_cli(fd, "-= User objects: %d static, %d realtime =-\n\n", suserobjs, ruserobjs);
09841    ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), &userl);
09842    ast_cli(fd, "-= Peer objects: %d static, %d realtime, %d autocreate =-\n\n", speerobjs, rpeerobjs, apeerobjs);
09843    ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), &peerl);
09844    ast_cli(fd, "-= Registry objects: %d =-\n\n", regobjs);
09845    ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), &regl);
09846    return RESULT_SUCCESS;
09847 }

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

Show one peer in detail.

Definition at line 10141 of file chan_sip.c.

References _sip_show_peer().

10142 {
10143    return _sip_show_peer(0, fd, NULL, NULL, argc, (const char **) argv);
10144 }

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

CLI Show Peers command.

Definition at line 9691 of file chan_sip.c.

References _sip_show_peers().

09692 {
09693    return _sip_show_peers(fd, NULL, NULL, NULL, argc, (const char **) argv);
09694 }

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

Show SIP Registry (registrations with other SIP proxies.

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

10415 {
10416 #define FORMAT2 "%-30.30s  %-12.12s  %8.8s %-20.20s %-25.25s\n"
10417 #define FORMAT  "%-30.30s  %-12.12s  %8d %-20.20s %-25.25s\n"
10418    char host[80];
10419    char tmpdat[256];
10420    struct tm tm;
10421 
10422 
10423    if (argc != 3)
10424       return RESULT_SHOWUSAGE;
10425    ast_cli(fd, FORMAT2, "Host", "Username", "Refresh", "State", "Reg.Time");
10426    ASTOBJ_CONTAINER_TRAVERSE(&regl, 1, do {
10427       ASTOBJ_RDLOCK(iterator);
10428       snprintf(host, sizeof(host), "%s:%d", iterator->hostname, iterator->portno ? iterator->portno : STANDARD_SIP_PORT);
10429       if (iterator->regtime) {
10430          ast_localtime(&iterator->regtime, &tm, NULL);
10431          strftime(tmpdat, sizeof(tmpdat), "%a, %d %b %Y %T", &tm);
10432       } else {
10433          tmpdat[0] = 0;
10434       }
10435       ast_cli(fd, FORMAT, host, iterator->username, iterator->refresh, regstate2str(iterator->regstate), tmpdat);
10436       ASTOBJ_UNLOCK(iterator);
10437    } while(0));
10438    return RESULT_SUCCESS;
10439 #undef FORMAT
10440 #undef FORMAT2
10441 }

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

List global settings for the SIP channel.

Definition at line 10444 of file chan_sip.c.

References ast_check_realtime(), ast_cli(), ast_getformatname_multiple(), ast_inet_ntoa(), AST_JB_ENABLED, AST_JB_FORCED, AST_JB_LOG, AST_LIST_EMPTY, ast_test_flag, ast_tos2str(), authl, bindaddr, default_prefs, dtmfmode2str(), global_flags, global_jbconf, ast_jb_conf::impl, ast_jb_conf::max_size, nat2str(), print_codec_to_cli(), RESULT_SHOWUSAGE, RESULT_SUCCESS, ast_jb_conf::resync_threshold, 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().

10445 {
10446    int realtimepeers;
10447    int realtimeusers;
10448    char codec_buf[BUFSIZ];
10449 
10450    realtimepeers = ast_check_realtime("sippeers");
10451    realtimeusers = ast_check_realtime("sipusers");
10452 
10453    if (argc != 3)
10454       return RESULT_SHOWUSAGE;
10455    ast_cli(fd, "\n\nGlobal Settings:\n");
10456    ast_cli(fd, "----------------\n");
10457    ast_cli(fd, "  SIP Port:               %d\n", ntohs(bindaddr.sin_port));
10458    ast_cli(fd, "  Bindaddress:            %s\n", ast_inet_ntoa(bindaddr.sin_addr));
10459    ast_cli(fd, "  Videosupport:           %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_VIDEOSUPPORT) ? "Yes" : "No");
10460    ast_cli(fd, "  AutoCreatePeer:         %s\n", autocreatepeer ? "Yes" : "No");
10461    ast_cli(fd, "  Allow unknown access:   %s\n", global_allowguest ? "Yes" : "No");
10462    ast_cli(fd, "  Allow subscriptions:    %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWSUBSCRIBE) ? "Yes" : "No");
10463    ast_cli(fd, "  Allow overlap dialing:  %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP) ? "Yes" : "No");
10464    ast_cli(fd, "  Promsic. redir:         %s\n", ast_test_flag(&global_flags[0], SIP_PROMISCREDIR) ? "Yes" : "No");
10465    ast_cli(fd, "  SIP domain support:     %s\n", AST_LIST_EMPTY(&domain_list) ? "No" : "Yes");
10466    ast_cli(fd, "  Call to non-local dom.: %s\n", allow_external_domains ? "Yes" : "No");
10467    ast_cli(fd, "  URI user is phone no:   %s\n", ast_test_flag(&global_flags[0], SIP_USEREQPHONE) ? "Yes" : "No");
10468    ast_cli(fd, "  Our auth realm          %s\n", global_realm);
10469    ast_cli(fd, "  Realm. auth:            %s\n", authl ? "Yes": "No");
10470    ast_cli(fd, "  Always auth rejects:    %s\n", global_alwaysauthreject ? "Yes" : "No");
10471    ast_cli(fd, "  Call limit peers only:  %s\n", global_limitonpeers ? "Yes" : "No");
10472    ast_cli(fd, "  Direct RTP setup:       %s\n", global_directrtpsetup ? "Yes" : "No");
10473    ast_cli(fd, "  User Agent:             %s\n", global_useragent);
10474    ast_cli(fd, "  MWI checking interval:  %d secs\n", global_mwitime);
10475    ast_cli(fd, "  Reg. context:           %s\n", S_OR(global_regcontext, "(not set)"));
10476    ast_cli(fd, "  Caller ID:              %s\n", default_callerid);
10477    ast_cli(fd, "  From: Domain:           %s\n", default_fromdomain);
10478    ast_cli(fd, "  Record SIP history:     %s\n", recordhistory ? "On" : "Off");
10479    ast_cli(fd, "  Call Events:            %s\n", global_callevents ? "On" : "Off");
10480    ast_cli(fd, "  IP ToS SIP:             %s\n", ast_tos2str(global_tos_sip));
10481    ast_cli(fd, "  IP ToS RTP audio:       %s\n", ast_tos2str(global_tos_audio));
10482    ast_cli(fd, "  IP ToS RTP video:       %s\n", ast_tos2str(global_tos_video));
10483    ast_cli(fd, "  T38 fax pt UDPTL:       %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT_UDPTL) ? "Yes" : "No");
10484 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS
10485    ast_cli(fd, "  T38 fax pt RTP:         %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT_RTP) ? "Yes" : "No");
10486    ast_cli(fd, "  T38 fax pt TCP:         %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT_TCP) ? "Yes" : "No");
10487 #endif
10488    ast_cli(fd, "  RFC2833 Compensation:   %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RFC2833_COMPENSATE) ? "Yes" : "No");
10489    ast_cli(fd, "  Jitterbuffer enabled:   %s\n", ast_test_flag(&global_jbconf, AST_JB_ENABLED) ? "Yes" : "No");
10490    ast_cli(fd, "  Jitterbuffer forced:    %s\n", ast_test_flag(&global_jbconf, AST_JB_FORCED) ? "Yes" : "No");
10491    ast_cli(fd, "  Jitterbuffer max size:  %ld\n", global_jbconf.max_size);
10492    ast_cli(fd, "  Jitterbuffer resync:    %ld\n", global_jbconf.resync_threshold);
10493    ast_cli(fd, "  Jitterbuffer impl:      %s\n", global_jbconf.impl);
10494    ast_cli(fd, "  Jitterbuffer log:       %s\n", ast_test_flag(&global_jbconf, AST_JB_LOG) ? "Yes" : "No");
10495    if (!realtimepeers && !realtimeusers)
10496       ast_cli(fd, "  SIP realtime:           Disabled\n" );
10497    else
10498       ast_cli(fd, "  SIP realtime:           Enabled\n" );
10499 
10500    ast_cli(fd, "\nGlobal Signalling Settings:\n");
10501    ast_cli(fd, "---------------------------\n");
10502    ast_cli(fd, "  Codecs:                 ");
10503    ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, global_capability);
10504    ast_cli(fd, "%s\n", codec_buf);
10505    ast_cli(fd, "  Codec Order:            ");
10506    print_codec_to_cli(fd, &default_prefs);
10507    ast_cli(fd, "\n");
10508    ast_cli(fd, "  T1 minimum:             %d\n", global_t1min);
10509    ast_cli(fd, "  Relax DTMF:             %s\n", global_relaxdtmf ? "Yes" : "No");
10510    ast_cli(fd, "  Compact SIP headers:    %s\n", compactheaders ? "Yes" : "No");
10511    ast_cli(fd, "  RTP Keepalive:          %d %s\n", global_rtpkeepalive, global_rtpkeepalive ? "" : "(Disabled)" );
10512    ast_cli(fd, "  RTP Timeout:            %d %s\n", global_rtptimeout, global_rtptimeout ? "" : "(Disabled)" );
10513    ast_cli(fd, "  RTP Hold Timeout:       %d %s\n", global_rtpholdtimeout, global_rtpholdtimeout ? "" : "(Disabled)");
10514    ast_cli(fd, "  MWI NOTIFY mime type:   %s\n", default_notifymime);
10515    ast_cli(fd, "  DNS SRV lookup:         %s\n", srvlookup ? "Yes" : "No");
10516    ast_cli(fd, "  Pedantic SIP support:   %s\n", pedanticsipchecking ? "Yes" : "No");
10517    ast_cli(fd, "  Reg. min duration       %d secs\n", min_expiry);
10518    ast_cli(fd, "  Reg. max duration:      %d secs\n", max_expiry);
10519    ast_cli(fd, "  Reg. default duration:  %d secs\n", default_expiry);
10520    ast_cli(fd, "  Outbound reg. timeout:  %d secs\n", global_reg_timeout);
10521    ast_cli(fd, "  Outbound reg. attempts: %d\n", global_regattempts_max);
10522    ast_cli(fd, "  Notify ringing state:   %s\n", global_notifyringing ? "Yes" : "No");
10523    ast_cli(fd, "  Notify hold state:      %s\n", global_notifyhold ? "Yes" : "No");
10524    ast_cli(fd, "  SIP Transfer mode:      %s\n", transfermode2str(global_allowtransfer));
10525    ast_cli(fd, "  Max Call Bitrate:       %d kbps\r\n", default_maxcallbitrate);
10526    ast_cli(fd, "  Auto-Framing:           %s \r\n", global_autoframing ? "Yes" : "No");
10527    ast_cli(fd, "\nDefault Settings:\n");
10528    ast_cli(fd, "-----------------\n");
10529    ast_cli(fd, "  Context:                %s\n", default_context);
10530    ast_cli(fd, "  Nat:                    %s\n", nat2str(ast_test_flag(&global_flags[0], SIP_NAT)));
10531    ast_cli(fd, "  DTMF:                   %s\n", dtmfmode2str(ast_test_flag(&global_flags[0], SIP_DTMF)));
10532    ast_cli(fd, "  Qualify:                %d\n", default_qualify);
10533    ast_cli(fd, "  Use ClientCode:         %s\n", ast_test_flag(&global_flags[0], SIP_USECLIENTCODE) ? "Yes" : "No");
10534    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" );
10535    ast_cli(fd, "  Language:               %s\n", S_OR(default_language, "(Defaults to English)"));
10536    ast_cli(fd, "  MOH Interpret:          %s\n", default_mohinterpret);
10537    ast_cli(fd, "  MOH Suggest:            %s\n", default_mohsuggest);
10538    ast_cli(fd, "  Voice Mail Extension:   %s\n", default_vmexten);
10539 
10540    
10541    if (realtimepeers || realtimeusers) {
10542       ast_cli(fd, "\nRealtime SIP Settings:\n");
10543       ast_cli(fd, "----------------------\n");
10544       ast_cli(fd, "  Realtime Peers:         %s\n", realtimepeers ? "Yes" : "No");
10545       ast_cli(fd, "  Realtime Users:         %s\n", realtimeusers ? "Yes" : "No");
10546       ast_cli(fd, "  Cache Friends:          %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS) ? "Yes" : "No");
10547       ast_cli(fd, "  Update:                 %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RTUPDATE) ? "Yes" : "No");
10548       ast_cli(fd, "  Ignore Reg. Expire:     %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_IGNOREREGEXPIRE) ? "Yes" : "No");
10549       ast_cli(fd, "  Save sys. name:         %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RTSAVE_SYSNAME) ? "Yes" : "No");
10550       ast_cli(fd, "  Auto Clear:             %d\n", global_rtautoclear);
10551    }
10552    ast_cli(fd, "\n----\n");
10553    return RESULT_SUCCESS;
10554 }

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

Show active SIP subscriptions.

Definition at line 10589 of file chan_sip.c.

References __sip_show_channels().

10590 {
10591         return __sip_show_channels(fd, argc, argv, 1);
10592 }

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

Show one user in detail.

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

10360 {
10361    char cbuf[256];
10362    struct sip_user *user;
10363    struct ast_variable *v;
10364    int load_realtime;
10365 
10366    if (argc < 4)
10367       return RESULT_SHOWUSAGE;
10368 
10369    /* Load from realtime storage? */
10370    load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? TRUE : FALSE;
10371 
10372    user = find_user(argv[3], load_realtime);
10373    if (user) {
10374       ast_cli(fd,"\n\n");
10375       ast_cli(fd, "  * Name       : %s\n", user->name);
10376       ast_cli(fd, "  Secret       : %s\n", ast_strlen_zero(user->secret)?"<Not set>":"<Set>");
10377       ast_cli(fd, "  MD5Secret    : %s\n", ast_strlen_zero(user->md5secret)?"<Not set>":"<Set>");
10378       ast_cli(fd, "  Context      : %s\n", user->context);
10379       ast_cli(fd, "  Language     : %s\n", user->language);
10380       if (!ast_strlen_zero(user->accountcode))
10381          ast_cli(fd, "  Accountcode  : %s\n", user->accountcode);
10382       ast_cli(fd, "  AMA flags    : %s\n", ast_cdr_flags2str(user->amaflags));
10383       ast_cli(fd, "  Transfer mode: %s\n", transfermode2str(user->allowtransfer));
10384       ast_cli(fd, "  MaxCallBR    : %d kbps\n", user->maxcallbitrate);
10385       ast_cli(fd, "  CallingPres  : %s\n", ast_describe_caller_presentation(user->callingpres));
10386       ast_cli(fd, "  Call limit   : %d\n", user->call_limit);
10387       ast_cli(fd, "  Callgroup    : ");
10388       print_group(fd, user->callgroup, 0);
10389       ast_cli(fd, "  Pickupgroup  : ");
10390       print_group(fd, user->pickupgroup, 0);
10391       ast_cli(fd, "  Callerid     : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), user->cid_name, user->cid_num, "<unspecified>"));
10392       ast_cli(fd, "  ACL          : %s\n", (user->ha?"Yes":"No"));
10393       ast_cli(fd, "  Codec Order  : (");
10394       print_codec_to_cli(fd, &user->prefs);
10395       ast_cli(fd, ")\n");
10396 
10397       ast_cli(fd, "  Auto-Framing:  %s \n", user->autoframing ? "Yes" : "No");
10398       if (user->chanvars) {
10399          ast_cli(fd, "  Variables    :\n");
10400          for (v = user->chanvars ; v ; v = v->next)
10401             ast_cli(fd, "                 %s = %s\n", v->name, v->value);
10402       }
10403       ast_cli(fd,"\n");
10404       ASTOBJ_UNREF(user,sip_destroy_user);
10405    } else {
10406       ast_cli(fd,"User %s not found.\n", argv[3]);
10407       ast_cli(fd,"\n");
10408    }
10409 
10410    return RESULT_SUCCESS;
10411 }

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

CLI Command 'SIP Show Users'.

Definition at line 9614 of file chan_sip.c.

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

09615 {
09616    regex_t regexbuf;
09617    int havepattern = FALSE;
09618 
09619 #define FORMAT  "%-25.25s  %-15.15s  %-15.15s  %-15.15s  %-5.5s%-10.10s\n"
09620 
09621    switch (argc) {
09622    case 5:
09623       if (!strcasecmp(argv[3], "like")) {
09624          if (regcomp(&regexbuf, argv[4], REG_EXTENDED | REG_NOSUB))
09625             return RESULT_SHOWUSAGE;
09626          havepattern = TRUE;
09627       } else
09628          return RESULT_SHOWUSAGE;
09629    case 3:
09630       break;
09631    default:
09632       return RESULT_SHOWUSAGE;
09633    }
09634 
09635    ast_cli(fd, FORMAT, "Username", "Secret", "Accountcode", "Def.Context", "ACL", "NAT");
09636    ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do {
09637       ASTOBJ_RDLOCK(iterator);
09638 
09639       if (havepattern && regexec(&regexbuf, iterator->name, 0, NULL, 0)) {
09640          ASTOBJ_UNLOCK(iterator);
09641          continue;
09642       }
09643 
09644       ast_cli(fd, FORMAT, iterator->name, 
09645          iterator->secret, 
09646          iterator->accountcode,
09647          iterator->context,
09648          iterator->ha ? "Yes" : "No",
09649          nat2str(ast_test_flag(&iterator->flags[0], SIP_NAT)));
09650       ASTOBJ_UNLOCK(iterator);
09651    } while (0)
09652    );
09653 
09654    if (havepattern)
09655       regfree(&regexbuf);
09656 
09657    return RESULT_SUCCESS;
09658 #undef FORMAT
09659 }

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

References ast_log(), ast_strdupa, ast_string_field_build, ast_strlen_zero(), get_header(), sip_pvt::initreq, LOG_ERROR, sip_alreadygone(), sip_scheddestroy(), SIP_TRANS_TIMEOUT, strcasestr(), strsep(), and transmit_response_reliable().

Referenced by sip_transfer().

17402 {
17403    char *cdest;
17404    char *extension, *host, *port;
17405    char tmp[80];
17406    
17407    cdest = ast_strdupa(dest);
17408    
17409    extension = strsep(&cdest, "@");
17410    host = strsep(&cdest, ":");
17411    port = strsep(&cdest, ":");
17412    if (ast_strlen_zero(extension)) {
17413       ast_log(LOG_ERROR, "Missing mandatory argument: extension\n");
17414       return 0;
17415    }
17416 
17417    /* we'll issue the redirect message here */
17418    if (!host) {
17419       char *localtmp;
17420       ast_copy_string(tmp, get_header(&p->initreq, "To"), sizeof(tmp));
17421       if (ast_strlen_zero(tmp)) {
17422          ast_log(LOG_ERROR, "Cannot retrieve the 'To' header from the original SIP request!\n");
17423          return 0;
17424       }
17425       if ((localtmp = strcasestr(tmp, "sip:")) && (localtmp = strchr(localtmp, '@'))) {
17426          char lhost[80], lport[80];
17427          memset(lhost, 0, sizeof(lhost));
17428          memset(lport, 0, sizeof(lport));
17429          localtmp++;
17430          /* This is okey because lhost and lport are as big as tmp */
17431          sscanf(localtmp, "%[^<>:; ]:%[^<>:; ]", lhost, lport);
17432          if (ast_strlen_zero(lhost)) {
17433             ast_log(LOG_ERROR, "Can't find the host address\n");
17434             return 0;
17435          }
17436          host = ast_strdupa(lhost);
17437          if (!ast_strlen_zero(lport)) {
17438             port = ast_strdupa(lport);
17439          }
17440       }
17441    }
17442 
17443    sip_alreadygone(p);
17444    ast_string_field_build(p, our_contact, "Transfer <sip:%s@%s%s%s>", extension, host, port ? ":" : "", port ? port : "");
17445    transmit_response_reliable(p, "302 Moved Temporarily", &p->initreq);
17446 
17447    sip_scheddestroy(p, SIP_TRANS_TIMEOUT);   /* Make sure we stop send this reply. */
17448    sip_alreadygone(p);
17449    return 0;
17450 }

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

Transfer SIP call.

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

03784 {
03785    struct sip_pvt *p = ast->tech_pvt;
03786    int res;
03787 
03788    if (dest == NULL) /* functions below do not take a NULL */
03789       dest = "";
03790    ast_mutex_lock(&p->lock);
03791    if (ast->_state == AST_STATE_RING)
03792       res = sip_sipredirect(p, dest);
03793    else
03794       res = transmit_refer(p, dest);
03795    ast_mutex_unlock(&p->lock);
03796    return res;
03797 }

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

Send frame to media channel (rtp).

Definition at line 3616 of file chan_sip.c.

References ast_channel::_state, ast_backtrace(), AST_FORMAT_AUDIO_MASK, ast_frame_dump(), 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, 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.

03617 {
03618    struct sip_pvt *p = ast->tech_pvt;
03619    int res = 0;
03620 
03621    switch (frame->frametype) {
03622    case AST_FRAME_VOICE:
03623       if (!(frame->subclass & ast->nativeformats)) {
03624          char s1[512], s2[512], s3[512];
03625          ast_log(LOG_WARNING, "Asked to transmit frame type %d, while native formats is %s(%d) read/write = %s(%d)/%s(%d)\n",
03626             frame->subclass, 
03627             ast_getformatname_multiple(s1, sizeof(s1) - 1, ast->nativeformats & AST_FORMAT_AUDIO_MASK),
03628             ast->nativeformats & AST_FORMAT_AUDIO_MASK,
03629             ast_getformatname_multiple(s2, sizeof(s2) - 1, ast->readformat),
03630             ast->readformat,
03631             ast_getformatname_multiple(s3, sizeof(s3) - 1, ast->writeformat),
03632             ast->writeformat);
03633          ast_frame_dump(ast->name, frame, "<<");
03634          ast_backtrace();
03635          return 0;
03636       }
03637       if (p) {
03638          ast_mutex_lock(&p->lock);
03639          if (p->rtp) {
03640             /* If channel is not up, activate early media session */
03641             if ((ast->_state != AST_STATE_UP) &&
03642                 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) &&
03643                 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
03644                transmit_response_with_sdp(p, "183 Session Progress", &p->initreq, XMIT_UNRELIABLE);
03645                ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT);  
03646             }
03647             p->lastrtptx = time(NULL);
03648             res = ast_rtp_write(p->rtp, frame);
03649          }
03650          ast_mutex_unlock(&p->lock);
03651       }
03652       break;
03653    case AST_FRAME_VIDEO:
03654       if (p) {
03655          ast_mutex_lock(&p->lock);
03656          if (p->vrtp) {
03657             /* Activate video early media */
03658             if ((ast->_state != AST_STATE_UP) &&
03659                 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) &&
03660                 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
03661                transmit_response_with_sdp(p, "183 Session Progress", &p->initreq, XMIT_UNRELIABLE);
03662                ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT);  
03663             }
03664             p->lastrtptx = time(NULL);
03665             res = ast_rtp_write(p->vrtp, frame);
03666          }
03667          ast_mutex_unlock(&p->lock);
03668       }
03669       break;
03670    case AST_FRAME_IMAGE:
03671       return 0;
03672       break;
03673    case AST_FRAME_MODEM:
03674       if (p) {
03675          ast_mutex_lock(&p->lock);
03676          /* UDPTL requires two-way communication, so early media is not needed here.
03677             we simply forget the frames if we get modem frames before the bridge is up.
03678             Fax will re-transmit.
03679          */
03680          if (p->udptl && ast->_state == AST_STATE_UP) 
03681             res = ast_udptl_write(p->udptl, frame);
03682          ast_mutex_unlock(&p->lock);
03683       }
03684       break;
03685    default: 
03686       ast_log(LOG_WARNING, "Can't send %d type frames with SIP write\n", frame->frametype);
03687       return 0;
03688    }
03689 
03690    return res;
03691 }

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

Referenced by do_monitor().

15092 {
15093    struct sip_request req;
15094    struct sockaddr_in sin = { 0, };
15095    struct sip_pvt *p;
15096    int res;
15097    socklen_t len = sizeof(sin);
15098    int nounlock;
15099    int recount = 0;
15100    int lockretry;
15101 
15102    memset(&req, 0, sizeof(req));
15103    res = recvfrom(sipsock, req.data, sizeof(req.data) - 1, 0, (struct sockaddr *)&sin, &len);
15104    if (res < 0) {
15105 #if !defined(__FreeBSD__)
15106       if (errno == EAGAIN)
15107          ast_log(LOG_NOTICE, "SIP: Received packet with bad UDP checksum\n");
15108       else 
15109 #endif
15110       if (errno != ECONNREFUSED)
15111          ast_log(LOG_WARNING, "Recv error: %s\n", strerror(errno));
15112       return 1;
15113    }
15114    if (option_debug && res == sizeof(req.data)) {
15115       ast_log(LOG_DEBUG, "Received packet exceeds buffer. Data is possibly lost\n");
15116       req.data[sizeof(req.data) - 1] = '\0';
15117    } else
15118       req.data[res] = '\0';
15119    req.len = res;
15120    if(sip_debug_test_addr(&sin)) /* Set the debug flag early on packet level */
15121       ast_set_flag(&req, SIP_PKT_DEBUG);
15122    if (pedanticsipchecking)
15123       req.len = lws2sws(req.data, req.len);  /* Fix multiline headers */
15124    if (ast_test_flag(&req, SIP_PKT_DEBUG))
15125       ast_verbose("\n<--- SIP read from %s:%d --->\n%s\n<------------->\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port), req.data);
15126 
15127    parse_request(&req);
15128    req.method = find_sip_method(req.rlPart1);
15129 
15130    if (ast_test_flag(&req, SIP_PKT_DEBUG))
15131       ast_verbose("--- (%d headers %d lines)%s ---\n", req.headers, req.lines, (req.headers + req.lines == 0) ? " Nat keepalive" : "");
15132 
15133    if (req.headers < 2) /* Must have at least two headers */
15134       return 1;
15135 
15136    /* Process request, with netlock held, and with usual deadlock avoidance */
15137    for (lockretry = 100; lockretry > 0; lockretry--) {
15138       ast_mutex_lock(&netlock);
15139 
15140       /* Find the active SIP dialog or create a new one */
15141       p = find_call(&req, &sin, req.method); /* returns p locked */
15142       if (p == NULL) {
15143          if (option_debug)
15144             ast_log(LOG_DEBUG, "Invalid SIP message - rejected , no callid, len %d\n", req.len);
15145          ast_mutex_unlock(&netlock);
15146          return 1;
15147       }
15148       /* Go ahead and lock the owner if it has one -- we may need it */
15149       /* becaues this is deadlock-prone, we need to try and unlock if failed */
15150       if (!p->owner || !ast_channel_trylock(p->owner))
15151          break;   /* locking succeeded */
15152       if (option_debug)
15153          ast_log(LOG_DEBUG, "Failed to grab owner channel lock, trying again. (SIP call %s)\n", p->callid);
15154       ast_mutex_unlock(&p->lock);
15155       ast_mutex_unlock(&netlock);
15156       /* Sleep for a very short amount of time */
15157       usleep(1);
15158    }
15159    p->recv = sin;
15160 
15161    if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) /* This is a request or response, note what it was for */
15162       append_history(p, "Rx", "%s / %s / %s", req.data, get_header(&req, "CSeq"), req.rlPart2);
15163 
15164    if (!lockretry) {
15165       if (p->owner)
15166          ast_log(LOG_ERROR, "We could NOT get the channel lock for %s! \n", S_OR(p->owner->name, "- no channel name ??? - "));
15167       ast_log(LOG_ERROR, "SIP transaction failed: %s \n", p->callid);
15168       if (req.method != SIP_ACK)
15169          transmit_response(p, "503 Server error", &req); /* We must respond according to RFC 3261 sec 12.2 */
15170       /* XXX We could add retry-after to make sure they come back */
15171       append_history(p, "LockFail", "Owner lock failed, transaction failed.");
15172       return 1;
15173    }
15174    nounlock = 0;
15175    if (handle_request(p, &req, &sin, &recount, &nounlock) == -1) {
15176       /* Request failed */
15177       if (option_debug)
15178          ast_log(LOG_DEBUG, "SIP message could not be handled, bad request: %-70.70s\n", p->callid[0] ? p->callid : "<no callid>");
15179    }
15180       
15181    if (p->owner && !nounlock)
15182       ast_channel_unlock(p->owner);
15183    ast_mutex_unlock(&p->lock);
15184    ast_mutex_unlock(&netlock);
15185    if (recount)
15186       ast_update_use_count();
15187 
15188    return 1;
15189 }

static void stop_media_flows ( struct sip_pvt p  )  [static]

Immediately stop RTP, VRTP and UDPTL as applicable.

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

12367 {
12368    /* Immediately stop RTP, VRTP and UDPTL as applicable */
12369    if (p->rtp)
12370       ast_rtp_stop(p->rtp);
12371    if (p->vrtp)
12372       ast_rtp_stop(p->vrtp);
12373    if (p->udptl)
12374       ast_udptl_stop(p->udptl);
12375 }

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

Show subscription type in string format.

Definition at line 10557 of file chan_sip.c.

References subscription_types, and type.

Referenced by sip_show_channel().

10558 {
10559    int i;
10560 
10561    for (i = 1; (i < (sizeof(subscription_types) / sizeof(subscription_types[0]))); i++) {
10562       if (subscription_types[i].type == subtype) {
10563          return subscription_types[i].text;
10564       }
10565    }
10566    return subscription_types[0].text;
10567 }

static int t38_get_rate ( int  t38cap  )  [static]

Get Max T.38 Transmission rate from T38 capabilities.

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

06122 {
06123    int maxrate = (t38cap & (T38FAX_RATE_14400 | T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400));
06124    
06125    if (maxrate & T38FAX_RATE_14400) {
06126       if (option_debug > 1)
06127          ast_log(LOG_DEBUG, "T38MaxFaxRate 14400 found\n");
06128       return 14400;
06129    } else if (maxrate & T38FAX_RATE_12000) {
06130       if (option_debug > 1)
06131          ast_log(LOG_DEBUG, "T38MaxFaxRate 12000 found\n");
06132       return 12000;
06133    } else if (maxrate & T38FAX_RATE_9600) {
06134       if (option_debug > 1)
06135          ast_log(LOG_DEBUG, "T38MaxFaxRate 9600 found\n");
06136       return 9600;
06137    } else if (maxrate & T38FAX_RATE_7200) {
06138       if (option_debug > 1)
06139          ast_log(LOG_DEBUG, "T38MaxFaxRate 7200 found\n");
06140       return 7200;
06141    } else if (maxrate & T38FAX_RATE_4800) {
06142       if (option_debug > 1)
06143          ast_log(LOG_DEBUG, "T38MaxFaxRate 4800 found\n");
06144       return 4800;
06145    } else if (maxrate & T38FAX_RATE_2400) {
06146       if (option_debug > 1)
06147          ast_log(LOG_DEBUG, "T38MaxFaxRate 2400 found\n");
06148       return 2400;
06149    } else {
06150       if (option_debug > 1)
06151          ast_log(LOG_DEBUG, "Strange, T38MaxFaxRate NOT found in peers T38 SDP.\n");
06152       return 0;
06153    }
06154 }

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

Create temporary peer (used in autocreatepeer mode).

Definition at line 16197 of file chan_sip.c.

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

Referenced by register_verify().

16198 {
16199    struct sip_peer *peer;
16200 
16201    if (!(peer = ast_calloc(1, sizeof(*peer))))
16202       return NULL;
16203 
16204    apeerobjs++;
16205    ASTOBJ_INIT(peer);
16206    set_peer_defaults(peer);
16207 
16208    ast_copy_string(peer->name, name, sizeof(peer->name));
16209 
16210    ast_set_flag(&peer->flags[1], SIP_PAGE2_SELFDESTRUCT);
16211    ast_set_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC);
16212    peer->prefs = default_prefs;
16213    reg_source_db(peer);
16214 
16215    return peer;
16216 }

static void temp_pvt_cleanup ( void *   )  [static]

Definition at line 5897 of file chan_sip.c.

References ast_string_field_free_pools, and free.

05898 {
05899    struct sip_pvt *p = data;
05900 
05901    ast_string_field_free_pools(p);
05902 
05903    free(data);
05904 }

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

Convert transfer mode to text string.

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

09562 {
09563    if (mode == TRANSFER_OPENFORALL)
09564       return "open";
09565    else if (mode == TRANSFER_CLOSED)
09566       return "closed";
09567    return "strict";
09568 }

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

08407 {
08408    ast_string_field_build(p, randdata, "%08lx", ast_random()); /* Create nonce for challenge */
08409    transmit_response_with_auth(p, "401 Unauthorized", req, p->randdata, reliable, "WWW-Authenticate", 0);
08410 }

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

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

Referenced by sip_senddigit_end().

07646 {
07647    struct sip_request req;
07648 
07649    reqprep(&req, p, SIP_INFO, 0, 1);
07650    add_digit(&req, digit, duration);
07651    return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
07652 }

static int transmit_info_with_vidupdate ( struct sip_pvt p  )  [static]

Send SIP INFO with video update request.

Definition at line 7655 of file chan_sip.c.

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

Referenced by sip_indicate().

07656 {
07657    struct sip_request req;
07658 
07659    reqprep(&req, p, SIP_INFO, 0, 1);
07660    add_vidupdate(&req);
07661    return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
07662 }

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

06924 {
06925    struct sip_request req;
06926    
06927    req.method = sipmethod;
06928    if (init) {    /* Seems like init always is 2 */
06929       /* Bump branch even on initial requests */
06930       p->branch ^= ast_random();
06931       build_via(p);
06932       if (init > 1)
06933          initreqprep(&req, p, sipmethod);
06934       else
06935          reqprep(&req, p, sipmethod, 0, 1);
06936    } else
06937       reqprep(&req, p, sipmethod, 0, 1);
06938       
06939    if (p->options && p->options->auth)
06940       add_header(&req, p->options->authheader, p->options->auth);
06941    append_date(&req);
06942    if (sipmethod == SIP_REFER) { /* Call transfer */
06943       if (p->refer) {
06944          char buf[BUFSIZ];
06945          if (!ast_strlen_zero(p->refer->refer_to))
06946             add_header(&req, "Refer-To", p->refer->refer_to);
06947          if (!ast_strlen_zero(p->refer->referred_by)) {
06948             sprintf(buf, "%s <%s>", p->refer->referred_by_name, p->refer->referred_by);
06949             add_header(&req, "Referred-By", buf);
06950          }
06951       }
06952    }
06953    /* This new INVITE is part of an attended transfer. Make sure that the
06954    other end knows and replace the current call with this new call */
06955    if (p->options && p->options->replaces && !ast_strlen_zero(p->options->replaces)) {
06956       add_header(&req, "Replaces", p->options->replaces);
06957       add_header(&req, "Require", "replaces");
06958    }
06959 
06960    add_header(&req, "Allow", ALLOWED_METHODS);
06961    add_header(&req, "Supported", SUPPORTED_EXTENSIONS);
06962    if (p->options && p->options->addsipheaders && p->owner) {
06963       struct ast_channel *ast = p->owner; /* The owner channel */
06964       struct varshead *headp = &ast->varshead;
06965 
06966          if (!headp)
06967             ast_log(LOG_WARNING,"No Headp for the channel...ooops!\n");
06968          else {
06969             const struct ast_var_t *current;
06970             AST_LIST_TRAVERSE(headp, current, entries) {  
06971                /* SIPADDHEADER: Add SIP header to outgoing call */
06972                if (!strncasecmp(ast_var_name(current), "SIPADDHEADER", strlen("SIPADDHEADER"))) {
06973                   char *content, *end;
06974                   const char *header = ast_var_value(current);
06975                   char *headdup = ast_strdupa(header);
06976 
06977                   /* Strip of the starting " (if it's there) */
06978                   if (*headdup == '"')
06979                      headdup++;
06980                   if ((content = strchr(headdup, ':'))) {
06981                      *content++ = '\0';
06982                      content = ast_skip_blanks(content); /* Skip white space */
06983                      /* Strip the ending " (if it's there) */
06984                      end = content + strlen(content) -1; 
06985                      if (*end == '"')
06986                         *end = '\0';
06987                   
06988                      add_header(&req, headdup, content);
06989                      if (sipdebug)
06990                         ast_log(LOG_DEBUG, "Adding SIP Header \"%s\" with content :%s: \n", headdup, content);
06991                   }
06992                }
06993             }
06994          }
06995    }
06996    if (sdp) {
06997       if (p->udptl && p->t38.state == T38_LOCAL_DIRECT) {
06998          ast_udptl_offered_from_local(p->udptl, 1);
06999          if (option_debug)
07000             ast_log(LOG_DEBUG, "T38 is in state %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>");
07001          add_t38_sdp(&req, p);
07002       } else if (p->rtp) 
07003          add_sdp(&req, p);
07004    } else {
07005       add_header_contentLength(&req, 0);
07006    }
07007 
07008    if (!p->initreq.headers)
07009       initialize_initreq(p, &req);
07010    p->lastinvite = p->ocseq;
07011    return send_request(p, &req, init ? XMIT_CRITICAL : XMIT_RELIABLE, p->ocseq);
07012 }

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

Transmit text with SIP MESSAGE method.

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

07554 {
07555    struct sip_request req;
07556 
07557    reqprep(&req, p, SIP_MESSAGE, 0, 1);
07558    add_text(&req, text);
07559    return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
07560 }

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

References add_header(), add_header_contentLength(), add_line(), ast_build_string(), ast_inet_ntoa(), ast_log(), ast_test_flag, sip_pvt::expiry, sip_pvt::flags, sip_request::headers, initialize_initreq(), sip_pvt::initreq, initreqprep(), sip_pvt::ocseq, sip_pvt::ourip, S_OR, send_request(), SIP_NOTIFY, SIP_PAGE2_BUGGY_MWI, sip_pvt::subscribed, t, and XMIT_RELIABLE.

Referenced by sip_send_mwi_to_peer().

07194 {
07195    struct sip_request req;
07196    char tmp[500];
07197    char *t = tmp;
07198    size_t maxbytes = sizeof(tmp);
07199 
07200    initreqprep(&req, p, SIP_NOTIFY);
07201    add_header(&req, "Event", "message-summary");
07202    add_header(&req, "Content-Type", default_notifymime);
07203 
07204    ast_build_string(&t, &maxbytes, "Messages-Waiting: %s\r\n", newmsgs ? "yes" : "no");
07205    ast_build_string(&t, &maxbytes, "Message-Account: sip:%s@%s\r\n",
07206       S_OR(vmexten, default_vmexten), S_OR(p->fromdomain, ast_inet_ntoa(p->ourip)));
07207    /* Cisco has a bug in the SIP stack where it can't accept the
07208       (0/0) notification. This can temporarily be disabled in
07209       sip.conf with the "buggymwi" option */
07210    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)"));
07211 
07212    if (p->subscribed) {
07213       if (p->expiry)
07214          add_header(&req, "Subscription-State", "active");
07215       else  /* Expired */
07216          add_header(&req, "Subscription-State", "terminated;reason=timeout");
07217    }
07218 
07219    if (t > tmp + sizeof(tmp))
07220       ast_log(LOG_WARNING, "Buffer overflow detected!!  (Please file a bug report)\n");
07221 
07222    add_header_contentLength(&req, strlen(tmp));
07223    add_line(&req, tmp);
07224 
07225    if (!p->initreq.headers) 
07226       initialize_initreq(p, &req);
07227    return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
07228 }

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

07240 {
07241    struct sip_request req;
07242    char tmp[BUFSIZ/2];
07243 
07244    reqprep(&req, p, SIP_NOTIFY, 0, 1);
07245    snprintf(tmp, sizeof(tmp), "refer;id=%d", cseq);
07246    add_header(&req, "Event", tmp);
07247    add_header(&req, "Subscription-state", terminate ? "terminated;reason=noresource" : "active");
07248    add_header(&req, "Content-Type", "message/sipfrag;version=2.0");
07249    add_header(&req, "Allow", ALLOWED_METHODS);
07250    add_header(&req, "Supported", SUPPORTED_EXTENSIONS);
07251 
07252    snprintf(tmp, sizeof(tmp), "SIP/2.0 %s\r\n", message);
07253    add_header_contentLength(&req, strlen(tmp));
07254    add_line(&req, tmp);
07255 
07256    if (!p->initreq.headers)
07257       initialize_initreq(p, &req);
07258 
07259    return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
07260 }

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

07575 {
07576    struct sip_request req = { 
07577       .headers = 0,  
07578    };
07579    char from[256];
07580    const char *of;
07581    char *c;
07582    char referto[256];
07583    char *ttag, *ftag;
07584    char *theirtag = ast_strdupa(p->theirtag);
07585 
07586    if (option_debug || sipdebug)
07587       ast_log(LOG_DEBUG, "SIP transfer of %s to %s\n", p->callid, dest);
07588 
07589    /* Are we transfering an inbound or outbound call ? */
07590    if (ast_test_flag(&p->flags[0], SIP_OUTGOING))  {
07591       of = get_header(&p->initreq, "To");
07592       ttag = theirtag;
07593       ftag = p->tag;
07594    } else {
07595       of = get_header(&p->initreq, "From");
07596       ftag = theirtag;
07597       ttag = p->tag;
07598    }
07599 
07600    ast_copy_string(from, of, sizeof(from));
07601    of = get_in_brackets(from);
07602    ast_string_field_set(p, from, of);
07603    if (strncasecmp(of, "sip:", 4))
07604       ast_log(LOG_NOTICE, "From address missing 'sip:', using it anyway\n");
07605    else
07606       of += 4;
07607    /* Get just the username part */
07608    if ((c = strchr(dest, '@')))
07609       c = NULL;
07610    else if ((c = strchr(of, '@')))
07611       *c++ = '\0';
07612    if (c) 
07613       snprintf(referto, sizeof(referto), "<sip:%s@%s>", dest, c);
07614    else
07615       snprintf(referto, sizeof(referto), "<sip:%s>", dest);
07616 
07617    /* save in case we get 407 challenge */
07618    sip_refer_allocate(p);
07619    ast_copy_string(p->refer->refer_to, referto, sizeof(p->refer->refer_to));
07620    ast_copy_string(p->refer->referred_by, p->our_contact, sizeof(p->refer->referred_by));
07621    p->refer->status = REFER_SENT;   /* Set refer status */
07622 
07623    reqprep(&req, p, SIP_REFER, 0, 1);
07624    add_header(&req, "Max-Forwards", DEFAULT_MAX_FORWARDS);
07625 
07626    add_header(&req, "Refer-To", referto);
07627    add_header(&req, "Allow", ALLOWED_METHODS);
07628    add_header(&req, "Supported", SUPPORTED_EXTENSIONS);
07629    if (!ast_strlen_zero(p->our_contact))
07630       add_header(&req, "Referred-By", p->our_contact);
07631 
07632    return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
07633    /* We should propably wait for a NOTIFY here until we ack the transfer */
07634    /* Maybe fork a new thread and wait for a STATUS of REFER_200OK on the refer status before returning to app_transfer */
07635 
07636    /*! \todo In theory, we should hang around and wait for a reply, before
07637    returning to the dial plan here. Don't know really how that would
07638    affect the transfer() app or the pbx, but, well, to make this
07639    useful we should have a STATUS code on transfer().
07640    */
07641 }

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

References __ourip, add_header(), add_header_contentLength(), append_history, ast_log(), ast_random(), ast_sched_add(), ast_sched_del(), ast_set_flag, ast_sip_ouraddrfor(), ast_string_field_free, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_verbose(), ASTOBJ_REF, bindaddr, sip_pvt::branch, build_callid_registry(), build_contact(), build_reply_digest(), build_via(), sip_registry::call, sip_registry::callid_valid, create_addr(), DEFAULT_MAX_FORWARDS, exten, sip_pvt::flags, sip_request::headers, init_req(), initialize_initreq(), sip_pvt::initreq, sip_request::lines, LOG_DEBUG, LOG_NOTICE, make_our_tag(), sip_pvt::noncecount, sip_registry::noncecount, sip_pvt::ocseq, sip_registry::ocseq, option_debug, sip_registry::portno, REG_STATE_AUTHSENT, REG_STATE_REGSENT, sip_registry::regattempts, sip_pvt::registry, sip_registry::regstate, sched, send_request(), sip_alloc(), sip_debug_test_pvt(), sip_destroy(), sip_methods, SIP_NO_HISTORY, SIP_OUTGOING, sip_reg_timeout(), SIP_REGISTER, sipdebug, STANDARD_SIP_PORT, sip_pvt::tag, cfsip_methods::text, sip_registry::timeout, TRUE, username, and XMIT_CRITICAL.

Referenced by __sip_do_register(), do_register_auth(), and sip_reg_timeout().

07363 {
07364    struct sip_request req;
07365    char from[256];
07366    char to[256];
07367    char tmp[80];
07368    char addr[80];
07369    struct sip_pvt *p;
07370 
07371    /* exit if we are already in process with this registrar ?*/
07372    if ( r == NULL || ((auth==NULL) && (r->regstate==REG_STATE_REGSENT || r->regstate==REG_STATE_AUTHSENT))) {
07373       ast_log(LOG_NOTICE, "Strange, trying to register %s@%s when registration already pending\n", r->username, r->hostname);
07374       return 0;
07375    }
07376 
07377    if (r->call) { /* We have a registration */
07378       if (!auth) {
07379          ast_log(LOG_WARNING, "Already have a REGISTER going on to %s@%s?? \n", r->username, r->hostname);
07380          return 0;
07381       } else {
07382          p = r->call;
07383          make_our_tag(p->tag, sizeof(p->tag));  /* create a new local tag for every register attempt */
07384          ast_string_field_free(p, theirtag); /* forget their old tag, so we don't match tags when getting response */
07385       }
07386    } else {
07387       /* Build callid for registration if we haven't registered before */
07388       if (!r->callid_valid) {
07389          build_callid_registry(r, __ourip, default_fromdomain);
07390          r->callid_valid = TRUE;
07391       }
07392       /* Allocate SIP packet for registration */
07393       if (!(p = sip_alloc( r->callid, NULL, 0, SIP_REGISTER))) {
07394          ast_log(LOG_WARNING, "Unable to allocate registration transaction (memory or socket error)\n");
07395          return 0;
07396       }
07397       if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY))
07398          append_history(p, "RegistryInit", "Account: %s@%s", r->username, r->hostname);
07399       /* Find address to hostname */
07400       if (create_addr(p, r->hostname)) {
07401          /* we have what we hope is a temporary network error,
07402           * probably DNS.  We need to reschedule a registration try */
07403          sip_destroy(p);
07404          if (r->timeout > -1) {
07405             ast_sched_del(sched, r->timeout);
07406             r->timeout = ast_sched_add(sched, global_reg_timeout*1000, sip_reg_timeout, r);
07407             ast_log(LOG_WARNING, "Still have a registration timeout for %s@%s (create_addr() error), %d\n", r->username, r->hostname, r->timeout);
07408          } else {
07409             r->timeout = ast_sched_add(sched, global_reg_timeout*1000, sip_reg_timeout, r);
07410             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);
07411          }
07412          r->regattempts++;
07413          return 0;
07414       }
07415       /* Copy back Call-ID in case create_addr changed it */
07416       ast_string_field_set(r, callid, p->callid);
07417       if (r->portno)
07418          p->sa.sin_port = htons(r->portno);
07419       else  /* Set registry port to the port set from the peer definition/srv or default */
07420          r->portno = ntohs(p->sa.sin_port);
07421       ast_set_flag(&p->flags[0], SIP_OUTGOING); /* Registration is outgoing call */
07422       r->call=p;        /* Save pointer to SIP packet */
07423       p->registry = ASTOBJ_REF(r);  /* Add pointer to registry in packet */
07424       if (!ast_strlen_zero(r->secret)) /* Secret (password) */
07425          ast_string_field_set(p, peersecret, r->secret);
07426       if (!ast_strlen_zero(r->md5secret))
07427          ast_string_field_set(p, peermd5secret, r->md5secret);
07428       /* User name in this realm  
07429       - if authuser is set, use that, otherwise use username */
07430       if (!ast_strlen_zero(r->authuser)) {   
07431          ast_string_field_set(p, peername, r->authuser);
07432          ast_string_field_set(p, authname, r->authuser);
07433       } else if (!ast_strlen_zero(r->username)) {
07434          ast_string_field_set(p, peername, r->username);
07435          ast_string_field_set(p, authname, r->username);
07436          ast_string_field_set(p, fromuser, r->username);
07437       }
07438       if (!ast_strlen_zero(r->username))
07439          ast_string_field_set(p, username, r->username);
07440       /* Save extension in packet */
07441       ast_string_field_set(p, exten, r->contact);
07442 
07443       /*
07444         check which address we should use in our contact header 
07445         based on whether the remote host is on the external or
07446         internal network so we can register through nat
07447        */
07448       if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
07449          p->ourip = bindaddr.sin_addr;
07450       build_contact(p);
07451    }
07452 
07453    /* set up a timeout */
07454    if (auth == NULL)  {
07455       if (r->timeout > -1) {
07456          ast_log(LOG_WARNING, "Still have a registration timeout, #%d - deleting it\n", r->timeout);
07457          ast_sched_del(sched, r->timeout);
07458       }
07459       r->timeout = ast_sched_add(sched, global_reg_timeout * 1000, sip_reg_timeout, r);
07460       if (option_debug)
07461          ast_log(LOG_DEBUG, "Scheduled a registration timeout for %s id  #%d \n", r->hostname, r->timeout);
07462    }
07463 
07464    if (strchr(r->username, '@')) {
07465       snprintf(from, sizeof(from), "<sip:%s>;tag=%s", r->username, p->tag);
07466       if (!ast_strlen_zero(p->theirtag))
07467          snprintf(to, sizeof(to), "<sip:%s>;tag=%s", r->username, p->theirtag);
07468       else
07469          snprintf(to, sizeof(to), "<sip:%s>", r->username);
07470    } else {
07471       snprintf(from, sizeof(from), "<sip:%s@%s>;tag=%s", r->username, p->tohost, p->tag);
07472       if (!ast_strlen_zero(p->theirtag))
07473          snprintf(to, sizeof(to), "<sip:%s@%s>;tag=%s", r->username, p->tohost, p->theirtag);
07474       else
07475          snprintf(to, sizeof(to), "<sip:%s@%s>", r->username, p->tohost);
07476    }
07477    
07478    /* Fromdomain is what we are registering to, regardless of actual
07479       host name from SRV */
07480    if (!ast_strlen_zero(p->fromdomain)) {
07481       if (r->portno && r->portno != STANDARD_SIP_PORT)
07482          snprintf(addr, sizeof(addr), "sip:%s:%d", p->fromdomain, r->portno);
07483       else
07484          snprintf(addr, sizeof(addr), "sip:%s", p->fromdomain);
07485    } else {
07486       if (r->portno && r->portno != STANDARD_SIP_PORT)
07487          snprintf(addr, sizeof(addr), "sip:%s:%d", r->hostname, r->portno);
07488       else
07489          snprintf(addr, sizeof(addr), "sip:%s", r->hostname);
07490    }
07491    ast_string_field_set(p, uri, addr);
07492 
07493    p->branch ^= ast_random();
07494 
07495    init_req(&req, sipmethod, addr);
07496 
07497    /* Add to CSEQ */
07498    snprintf(tmp, sizeof(tmp), "%u %s", ++r->ocseq, sip_methods[sipmethod].text);
07499    p->ocseq = r->ocseq;
07500 
07501    build_via(p);
07502    add_header(&req, "Via", p->via);
07503    add_header(&req, "From", from);
07504    add_header(&req, "To", to);
07505    add_header(&req, "Call-ID", p->callid);
07506    add_header(&req, "CSeq", tmp);
07507    if (!ast_strlen_zero(global_useragent))
07508       add_header(&req, "User-Agent", global_useragent);
07509    add_header(&req, "Max-Forwards", DEFAULT_MAX_FORWARDS);
07510 
07511    
07512    if (auth)   /* Add auth header */
07513       add_header(&req, authheader, auth);
07514    else if (!ast_strlen_zero(r->nonce)) {
07515       char digest[1024];
07516 
07517       /* We have auth data to reuse, build a digest header! */
07518       if (sipdebug)
07519          ast_log(LOG_DEBUG, "   >>> Re-using Auth data for %s@%s\n", r->username, r->hostname);
07520       ast_string_field_set(p, realm, r->realm);
07521       ast_string_field_set(p, nonce, r->nonce);
07522       ast_string_field_set(p, domain, r->domain);
07523       ast_string_field_set(p, opaque, r->opaque);
07524       ast_string_field_set(p, qop, r->qop);
07525       r->noncecount++;
07526       p->noncecount = r->noncecount;
07527 
07528       memset(digest,0,sizeof(digest));
07529       if(!build_reply_digest(p, sipmethod, digest, sizeof(digest)))
07530          add_header(&req, "Authorization", digest);
07531       else
07532          ast_log(LOG_NOTICE, "No authorization available for authentication of registration to %s@%s\n", r->username, r->hostname);
07533    
07534    }
07535 
07536    snprintf(tmp, sizeof(tmp), "%d", default_expiry);
07537    add_header(&req, "Expires", tmp);
07538    add_header(&req, "Contact", p->our_contact);
07539    add_header(&req, "Event", "registration");
07540    add_header_contentLength(&req, 0);
07541 
07542    initialize_initreq(p, &req);
07543    if (sip_debug_test_pvt(p))
07544       ast_verbose("REGISTER %d headers, %d lines\n", p->initreq.headers, p->initreq.lines);
07545    r->regstate = auth ? REG_STATE_AUTHSENT : REG_STATE_REGSENT;
07546    r->regattempts++; /* Another attempt */
07547    if (option_debug > 3)
07548       ast_verbose("REGISTER attempt %d to %s@%s\n", r->regattempts, r->username, r->hostname);
07549    return send_request(p, &req, XMIT_CRITICAL, p->ocseq);
07550 }

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

References add_header(), add_sdp(), ALLOWED_METHODS, append_history, ast_set_flag, ast_test_flag, sip_pvt::flags, initialize_initreq(), reqprep(), send_request(), SIP_INVITE, SIP_NO_HISTORY, SIP_OUTGOING, SIP_REINVITE_UPDATE, SIP_UPDATE, sipdebug, SUPPORTED_EXTENSIONS, and XMIT_CRITICAL.

Referenced by check_pendings(), and sip_set_rtp_peer().

06644 {
06645    struct sip_request req;
06646 
06647    reqprep(&req, p, ast_test_flag(&p->flags[0], SIP_REINVITE_UPDATE) ?  SIP_UPDATE : SIP_INVITE, 0, 1);
06648    
06649    add_header(&req, "Allow", ALLOWED_METHODS);
06650    add_header(&req, "Supported", SUPPORTED_EXTENSIONS);
06651    if (sipdebug)
06652       add_header(&req, "X-asterisk-Info", "SIP re-invite (External RTP bridge)");
06653    if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY))
06654       append_history(p, "ReInv", "Re-invite sent");
06655    add_sdp(&req, p);
06656    /* Use this as the basis */
06657    initialize_initreq(p, &req);
06658    p->lastinvite = p->ocseq;
06659    ast_set_flag(&p->flags[0], SIP_OUTGOING);    /* Change direction of this dialog */
06660    return send_request(p, &req, XMIT_CRITICAL, p->ocseq);
06661 }

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

06668 {
06669    struct sip_request req;
06670 
06671    reqprep(&req, p, ast_test_flag(&p->flags[0], SIP_REINVITE_UPDATE) ?  SIP_UPDATE : SIP_INVITE, 0, 1);
06672    
06673    add_header(&req, "Allow", ALLOWED_METHODS);
06674    add_header(&req, "Supported", SUPPORTED_EXTENSIONS);
06675    if (sipdebug)
06676       add_header(&req, "X-asterisk-info", "SIP re-invite (T38 switchover)");
06677    ast_udptl_offered_from_local(p->udptl, 1);
06678    add_t38_sdp(&req, p);
06679    /* Use this as the basis */
06680    initialize_initreq(p, &req);
06681    ast_set_flag(&p->flags[0], SIP_OUTGOING);    /* Change direction of this dialog */
06682    p->lastinvite = p->ocseq;
06683    return send_request(p, &req, XMIT_CRITICAL, p->ocseq);
06684 }

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

07668 {
07669    struct sip_request resp;
07670 
07671    if (sipmethod == SIP_ACK)
07672       p->invitestate = INV_CONFIRMED;
07673 
07674    reqprep(&resp, p, sipmethod, seqno, newbranch);
07675    add_header_contentLength(&resp, 0);
07676    return send_request(p, &resp, reliable, seqno ? seqno : p->ocseq);
07677 }

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

References add_header(), add_header_contentLength(), ast_cause2str(), ast_log(), ast_strlen_zero(), sip_invite_param::auth_type, build_reply_digest(), ast_channel::hangupcause, sip_pvt::ocseq, sip_pvt::options, sip_pvt::owner, PROXY_AUTH, reqprep(), send_request(), SIP_BYE, and WWW_AUTH.

Referenced by __sip_autodestruct(), check_pendings(), and sip_hangup().

07681 {
07682    struct sip_request resp;
07683 
07684    reqprep(&resp, p, sipmethod, seqno, newbranch);
07685    if (!ast_strlen_zero(p->realm)) {
07686       char digest[1024];
07687 
07688       memset(digest, 0, sizeof(digest));
07689       if(!build_reply_digest(p, sipmethod, digest, sizeof(digest))) {
07690          if (p->options && p->options->auth_type == PROXY_AUTH)
07691             add_header(&resp, "Proxy-Authorization", digest);
07692          else if (p->options && p->options->auth_type == WWW_AUTH)
07693             add_header(&resp, "Authorization", digest);
07694          else  /* Default, to be backwards compatible (maybe being too careful, but leaving it for now) */
07695             add_header(&resp, "Proxy-Authorization", digest);
07696       } else
07697          ast_log(LOG_WARNING, "No authentication available for call %s\n", p->callid);
07698    }
07699    /* If we are hanging up and know a cause for that, send it in clear text to make
07700       debugging easier. */
07701    if (sipmethod == SIP_BYE && p->owner && p->owner->hangupcause) {
07702       char buf[10];
07703 
07704       add_header(&resp, "X-Asterisk-HangupCause", ast_cause2str(p->owner->hangupcause));
07705       snprintf(buf, sizeof(buf), "%d", p->owner->hangupcause);
07706       add_header(&resp, "X-Asterisk-HangupCauseCode", buf);
07707    }
07708 
07709    add_header_contentLength(&resp, 0);
07710    return send_request(p, &resp, reliable, seqno ? seqno : p->ocseq);   
07711 }

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

Transmit response, no retransmits.

Definition at line 5957 of file chan_sip.c.

References __transmit_response(), and XMIT_UNRELIABLE.

05958 {
05959    return __transmit_response(p, msg, req, XMIT_UNRELIABLE);
05960 }

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

05977 {
05978    return __transmit_response(p, msg, req, XMIT_CRITICAL);
05979 }

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 5907 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, build_via(), do_setnat(), global_flags, INITIAL_CSEQ, LOG_NOTICE, make_our_tag(), SIP_NAT, SIP_NAT_ROUTE, SIP_NO_HISTORY, and XMIT_UNRELIABLE.

05908 {
05909    struct sip_pvt *p = NULL;
05910 
05911    if (!(p = ast_threadstorage_get(&ts_temp_pvt, sizeof(*p)))) {
05912       ast_log(LOG_NOTICE, "Failed to get temporary pvt\n");
05913       return -1;
05914    }
05915 
05916    /* if the structure was just allocated, initialize it */
05917    if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) {
05918       ast_set_flag(&p->flags[0], SIP_NO_HISTORY);
05919       if (ast_string_field_init(p, 512))
05920          return -1;
05921    }
05922 
05923    /* Initialize the bare minimum */
05924    p->method = intended_method;
05925 
05926    if (sin) {
05927       p->sa = *sin;
05928       if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
05929          p->ourip = __ourip;
05930    } else
05931       p->ourip = __ourip;
05932 
05933    p->branch = ast_random();
05934    make_our_tag(p->tag, sizeof(p->tag));
05935    p->ocseq = INITIAL_CSEQ;
05936 
05937    if (useglobal_nat && sin) {
05938       ast_copy_flags(&p->flags[0], &global_flags[0], SIP_NAT);
05939       p->recv = *sin;
05940       do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE);
05941    }
05942 
05943    ast_string_field_set(p, fromdomain, default_fromdomain);
05944    build_via(p);
05945    ast_string_field_set(p, callid, callid);
05946 
05947    /* Use this temporary pvt structure to send the message */
05948    __transmit_response(p, msg, req, XMIT_UNRELIABLE);
05949 
05950    /* Free the string fields, but not the pool space */
05951    ast_string_field_free_all(p);
05952 
05953    return 0;
05954 }

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

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

Referenced by handle_request(), and handle_request_options().

06005 {
06006    struct sip_request resp;
06007    respprep(&resp, p, msg, req);
06008    add_header(&resp, "Accept", "application/sdp");
06009    add_header_contentLength(&resp, 0);
06010    return send_response(p, &resp, reliable, 0);
06011 }

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

References add_header(), add_header_contentLength(), append_history, ast_log(), get_header(), sip_pvt::noncecount, respprep(), and send_response().

Referenced by check_auth(), and transmit_fake_auth_response().

06015 {
06016    struct sip_request resp;
06017    char tmp[512];
06018    int seqno = 0;
06019 
06020    if (reliable && (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1)) {
06021       ast_log(LOG_WARNING, "Unable to determine sequence number from '%s'\n", get_header(req, "CSeq"));
06022       return -1;
06023    }
06024    /* Stale means that they sent us correct authentication, but 
06025       based it on an old challenge (nonce) */
06026    snprintf(tmp, sizeof(tmp), "Digest algorithm=MD5, realm=\"%s\", nonce=\"%s\"%s", global_realm, randdata, stale ? ", stale=true" : "");
06027    respprep(&resp, p, msg, req);
06028    add_header(&resp, header, tmp);
06029    add_header_contentLength(&resp, 0);
06030    append_history(p, "AuthChal", "Auth challenge sent for %s - nc %d", p->username, p->noncecount);
06031    return send_response(p, &resp, reliable, seqno);
06032 }

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

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

Referenced by register_verify().

05995 {
05996    struct sip_request resp;
05997    respprep(&resp, p, msg, req);
05998    append_date(&resp);
05999    add_header_contentLength(&resp, 0);
06000    return send_response(p, &resp, XMIT_UNRELIABLE, 0);
06001 }

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

References add_sdp(), ast_log(), ast_rtp_codec_setpref(), ast_test_flag, sip_pvt::autoframing, sip_pvt::flags, get_header(), LOG_DEBUG, LOG_ERROR, option_debug, sip_pvt::pendinginvite, sip_pvt::prefs, respprep(), sip_pvt::rtp, send_response(), SIP_OUTGOING, and try_suggested_sip_codec().

Referenced by handle_invite_replaces(), handle_request_invite(), sip_answer(), sip_indicate(), and sip_write().

06573 {
06574    struct sip_request resp;
06575    int seqno;
06576    if (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1) {
06577       ast_log(LOG_WARNING, "Unable to get seqno from '%s'\n", get_header(req, "CSeq"));
06578       return -1;
06579    }
06580    respprep(&resp, p, msg, req);
06581    if (p->rtp) {
06582       if (!p->autoframing && !ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
06583          if (option_debug)
06584             ast_log(LOG_DEBUG, "Setting framing from config on incoming call\n");
06585          ast_rtp_codec_setpref(p->rtp, &p->prefs);
06586       }
06587       try_suggested_sip_codec(p);   
06588       add_sdp(&resp, p);
06589    } else 
06590       ast_log(LOG_ERROR, "Can't add SDP to response, since we have no RTP session allocated. Call-ID %s\n", p->callid);
06591    if (reliable && !p->pendinginvite)
06592       p->pendinginvite = seqno;     /* Buggy clients sends ACK on RINGING too */
06593    return send_response(p, &resp, reliable, seqno);
06594 }

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

References add_t38_sdp(), ast_log(), ast_udptl_offered_from_local(), get_header(), LOG_ERROR, sip_pvt::pendinginvite, respprep(), send_response(), and sip_pvt::udptl.

Referenced by handle_request_invite(), sip_answer(), and sip_handle_t38_reinvite().

06533 {
06534    struct sip_request resp;
06535    int seqno;
06536    
06537    if (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1) {
06538       ast_log(LOG_WARNING, "Unable to get seqno from '%s'\n", get_header(req, "CSeq"));
06539       return -1;
06540    }
06541    respprep(&resp, p, msg, req);
06542    if (p->udptl) {
06543       ast_udptl_offered_from_local(p->udptl, 0);
06544       add_t38_sdp(&resp, p);
06545    } else 
06546       ast_log(LOG_ERROR, "Can't add SDP to response, since we have no UDPTL session allocated. Call-ID %s\n", p->callid);
06547    if (retrans && !p->pendinginvite)
06548       p->pendinginvite = seqno;     /* Buggy clients sends ACK on RINGING too */
06549    return send_response(p, &resp, retrans, seqno);
06550 }

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

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

Referenced by handle_request_invite().

05964 {
05965    struct sip_request resp;
05966    respprep(&resp, p, msg, req);
05967    append_date(&resp);
05968    add_header(&resp, "Unsupported", unsupported);
05969    add_header_contentLength(&resp, 0);
05970    return send_response(p, &resp, XMIT_UNRELIABLE, 0);
05971 }

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

07232 {
07233    if (!p->initreq.headers)   /* Initialize first request before sending */
07234       initialize_initreq(p, req);
07235    return send_request(p, req, XMIT_UNRELIABLE, p->ocseq);
07236 }

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

References add_header(), add_header_contentLength(), add_line(), ast_build_string(), ast_device_state(), AST_DEVICE_UNAVAILABLE, AST_EXTENSION_BUSY, AST_EXTENSION_DEACTIVATED, AST_EXTENSION_INUSE, AST_EXTENSION_NOT_INUSE, AST_EXTENSION_ONHOLD, AST_EXTENSION_REMOVED, AST_EXTENSION_RINGING, AST_EXTENSION_UNAVAILABLE, ast_get_hint(), ast_log(), AST_MAX_EXTENSION, CPIM_PIDF_XML, DIALOG_INFO_XML, sip_pvt::dialogver, sip_pvt::expiry, find_subscription_type(), get_header(), get_in_brackets(), sip_pvt::initreq, NONE, sip_pvt::ocseq, 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().

07016 {
07017    char tmp[4000], from[256], to[256];
07018    char *t = tmp, *c, *mfrom, *mto;
07019    size_t maxbytes = sizeof(tmp);
07020    struct sip_request req;
07021    char hint[AST_MAX_EXTENSION];
07022    char *statestring = "terminated";
07023    const struct cfsubscription_types *subscriptiontype;
07024    enum state { NOTIFY_OPEN, NOTIFY_INUSE, NOTIFY_CLOSED } local_state = NOTIFY_OPEN;
07025    char *pidfstate = "--";
07026    char *pidfnote= "Ready";
07027 
07028    memset(from, 0, sizeof(from));
07029    memset(to, 0, sizeof(to));
07030    memset(tmp, 0, sizeof(tmp));
07031 
07032    switch (state) {
07033    case (AST_EXTENSION_RINGING | AST_EXTENSION_INUSE):
07034       statestring = (global_notifyringing) ? "early" : "confirmed";
07035       local_state = NOTIFY_INUSE;
07036       pidfstate = "busy";
07037       pidfnote = "Ringing";
07038       break;
07039    case AST_EXTENSION_RINGING:
07040       statestring = "early";
07041       local_state = NOTIFY_INUSE;
07042       pidfstate = "busy";
07043       pidfnote = "Ringing";
07044       break;
07045    case AST_EXTENSION_INUSE:
07046       statestring = "confirmed";
07047       local_state = NOTIFY_INUSE;
07048       pidfstate = "busy";
07049       pidfnote = "On the phone";
07050       break;
07051    case AST_EXTENSION_BUSY:
07052       statestring = "confirmed";
07053       local_state = NOTIFY_CLOSED;
07054       pidfstate = "busy";
07055       pidfnote = "On the phone";
07056       break;
07057    case AST_EXTENSION_UNAVAILABLE:
07058       statestring = "terminated";
07059       local_state = NOTIFY_CLOSED;
07060       pidfstate = "away";
07061       pidfnote = "Unavailable";
07062       break;
07063    case AST_EXTENSION_ONHOLD:
07064       statestring = "confirmed";
07065       local_state = NOTIFY_INUSE;
07066       pidfstate = "busy";
07067       pidfnote = "On Hold";
07068       break;
07069    case AST_EXTENSION_NOT_INUSE:
07070    default:
07071       /* Default setting */
07072       break;
07073    }
07074 
07075    subscriptiontype = find_subscription_type(p->subscribed);
07076    
07077    /* Check which device/devices we are watching  and if they are registered */
07078    if (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, p->context, p->exten)) {
07079       char *hint2 = hint, *individual_hint = NULL;
07080       while ((individual_hint = strsep(&hint2, "&"))) {
07081          /* If they are not registered, we will override notification and show no availability */
07082          if (ast_device_state(individual_hint) == AST_DEVICE_UNAVAILABLE) {
07083             local_state = NOTIFY_CLOSED;
07084             pidfstate = "away";
07085             pidfnote = "Not online";
07086          }
07087       }
07088    }
07089 
07090    ast_copy_string(from, get_header(&p->initreq, "From"), sizeof(from));
07091    c = get_in_brackets(from);
07092    if (strncasecmp(c, "sip:", 4)) {
07093       ast_log(LOG_WARNING, "Huh?  Not a SIP header (%s)?\n", c);
07094       return -1;
07095    }
07096    mfrom = strsep(&c, ";");   /* trim ; and beyond */
07097 
07098    ast_copy_string(to, get_header(&p->initreq, "To"), sizeof(to));
07099    c = get_in_brackets(to);
07100    if (strncasecmp(c, "sip:", 4)) {
07101       ast_log(LOG_WARNING, "Huh?  Not a SIP header (%s)?\n", c);
07102       return -1;
07103    }
07104    mto = strsep(&c, ";");  /* trim ; and beyond */
07105 
07106    reqprep(&req, p, SIP_NOTIFY, 0, 1);
07107 
07108    
07109    add_header(&req, "Event", subscriptiontype->event);
07110    add_header(&req, "Content-Type", subscriptiontype->mediatype);
07111    switch(state) {
07112    case AST_EXTENSION_DEACTIVATED:
07113       if (timeout)
07114          add_header(&req, "Subscription-State", "terminated;reason=timeout");
07115       else {
07116          add_header(&req, "Subscription-State", "terminated;reason=probation");
07117          add_header(&req, "Retry-After", "60");
07118       }
07119       break;
07120    case AST_EXTENSION_REMOVED:
07121       add_header(&req, "Subscription-State", "terminated;reason=noresource");
07122       break;
07123    default:
07124       if (p->expiry)
07125          add_header(&req, "Subscription-State", "active");
07126       else  /* Expired */
07127          add_header(&req, "Subscription-State", "terminated;reason=timeout");
07128    }
07129    switch (p->subscribed) {
07130    case XPIDF_XML:
07131    case CPIM_PIDF_XML:
07132       ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\"?>\n");
07133       ast_build_string(&t, &maxbytes, "<!DOCTYPE presence PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n");
07134       ast_build_string(&t, &maxbytes, "<presence>\n");
07135       ast_build_string(&t, &maxbytes, "<presentity uri=\"%s;method=SUBSCRIBE\" />\n", mfrom);
07136       ast_build_string(&t, &maxbytes, "<atom id=\"%s\">\n", p->exten);
07137       ast_build_string(&t, &maxbytes, "<address uri=\"%s;user=ip\" priority=\"0.800000\">\n", mto);
07138       ast_build_string(&t, &maxbytes, "<status status=\"%s\" />\n", (local_state ==  NOTIFY_OPEN) ? "open" : (local_state == NOTIFY_INUSE) ? "inuse" : "closed");
07139       ast_build_string(&t, &maxbytes, "<msnsubstatus substatus=\"%s\" />\n", (local_state == NOTIFY_OPEN) ? "online" : (local_state == NOTIFY_INUSE) ? "onthephone" : "offline");
07140       ast_build_string(&t, &maxbytes, "</address>\n</atom>\n</presence>\n");
07141       break;
07142    case PIDF_XML: /* Eyebeam supports this format */
07143       ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n");
07144       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);
07145       ast_build_string(&t, &maxbytes, "<pp:person><status>\n");
07146       if (pidfstate[0] != '-')
07147          ast_build_string(&t, &maxbytes, "<ep:activities><ep:%s/></ep:activities>\n", pidfstate);
07148       ast_build_string(&t, &maxbytes, "</status></pp:person>\n");
07149       ast_build_string(&t, &maxbytes, "<note>%s</note>\n", pidfnote); /* Note */
07150       ast_build_string(&t, &maxbytes, "<tuple id=\"%s\">\n", p->exten); /* Tuple start */
07151       ast_build_string(&t, &maxbytes, "<contact priority=\"1\">%s</contact>\n", mto);
07152       if (pidfstate[0] == 'b') /* Busy? Still open ... */
07153          ast_build_string(&t, &maxbytes, "<status><basic>open</basic></status>\n");
07154       else
07155          ast_build_string(&t, &maxbytes, "<status><basic>%s</basic></status>\n", (local_state != NOTIFY_CLOSED) ? "open" : "closed");
07156       ast_build_string(&t, &maxbytes, "</tuple>\n</presence>\n");
07157       break;
07158    case DIALOG_INFO_XML: /* SNOM subscribes in this format */
07159       ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\"?>\n");
07160       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);
07161       if ((state & AST_EXTENSION_RINGING) && global_notifyringing)
07162          ast_build_string(&t, &maxbytes, "<dialog id=\"%s\" direction=\"recipient\">\n", p->exten);
07163       else
07164          ast_build_string(&t, &maxbytes, "<dialog id=\"%s\">\n", p->exten);
07165       ast_build_string(&t, &maxbytes, "<state>%s</state>\n", statestring);
07166       if (state == AST_EXTENSION_ONHOLD) {
07167          ast_build_string(&t, &maxbytes, "<local>\n<target uri=\"%s\">\n"
07168                                          "<param pname=\"+sip.rendering\" pvalue=\"no\">\n"
07169                                          "</target>\n</local>\n", mto);
07170       }
07171       ast_build_string(&t, &maxbytes, "</dialog>\n</dialog-info>\n");
07172       break;
07173    case NONE:
07174    default:
07175       break;
07176    }
07177 
07178    if (t > tmp + sizeof(tmp))
07179       ast_log(LOG_WARNING, "Buffer overflow detected!!  (Please file a bug report)\n");
07180 
07181    add_header_contentLength(&req, strlen(tmp));
07182    add_line(&req, tmp);
07183 
07184    return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
07185 }

static void try_suggested_sip_codec ( struct sip_pvt p  )  [static]

Try setting codec suggested by the SIP_CODEC channel variable.

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

03568 {
03569    int fmt;
03570    const char *codec;
03571 
03572    codec = pbx_builtin_getvar_helper(p->owner, "SIP_CODEC");
03573    if (!codec) 
03574       return;
03575 
03576    fmt = ast_getformatbyname(codec);
03577    if (fmt) {
03578       ast_log(LOG_NOTICE, "Changing codec to '%s' for this call because of ${SIP_CODEC} variable\n", codec);
03579       if (p->jointcapability & fmt) {
03580          p->jointcapability &= fmt;
03581          p->capability &= fmt;
03582       } else
03583          ast_log(LOG_NOTICE, "Ignoring ${SIP_CODEC} variable because it is not shared by both ends.\n");
03584    } else
03585       ast_log(LOG_NOTICE, "Ignoring ${SIP_CODEC} variable because of unrecognized/not configured codec (check allow/disallow in sip.conf): %s\n", codec);
03586    return;  
03587 }

static int unload_module ( void   )  [static]

PBX unload module API.

Definition at line 17753 of file chan_sip.c.

References __sip_destroy(), ast_channel_unregister(), ast_cli_unregister_multiple(), ast_custom_function_unregister(), ast_free_ha(), ast_manager_unregister(), ast_mutex_lock(), ast_mutex_unlock(), AST_PTHREADT_NULL, AST_PTHREADT_STOP, ast_rtp_proto_unregister(), ast_softhangup(), AST_SOFTHANGUP_APPUNLOAD, ast_udptl_proto_unregister(), ast_unregister_application(), ASTOBJ_CONTAINER_DESTROY, ASTOBJ_CONTAINER_DESTROYALL, authl, checksipdomain_function, clear_realm_authentication(), clear_sip_domains(), cli_sip, iflist, localaddr, sip_pvt::next, sip_pvt::owner, peerl, regl, sched, sched_context_destroy(), sip_destroy_peer(), sip_destroy_user(), sip_header_function, sip_registry_destroy(), sip_rtp, sip_tech, sip_udptl, sipchaninfo_function, sippeer_function, sipsock, TRUE, and userl.

17754 {
17755    struct sip_pvt *p, *pl;
17756    
17757    /* First, take us out of the channel type list */
17758    ast_channel_unregister(&sip_tech);
17759 
17760    /* Unregister dial plan functions */
17761    ast_custom_function_unregister(&sipchaninfo_function);
17762    ast_custom_function_unregister(&sippeer_function);
17763    ast_custom_function_unregister(&sip_header_function);
17764    ast_custom_function_unregister(&checksipdomain_function);
17765 
17766    /* Unregister dial plan applications */
17767    ast_unregister_application(app_dtmfmode);
17768    ast_unregister_application(app_sipaddheader);
17769 
17770    /* Unregister CLI commands */
17771    ast_cli_unregister_multiple(cli_sip, sizeof(cli_sip) / sizeof(struct ast_cli_entry));
17772 
17773    /* Disconnect from the RTP subsystem */
17774    ast_rtp_proto_unregister(&sip_rtp);
17775 
17776    /* Disconnect from UDPTL */
17777    ast_udptl_proto_unregister(&sip_udptl);
17778 
17779    /* Unregister AMI actions */
17780    ast_manager_unregister("SIPpeers");
17781    ast_manager_unregister("SIPshowpeer");
17782 
17783    ast_mutex_lock(&iflock);
17784    /* Hangup all interfaces if they have an owner */
17785    for (p = iflist; p ; p = p->next) {
17786       if (p->owner)
17787          ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD);
17788    }
17789    ast_mutex_unlock(&iflock);
17790 
17791    ast_mutex_lock(&monlock);
17792    if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP) && (monitor_thread != AST_PTHREADT_NULL)) {
17793       pthread_cancel(monitor_thread);
17794       pthread_kill(monitor_thread, SIGURG);
17795       pthread_join(monitor_thread, NULL);
17796    }
17797    monitor_thread = AST_PTHREADT_STOP;
17798    ast_mutex_unlock(&monlock);
17799 
17800    ast_mutex_lock(&iflock);
17801    /* Destroy all the interfaces and free their memory */
17802    p = iflist;
17803    while (p) {
17804       pl = p;
17805       p = p->next;
17806       __sip_destroy(pl, TRUE);
17807    }
17808    iflist = NULL;
17809    ast_mutex_unlock(&iflock);
17810 
17811    /* Free memory for local network address mask */
17812    ast_free_ha(localaddr);
17813 
17814    ASTOBJ_CONTAINER_DESTROYALL(&userl, sip_destroy_user);
17815    ASTOBJ_CONTAINER_DESTROY(&userl);
17816    ASTOBJ_CONTAINER_DESTROYALL(&peerl, sip_destroy_peer);
17817    ASTOBJ_CONTAINER_DESTROY(&peerl);
17818    ASTOBJ_CONTAINER_DESTROYALL(&regl, sip_registry_destroy);
17819    ASTOBJ_CONTAINER_DESTROY(&regl);
17820 
17821    clear_realm_authentication(authl);
17822    clear_sip_domains();
17823    close(sipsock);
17824    sched_context_destroy(sched);
17825       
17826    return 0;
17827 }

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

03125 {
03126    char name[256];
03127    int *inuse = NULL, *call_limit = NULL, *inringing = NULL;
03128    int outgoing = ast_test_flag(&fup->flags[1], SIP_PAGE2_OUTGOING_CALL);
03129    struct sip_user *u = NULL;
03130    struct sip_peer *p = NULL;
03131 
03132    if (option_debug > 2)
03133       ast_log(LOG_DEBUG, "Updating call counter for %s call\n", outgoing ? "outgoing" : "incoming");
03134 
03135    /* Test if we need to check call limits, in order to avoid 
03136       realtime lookups if we do not need it */
03137    if (!ast_test_flag(&fup->flags[0], SIP_CALL_LIMIT) && !ast_test_flag(&fup->flags[1], SIP_PAGE2_CALL_ONHOLD))
03138       return 0;
03139 
03140    ast_copy_string(name, fup->username, sizeof(name));
03141 
03142    /* Check the list of users only for incoming calls */
03143    if (global_limitonpeers == FALSE && !outgoing && (u = find_user(name, 1)))  {
03144       inuse = &u->inUse;
03145       call_limit = &u->call_limit;
03146       inringing = NULL;
03147    } else if ( (p = find_peer(ast_strlen_zero(fup->peername) ? name : fup->peername, NULL, 1) ) ) { /* Try to find peer */
03148       inuse = &p->inUse;
03149       call_limit = &p->call_limit;
03150       inringing = &p->inRinging;
03151       ast_copy_string(name, fup->peername, sizeof(name));
03152    } 
03153    if (!p && !u) {
03154       if (option_debug > 1)
03155          ast_log(LOG_DEBUG, "%s is not a local device, no call limit\n", name);
03156       return 0;
03157    }
03158 
03159    switch(event) {
03160    /* incoming and outgoing affects the inUse counter */
03161    case DEC_CALL_LIMIT:
03162       if ( *inuse > 0 ) {
03163          if (ast_test_flag(&fup->flags[0], SIP_INC_COUNT)) {
03164             (*inuse)--;
03165             ast_clear_flag(&fup->flags[0], SIP_INC_COUNT);
03166          }
03167       } else {
03168          *inuse = 0;
03169       }
03170       if (inringing) {
03171          if (ast_test_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING)) {
03172             if (*inringing > 0)
03173                (*inringing)--;
03174             else if (!ast_test_flag(&fup->flags[0], SIP_REALTIME) || ast_test_flag(&fup->flags[1], SIP_PAGE2_RTCACHEFRIENDS))
03175                ast_log(LOG_WARNING, "Inringing for peer '%s' < 0?\n", fup->peername);
03176             ast_clear_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING);
03177          }
03178       }
03179       if (ast_test_flag(&fup->flags[1], SIP_PAGE2_CALL_ONHOLD) && global_notifyhold) {
03180          ast_clear_flag(&fup->flags[1], SIP_PAGE2_CALL_ONHOLD);
03181          sip_peer_hold(fup, 0);
03182       }
03183       if (option_debug > 1 || sipdebug) {
03184          ast_log(LOG_DEBUG, "Call %s %s '%s' removed from call limit %d\n", outgoing ? "to" : "from", u ? "user":"peer", name, *call_limit);
03185       }
03186       break;
03187 
03188    case INC_CALL_RINGING:
03189    case INC_CALL_LIMIT:
03190       if (*call_limit > 0 ) {
03191          if (*inuse >= *call_limit) {
03192             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);
03193             if (u)
03194                ASTOBJ_UNREF(u, sip_destroy_user);
03195             else
03196                ASTOBJ_UNREF(p, sip_destroy_peer);
03197             return -1; 
03198          }
03199       }
03200       if (inringing && (event == INC_CALL_RINGING)) {
03201          if (!ast_test_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING)) {
03202             (*inringing)++;
03203             ast_set_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING);
03204          }
03205       }
03206       /* Continue */
03207       (*inuse)++;
03208       ast_set_flag(&fup->flags[0], SIP_INC_COUNT);
03209       if (option_debug > 1 || sipdebug) {
03210          ast_log(LOG_DEBUG, "Call %s %s '%s' is %d out of %d\n", outgoing ? "to" : "from", u ? "user":"peer", name, *inuse, *call_limit);
03211       }
03212       break;
03213 
03214    case DEC_CALL_RINGING:
03215       if (inringing) {
03216          if (ast_test_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING)) {
03217             if (*inringing > 0)
03218                (*inringing)--;
03219             else if (!ast_test_flag(&fup->flags[0], SIP_REALTIME) || ast_test_flag(&fup->flags[1], SIP_PAGE2_RTCACHEFRIENDS))
03220                ast_log(LOG_WARNING, "Inringing for peer '%s' < 0?\n", p->name);
03221             ast_clear_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING);
03222          }
03223       }
03224       break;
03225 
03226    default:
03227       ast_log(LOG_ERROR, "update_call_counter(%s, %d) called with no event!\n", name, event);
03228    }
03229    if (p) {
03230       ast_device_state_changed("SIP/%s", p->name);
03231       ASTOBJ_UNREF(p, sip_destroy_peer);
03232    } else /* u must be set */
03233       ASTOBJ_UNREF(u, sip_destroy_user);
03234    return 0;
03235 }

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

Update peer data in database (if used).

Definition at line 2460 of file chan_sip.c.

References sip_peer::addr, ast_test_flag, sip_peer::flags, sip_peer::fullcontact, global_flags, realtime_update_peer(), SIP_PAGE2_RTCACHEFRIENDS, SIP_PAGE2_RTUPDATE, SIP_REALTIME, and sip_peer::username.

Referenced by register_verify().

02461 {
02462    int rtcachefriends = ast_test_flag(&p->flags[1], SIP_PAGE2_RTCACHEFRIENDS);
02463    if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTUPDATE) &&
02464        (ast_test_flag(&p->flags[0], SIP_REALTIME) || rtcachefriends)) {
02465       realtime_update_peer(p->name, &p->addr, p->username, rtcachefriends ? p->fullcontact : NULL, expiry);
02466    }
02467 }


Variable Documentation

struct in_addr __ourip [static]

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

char* app_sipaddheader = "SIPAddHeader" [static]

Definition at line 17294 of file chan_sip.c.

struct sip_auth* authl = NULL [static]

Definition at line 1186 of file chan_sip.c.

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

struct ast_custom_function checksipdomain_function [static]

Definition at line 11575 of file chan_sip.c.

Referenced by load_module(), and unload_module().

struct ast_cli_entry cli_sip[] [static]

Definition at line 17589 of file chan_sip.c.

Referenced by load_module(), and unload_module().

struct ast_cli_entry cli_sip_debug_deprecated [static]

Initial value:

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

Definition at line 17579 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 17584 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 11459 of file chan_sip.c.

struct sockaddr_in debugaddr [static]

Definition at line 1200 of file chan_sip.c.

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

char default_callerid[AST_MAX_EXTENSION] [static]

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

char* descrip_sipaddheader [static]

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

Referenced by complete_dpreply().

time_t externexpire = 0 [static]

Expiration counter for re-resolving external host name in dynamic DNS

Definition at line 1194 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 1193 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 1192 of file chan_sip.c.

int externrefresh = 10 [static]

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

Referenced by build_peer(), build_radius_record(), build_user(), destroy_association(), get_destination(), load_module(), realtime_update_peer(), reload_config(), set_peer_defaults(), sip_alloc(), sip_do_debug(), sip_do_debug_deprecated(), sip_do_debug_ip(), sip_do_debug_peer(), sip_no_debug(), sip_no_debug_deprecated(), sip_show_settings(), transmit_response_using_temp(), and update_peer().

struct ast_jb_conf global_jbconf [static]

Definition at line 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 11476 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 1196 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 10110 of file chan_sip.c.

char mandescr_show_peers[] [static]

Initial value:

 
"Description: Lists SIP peers in text format with details on current status.\n"
"Variables: \n"
"  ActionID: <id> Action ID for this transaction. Will be returned.\n"

Definition at line 9661 of file chan_sip.c.

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 11468 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 11472 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 1202 of file chan_sip.c.

Referenced by complete_sipnotify(), and sip_notify().

char notify_usage[] [static]

Initial value:

"Usage: sip notify <type> <peer> [<peer>...]\n"
"       Send a NOTIFY message to a SIP peer or peers\n"
"       Message types are defined in sip_notify.conf\n"

Definition at line 11408 of file chan_sip.c.

int ourport [static]

Definition at line 1199 of file chan_sip.c.

struct sockaddr_in outboundproxyip [static]

Definition at line 1198 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 11450 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 11432 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 11428 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 11403 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 11436 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 11423 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 11489 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 11445 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 11440 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 11455 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 11493 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 11485 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 11418 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 11413 of file chan_sip.c.

struct ast_custom_function sip_header_function [static]

Definition at line 11551 of file chan_sip.c.

Referenced by load_module(), and unload_module().

struct cfsip_methods sip_methods[] [static]

XXX Note that sip_methods[i].id == i must hold or the code breaks

Referenced by __sip_ack(), __sip_autodestruct(), __sip_destroy(), __sip_pretend_ack(), __sip_semi_ack(), build_reply_digest(), check_auth(), do_proxy_auth(), find_sip_method(), get_destination(), handle_request(), handle_request_subscribe(), handle_response(), init_req(), initreqprep(), method_match(), reqprep(), retrans_pkt(), send_request(), send_response(), sip_alloc(), sip_scheddestroy(), and transmit_register().

struct cfsip_options sip_options[] [static]

List of well-known SIP options. If we get this in a require, we should check the list and answer accordingly.

Referenced by _sip_show_peer(), parse_sip_options(), and sip_show_channel().

char sip_reload_usage[] [static]

Initial value:

"Usage: sip reload\n"
"       Reloads SIP configuration from sip.conf\n"

Definition at line 11481 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 1600 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 1542 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 1568 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 1609 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 11730 of file chan_sip.c.

Referenced by load_module(), and unload_module().

struct ast_custom_function sippeer_function

Structure to declare a dialplan function: SIPPEER.

Definition at line 11650 of file chan_sip.c.

Referenced by load_module(), and unload_module().

int sipsock = -1 [static]

Main socket for SIP network communication

Definition at line 1190 of file chan_sip.c.

Referenced by __sip_xmit(), do_monitor(), reg_source_db(), sipsock_read(), and unload_module().

int* sipsock_read_id [static]

ID of IO entry for sipsock FD

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

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

Definition at line 17295 of file chan_sip.c.

struct ast_user_list userl [static]

The user list: Users and friends.


Generated on Fri Aug 24 02:24:07 2007 for Asterisk - the Open Source PBX by  doxygen 1.5.1