Mon Apr 30 07:39:56 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_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_INACTIVE   (1 << 24)
#define SIP_PAGE2_CALL_ONHOLD_ONEDIR   (1 << 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

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
}
 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 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)
 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_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.
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 464 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 1810 of file chan_sip.c.

Referenced by __sip_autodestruct(), auto_congest(), build_reply_digest(), cb_extensionstate(), 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(), local_attended_transfer(), process_sdp(), 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 192 of file chan_sip.c.

Referenced by initreqprep().

#define CAN_CREATE_DIALOG   1

Definition at line 357 of file chan_sip.c.

#define CAN_CREATE_DIALOG_UNSUPPORTED_METHOD   2

Definition at line 358 of file chan_sip.c.

#define CAN_NOT_CREATE_DIALOG   0

Definition at line 356 of file chan_sip.c.

#define DEC_CALL_LIMIT   0

Definition at line 597 of file chan_sip.c.

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

#define DEC_CALL_RINGING   2

Definition at line 599 of file chan_sip.c.

Referenced by handle_response_invite(), and update_call_counter().

#define DEFAULT_ALLOW_EXT_DOM   TRUE

Definition at line 496 of file chan_sip.c.

Referenced by reload_config().

#define DEFAULT_ALLOWGUEST   TRUE

Definition at line 490 of file chan_sip.c.

Referenced by reload_config().

#define DEFAULT_AUTOCREATEPEER   FALSE

Definition at line 500 of file chan_sip.c.

Referenced by reload_config().

#define DEFAULT_CALLERID   "asterisk"

Definition at line 487 of file chan_sip.c.

Referenced by reload_config().

#define DEFAULT_COMPACTHEADERS   FALSE

Definition at line 492 of file chan_sip.c.

Referenced by reload_config().

#define DEFAULT_CONTEXT   "default"

Definition at line 483 of file chan_sip.c.

Referenced by reload_config().

#define DEFAULT_DEFAULT_EXPIRY   120

Definition at line 164 of file chan_sip.c.

#define DEFAULT_EXPIRY   900

Expire slowly

Definition at line 181 of file chan_sip.c.

#define DEFAULT_FREQ_NOTOK   10 * 1000

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

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

#define DEFAULT_MAX_CALL_BITRATE   (384)

Max bitrate for video

Definition at line 503 of file chan_sip.c.

Referenced by reload_config().

#define DEFAULT_MAX_EXPIRY   3600

Definition at line 166 of file chan_sip.c.

#define DEFAULT_MAX_FORWARDS   "70"

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

#define DEFAULT_MIN_EXPIRY   60

Definition at line 165 of file chan_sip.c.

#define DEFAULT_MOHINTERPRET   "default"

Definition at line 484 of file chan_sip.c.

Referenced by reload_config().

#define DEFAULT_MOHSUGGEST   ""

Definition at line 485 of file chan_sip.c.

Referenced by reload_config().

#define DEFAULT_MWITIME   10

Definition at line 489 of file chan_sip.c.

Referenced by reload_config().

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

Definition at line 488 of file chan_sip.c.

Referenced by reload_config().

#define DEFAULT_NOTIFYRINGING   TRUE

Definition at line 498 of file chan_sip.c.

Referenced by reload_config().

#define DEFAULT_PEDANTIC   FALSE

Definition at line 499 of file chan_sip.c.

Referenced by reload_config().

#define DEFAULT_QUALIFY   FALSE

Definition at line 501 of file chan_sip.c.

Referenced by reload_config().

#define DEFAULT_REALM   "asterisk"

Definition at line 497 of file chan_sip.c.

Referenced by reload_config().

#define DEFAULT_REGISTRATION_TIMEOUT   20

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

#define DEFAULT_SRVLOOKUP   FALSE

Recommended setting is ON

Definition at line 491 of file chan_sip.c.

Referenced by reload_config().

#define DEFAULT_T1MIN   100

100 MS for minimal roundtrip time

Definition at line 502 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 494 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 493 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 495 of file chan_sip.c.

Referenced by reload_config().

#define DEFAULT_TRANS_TIMEOUT   -1

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

Referenced by reload_config().

#define DEFAULT_VMEXTEN   "asterisk"

Definition at line 486 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 173 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 175 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 179 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 172 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 1007 of file chan_sip.c.

Referenced by __sip_reliable_xmit(), and retrans_pkt().

#define FLAG_RESPONSE   (1 << 0)

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

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

#define INC_CALL_RINGING   3

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

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

#define IPTOS_MINCOST   0x02

Definition at line 159 of file chan_sip.c.

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

Definition at line 189 of file chan_sip.c.

#define MAX_AUTHTRIES   3

Try authentication three times, then fail

Definition at line 204 of file chan_sip.c.

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

#define MAX_RETRANS   6

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

Definition at line 199 of file chan_sip.c.

#define NO_RTP   0

Definition at line 226 of file chan_sip.c.

#define NOT_SUPPORTED   0

Definition at line 397 of file chan_sip.c.

#define RTP   1

Definition at line 225 of file chan_sip.c.

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

Definition at line 6134 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 704 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 745 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 733 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 734 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 719 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 720 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 724 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 722 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 723 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 721 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 750 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 718 of file chan_sip.c.

#define SIP_G726_NONSTANDARD   (1 << 31)

Use non-standard packing for G726-32 data

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

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

#define SIP_INSECURE_INVITE   (1 << 24)

don't require authentication for incoming INVITEs

Definition at line 738 of file chan_sip.c.

Referenced by _sip_show_peer(), check_user_full(), and handle_common_options().

#define SIP_INSECURE_PORT   (1 << 23)

don't require matching port for incoming requests

Definition at line 737 of file chan_sip.c.

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

#define SIP_MAX_HEADERS   64

Max amount of SIP headers to read

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

#define SIP_NAT   (3 << 18)

four settings, uses two bits

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

Referenced by handle_common_options(), and nat2str().

#define SIP_NAT_RFC3581   (1 << 18)

NAT RFC3581

Definition at line 728 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 729 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 705 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 709 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 744 of file chan_sip.c.

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

#define SIP_NOVIDEO   (1 << 2)

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

Definition at line 706 of file chan_sip.c.

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

#define SIP_OPT_100REL   (1 << 1)

Definition at line 400 of file chan_sip.c.

#define SIP_OPT_EARLY_SESSION   (1 << 3)

Definition at line 402 of file chan_sip.c.

#define SIP_OPT_EVENTLIST   (1 << 11)

Definition at line 410 of file chan_sip.c.

#define SIP_OPT_GRUU   (1 << 12)

Definition at line 411 of file chan_sip.c.

#define SIP_OPT_HISTINFO   (1 << 15)

Definition at line 414 of file chan_sip.c.

#define SIP_OPT_JOIN   (1 << 4)

Definition at line 403 of file chan_sip.c.

#define SIP_OPT_NOREFERSUB   (1 << 14)

Definition at line 413 of file chan_sip.c.

#define SIP_OPT_PATH   (1 << 5)

Definition at line 404 of file chan_sip.c.

#define SIP_OPT_PRECONDITION   (1 << 7)

Definition at line 406 of file chan_sip.c.

#define SIP_OPT_PREF   (1 << 6)

Definition at line 405 of file chan_sip.c.

#define SIP_OPT_PRIVACY   (1 << 8)

Definition at line 407 of file chan_sip.c.

#define SIP_OPT_REPLACES   (1 << 0)

Definition at line 399 of file chan_sip.c.

Referenced by handle_request_invite().

#define SIP_OPT_RESPRIORITY   (1 << 16)

Definition at line 415 of file chan_sip.c.

#define SIP_OPT_SDP_ANAT   (1 << 9)

Definition at line 408 of file chan_sip.c.

#define SIP_OPT_SEC_AGREE   (1 << 10)

Definition at line 409 of file chan_sip.c.

#define SIP_OPT_TARGET_DIALOG   (1 << 13)

Definition at line 412 of file chan_sip.c.

#define SIP_OPT_TIMER   (1 << 2)

Definition at line 401 of file chan_sip.c.

#define SIP_OUTGOING   (1 << 13)

Direction of the last transaction in this dialog

Definition at line 717 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 771 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 770 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 782 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 778 of file chan_sip.c.

Referenced by __sip_show_channels(), process_sdp(), and update_call_counter().

#define SIP_PAGE2_CALL_ONHOLD_INACTIVE   (1 << 24)

24: Inactive

Definition at line 780 of file chan_sip.c.

Referenced by add_sdp(), and process_sdp().

#define SIP_PAGE2_CALL_ONHOLD_ONEDIR   (1 << 23)

23: One directional hold

Definition at line 779 of file chan_sip.c.

Referenced by add_sdp(), and process_sdp().

#define SIP_PAGE2_DEBUG   (3 << 11)

Definition at line 764 of file chan_sip.c.

#define SIP_PAGE2_DEBUG_CONFIG   (1 << 11)

Definition at line 765 of file chan_sip.c.

Referenced by reload_config().

#define SIP_PAGE2_DEBUG_CONSOLE   (1 << 12)

Definition at line 766 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 767 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 785 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 763 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 773 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 783 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 781 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 760 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 759 of file chan_sip.c.

Referenced by expire_register().

#define SIP_PAGE2_RTCACHEFRIENDS   (1 << 0)

Definition at line 757 of file chan_sip.c.

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

#define SIP_PAGE2_RTSAVE_SYSNAME   (1 << 5)

Definition at line 761 of file chan_sip.c.

Referenced by realtime_update_peer(), and sip_show_settings().

#define SIP_PAGE2_RTUPDATE   (1 << 1)

Definition at line 758 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 768 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 772 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 774 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 776 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 777 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 775 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 769 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 710 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 790 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 792 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 794 of file chan_sip.c.

Referenced by handle_request().

#define SIP_PKT_IGNORE_RESP   (1 << 3)

Resp ignore - ???

Definition at line 793 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 791 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 740 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 741 of file chan_sip.c.

Referenced by sip_indicate(), and sip_show_settings().

#define SIP_PROG_INBAND_NO   (1 << 25)

Definition at line 742 of file chan_sip.c.

Referenced by handle_common_options(), and sip_show_settings().

#define SIP_PROG_INBAND_YES   (2 << 25)

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

Referenced by sip_indicate(), and sip_write().

#define SIP_PROMISCREDIR   (1 << 8)

Promiscuous redirection

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

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

#define SIP_REINVITE   (7 << 20)

three bits used

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

Referenced by sip_indicate().

#define SIP_SENDRPID   (1 << 29)

Remote Party-ID Support

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

Referenced by sip_call().

#define SIP_TRUSTRPID   (1 << 9)

Trust RPID headers?

Definition at line 713 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 716 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 714 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 822 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 823 of file chan_sip.c.

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

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

#define SUPPORTED_EXTENSIONS   "replaces"

SIP Extensions we support.

Definition at line 467 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 797 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 816 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 817 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 812 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 813 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 814 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 815 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 802 of file chan_sip.c.

Referenced by add_t38_sdp(), and process_sdp().

#define T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF   (0 << 3)

Definition at line 801 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 799 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 798 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 805 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 804 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 806 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 808 of file chan_sip.c.

Referenced by add_t38_sdp().

#define T38FAX_VERSION_0   (0 << 6)

Version 0

Definition at line 809 of file chan_sip.c.

Referenced by add_t38_sdp(), and process_sdp().

#define T38FAX_VERSION_1   (1 << 6)

Version 1

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


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 

Definition at line 334 of file chan_sip.c.

00334                        {
00335    AUTH_SUCCESSFUL = 0,
00336    AUTH_CHALLENGE_SENT = 1,
00337    AUTH_SECRET_FAILED = -1,
00338    AUTH_USERNAME_MISMATCH = -2,
00339    AUTH_NOT_FOUND = -3,
00340    AUTH_FAKE_AUTH = -4,
00341    AUTH_UNKNOWN_DOMAIN = -5,
00342 };

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

00667                  {
00668    SIP_DOMAIN_AUTO,     /*!< This domain is auto-configured */
00669    SIP_DOMAIN_CONFIG,      /*!< This domain is from configuration */
00670 };

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

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

enum parse_register_result

Enumerator:
PARSE_REGISTER_FAILED 
PARSE_REGISTER_UPDATE 
PARSE_REGISTER_QUERY 

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

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

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

00328                    {
00329    PROXY_AUTH,
00330    WWW_AUTH,
00331 };

enum sip_result

Enumerator:
AST_SUCCESS 
AST_FAILURE 

Definition at line 237 of file chan_sip.c.

00237                 {
00238    AST_SUCCESS = 0,
00239    AST_FAILURE = -1,
00240 };

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

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

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

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

enum subscriptiontype

Enumerator:
NONE 
XPIDF_XML 
DIALOG_INFO_XML 
CPIM_PIDF_XML 
PIDF_XML 
MWI_NOTIFICATION 

Definition at line 278 of file chan_sip.c.

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

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

00827               {
00828         T38_DISABLED = 0,                /*!< Not enabled */
00829         T38_LOCAL_DIRECT,                /*!< Offered from local */
00830         T38_LOCAL_REINVITE,              /*!< Offered from local - REINVITE */
00831         T38_PEER_DIRECT,                 /*!< Offered from peer */
00832         T38_PEER_REINVITE,               /*!< Offered from peer - REINVITE */
00833         T38_ENABLED                      /*!< Negotiated (enabled) */
00834 };

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

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

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

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


Function Documentation

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

Definition at line 4006 of file chan_sip.c.

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

04007 {
04008    int pass;
04009 
04010    /*
04011     * Technically you can place arbitrary whitespace both before and after the ':' in
04012     * a header, although RFC3261 clearly says you shouldn't before, and place just
04013     * one afterwards.  If you shouldn't do it, what absolute idiot decided it was 
04014     * a good idea to say you can do it, and if you can do it, why in the hell would.
04015     * you say you shouldn't.
04016     * Anyways, pedanticsipchecking controls whether we allow spaces before ':',
04017     * and we always allow spaces after that for compatibility.
04018     */
04019    for (pass = 0; name && pass < 2;pass++) {
04020       int x, len = strlen(name);
04021       for (x=*start; x<req->headers; x++) {
04022          if (!strncasecmp(req->header[x], name, len)) {
04023             char *r = req->header[x] + len;  /* skip name */
04024             if (pedanticsipchecking)
04025                r = ast_skip_blanks(r);
04026 
04027             if (*r == ':') {
04028                *start = x+1;
04029                return ast_skip_blanks(r+1);
04030             }
04031          }
04032       }
04033       if (pass == 0) /* Try aliases */
04034          name = find_alias(name, NULL);
04035    }
04036 
04037    /* Don't return NULL, so get_header is always a valid pointer */
04038    return "";
04039 }

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

02056 {
02057    struct sip_pkt *cur, *prev = NULL;
02058 
02059    /* Just in case... */
02060    char *msg;
02061    int res = FALSE;
02062 
02063    msg = sip_methods[sipmethod].text;
02064 
02065    ast_mutex_lock(&p->lock);
02066    for (cur = p->packets; cur; prev = cur, cur = cur->next) {
02067       if ((cur->seqno == seqno) && ((ast_test_flag(cur, FLAG_RESPONSE)) == resp) &&
02068          ((ast_test_flag(cur, FLAG_RESPONSE)) || 
02069           (!strncasecmp(msg, cur->data, strlen(msg)) && (cur->data[strlen(msg)] < 33)))) {
02070          if (!resp && (seqno == p->pendinginvite)) {
02071             if (option_debug)
02072                ast_log(LOG_DEBUG, "Acked pending invite %d\n", p->pendinginvite);
02073             p->pendinginvite = 0;
02074          }
02075          /* this is our baby */
02076          res = TRUE;
02077          UNLINK(cur, p->packets, prev);
02078          if (cur->retransid > -1) {
02079             if (sipdebug && option_debug > 3)
02080                ast_log(LOG_DEBUG, "** SIP TIMER: Cancelling retransmit of packet (reply received) Retransid #%d\n", cur->retransid);
02081             ast_sched_del(sched, cur->retransid);
02082             cur->retransid = -1;
02083          }
02084          free(cur);
02085          break;
02086       }
02087    }
02088    ast_mutex_unlock(&p->lock);
02089    if (option_debug)
02090       ast_log(LOG_DEBUG, "Stopping retransmission on '%s' of %s %d: Match %s\n", p->callid, resp ? "Response" : "Request", seqno, res ? "Not Found" : "Found");
02091 }

static int __sip_autodestruct ( void *  data  )  [static]

Kill a SIP dialog (called by scheduler).

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

01990 {
01991    struct sip_pvt *p = data;
01992 
01993    /* If this is a subscription, tell the phone that we got a timeout */
01994    if (p->subscribed) {
01995       transmit_state_notify(p, AST_EXTENSION_DEACTIVATED, 1, TRUE);  /* Send last notification */
01996       p->subscribed = NONE;
01997       append_history(p, "Subscribestatus", "timeout");
01998       if (option_debug > 2)
01999          ast_log(LOG_DEBUG, "Re-scheduled destruction of SIP subsription %s\n", p->callid ? p->callid : "<unknown>");
02000       return 10000;  /* Reschedule this destruction so that we know that it's gone */
02001    }
02002 
02003    /* If we're destroying a subscription, dereference peer object too */
02004    if (p->subscribed == MWI_NOTIFICATION && p->relatedpeer)
02005       ASTOBJ_UNREF(p->relatedpeer,sip_destroy_peer);
02006 
02007    /* Reset schedule ID */
02008    p->autokillid = -1;
02009 
02010    if (option_debug)
02011       ast_log(LOG_DEBUG, "Auto destroying SIP dialog '%s'\n", p->callid);
02012    append_history(p, "AutoDestroy", "%s", p->callid);
02013    if (p->owner) {
02014       ast_log(LOG_WARNING, "Autodestruct on dialog '%s' with owner in place (Method: %s)\n", p->callid, sip_methods[p->method].text);
02015       ast_queue_hangup(p->owner);
02016    } else if (p->refer) {
02017       if (option_debug > 2)
02018          ast_log(LOG_DEBUG, "Finally hanging up channel after transfer: %s\n", p->callid);
02019       transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, 1);
02020       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
02021    } else
02022       sip_destroy(p);
02023    return 0;
02024 }

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

Execute destruction of SIP dialog structure, release memory.

Definition at line 2884 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, LOG_WARNING, 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_registry_destroy(), cfsip_methods::text, UNLINK, and update_call_counter().

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

02885 {
02886    struct sip_pvt *cur, *prev = NULL;
02887    struct sip_pkt *cp;
02888 
02889    if (sip_debug_test_pvt(p) || option_debug > 2)
02890       ast_verbose("Really destroying SIP dialog '%s' Method: %s\n", p->callid, sip_methods[p->method].text);
02891 
02892    if (ast_test_flag(&p->flags[0], SIP_INC_COUNT)) {
02893       update_call_counter(p, DEC_CALL_LIMIT);
02894       if (option_debug > 1)
02895          ast_log(LOG_DEBUG, "This call did not properly clean up call limits. Call ID %s\n", p->callid);
02896    }
02897 
02898    /* Remove link from peer to subscription of MWI */
02899    if (p->relatedpeer && p->relatedpeer->mwipvt)
02900       p->relatedpeer->mwipvt = NULL;
02901 
02902    if (dumphistory)
02903       sip_dump_history(p);
02904 
02905    if (p->options)
02906       free(p->options);
02907 
02908    if (p->stateid > -1)
02909       ast_extension_state_del(p->stateid, NULL);
02910    if (p->initid > -1)
02911       ast_sched_del(sched, p->initid);
02912    if (p->autokillid > -1)
02913       ast_sched_del(sched, p->autokillid);
02914 
02915    if (p->rtp)
02916       ast_rtp_destroy(p->rtp);
02917    if (p->vrtp)
02918       ast_rtp_destroy(p->vrtp);
02919    if (p->udptl)
02920       ast_udptl_destroy(p->udptl);
02921    if (p->refer)
02922       free(p->refer);
02923    if (p->route) {
02924       free_old_route(p->route);
02925       p->route = NULL;
02926    }
02927    if (p->registry) {
02928       if (p->registry->call == p)
02929          p->registry->call = NULL;
02930       ASTOBJ_UNREF(p->registry, sip_registry_destroy);
02931    }
02932 
02933    /* Unlink us from the owner if we have one */
02934    if (p->owner) {
02935       if (lockowner)
02936          ast_channel_lock(p->owner);
02937       if (option_debug)
02938          ast_log(LOG_DEBUG, "Detaching from %s\n", p->owner->name);
02939       p->owner->tech_pvt = NULL;
02940       if (lockowner)
02941          ast_channel_unlock(p->owner);
02942    }
02943    /* Clear history */
02944    if (p->history) {
02945       struct sip_history *hist;
02946       while( (hist = AST_LIST_REMOVE_HEAD(p->history, list)) )
02947          free(hist);
02948       free(p->history);
02949       p->history = NULL;
02950    }
02951 
02952    for (prev = NULL, cur = iflist; cur; prev = cur, cur = cur->next) {
02953       if (cur == p) {
02954          UNLINK(cur, iflist, prev);
02955          break;
02956       }
02957    }
02958    if (!cur) {
02959       ast_log(LOG_WARNING, "Trying to destroy \"%s\", not found in dialog list?!?! \n", p->callid);
02960       return;
02961    } 
02962 
02963    /* remove all current packets in this dialog */
02964    while((cp = p->packets)) {
02965       p->packets = p->packets->next;
02966       if (cp->retransid > -1)
02967          ast_sched_del(sched, cp->retransid);
02968       free(cp);
02969    }
02970    if (p->chanvars) {
02971       ast_variables_destroy(p->chanvars);
02972       p->chanvars = NULL;
02973    }
02974    ast_mutex_destroy(&p->lock);
02975 
02976    ast_string_field_free_pools(p);
02977 
02978    free(p);
02979 }

static int __sip_do_register ( struct sip_registry r  )  [static]

Register with SIP proxy.

Definition at line 7166 of file chan_sip.c.

References SIP_REGISTER, and transmit_register().

Referenced by sip_reregister().

07167 {
07168    int res;
07169 
07170    res = transmit_register(r, SIP_REGISTER, NULL, NULL);
07171    return res;
07172 }

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

02096 {
02097    struct sip_pkt *cur = NULL;
02098 
02099    while (p->packets) {
02100       int method;
02101       if (cur == p->packets) {
02102          ast_log(LOG_WARNING, "Have a packet that doesn't want to give up! %s\n", sip_methods[cur->method].text);
02103          return;
02104       }
02105       cur = p->packets;
02106       method = (cur->method) ? cur->method : find_sip_method(cur->data);
02107       __sip_ack(p, cur->seqno, ast_test_flag(cur, FLAG_RESPONSE), method);
02108    }
02109 }

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

References __sip_xmit(), ast_calloc, AST_FAILURE, ast_log(), ast_sched_add_variable(), ast_set_flag, AST_SUCCESS, 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, and sip_pvt::timer_t1.

Referenced by send_request(), and send_response().

01952 {
01953    struct sip_pkt *pkt;
01954    int siptimer_a = DEFAULT_RETRANS;
01955 
01956    if (!(pkt = ast_calloc(1, sizeof(*pkt) + len + 1)))
01957       return AST_FAILURE;
01958    memcpy(pkt->data, data, len);
01959    pkt->method = sipmethod;
01960    pkt->packetlen = len;
01961    pkt->next = p->packets;
01962    pkt->owner = p;
01963    pkt->seqno = seqno;
01964    if (resp)
01965       ast_set_flag(pkt, FLAG_RESPONSE);
01966    pkt->data[len] = '\0';
01967    pkt->timer_t1 = p->timer_t1;  /* Set SIP timer T1 */
01968    if (fatal)
01969       ast_set_flag(pkt, FLAG_FATAL);
01970    if (pkt->timer_t1)
01971       siptimer_a = pkt->timer_t1 * 2;
01972 
01973    /* Schedule retransmission */
01974    pkt->retransid = ast_sched_add_variable(sched, siptimer_a, retrans_pkt, pkt, 1);
01975    if (option_debug > 3 && sipdebug)
01976       ast_log(LOG_DEBUG, "*** SIP TIMER: Initalizing retransmit timer on packet: Id  #%d\n", pkt->retransid);
01977    pkt->next = p->packets;
01978    p->packets = pkt;
01979 
01980    __sip_xmit(pkt->owner, pkt->data, pkt->packetlen); /* Send packet */
01981    if (sipmethod == SIP_INVITE) {
01982       /* Note this is a pending invite */
01983       p->pendinginvite = seqno;
01984    }
01985    return AST_SUCCESS;
01986 }

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

02113 {
02114    struct sip_pkt *cur;
02115    int res = -1;
02116 
02117    for (cur = p->packets; cur; cur = cur->next) {
02118       if (cur->seqno == seqno && ast_test_flag(cur, FLAG_RESPONSE) == resp &&
02119          (ast_test_flag(cur, FLAG_RESPONSE) || method_match(sipmethod, cur->data))) {
02120          /* this is our baby */
02121          if (cur->retransid > -1) {
02122             if (option_debug > 3 && sipdebug)
02123                ast_log(LOG_DEBUG, "*** SIP TIMER: Cancelling retransmission #%d - %s (got response)\n", cur->retransid, sip_methods[sipmethod].text);
02124             ast_sched_del(sched, cur->retransid);
02125             cur->retransid = -1;
02126          }
02127          res = 0;
02128          break;
02129       }
02130    }
02131    if (option_debug)
02132       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");
02133    return res;
02134 }

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

SIP show channels CLI (main function).

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

10448 {
10449 #define FORMAT3 "%-15.15s  %-10.10s  %-11.11s  %-15.15s  %-13.13s  %-15.15s %-10.10s\n"
10450 #define FORMAT2 "%-15.15s  %-10.10s  %-11.11s  %-11.11s  %-4.4s  %-7.7s  %-15.15s\n"
10451 #define FORMAT  "%-15.15s  %-10.10s  %-11.11s  %5.5d/%5.5d  %-4.4s  %-3.3s %-3.3s  %-15.15s %-10.10s\n"
10452    struct sip_pvt *cur;
10453    int numchans = 0;
10454    char *referstatus = NULL;
10455 
10456    if (argc != 3)
10457       return RESULT_SHOWUSAGE;
10458    ast_mutex_lock(&iflock);
10459    cur = iflist;
10460    if (!subscriptions)
10461       ast_cli(fd, FORMAT2, "Peer", "User/ANR", "Call ID", "Seq (Tx/Rx)", "Format", "Hold", "Last Message");
10462    else 
10463       ast_cli(fd, FORMAT3, "Peer", "User", "Call ID", "Extension", "Last state", "Type", "Mailbox");
10464    for (; cur; cur = cur->next) {
10465       referstatus = "";
10466       if (cur->refer) { /* SIP transfer in progress */
10467          referstatus = referstatus2str(cur->refer->status);
10468       }
10469       if (cur->subscribed == NONE && !subscriptions) {
10470          ast_cli(fd, FORMAT, ast_inet_ntoa(cur->sa.sin_addr), 
10471             S_OR(cur->username, S_OR(cur->cid_num, "(None)")),
10472             cur->callid, 
10473             cur->ocseq, cur->icseq, 
10474             ast_getformatname(cur->owner ? cur->owner->nativeformats : 0), 
10475             ast_test_flag(&cur->flags[1], SIP_PAGE2_CALL_ONHOLD) ? "Yes" : "No",
10476             ast_test_flag(&cur->flags[0], SIP_NEEDDESTROY) ? "(d)" : "",
10477             cur->lastmsg ,
10478             referstatus
10479          );
10480          numchans++;
10481       }
10482       if (cur->subscribed != NONE && subscriptions) {
10483          ast_cli(fd, FORMAT3, ast_inet_ntoa(cur->sa.sin_addr),
10484             S_OR(cur->username, S_OR(cur->cid_num, "(None)")), 
10485                cur->callid,
10486             /* the 'complete' exten/context is hidden in the refer_to field for subscriptions */
10487             cur->subscribed == MWI_NOTIFICATION ? "--" : cur->subscribeuri,
10488             cur->subscribed == MWI_NOTIFICATION ? "<none>" : ast_extension_state2str(cur->laststate), 
10489             subscription_type2str(cur->subscribed),
10490             cur->subscribed == MWI_NOTIFICATION ? (cur->relatedpeer ? cur->relatedpeer->mailbox : "<none>") : "<none>"
10491 );
10492          numchans++;
10493       }
10494    }
10495    ast_mutex_unlock(&iflock);
10496    if (!subscriptions)
10497       ast_cli(fd, "%d active SIP channel%s\n", numchans, (numchans != 1) ? "s" : "");
10498    else
10499       ast_cli(fd, "%d active SIP subscription%s\n", numchans, (numchans != 1) ? "s" : "");
10500    return RESULT_SUCCESS;
10501 #undef FORMAT
10502 #undef FORMAT2
10503 #undef FORMAT3
10504 }

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

Transmit SIP message.

Definition at line 1747 of file chan_sip.c.

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

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

01748 {
01749    int res;
01750    const struct sockaddr_in *dst = sip_real_dst(p);
01751    res = sendto(sipsock, data, len, 0, (const struct sockaddr *)dst, sizeof(struct sockaddr_in));
01752 
01753    if (res != len)
01754       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));
01755    return res;
01756 }

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

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

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

05738 {
05739    struct sip_request resp;
05740    int seqno = 0;
05741 
05742    if (reliable && (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1)) {
05743       ast_log(LOG_WARNING, "Unable to determine sequence number from '%s'\n", get_header(req, "CSeq"));
05744       return -1;
05745    }
05746    respprep(&resp, p, msg, req);
05747    add_header_contentLength(&resp, 0);
05748    /* If we are cancelling an incoming invite for some reason, add information
05749       about the reason why we are doing this in clear text */
05750    if (p->method == SIP_INVITE && msg[0] != '1' && p->owner && p->owner->hangupcause) {
05751       char buf[10];
05752 
05753       add_header(&resp, "X-Asterisk-HangupCause", ast_cause2str(p->owner->hangupcause));
05754       snprintf(buf, sizeof(buf), "%d", p->owner->hangupcause);
05755       add_header(&resp, "X-Asterisk-HangupCauseCode", buf);
05756    }
05757    return send_response(p, &resp, reliable, seqno);
05758 }

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

10000 {
10001    char status[30] = "";
10002    char cbuf[256];
10003    struct sip_peer *peer;
10004    char codec_buf[512];
10005    struct ast_codec_pref *pref;
10006    struct ast_variable *v;
10007    struct sip_auth *auth;
10008    int x = 0, codec = 0, load_realtime;
10009    int realtimepeers;
10010 
10011    realtimepeers = ast_check_realtime("sippeers");
10012 
10013    if (argc < 4)
10014       return RESULT_SHOWUSAGE;
10015 
10016    load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? TRUE : FALSE;
10017    peer = find_peer(argv[3], NULL, load_realtime);
10018    if (s) {    /* Manager */
10019       if (peer) {
10020          const char *id = astman_get_header(m,"ActionID");
10021 
10022          astman_append(s, "Response: Success\r\n");
10023          if (!ast_strlen_zero(id))
10024             astman_append(s, "ActionID: %s\r\n",id);
10025       } else {
10026          snprintf (cbuf, sizeof(cbuf), "Peer %s not found.\n", argv[3]);
10027          astman_send_error(s, m, cbuf);
10028          return 0;
10029       }
10030    }
10031    if (peer && type==0 ) { /* Normal listing */
10032       ast_cli(fd,"\n\n");
10033       ast_cli(fd, "  * Name       : %s\n", peer->name);
10034       if (realtimepeers) { /* Realtime is enabled */
10035          ast_cli(fd, "  Realtime peer: %s\n", ast_test_flag(&peer->flags[0], SIP_REALTIME) ? "Yes, cached" : "No");
10036       }
10037       ast_cli(fd, "  Secret       : %s\n", ast_strlen_zero(peer->secret)?"<Not set>":"<Set>");
10038       ast_cli(fd, "  MD5Secret    : %s\n", ast_strlen_zero(peer->md5secret)?"<Not set>":"<Set>");
10039       for (auth = peer->auth; auth; auth = auth->next) {
10040          ast_cli(fd, "  Realm-auth   : Realm %-15.15s User %-10.20s ", auth->realm, auth->username);
10041          ast_cli(fd, "%s\n", !ast_strlen_zero(auth->secret)?"<Secret set>":(!ast_strlen_zero(auth->md5secret)?"<MD5secret set>" : "<Not set>"));
10042       }
10043       ast_cli(fd, "  Context      : %s\n", peer->context);
10044       ast_cli(fd, "  Subscr.Cont. : %s\n", S_OR(peer->subscribecontext, "<Not set>") );
10045       ast_cli(fd, "  Language     : %s\n", peer->language);
10046       if (!ast_strlen_zero(peer->accountcode))
10047          ast_cli(fd, "  Accountcode  : %s\n", peer->accountcode);
10048       ast_cli(fd, "  AMA flags    : %s\n", ast_cdr_flags2str(peer->amaflags));
10049       ast_cli(fd, "  Transfer mode: %s\n", transfermode2str(peer->allowtransfer));
10050       ast_cli(fd, "  CallingPres  : %s\n", ast_describe_caller_presentation(peer->callingpres));
10051       if (!ast_strlen_zero(peer->fromuser))
10052          ast_cli(fd, "  FromUser     : %s\n", peer->fromuser);
10053       if (!ast_strlen_zero(peer->fromdomain))
10054          ast_cli(fd, "  FromDomain   : %s\n", peer->fromdomain);
10055       ast_cli(fd, "  Callgroup    : ");
10056       print_group(fd, peer->callgroup, 0);
10057       ast_cli(fd, "  Pickupgroup  : ");
10058       print_group(fd, peer->pickupgroup, 0);
10059       ast_cli(fd, "  Mailbox      : %s\n", peer->mailbox);
10060       ast_cli(fd, "  VM Extension : %s\n", peer->vmexten);
10061       ast_cli(fd, "  LastMsgsSent : %d/%d\n", (peer->lastmsgssent & 0x7fff0000) >> 16, peer->lastmsgssent & 0xffff);
10062       ast_cli(fd, "  Call limit   : %d\n", peer->call_limit);
10063       ast_cli(fd, "  Dynamic      : %s\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)?"Yes":"No"));
10064       ast_cli(fd, "  Callerid     : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>"));
10065       ast_cli(fd, "  MaxCallBR    : %d kbps\n", peer->maxcallbitrate);
10066       ast_cli(fd, "  Expire       : %ld\n", ast_sched_when(sched, peer->expire));
10067       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)));
10068       ast_cli(fd, "  Nat          : %s\n", nat2str(ast_test_flag(&peer->flags[0], SIP_NAT)));
10069       ast_cli(fd, "  ACL          : %s\n", (peer->ha?"Yes":"No"));
10070       ast_cli(fd, "  T38 pt UDPTL : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT_UDPTL)?"Yes":"No");
10071 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS
10072       ast_cli(fd, "  T38 pt RTP   : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT_RTP)?"Yes":"No");
10073       ast_cli(fd, "  T38 pt TCP   : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT_TCP)?"Yes":"No");
10074 #endif
10075       ast_cli(fd, "  CanReinvite  : %s\n", ast_test_flag(&peer->flags[0], SIP_CAN_REINVITE)?"Yes":"No");
10076       ast_cli(fd, "  PromiscRedir : %s\n", ast_test_flag(&peer->flags[0], SIP_PROMISCREDIR)?"Yes":"No");
10077       ast_cli(fd, "  User=Phone   : %s\n", ast_test_flag(&peer->flags[0], SIP_USEREQPHONE)?"Yes":"No");
10078       ast_cli(fd, "  Video Support: %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_VIDEOSUPPORT)?"Yes":"No");
10079       ast_cli(fd, "  Trust RPID   : %s\n", ast_test_flag(&peer->flags[0], SIP_TRUSTRPID) ? "Yes" : "No");
10080       ast_cli(fd, "  Send RPID    : %s\n", ast_test_flag(&peer->flags[0], SIP_SENDRPID) ? "Yes" : "No");
10081       ast_cli(fd, "  Subscriptions: %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE) ? "Yes" : "No");
10082       ast_cli(fd, "  Overlap dial : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWOVERLAP) ? "Yes" : "No");
10083 
10084       /* - is enumerated */
10085       ast_cli(fd, "  DTMFmode     : %s\n", dtmfmode2str(ast_test_flag(&peer->flags[0], SIP_DTMF)));
10086       ast_cli(fd, "  LastMsg      : %d\n", peer->lastmsg);
10087       ast_cli(fd, "  ToHost       : %s\n", peer->tohost);
10088       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));
10089       ast_cli(fd, "  Defaddr->IP  : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port));
10090       if (!ast_strlen_zero(global_regcontext))
10091          ast_cli(fd, "  Reg. exten   : %s\n", peer->regexten);
10092       ast_cli(fd, "  Def. Username: %s\n", peer->username);
10093       ast_cli(fd, "  SIP Options  : ");
10094       if (peer->sipoptions) {
10095          int lastoption = -1;
10096          for (x=0 ; (x < (sizeof(sip_options) / sizeof(sip_options[0]))); x++) {
10097             if (sip_options[x].id != lastoption) {
10098                if (peer->sipoptions & sip_options[x].id)
10099                   ast_cli(fd, "%s ", sip_options[x].text);
10100                lastoption = x;
10101             }
10102          }
10103       } else
10104          ast_cli(fd, "(none)");
10105 
10106       ast_cli(fd, "\n");
10107       ast_cli(fd, "  Codecs       : ");
10108       ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability);
10109       ast_cli(fd, "%s\n", codec_buf);
10110       ast_cli(fd, "  Codec Order  : (");
10111       print_codec_to_cli(fd, &peer->prefs);
10112       ast_cli(fd, ")\n");
10113 
10114       ast_cli(fd, "  Auto-Framing:  %s \n", peer->autoframing ? "Yes" : "No");
10115       ast_cli(fd, "  Status       : ");
10116       peer_status(peer, status, sizeof(status));
10117       ast_cli(fd, "%s\n",status);
10118       ast_cli(fd, "  Useragent    : %s\n", peer->useragent);
10119       ast_cli(fd, "  Reg. Contact : %s\n", peer->fullcontact);
10120       if (peer->chanvars) {
10121          ast_cli(fd, "  Variables    :\n");
10122          for (v = peer->chanvars ; v ; v = v->next)
10123             ast_cli(fd, "                 %s = %s\n", v->name, v->value);
10124       }
10125       ast_cli(fd,"\n");
10126       ASTOBJ_UNREF(peer,sip_destroy_peer);
10127    } else  if (peer && type == 1) { /* manager listing */
10128       char buf[256];
10129       astman_append(s, "Channeltype: SIP\r\n");
10130       astman_append(s, "ObjectName: %s\r\n", peer->name);
10131       astman_append(s, "ChanObjectType: peer\r\n");
10132       astman_append(s, "SecretExist: %s\r\n", ast_strlen_zero(peer->secret)?"N":"Y");
10133       astman_append(s, "MD5SecretExist: %s\r\n", ast_strlen_zero(peer->md5secret)?"N":"Y");
10134       astman_append(s, "Context: %s\r\n", peer->context);
10135       astman_append(s, "Language: %s\r\n", peer->language);
10136       if (!ast_strlen_zero(peer->accountcode))
10137          astman_append(s, "Accountcode: %s\r\n", peer->accountcode);
10138       astman_append(s, "AMAflags: %s\r\n", ast_cdr_flags2str(peer->amaflags));
10139       astman_append(s, "CID-CallingPres: %s\r\n", ast_describe_caller_presentation(peer->callingpres));
10140       if (!ast_strlen_zero(peer->fromuser))
10141          astman_append(s, "SIP-FromUser: %s\r\n", peer->fromuser);
10142       if (!ast_strlen_zero(peer->fromdomain))
10143          astman_append(s, "SIP-FromDomain: %s\r\n", peer->fromdomain);
10144       astman_append(s, "Callgroup: ");
10145       astman_append(s, "%s\r\n", ast_print_group(buf, sizeof(buf), peer->callgroup));
10146       astman_append(s, "Pickupgroup: ");
10147       astman_append(s, "%s\r\n", ast_print_group(buf, sizeof(buf), peer->pickupgroup));
10148       astman_append(s, "VoiceMailbox: %s\r\n", peer->mailbox);
10149       astman_append(s, "TransferMode: %s\r\n", transfermode2str(peer->allowtransfer));
10150       astman_append(s, "LastMsgsSent: %d\r\n", peer->lastmsgssent);
10151       astman_append(s, "Call-limit: %d\r\n", peer->call_limit);
10152       astman_append(s, "MaxCallBR: %d kbps\r\n", peer->maxcallbitrate);
10153       astman_append(s, "Dynamic: %s\r\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)?"Y":"N"));
10154       astman_append(s, "Callerid: %s\r\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, ""));
10155       astman_append(s, "RegExpire: %ld seconds\r\n", ast_sched_when(sched,peer->expire));
10156       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)));
10157       astman_append(s, "SIP-NatSupport: %s\r\n", nat2str(ast_test_flag(&peer->flags[0], SIP_NAT)));
10158       astman_append(s, "ACL: %s\r\n", (peer->ha?"Y":"N"));
10159       astman_append(s, "SIP-CanReinvite: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_CAN_REINVITE)?"Y":"N"));
10160       astman_append(s, "SIP-PromiscRedir: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_PROMISCREDIR)?"Y":"N"));
10161       astman_append(s, "SIP-UserPhone: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_USEREQPHONE)?"Y":"N"));
10162       astman_append(s, "SIP-VideoSupport: %s\r\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_VIDEOSUPPORT)?"Y":"N"));
10163 
10164       /* - is enumerated */
10165       astman_append(s, "SIP-DTMFmode: %s\r\n", dtmfmode2str(ast_test_flag(&peer->flags[0], SIP_DTMF)));
10166       astman_append(s, "SIPLastMsg: %d\r\n", peer->lastmsg);
10167       astman_append(s, "ToHost: %s\r\n", peer->tohost);
10168       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));
10169       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));
10170       astman_append(s, "Default-Username: %s\r\n", peer->username);
10171       if (!ast_strlen_zero(global_regcontext))
10172          astman_append(s, "RegExtension: %s\r\n", peer->regexten);
10173       astman_append(s, "Codecs: ");
10174       ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability);
10175       astman_append(s, "%s\r\n", codec_buf);
10176       astman_append(s, "CodecOrder: ");
10177       pref = &peer->prefs;
10178       for(x = 0; x < 32 ; x++) {
10179          codec = ast_codec_pref_index(pref,x);
10180          if (!codec)
10181             break;
10182          astman_append(s, "%s", ast_getformatname(codec));
10183          if (x < 31 && ast_codec_pref_index(pref,x+1))
10184             astman_append(s, ",");
10185       }
10186 
10187       astman_append(s, "\r\n");
10188       astman_append(s, "Status: ");
10189       peer_status(peer, status, sizeof(status));
10190       astman_append(s, "%s\r\n", status);
10191       astman_append(s, "SIP-Useragent: %s\r\n", peer->useragent);
10192       astman_append(s, "Reg-Contact : %s\r\n", peer->fullcontact);
10193       if (peer->chanvars) {
10194          for (v = peer->chanvars ; v ; v = v->next) {
10195             astman_append(s, "ChanVariable:\n");
10196             astman_append(s, " %s,%s\r\n", v->name, v->value);
10197          }
10198       }
10199 
10200       ASTOBJ_UNREF(peer,sip_destroy_peer);
10201 
10202    } else {
10203       ast_cli(fd,"Peer %s not found.\n", argv[3]);
10204       ast_cli(fd,"\n");
10205    }
10206 
10207    return RESULT_SUCCESS;
10208 }

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

09550 {
09551    regex_t regexbuf;
09552    int havepattern = FALSE;
09553 
09554 #define FORMAT2 "%-25.25s  %-15.15s %-3.3s %-3.3s %-3.3s %-8s %-10s %-10s\n"
09555 #define FORMAT  "%-25.25s  %-15.15s %-3.3s %-3.3s %-3.3s %-8d %-10s %-10s\n"
09556 
09557    char name[256];
09558    int total_peers = 0;
09559    int peers_mon_online = 0;
09560    int peers_mon_offline = 0;
09561    int peers_unmon_offline = 0;
09562    int peers_unmon_online = 0;
09563    const char *id;
09564    char idtext[256] = "";
09565    int realtimepeers;
09566 
09567    realtimepeers = ast_check_realtime("sippeers");
09568 
09569    if (s) { /* Manager - get ActionID */
09570       id = astman_get_header(m,"ActionID");
09571       if (!ast_strlen_zero(id))
09572          snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
09573    }
09574 
09575    switch (argc) {
09576    case 5:
09577       if (!strcasecmp(argv[3], "like")) {
09578          if (regcomp(&regexbuf, argv[4], REG_EXTENDED | REG_NOSUB))
09579             return RESULT_SHOWUSAGE;
09580          havepattern = TRUE;
09581       } else
09582          return RESULT_SHOWUSAGE;
09583    case 3:
09584       break;
09585    default:
09586       return RESULT_SHOWUSAGE;
09587    }
09588 
09589    if (!s) /* Normal list */
09590       ast_cli(fd, FORMAT2, "Name/username", "Host", "Dyn", "Nat", "ACL", "Port", "Status", (realtimepeers ? "Realtime" : ""));
09591    
09592    ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do {
09593       char status[20] = "";
09594       char srch[2000];
09595       char pstatus;
09596       
09597       ASTOBJ_RDLOCK(iterator);
09598 
09599       if (havepattern && regexec(&regexbuf, iterator->name, 0, NULL, 0)) {
09600          ASTOBJ_UNLOCK(iterator);
09601          continue;
09602       }
09603 
09604       if (!ast_strlen_zero(iterator->username) && !s)
09605          snprintf(name, sizeof(name), "%s/%s", iterator->name, iterator->username);
09606       else
09607          ast_copy_string(name, iterator->name, sizeof(name));
09608       
09609       pstatus = peer_status(iterator, status, sizeof(status));
09610       if (pstatus == 1)
09611          peers_mon_online++;
09612       else if (pstatus == 0)
09613          peers_mon_offline++;
09614       else {
09615          if (iterator->addr.sin_port == 0)
09616             peers_unmon_offline++;
09617          else
09618             peers_unmon_online++;
09619       }
09620 
09621       snprintf(srch, sizeof(srch), FORMAT, name,
09622          iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iterator->addr.sin_addr) : "(Unspecified)",
09623          ast_test_flag(&iterator->flags[1], SIP_PAGE2_DYNAMIC) ? " D " : "   ",  /* Dynamic or not? */
09624          ast_test_flag(&iterator->flags[0], SIP_NAT_ROUTE) ? " N " : "   ",   /* NAT=yes? */
09625          iterator->ha ? " A " : "   ",    /* permit/deny */
09626          ntohs(iterator->addr.sin_port), status,
09627          realtimepeers ? (ast_test_flag(&iterator->flags[0], SIP_REALTIME) ? "Cached RT":"") : "");
09628 
09629       if (!s)  {/* Normal CLI list */
09630          ast_cli(fd, FORMAT, name, 
09631          iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iterator->addr.sin_addr) : "(Unspecified)",
09632          ast_test_flag(&iterator->flags[1], SIP_PAGE2_DYNAMIC) ? " D " : "   ",  /* Dynamic or not? */
09633          ast_test_flag(&iterator->flags[0], SIP_NAT_ROUTE) ? " N " : "   ",   /* NAT=yes? */
09634          iterator->ha ? " A " : "   ",       /* permit/deny */
09635          
09636          ntohs(iterator->addr.sin_port), status,
09637          realtimepeers ? (ast_test_flag(&iterator->flags[0], SIP_REALTIME) ? "Cached RT":"") : "");
09638       } else { /* Manager format */
09639          /* The names here need to be the same as other channels */
09640          astman_append(s, 
09641          "Event: PeerEntry\r\n%s"
09642          "Channeltype: SIP\r\n"
09643          "ObjectName: %s\r\n"
09644          "ChanObjectType: peer\r\n" /* "peer" or "user" */
09645          "IPaddress: %s\r\n"
09646          "IPport: %d\r\n"
09647          "Dynamic: %s\r\n"
09648          "Natsupport: %s\r\n"
09649          "VideoSupport: %s\r\n"
09650          "ACL: %s\r\n"
09651          "Status: %s\r\n"
09652          "RealtimeDevice: %s\r\n\r\n", 
09653          idtext,
09654          iterator->name, 
09655          iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iterator->addr.sin_addr) : "-none-",
09656          ntohs(iterator->addr.sin_port), 
09657          ast_test_flag(&iterator->flags[1], SIP_PAGE2_DYNAMIC) ? "yes" : "no",   /* Dynamic or not? */
09658          ast_test_flag(&iterator->flags[0], SIP_NAT_ROUTE) ? "yes" : "no", /* NAT=yes? */
09659          ast_test_flag(&iterator->flags[1], SIP_PAGE2_VIDEOSUPPORT) ? "yes" : "no", /* VIDEOSUPPORT=yes? */
09660          iterator->ha ? "yes" : "no",       /* permit/deny */
09661          status,
09662          realtimepeers ? (ast_test_flag(&iterator->flags[0], SIP_REALTIME) ? "yes":"no") : "no");
09663       }
09664 
09665       ASTOBJ_UNLOCK(iterator);
09666 
09667       total_peers++;
09668    } while(0) );
09669    
09670    if (!s)
09671       ast_cli(fd, "%d sip peers [Monitored: %d online, %d offline Unmonitored: %d online, %d offline]\n",
09672               total_peers, peers_mon_online, peers_mon_offline, peers_unmon_online, peers_unmon_offline);
09673 
09674    if (havepattern)
09675       regfree(&regexbuf);
09676 
09677    if (total)
09678       *total = total_peers;
09679    
09680 
09681    return RESULT_SUCCESS;
09682 #undef FORMAT
09683 #undef FORMAT2
09684 }

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

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

14160 {
14161    struct ast_rtp_quality qos;
14162    struct sip_pvt *p = chan->tech_pvt;
14163    char *all = "", *parse = ast_strdupa(preparse);
14164    AST_DECLARE_APP_ARGS(args,
14165       AST_APP_ARG(param);
14166       AST_APP_ARG(type);
14167       AST_APP_ARG(field);
14168    );
14169    AST_STANDARD_APP_ARGS(args, parse);
14170 
14171    /* Sanity check */
14172    if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) {
14173       ast_log(LOG_ERROR, "Cannot call %s on a non-SIP channel\n", funcname);
14174       return 0;
14175    }
14176 
14177    if (strcasecmp(args.param, "rtpqos"))
14178       return 0;
14179 
14180    memset(buf, 0, buflen);
14181    memset(&qos, 0, sizeof(qos));
14182 
14183    if (strcasecmp(args.type, "AUDIO") == 0) {
14184       all = ast_rtp_get_quality(p->rtp, &qos);
14185    } else if (strcasecmp(args.type, "VIDEO") == 0) {
14186       all = ast_rtp_get_quality(p->vrtp, &qos);
14187    }
14188 
14189    if (strcasecmp(args.field, "local_ssrc") == 0)
14190       snprintf(buf, buflen, "%u", qos.local_ssrc);
14191    else if (strcasecmp(args.field, "local_lostpackets") == 0)
14192       snprintf(buf, buflen, "%u", qos.local_lostpackets);
14193    else if (strcasecmp(args.field, "local_jitter") == 0)
14194       snprintf(buf, buflen, "%.0lf", qos.local_jitter * 1000.0);
14195    else if (strcasecmp(args.field, "local_count") == 0)
14196       snprintf(buf, buflen, "%u", qos.local_count);
14197    else if (strcasecmp(args.field, "remote_ssrc") == 0)
14198       snprintf(buf, buflen, "%u", qos.remote_ssrc);
14199    else if (strcasecmp(args.field, "remote_lostpackets") == 0)
14200       snprintf(buf, buflen, "%u", qos.remote_lostpackets);
14201    else if (strcasecmp(args.field, "remote_jitter") == 0)
14202       snprintf(buf, buflen, "%.0lf", qos.remote_jitter * 1000.0);
14203    else if (strcasecmp(args.field, "remote_count") == 0)
14204       snprintf(buf, buflen, "%u", qos.remote_count);
14205    else if (strcasecmp(args.field, "rtt") == 0)
14206       snprintf(buf, buflen, "%.0lf", qos.rtt * 1000.0);
14207    else if (strcasecmp(args.field, "all") == 0)
14208       ast_copy_string(buf, all, buflen);
14209    else {
14210       ast_log(LOG_WARNING, "Unrecognized argument '%s' to %s\n", preparse, funcname);
14211       return -1;
14212    }
14213    return 0;
14214 }

static void add_blank ( struct sip_request req  )  [static]

add a blank line if no body

Definition at line 2147 of file chan_sip.c.

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

Referenced by send_request(), and send_response().

02148 {
02149    if (!req->lines) {
02150       /* Add extra empty return. add_header() reserves 4 bytes so cannot be truncated */
02151       snprintf(req->data + req->len, sizeof(req->data) - req->len, "\r\n");
02152       req->len += strlen(req->data + req->len);
02153    }
02154 }

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

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

05944 {
05945    int rtp_code;
05946    struct ast_format_list fmt;
05947 
05948 
05949    if (debug)
05950       ast_verbose("Adding codec 0x%x (%s) to SDP\n", codec, ast_getformatname(codec));
05951    if ((rtp_code = ast_rtp_lookup_code(p->rtp, 1, codec)) == -1)
05952       return;
05953 
05954    if (p->rtp) {
05955       struct ast_codec_pref *pref = ast_rtp_codec_getpref(p->rtp);
05956       fmt = ast_codec_pref_getsize(pref, codec);
05957    } 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 */
05958       return;
05959    ast_build_string(m_buf, m_size, " %d", rtp_code);
05960    ast_build_string(a_buf, a_size, "a=rtpmap:%d %s/%d\r\n", rtp_code,
05961           ast_rtp_lookup_mime_subtype(1, codec,
05962                        ast_test_flag(&p->flags[0], SIP_G726_NONSTANDARD) ? AST_RTP_OPT_G726_NONSTANDARD : 0),
05963           sample_rate);
05964    if (codec == AST_FORMAT_G729A) {
05965       /* Indicate that we don't support VAD (G.729 annex B) */
05966       ast_build_string(a_buf, a_size, "a=fmtp:%d annexb=no\r\n", rtp_code);
05967    } else if (codec == AST_FORMAT_ILBC) {
05968       /* Add information about us using only 20/30 ms packetization */
05969       ast_build_string(a_buf, a_size, "a=fmtp:%d mode=%d\r\n", rtp_code, fmt.cur_ms);
05970    }
05971 
05972    if (fmt.cur_ms && (fmt.cur_ms < *min_packet_size))
05973       *min_packet_size = fmt.cur_ms;
05974 
05975    /* Our first codec packetization processed cannot be less than zero */
05976    if ((*min_packet_size) == 0  && fmt.cur_ms)
05977       *min_packet_size = fmt.cur_ms;
05978 }

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

Add DTMF INFO tone to sip message.

Definition at line 5909 of file chan_sip.c.

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

Referenced by transmit_info_with_digit().

05910 {
05911    char tmp[256];
05912 
05913    snprintf(tmp, sizeof(tmp), "Signal=%c\r\nDuration=%u\r\n", digit, duration);
05914    add_header(req, "Content-Type", "application/dtmf-relay");
05915    add_header_contentLength(req, strlen(tmp));
05916    add_line(req, tmp);
05917    return 0;
05918 }

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

Add header to SIP message.

Definition at line 5300 of file chan_sip.c.

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

05301 {
05302    int maxlen = sizeof(req->data) - 4 - req->len; /* 4 bytes are for two \r\n ? */
05303 
05304    if (req->headers == SIP_MAX_HEADERS) {
05305       ast_log(LOG_WARNING, "Out of SIP header space\n");
05306       return -1;
05307    }
05308 
05309    if (req->lines) {
05310       ast_log(LOG_WARNING, "Can't add more headers when lines have been added\n");
05311       return -1;
05312    }
05313 
05314    if (maxlen <= 0) {
05315       ast_log(LOG_WARNING, "Out of space, can't add anymore (%s:%s)\n", var, value);
05316       return -1;
05317    }
05318 
05319    req->header[req->headers] = req->data + req->len;
05320 
05321    if (compactheaders)
05322       var = find_alias(var, var);
05323 
05324    snprintf(req->header[req->headers], maxlen, "%s: %s\r\n", var, value);
05325    req->len += strlen(req->header[req->headers]);
05326    req->headers++;
05327    if (req->headers < SIP_MAX_HEADERS)
05328       req->headers++;
05329    else
05330       ast_log(LOG_WARNING, "Out of SIP header space... Will generate broken SIP message\n");
05331 
05332    return 0;   
05333 }

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

Add 'Content-Length' header to SIP message.

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

05337 {
05338    char clen[10];
05339 
05340    snprintf(clen, sizeof(clen), "%d", len);
05341    return add_header(req, "Content-Length", clen);
05342 }

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

Add content (not header) to SIP message.

Definition at line 5345 of file chan_sip.c.

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

05346 {
05347    if (req->lines == SIP_MAX_LINES)  {
05348       ast_log(LOG_WARNING, "Out of SIP line space\n");
05349       return -1;
05350    }
05351    if (!req->lines) {
05352       /* Add extra empty return */
05353       snprintf(req->data + req->len, sizeof(req->data) - req->len, "\r\n");
05354       req->len += strlen(req->data + req->len);
05355    }
05356    if (req->len >= sizeof(req->data) - 4) {
05357       ast_log(LOG_WARNING, "Out of space, can't add anymore\n");
05358       return -1;
05359    }
05360    req->line[req->lines] = req->data + req->len;
05361    snprintf(req->line[req->lines], sizeof(req->data) - req->len, "%s", line);
05362    req->len += strlen(req->line[req->lines]);
05363    req->lines++;
05364    return 0;   
05365 }

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

06117 {
06118    int rtp_code;
06119 
06120    if (debug)
06121       ast_verbose("Adding non-codec 0x%x (%s) to SDP\n", format, ast_rtp_lookup_mime_subtype(0, format, 0));
06122    if ((rtp_code = ast_rtp_lookup_code(p->rtp, 0, format)) == -1)
06123       return;
06124 
06125    ast_build_string(m_buf, m_size, " %d", rtp_code);
06126    ast_build_string(a_buf, a_size, "a=rtpmap:%d %s/%d\r\n", rtp_code,
06127           ast_rtp_lookup_mime_subtype(0, format, 0),
06128           sample_rate);
06129    if (format == AST_RTP_DTMF)
06130       /* Indicate we support DTMF and FLASH... */
06131       ast_build_string(a_buf, a_size, "a=fmtp:%d 0-16\r\n", rtp_code);
06132 }

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

Add realm authentication in list.

Definition at line 15680 of file chan_sip.c.

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

Referenced by build_peer().

15681 {
15682    char authcopy[256];
15683    char *username=NULL, *realm=NULL, *secret=NULL, *md5secret=NULL;
15684    char *stringp;
15685    struct sip_auth *a, *b, *auth;
15686 
15687    if (ast_strlen_zero(configuration))
15688       return authlist;
15689 
15690    if (option_debug)
15691       ast_log(LOG_DEBUG, "Auth config ::  %s\n", configuration);
15692 
15693    ast_copy_string(authcopy, configuration, sizeof(authcopy));
15694    stringp = authcopy;
15695 
15696    username = stringp;
15697    realm = strrchr(stringp, '@');
15698    if (realm)
15699       *realm++ = '\0';
15700    if (ast_strlen_zero(username) || ast_strlen_zero(realm)) {
15701       ast_log(LOG_WARNING, "Format for authentication entry is user[:secret]@realm at line %d\n", lineno);
15702       return authlist;
15703    }
15704    stringp = username;
15705    username = strsep(&stringp, ":");
15706    if (username) {
15707       secret = strsep(&stringp, ":");
15708       if (!secret) {
15709          stringp = username;
15710          md5secret = strsep(&stringp,"#");
15711       }
15712    }
15713    if (!(auth = ast_calloc(1, sizeof(*auth))))
15714       return authlist;
15715 
15716    ast_copy_string(auth->realm, realm, sizeof(auth->realm));
15717    ast_copy_string(auth->username, username, sizeof(auth->username));
15718    if (secret)
15719       ast_copy_string(auth->secret, secret, sizeof(auth->secret));
15720    if (md5secret)
15721       ast_copy_string(auth->md5secret, md5secret, sizeof(auth->md5secret));
15722 
15723    /* find the end of the list */
15724    for (b = NULL, a = authlist; a ; b = a, a = a->next)
15725       ;
15726    if (b)
15727       b->next = auth;   /* Add structure add end of list */
15728    else
15729       authlist = auth;
15730 
15731    if (option_verbose > 2)
15732       ast_verbose("Added authentication for realm %s\n", realm);
15733 
15734    return authlist;
15735 
15736 }

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

Add route header into request per learned route.

Definition at line 5466 of file chan_sip.c.

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

Referenced by reqprep().

05467 {
05468    char r[BUFSIZ*2], *p;
05469    int n, rem = sizeof(r);
05470 
05471    if (!route)
05472       return;
05473 
05474    p = r;
05475    for (;route ; route = route->next) {
05476       n = strlen(route->hop);
05477       if (rem < n+3) /* we need room for ",<route>" */
05478          break;
05479       if (p != r) {  /* add a separator after fist route */
05480          *p++ = ',';
05481          --rem;
05482       }
05483       *p++ = '<';
05484       ast_copy_string(p, route->hop, rem); /* cannot fail */
05485       p += n;
05486       *p++ = '>';
05487       rem -= (n+2);
05488    }
05489    *p = '\0';
05490    add_header(req, "Route", r);
05491 }

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

Add Session Description Protocol message.

Definition at line 6137 of file chan_sip.c.

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

06138 {
06139    int len = 0;
06140    int alreadysent = 0;
06141 
06142    struct sockaddr_in sin;
06143    struct sockaddr_in vsin;
06144    struct sockaddr_in dest;
06145    struct sockaddr_in vdest = { 0, };
06146 
06147    /* SDP fields */
06148    char *version =   "v=0\r\n";     /* Protocol version */
06149    char *subject =   "s=session\r\n";  /* Subject of the session */
06150    char owner[256];           /* Session owner/creator */
06151    char connection[256];            /* Connection data */
06152    char *stime = "t=0 0\r\n";          /* Time the session is active */
06153    char bandwidth[256] = "";        /* Max bitrate */
06154    char *hold;
06155    char m_audio[256];            /* Media declaration line for audio */
06156    char m_video[256];            /* Media declaration line for video */
06157    char a_audio[1024];           /* Attributes for audio */
06158    char a_video[1024];           /* Attributes for video */
06159    char *m_audio_next = m_audio;
06160    char *m_video_next = m_video;
06161    size_t m_audio_left = sizeof(m_audio);
06162    size_t m_video_left = sizeof(m_video);
06163    char *a_audio_next = a_audio;
06164    char *a_video_next = a_video;
06165    size_t a_audio_left = sizeof(a_audio);
06166    size_t a_video_left = sizeof(a_video);
06167 
06168    int x;
06169    int capability;
06170    int needvideo = FALSE;
06171    int debug = sip_debug_test_pvt(p);
06172    int min_audio_packet_size = 0;
06173    int min_video_packet_size = 0;
06174 
06175    m_video[0] = '\0';   /* Reset the video media string if it's not needed */
06176 
06177    if (!p->rtp) {
06178       ast_log(LOG_WARNING, "No way to add SDP without an RTP structure\n");
06179       return AST_FAILURE;
06180    }
06181 
06182    /* Set RTP Session ID and version */
06183    if (!p->sessionid) {
06184       p->sessionid = getpid();
06185       p->sessionversion = p->sessionid;
06186    } else
06187       p->sessionversion++;
06188 
06189    /* Get our addresses */
06190    ast_rtp_get_us(p->rtp, &sin);
06191    if (p->vrtp)
06192       ast_rtp_get_us(p->vrtp, &vsin);
06193 
06194    /* Is this a re-invite to move the media out, then use the original offer from caller  */
06195    if (p->redirip.sin_addr.s_addr) {
06196       dest.sin_port = p->redirip.sin_port;
06197       dest.sin_addr = p->redirip.sin_addr;
06198    } else {
06199       dest.sin_addr = p->ourip;
06200       dest.sin_port = sin.sin_port;
06201    }
06202 
06203    capability = p->jointcapability;
06204 
06205 
06206    if (option_debug > 1) {
06207       char codecbuf[BUFSIZ];
06208       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");
06209       ast_log(LOG_DEBUG, "** Our prefcodec: %s \n", ast_getformatname_multiple(codecbuf, sizeof(codecbuf), p->prefcodec));
06210    }
06211    
06212 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS
06213    if (ast_test_flag(&p->t38.t38support, SIP_PAGE2_T38SUPPORT_RTP)) {
06214       ast_build_string(&m_audio_next, &m_audio_left, " %d", 191);
06215       ast_build_string(&a_audio_next, &a_audio_left, "a=rtpmap:%d %s/%d\r\n", 191, "t38", 8000);
06216    }
06217 #endif
06218 
06219    /* Check if we need video in this call */
06220    if ((capability & AST_FORMAT_VIDEO_MASK) && !ast_test_flag(&p->flags[0], SIP_NOVIDEO)) {
06221       if (p->vrtp) {
06222          needvideo = TRUE;
06223          if (option_debug > 1)
06224             ast_log(LOG_DEBUG, "This call needs video offers!\n");
06225       } else if (option_debug > 1)
06226          ast_log(LOG_DEBUG, "This call needs video offers, but there's no video support enabled!\n");
06227    }
06228       
06229 
06230    /* Ok, we need video. Let's add what we need for video and set codecs.
06231       Video is handled differently than audio since we can not transcode. */
06232    if (needvideo) {
06233       /* Determine video destination */
06234       if (p->vredirip.sin_addr.s_addr) {
06235          vdest.sin_addr = p->vredirip.sin_addr;
06236          vdest.sin_port = p->vredirip.sin_port;
06237       } else {
06238          vdest.sin_addr = p->ourip;
06239          vdest.sin_port = vsin.sin_port;
06240       }
06241       ast_build_string(&m_video_next, &m_video_left, "m=video %d RTP/AVP", ntohs(vdest.sin_port));
06242 
06243       /* Build max bitrate string */
06244       if (p->maxcallbitrate)
06245          snprintf(bandwidth, sizeof(bandwidth), "b=CT:%d\r\n", p->maxcallbitrate);
06246       if (debug) 
06247          ast_verbose("Video is at %s port %d\n", ast_inet_ntoa(p->ourip), ntohs(vsin.sin_port));   
06248    }
06249 
06250    if (debug) 
06251       ast_verbose("Audio is at %s port %d\n", ast_inet_ntoa(p->ourip), ntohs(sin.sin_port)); 
06252 
06253    /* Start building generic SDP headers */
06254 
06255    /* We break with the "recommendation" and send our IP, in order that our
06256       peer doesn't have to ast_gethostbyname() us */
06257 
06258    snprintf(owner, sizeof(owner), "o=root %d %d IN IP4 %s\r\n", p->sessionid, p->sessionversion, ast_inet_ntoa(dest.sin_addr));
06259    snprintf(connection, sizeof(connection), "c=IN IP4 %s\r\n", ast_inet_ntoa(dest.sin_addr));
06260    ast_build_string(&m_audio_next, &m_audio_left, "m=audio %d RTP/AVP", ntohs(dest.sin_port));
06261 
06262    if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD_ONEDIR))
06263       hold = "a=recvonly\r\n";
06264    else if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD_INACTIVE))
06265       hold = "a=inactive\r\n";
06266    else
06267       hold = "a=sendrecv\r\n";
06268 
06269    /* Now, start adding audio codecs. These are added in this order:
06270       - First what was requested by the calling channel
06271       - Then preferences in order from sip.conf device config for this peer/user
06272       - Then other codecs in capabilities, including video
06273    */
06274 
06275    /* Prefer the audio codec we were requested to use, first, no matter what 
06276       Note that p->prefcodec can include video codecs, so mask them out
06277     */
06278    if (capability & p->prefcodec) {
06279       int codec = p->prefcodec & AST_FORMAT_AUDIO_MASK;
06280 
06281       add_codec_to_sdp(p, codec, SDP_SAMPLE_RATE(codec),
06282              &m_audio_next, &m_audio_left,
06283              &a_audio_next, &a_audio_left,
06284              debug, &min_audio_packet_size);
06285       alreadysent |= codec;
06286    }
06287 
06288    /* Start by sending our preferred audio codecs */
06289    for (x = 0; x < 32; x++) {
06290       int codec;
06291 
06292       if (!(codec = ast_codec_pref_index(&p->prefs, x)))
06293          break; 
06294 
06295       if (!(capability & codec))
06296          continue;
06297 
06298       if (alreadysent & codec)
06299          continue;
06300 
06301       add_codec_to_sdp(p, codec, SDP_SAMPLE_RATE(codec),
06302              &m_audio_next, &m_audio_left,
06303              &a_audio_next, &a_audio_left,
06304              debug, &min_audio_packet_size);
06305       alreadysent |= codec;
06306    }
06307 
06308    /* Now send any other common audio and video codecs, and non-codec formats: */
06309    for (x = 1; x <= (needvideo ? AST_FORMAT_MAX_VIDEO : AST_FORMAT_MAX_AUDIO); x <<= 1) {
06310       if (!(capability & x))  /* Codec not requested */
06311          continue;
06312 
06313       if (alreadysent & x) /* Already added to SDP */
06314          continue;
06315 
06316       if (x <= AST_FORMAT_MAX_AUDIO)
06317          add_codec_to_sdp(p, x, SDP_SAMPLE_RATE(x),
06318                 &m_audio_next, &m_audio_left,
06319                 &a_audio_next, &a_audio_left,
06320                 debug, &min_audio_packet_size);
06321       else 
06322          add_codec_to_sdp(p, x, 90000,
06323                 &m_video_next, &m_video_left,
06324                 &a_video_next, &a_video_left,
06325                 debug, &min_video_packet_size);
06326    }
06327 
06328    /* Now add DTMF RFC2833 telephony-event as a codec */
06329    for (x = 1; x <= AST_RTP_MAX; x <<= 1) {
06330       if (!(p->jointnoncodeccapability & x))
06331          continue;
06332 
06333       add_noncodec_to_sdp(p, x, 8000,
06334                 &m_audio_next, &m_audio_left,
06335                 &a_audio_next, &a_audio_left,
06336                 debug);
06337    }
06338 
06339    if (option_debug > 2)
06340       ast_log(LOG_DEBUG, "-- Done with adding codecs to SDP\n");
06341 
06342    if (!p->owner || !ast_internal_timing_enabled(p->owner))
06343       ast_build_string(&a_audio_next, &a_audio_left, "a=silenceSupp:off - - - -\r\n");
06344 
06345    if (min_audio_packet_size)
06346       ast_build_string(&a_audio_next, &a_audio_left, "a=ptime:%d\r\n", min_audio_packet_size);
06347 
06348    if (min_video_packet_size)
06349       ast_build_string(&a_video_next, &a_video_left, "a=ptime:%d\r\n", min_video_packet_size);
06350 
06351    if ((m_audio_left < 2) || (m_video_left < 2) || (a_audio_left == 0) || (a_video_left == 0))
06352       ast_log(LOG_WARNING, "SIP SDP may be truncated due to undersized buffer!!\n");
06353 
06354    ast_build_string(&m_audio_next, &m_audio_left, "\r\n");
06355    if (needvideo)
06356       ast_build_string(&m_video_next, &m_video_left, "\r\n");
06357 
06358    len = strlen(version) + strlen(subject) + strlen(owner) + strlen(connection) + strlen(stime) + strlen(m_audio) + strlen(a_audio) + strlen(hold);
06359    if (needvideo) /* only if video response is appropriate */
06360       len += strlen(m_video) + strlen(a_video) + strlen(bandwidth) + strlen(hold);
06361 
06362    add_header(resp, "Content-Type", "application/sdp");
06363    add_header_contentLength(resp, len);
06364    add_line(resp, version);
06365    add_line(resp, owner);
06366    add_line(resp, subject);
06367    add_line(resp, connection);
06368    if (needvideo)    /* only if video response is appropriate */
06369       add_line(resp, bandwidth);
06370    add_line(resp, stime);
06371    add_line(resp, m_audio);
06372    add_line(resp, a_audio);
06373    add_line(resp, hold);
06374    if (needvideo) { /* only if video response is appropriate */
06375       add_line(resp, m_video);
06376       add_line(resp, a_video);
06377       add_line(resp, hold);   /* Repeat hold for the video stream */
06378    }
06379 
06380    /* Update lastrtprx when we send our SDP */
06381    p->lastrtprx = p->lastrtptx = time(NULL); /* XXX why both ? */
06382 
06383    if (option_debug > 2) {
06384       char buf[BUFSIZ];
06385       ast_log(LOG_DEBUG, "Done building SDP. Settling with this capability: %s\n", ast_getformatname_multiple(buf, BUFSIZ, capability));
06386    }
06387 
06388    return AST_SUCCESS;
06389 }

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 15616 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, LOG_WARNING, and sipdebug.

15617 {
15618    struct domain *d;
15619 
15620    if (ast_strlen_zero(domain)) {
15621       ast_log(LOG_WARNING, "Zero length domain.\n");
15622       return 1;
15623    }
15624 
15625    if (!(d = ast_calloc(1, sizeof(*d))))
15626       return 0;
15627 
15628    ast_copy_string(d->domain, domain, sizeof(d->domain));
15629 
15630    if (!ast_strlen_zero(context))
15631       ast_copy_string(d->context, context, sizeof(d->context));
15632 
15633    d->mode = mode;
15634 
15635    AST_LIST_LOCK(&domain_list);
15636    AST_LIST_INSERT_TAIL(&domain_list, d, list);
15637    AST_LIST_UNLOCK(&domain_list);
15638 
15639    if (sipdebug)  
15640       ast_log(LOG_DEBUG, "Added local SIP domain '%s'\n", domain);
15641 
15642    return 1;
15643 }

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

Add T.38 Session Description Protocol message.

Definition at line 6017 of file chan_sip.c.

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

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

06018 {
06019    int len = 0;
06020    int x = 0;
06021    struct sockaddr_in udptlsin;
06022    char v[256] = "";
06023    char s[256] = "";
06024    char o[256] = "";
06025    char c[256] = "";
06026    char t[256] = "";
06027    char m_modem[256];
06028    char a_modem[1024];
06029    char *m_modem_next = m_modem;
06030    size_t m_modem_left = sizeof(m_modem);
06031    char *a_modem_next = a_modem;
06032    size_t a_modem_left = sizeof(a_modem);
06033    struct sockaddr_in udptldest = { 0, };
06034    int debug;
06035    
06036    debug = sip_debug_test_pvt(p);
06037    len = 0;
06038    if (!p->udptl) {
06039       ast_log(LOG_WARNING, "No way to add SDP without an UDPTL structure\n");
06040       return -1;
06041    }
06042    
06043    if (!p->sessionid) {
06044       p->sessionid = getpid();
06045       p->sessionversion = p->sessionid;
06046    } else
06047       p->sessionversion++;
06048    
06049    /* Our T.38 end is */
06050    ast_udptl_get_us(p->udptl, &udptlsin);
06051    
06052    /* Determine T.38 UDPTL destination */
06053    if (p->udptlredirip.sin_addr.s_addr) {
06054       udptldest.sin_port = p->udptlredirip.sin_port;
06055       udptldest.sin_addr = p->udptlredirip.sin_addr;
06056    } else {
06057       udptldest.sin_addr = p->ourip;
06058       udptldest.sin_port = udptlsin.sin_port;
06059    }
06060    
06061    if (debug) 
06062       ast_log(LOG_DEBUG, "T.38 UDPTL is at %s port %d\n", ast_inet_ntoa(p->ourip), ntohs(udptlsin.sin_port));
06063    
06064    /* We break with the "recommendation" and send our IP, in order that our
06065       peer doesn't have to ast_gethostbyname() us */
06066    
06067    if (debug) {
06068       ast_log(LOG_DEBUG, "Our T38 capability (%d), peer T38 capability (%d), joint capability (%d)\n",
06069          p->t38.capability,
06070          p->t38.peercapability,
06071          p->t38.jointcapability);
06072    }
06073    snprintf(v, sizeof(v), "v=0\r\n");
06074    snprintf(o, sizeof(o), "o=root %d %d IN IP4 %s\r\n", p->sessionid, p->sessionversion, ast_inet_ntoa(udptldest.sin_addr));
06075    snprintf(s, sizeof(s), "s=session\r\n");
06076    snprintf(c, sizeof(c), "c=IN IP4 %s\r\n", ast_inet_ntoa(udptldest.sin_addr));
06077    snprintf(t, sizeof(t), "t=0 0\r\n");
06078    ast_build_string(&m_modem_next, &m_modem_left, "m=image %d udptl t38\r\n", ntohs(udptldest.sin_port));
06079    
06080    if ((p->t38.jointcapability & T38FAX_VERSION) == T38FAX_VERSION_0)
06081       ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxVersion:0\r\n");
06082    if ((p->t38.jointcapability & T38FAX_VERSION) == T38FAX_VERSION_1)
06083       ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxVersion:1\r\n");
06084    if ((x = t38_get_rate(p->t38.jointcapability)))
06085       ast_build_string(&a_modem_next, &a_modem_left, "a=T38MaxBitRate:%d\r\n",x);
06086    ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxFillBitRemoval:%d\r\n", (p->t38.jointcapability & T38FAX_FILL_BIT_REMOVAL) ? 1 : 0);
06087    ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxTranscodingMMR:%d\r\n", (p->t38.jointcapability & T38FAX_TRANSCODING_MMR) ? 1 : 0);
06088    ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxTranscodingJBIG:%d\r\n", (p->t38.jointcapability & T38FAX_TRANSCODING_JBIG) ? 1 : 0);
06089    ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxRateManagement:%s\r\n", (p->t38.jointcapability & T38FAX_RATE_MANAGEMENT_LOCAL_TCF) ? "localTCF" : "transferredTCF");
06090    x = ast_udptl_get_local_max_datagram(p->udptl);
06091    ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxMaxBuffer:%d\r\n",x);
06092    ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxMaxDatagram:%d\r\n",x);
06093    if (p->t38.jointcapability != T38FAX_UDP_EC_NONE)
06094       ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxUdpEC:%s\r\n", (p->t38.jointcapability & T38FAX_UDP_EC_REDUNDANCY) ? "t38UDPRedundancy" : "t38UDPFEC");
06095    len = strlen(v) + strlen(s) + strlen(o) + strlen(c) + strlen(t) + strlen(m_modem) + strlen(a_modem);
06096    add_header(resp, "Content-Type", "application/sdp");
06097    add_header_contentLength(resp, len);
06098    add_line(resp, v);
06099    add_line(resp, o);
06100    add_line(resp, s);
06101    add_line(resp, c);
06102    add_line(resp, t);
06103    add_line(resp, m_modem);
06104    add_line(resp, a_modem);
06105    
06106    /* Update lastrtprx when we send our SDP */
06107    p->lastrtprx = p->lastrtptx = time(NULL);
06108    
06109    return 0;
06110 }

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

Add text body to SIP message.

Definition at line 5898 of file chan_sip.c.

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

Referenced by transmit_message_with_text().

05899 {
05900    /* XXX Convert \n's to \r\n's XXX */
05901    add_header(req, "Content-Type", "text/plain");
05902    add_header_contentLength(req, strlen(text));
05903    add_line(req, text);
05904    return 0;
05905 }

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

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

Referenced by transmit_info_with_vidupdate().

05923 {
05924    const char *xml_is_a_huge_waste_of_space =
05925       "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\r\n"
05926       " <media_control>\r\n"
05927       "  <vc_primitive>\r\n"
05928       "   <to_encoder>\r\n"
05929       "    <picture_fast_update>\r\n"
05930       "    </picture_fast_update>\r\n"
05931       "   </to_encoder>\r\n"
05932       "  </vc_primitive>\r\n"
05933       " </media_control>\r\n";
05934    add_header(req, "Content-Type", "application/media_control+xml");
05935    add_header_contentLength(req, strlen(xml_is_a_huge_waste_of_space));
05936    add_line(req, xml_is_a_huge_waste_of_space);
05937    return 0;
05938 }

static void append_date ( struct sip_request req  )  [static]

Append date to SIP message.

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

05846 {
05847    char tmpdat[256];
05848    struct tm tm;
05849    time_t t = time(NULL);
05850 
05851    gmtime_r(&t, &tm);
05852    strftime(tmpdat, sizeof(tmpdat), "%a, %d %b %Y %T GMT", &tm);
05853    add_header(req, "Date", tmpdat);
05854 }

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

Append to SIP dialog history with arg list.

Definition at line 1836 of file chan_sip.c.

References append_history_va().

01837 {
01838    va_list ap;
01839 
01840    if (!p)
01841       return;
01842    va_start(ap, fmt);
01843    append_history_va(p, fmt, ap);
01844    va_end(ap);
01845 
01846    return;
01847 }

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

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

Referenced by append_history_full().

01817 {
01818    char buf[80], *c = buf; /* max history length */
01819    struct sip_history *hist;
01820    int l;
01821 
01822    vsnprintf(buf, sizeof(buf), fmt, ap);
01823    strsep(&c, "\r\n"); /* Trim up everything after \r or \n */
01824    l = strlen(buf) + 1;
01825    if (!(hist = ast_calloc(1, sizeof(*hist) + l)))
01826       return;
01827    if (!p->history && !(p->history = ast_calloc(1, sizeof(*p->history)))) {
01828       free(hist);
01829       return;
01830    }
01831    memcpy(hist->event, buf, l);
01832    AST_LIST_INSERT_TAIL(p->history, hist, list);
01833 }

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

12747 {
12748    if (chan && chan->_state == AST_STATE_UP) {
12749       if (chan->generatordata)
12750          ast_deactivate_generator(chan);
12751    }
12752 }

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

01777 {
01778    struct sockaddr_in theirs, ours;
01779 
01780    /* Get our local information */
01781    ast_ouraddrfor(them, us);
01782    theirs.sin_addr = *them;
01783    ours.sin_addr = *us;
01784 
01785    if (localaddr && externip.sin_addr.s_addr &&
01786        (ast_apply_ha(localaddr, &theirs)) &&
01787        (!global_matchexterniplocally || !ast_apply_ha(localaddr, &ours))) {
01788       if (externexpire && time(NULL) >= externexpire) {
01789          struct ast_hostent ahp;
01790          struct hostent *hp;
01791 
01792          externexpire = time(NULL) + externrefresh;
01793          if ((hp = ast_gethostbyname(externhost, &ahp))) {
01794             memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr));
01795          } else
01796             ast_log(LOG_NOTICE, "Warning: Re-lookup of '%s' failed!\n", externhost);
01797       }
01798       *us = externip.sin_addr;
01799       if (option_debug) {
01800          ast_log(LOG_DEBUG, "Target address %s is not local, substituting externip\n", 
01801             ast_inet_ntoa(*(struct in_addr *)&them->s_addr));
01802       }
01803    } else if (bindaddr.sin_addr.s_addr)
01804       *us = bindaddr.sin_addr;
01805    return AST_SUCCESS;
01806 }

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 12756 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, LOG_WARNING, and option_debug.

12757 {
12758    int res = 0;
12759    struct ast_channel *peera = NULL,   
12760       *peerb = NULL,
12761       *peerc = NULL,
12762       *peerd = NULL;
12763 
12764 
12765    /* We will try to connect the transferee with the target and hangup
12766       all channels to the transferer */   
12767    if (option_debug > 3) {
12768       ast_log(LOG_DEBUG, "Sip transfer:--------------------\n");
12769       if (transferer->chan1)
12770          ast_log(LOG_DEBUG, "-- Transferer to PBX channel: %s State %s\n", transferer->chan1->name, ast_state2str(transferer->chan1->_state));
12771       else
12772          ast_log(LOG_DEBUG, "-- No transferer first channel - odd??? \n");
12773       if (target->chan1)
12774          ast_log(LOG_DEBUG, "-- Transferer to PBX second channel (target): %s State %s\n", target->chan1->name, ast_state2str(target->chan1->_state));
12775       else
12776          ast_log(LOG_DEBUG, "-- No target first channel ---\n");
12777       if (transferer->chan2)
12778          ast_log(LOG_DEBUG, "-- Bridged call to transferee: %s State %s\n", transferer->chan2->name, ast_state2str(transferer->chan2->_state));
12779       else
12780          ast_log(LOG_DEBUG, "-- No bridged call to transferee\n");
12781       if (target->chan2)
12782          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)");
12783       else
12784          ast_log(LOG_DEBUG, "-- No target second channel ---\n");
12785       ast_log(LOG_DEBUG, "-- END Sip transfer:--------------------\n");
12786    }
12787    if (transferer->chan2) { /* We have a bridge on the transferer's channel */
12788       peera = transferer->chan1; /* Transferer - PBX -> transferee channel * the one we hangup */
12789       peerb = target->chan1;     /* Transferer - PBX -> target channel - This will get lost in masq */
12790       peerc = transferer->chan2; /* Asterisk to Transferee */
12791       peerd = target->chan2;     /* Asterisk to Target */
12792       if (option_debug > 2)
12793          ast_log(LOG_DEBUG, "SIP transfer: Four channels to handle\n");
12794    } else if (target->chan2) {   /* Transferer has no bridge (IVR), but transferee */
12795       peera = target->chan1;     /* Transferer to PBX -> target channel */
12796       peerb = transferer->chan1; /* Transferer to IVR*/
12797       peerc = target->chan2;     /* Asterisk to Target */
12798       peerd = transferer->chan2; /* Nothing */
12799       if (option_debug > 2)
12800          ast_log(LOG_DEBUG, "SIP transfer: Three channels to handle\n");
12801    }
12802 
12803    if (peera && peerb && peerc && (peerb != peerc)) {
12804       ast_quiet_chan(peera);     /* Stop generators */
12805       ast_quiet_chan(peerb);  
12806       ast_quiet_chan(peerc);
12807       if (peerd)
12808          ast_quiet_chan(peerd);
12809 
12810       /* Fix CDRs so they're attached to the remaining channel */
12811       if (peera->cdr && peerb->cdr)
12812          peerb->cdr = ast_cdr_append(peerb->cdr, peera->cdr);
12813       else if (peera->cdr) 
12814          peerb->cdr = peera->cdr;
12815       peera->cdr = NULL;
12816 
12817       if (peerb->cdr && peerc->cdr) 
12818          peerb->cdr = ast_cdr_append(peerb->cdr, peerc->cdr);
12819       else if (peerc->cdr)
12820          peerb->cdr = peerc->cdr;
12821       peerc->cdr = NULL;
12822    
12823       if (option_debug > 3)
12824          ast_log(LOG_DEBUG, "SIP transfer: trying to masquerade %s into %s\n", peerc->name, peerb->name);
12825       if (ast_channel_masquerade(peerb, peerc)) {
12826          ast_log(LOG_WARNING, "Failed to masquerade %s into %s\n", peerb->name, peerc->name);
12827          res = -1;
12828       } else
12829          ast_log(LOG_DEBUG, "SIP transfer: Succeeded to masquerade channels.\n");
12830       return res;
12831    } else {
12832       ast_log(LOG_NOTICE, "SIP Transfer attempted with no appropriate bridged calls to transfer\n");
12833       if (transferer->chan1)
12834          ast_softhangup_nolock(transferer->chan1, AST_SOFTHANGUP_DEV);
12835       if (target->chan1)
12836          ast_softhangup_nolock(target->chan1, AST_SOFTHANGUP_DEV);
12837       return -1;
12838    }
12839    return 0;
12840 }

static int auto_congest ( void *  nothing  )  [static]

Scheduled congestion on a call.

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

02750 {
02751    struct sip_pvt *p = nothing;
02752 
02753    ast_mutex_lock(&p->lock);
02754    p->initid = -1;
02755    if (p->owner) {
02756       /* XXX fails on possible deadlock */
02757       if (!ast_channel_trylock(p->owner)) {
02758          ast_log(LOG_NOTICE, "Auto-congesting %s\n", p->owner->name);
02759          append_history(p, "Cong", "Auto-congesting (timer)");
02760          ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
02761          ast_channel_unlock(p->owner);
02762       }
02763    }
02764    ast_mutex_unlock(&p->lock);
02765    return 0;
02766 }

static void build_callid_pvt ( struct sip_pvt pvt  )  [static]

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

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

04176 {
04177    char buf[33];
04178 
04179    const char *host = S_OR(pvt->fromdomain, ast_inet_ntoa(pvt->ourip));
04180    
04181    ast_string_field_build(pvt, callid, "%s@%s", generate_random_string(buf, sizeof(buf)), host);
04182 
04183 }

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

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

Referenced by transmit_register().

04187 {
04188    char buf[33];
04189 
04190    const char *host = S_OR(fromdomain, ast_inet_ntoa(ourip));
04191 
04192    ast_string_field_build(reg, callid, "%s@%s", generate_random_string(buf, sizeof(buf)), host);
04193 }

static void build_contact ( struct sip_pvt p  )  [static]

Build contact header - the contact header we send out.

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

06559 {
06560    /* Construct Contact: header */
06561    if (ourport != STANDARD_SIP_PORT)
06562       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);
06563    else
06564       ast_string_field_build(p, our_contact, "<sip:%s%s%s>", p->exten, ast_strlen_zero(p->exten) ? "" : "@", ast_inet_ntoa(p->ourip));
06565 }

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 15946 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, 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, LOG_WARNING, sip_peer::mailbox, sip_peer::maxcallbitrate, sip_peer::maxms, sip_peer::md5secret, sip_peer::mohinterpret, sip_peer::mohsuggest, ast_variable::name, ast_variable::next, option_debug, peerl, sip_peer::pickupgroup, sip_peer::prefs, reg_source_db(), sip_peer::regexten, sip_peer::rtpholdtimeout, sip_peer::rtpkeepalive, sip_peer::rtptimeout, 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.

15947 {
15948    struct sip_peer *peer = NULL;
15949    struct ast_ha *oldha = NULL;
15950    int obproxyfound=0;
15951    int found=0;
15952    int firstpass=1;
15953    int format=0;     /* Ama flags */
15954    time_t regseconds = 0;
15955    char *varname = NULL, *varval = NULL;
15956    struct ast_variable *tmpvar = NULL;
15957    struct ast_flags peerflags[2] = {{(0)}};
15958    struct ast_flags mask[2] = {{(0)}};
15959 
15960 
15961    if (!realtime)
15962       /* Note we do NOT use find_peer here, to avoid realtime recursion */
15963       /* We also use a case-sensitive comparison (unlike find_peer) so
15964          that case changes made to the peer name will be properly handled
15965          during reload
15966       */
15967       peer = ASTOBJ_CONTAINER_FIND_UNLINK_FULL(&peerl, name, name, 0, 0, strcmp);
15968 
15969    if (peer) {
15970       /* Already in the list, remove it and it will be added back (or FREE'd)  */
15971       found = 1;
15972       if (!(peer->objflags & ASTOBJ_FLAG_MARKED))
15973          firstpass = 0;
15974    } else {
15975       if (!(peer = ast_calloc(1, sizeof(*peer))))
15976          return NULL;
15977 
15978       if (realtime)
15979          rpeerobjs++;
15980       else
15981          speerobjs++;
15982       ASTOBJ_INIT(peer);
15983    }
15984    /* Note that our peer HAS had its reference count incrased */
15985    if (firstpass) {
15986       peer->lastmsgssent = -1;
15987       oldha = peer->ha;
15988       peer->ha = NULL;
15989       set_peer_defaults(peer);   /* Set peer defaults */
15990    }
15991    if (!found && name)
15992          ast_copy_string(peer->name, name, sizeof(peer->name));
15993 
15994    /* If we have channel variables, remove them (reload) */
15995    if (peer->chanvars) {
15996       ast_variables_destroy(peer->chanvars);
15997       peer->chanvars = NULL;
15998       /* XXX should unregister ? */
15999    }
16000    for (; v || ((v = alt) && !(alt=NULL)); v = v->next) {
16001       if (handle_common_options(&peerflags[0], &mask[0], v))
16002          continue;
16003       if (realtime && !strcasecmp(v->name, "regseconds")) {
16004          ast_get_time_t(v->value, &regseconds, 0, NULL);
16005       } else if (realtime && !strcasecmp(v->name, "ipaddr") && !ast_strlen_zero(v->value) ) {
16006          inet_aton(v->value, &(peer->addr.sin_addr));
16007       } else if (realtime && !strcasecmp(v->name, "name"))
16008          ast_copy_string(peer->name, v->value, sizeof(peer->name));
16009       else if (realtime && !strcasecmp(v->name, "fullcontact")) {
16010          ast_copy_string(peer->fullcontact, v->value, sizeof(peer->fullcontact));
16011          ast_set_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT);
16012       } else if (!strcasecmp(v->name, "secret")) 
16013          ast_copy_string(peer->secret, v->value, sizeof(peer->secret));
16014       else if (!strcasecmp(v->name, "md5secret")) 
16015          ast_copy_string(peer->md5secret, v->value, sizeof(peer->md5secret));
16016       else if (!strcasecmp(v->name, "auth"))
16017          peer->auth = add_realm_authentication(peer->auth, v->value, v->lineno);
16018       else if (!strcasecmp(v->name, "callerid")) {
16019          ast_callerid_split(v->value, peer->cid_name, sizeof(peer->cid_name), peer->cid_num, sizeof(peer->cid_num));
16020       } else if (!strcasecmp(v->name, "fullname")) {
16021          ast_copy_string(peer->cid_name, v->value, sizeof(peer->cid_name));
16022       } else if (!strcasecmp(v->name, "cid_number")) {
16023          ast_copy_string(peer->cid_num, v->value, sizeof(peer->cid_num));
16024       } else if (!strcasecmp(v->name, "context")) {
16025          ast_copy_string(peer->context, v->value, sizeof(peer->context));
16026       } else if (!strcasecmp(v->name, "subscribecontext")) {
16027          ast_copy_string(peer->subscribecontext, v->value, sizeof(peer->subscribecontext));
16028       } else if (!strcasecmp(v->name, "fromdomain")) {
16029          ast_copy_string(peer->fromdomain, v->value, sizeof(peer->fromdomain));
16030       } else if (!strcasecmp(v->name, "usereqphone")) {
16031          ast_set2_flag(&peer->flags[0], ast_true(v->value), SIP_USEREQPHONE);
16032       } else if (!strcasecmp(v->name, "fromuser")) {
16033          ast_copy_string(peer->fromuser, v->value, sizeof(peer->fromuser));
16034       } else if (!strcasecmp(v->name, "host") || !strcasecmp(v->name, "outboundproxy")) {
16035          if (!strcasecmp(v->value, "dynamic")) {
16036             if (!strcasecmp(v->name, "outboundproxy") || obproxyfound) {
16037                ast_log(LOG_WARNING, "You can't have a dynamic outbound proxy, you big silly head at line %d.\n", v->lineno);
16038             } else {
16039                /* They'll register with us */
16040                if (!found || !ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)) {
16041                   /* Initialize stuff if this is a new peer, or if it used to be
16042                    * non-dynamic before the reload. */
16043                   memset(&peer->addr.sin_addr, 0, 4);
16044                   if (peer->addr.sin_port) {
16045                      /* If we've already got a port, make it the default rather than absolute */
16046                      peer->defaddr.sin_port = peer->addr.sin_port;
16047                      peer->addr.sin_port = 0;
16048                   }
16049                }
16050                ast_set_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC);
16051             }
16052          } else {
16053             /* Non-dynamic.  Make sure we become that way if we're not */
16054             if (peer->expire > -1)
16055                ast_sched_del(sched, peer->expire);
16056             peer->expire = -1;
16057             ast_clear_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC);
16058             if (!obproxyfound || !strcasecmp(v->name, "outboundproxy")) {
16059                if (ast_get_ip_or_srv(&peer->addr, v->value, srvlookup ? "_sip._udp" : NULL)) {
16060                   ASTOBJ_UNREF(peer, sip_destroy_peer);
16061                   return NULL;
16062                }
16063             }
16064             if (!strcasecmp(v->name, "outboundproxy"))
16065                obproxyfound=1;
16066             else {
16067                ast_copy_string(peer->tohost, v->value, sizeof(peer->tohost));
16068                if (!peer->addr.sin_port)
16069                   peer->addr.sin_port = htons(STANDARD_SIP_PORT);
16070             }
16071          }
16072       } else if (!strcasecmp(v->name, "defaultip")) {
16073          if (ast_get_ip(&peer->defaddr, v->value)) {
16074             ASTOBJ_UNREF(peer, sip_destroy_peer);
16075             return NULL;
16076          }
16077       } else if (!strcasecmp(v->name, "permit") || !strcasecmp(v->name, "deny")) {
16078          peer->ha = ast_append_ha(v->name, v->value, peer->ha);
16079       } else if (!strcasecmp(v->name, "port")) {
16080          if (!realtime && ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC))
16081             peer->defaddr.sin_port = htons(atoi(v->value));
16082          else
16083             peer->addr.sin_port = htons(atoi(v->value));
16084       } else if (!strcasecmp(v->name, "callingpres")) {
16085          peer->callingpres = ast_parse_caller_presentation(v->value);
16086          if (peer->callingpres == -1)
16087             peer->callingpres = atoi(v->value);
16088       } else if (!strcasecmp(v->name, "username")) {
16089          ast_copy_string(peer->username, v->value, sizeof(peer->username));
16090       } else if (!strcasecmp(v->name, "language")) {
16091          ast_copy_string(peer->language, v->value, sizeof(peer->language));
16092       } else if (!strcasecmp(v->name, "regexten")) {
16093          ast_copy_string(peer->regexten, v->value, sizeof(peer->regexten));
16094       } else if (!strcasecmp(v->name, "call-limit") || !strcasecmp(v->name, "incominglimit")) {
16095          peer->call_limit = atoi(v->value);
16096          if (peer->call_limit < 0)
16097             peer->call_limit = 0;
16098       } else if (!strcasecmp(v->name, "amaflags")) {
16099          format = ast_cdr_amaflags2int(v->value);
16100          if (format < 0) {
16101             ast_log(LOG_WARNING, "Invalid AMA Flags for peer: %s at line %d\n", v->value, v->lineno);
16102          } else {
16103             peer->amaflags = format;
16104          }
16105       } else if (!strcasecmp(v->name, "accountcode")) {
16106          ast_copy_string(peer->accountcode, v->value, sizeof(peer->accountcode));
16107       } else if (!strcasecmp(v->name, "mohinterpret")
16108          || !strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) {
16109          ast_copy_string(peer->mohinterpret, v->value, sizeof(peer->mohinterpret));
16110       } else if (!strcasecmp(v->name, "mohsuggest")) {
16111          ast_copy_string(peer->mohsuggest, v->value, sizeof(peer->mohsuggest));
16112       } else if (!strcasecmp(v->name, "mailbox")) {
16113          ast_copy_string(peer->mailbox, v->value, sizeof(peer->mailbox));
16114       } else if (!strcasecmp(v->name, "subscribemwi")) {
16115          ast_set2_flag(&peer->flags[1], ast_true(v->value), SIP_PAGE2_SUBSCRIBEMWIONLY);
16116       } else if (!strcasecmp(v->name, "vmexten")) {
16117          ast_copy_string(peer->vmexten, v->value, sizeof(peer->vmexten));
16118       } else if (!strcasecmp(v->name, "callgroup")) {
16119          peer->callgroup = ast_get_group(v->value);
16120       } else if (!strcasecmp(v->name, "allowtransfer")) {
16121          peer->allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED;
16122       } else if (!strcasecmp(v->name, "pickupgroup")) {
16123          peer->pickupgroup = ast_get_group(v->value);
16124       } else if (!strcasecmp(v->name, "allow")) {
16125          ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1);
16126       } else if (!strcasecmp(v->name, "disallow")) {
16127          ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0);
16128       } else if (!strcasecmp(v->name, "autoframing")) {
16129          peer->autoframing = ast_true(v->value);
16130       } else if (!strcasecmp(v->name, "rtptimeout")) {
16131          if ((sscanf(v->value, "%d", &peer->rtptimeout) != 1) || (peer->rtptimeout < 0)) {
16132             ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d.  Using default.\n", v->value, v->lineno);
16133             peer->rtptimeout = global_rtptimeout;
16134          }
16135       } else if (!strcasecmp(v->name, "rtpholdtimeout")) {
16136          if ((sscanf(v->value, "%d", &peer->rtpholdtimeout) != 1) || (peer->rtpholdtimeout < 0)) {
16137             ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d.  Using default.\n", v->value, v->lineno);
16138             peer->rtpholdtimeout = global_rtpholdtimeout;
16139          }
16140       } else if (!strcasecmp(v->name, "rtpkeepalive")) {
16141          if ((sscanf(v->value, "%d", &peer->rtpkeepalive) != 1) || (peer->rtpkeepalive < 0)) {
16142             ast_log(LOG_WARNING, "'%s' is not a valid RTP keepalive time at line %d.  Using default.\n", v->value, v->lineno);
16143             peer->rtpkeepalive = global_rtpkeepalive;
16144          }
16145       } else if (!strcasecmp(v->name, "setvar")) {
16146          /* Set peer channel variable */
16147          varname = ast_strdupa(v->value);
16148          if ((varval = strchr(varname, '='))) {
16149             *varval++ = '\0';
16150             if ((tmpvar = ast_variable_new(varname, varval))) {
16151                tmpvar->next = peer->chanvars;
16152                peer->chanvars = tmpvar;
16153             }
16154          }
16155       } else if (!strcasecmp(v->name, "qualify")) {
16156          if (!strcasecmp(v->value, "no")) {
16157             peer->maxms = 0;
16158          } else if (!strcasecmp(v->value, "yes")) {
16159             peer->maxms = DEFAULT_MAXMS;
16160          } else if (sscanf(v->value, "%d", &peer->maxms) != 1) {
16161             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);
16162             peer->maxms = 0;
16163          }
16164       } else if (!strcasecmp(v->name, "maxcallbitrate")) {
16165          peer->maxcallbitrate = atoi(v->value);
16166          if (peer->maxcallbitrate < 0)
16167             peer->maxcallbitrate = default_maxcallbitrate;
16168       }
16169    }
16170    if (!ast_test_flag(&global_flags[1], SIP_PAGE2_IGNOREREGEXPIRE) && ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC) && realtime) {
16171       time_t nowtime = time(NULL);
16172 
16173       if ((nowtime - regseconds) > 0) {
16174          destroy_association(peer);
16175          memset(&peer->addr, 0, sizeof(peer->addr));
16176          if (option_debug)
16177             ast_log(LOG_DEBUG, "Bah, we're expired (%d/%d/%d)!\n", (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
16178       }
16179    }
16180    ast_copy_flags(&peer->flags[0], &peerflags[0], mask[0].flags);
16181    ast_copy_flags(&peer->flags[1], &peerflags[1], mask[1].flags);
16182    if (ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE))
16183       global_allowsubscribe = TRUE; /* No global ban any more */
16184    if (!found && ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC) && !ast_test_flag(&peer->flags[0], SIP_REALTIME))
16185       reg_source_db(peer);
16186    ASTOBJ_UNMARK(peer);
16187    ast_free_ha(oldha);
16188    return peer;
16189 }

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

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

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

11188 {
11189    char a1[256];
11190    char a2[256];
11191    char a1_hash[256];
11192    char a2_hash[256];
11193    char resp[256];
11194    char resp_hash[256];
11195    char uri[256];
11196    char cnonce[80];
11197    const char *username;
11198    const char *secret;
11199    const char *md5secret;
11200    struct sip_auth *auth = NULL; /* Realm authentication */
11201 
11202    if (!ast_strlen_zero(p->domain))
11203       ast_copy_string(uri, p->domain, sizeof(uri));
11204    else if (!ast_strlen_zero(p->uri))
11205       ast_copy_string(uri, p->uri, sizeof(uri));
11206    else
11207       snprintf(uri, sizeof(uri), "sip:%s@%s",p->username, ast_inet_ntoa(p->sa.sin_addr));
11208 
11209    snprintf(cnonce, sizeof(cnonce), "%08lx", ast_random());
11210 
11211    /* Check if we have separate auth credentials */
11212    if ((auth = find_realm_authentication(authl, p->realm))) {
11213       ast_log(LOG_WARNING, "use realm [%s] from peer [%s][%s]\n",
11214          auth->username, p->peername, p->username);
11215       username = auth->username;
11216       secret = auth->secret;
11217       md5secret = auth->md5secret;
11218       if (sipdebug)
11219          ast_log(LOG_DEBUG,"Using realm %s authentication for call %s\n", p->realm, p->callid);
11220    } else {
11221       /* No authentication, use peer or register= config */
11222       username = p->authname;
11223       secret =  p->peersecret;
11224       md5secret = p->peermd5secret;
11225    }
11226    if (ast_strlen_zero(username))   /* We have no authentication */
11227       return -1;
11228 
11229    /* Calculate SIP digest response */
11230    snprintf(a1,sizeof(a1),"%s:%s:%s", username, p->realm, secret);
11231    snprintf(a2,sizeof(a2),"%s:%s", sip_methods[method].text, uri);
11232    if (!ast_strlen_zero(md5secret))
11233       ast_copy_string(a1_hash, md5secret, sizeof(a1_hash));
11234    else
11235       ast_md5_hash(a1_hash,a1);
11236    ast_md5_hash(a2_hash,a2);
11237 
11238    p->noncecount++;
11239    if (!ast_strlen_zero(p->qop))
11240       snprintf(resp,sizeof(resp),"%s:%s:%08x:%s:%s:%s", a1_hash, p->nonce, p->noncecount, cnonce, "auth", a2_hash);
11241    else
11242       snprintf(resp,sizeof(resp),"%s:%s:%s", a1_hash, p->nonce, a2_hash);
11243    ast_md5_hash(resp_hash, resp);
11244    /* XXX We hard code our qop to "auth" for now.  XXX */
11245    if (!ast_strlen_zero(p->qop))
11246       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);
11247    else
11248       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);
11249 
11250    append_history(p, "AuthResp", "Auth response sent for %s in realm %s - nc %d", username, p->realm, p->noncecount);
11251 
11252    return 0;
11253 }

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

07934 {
07935    struct sip_route *thishop, *head, *tail;
07936    int start = 0;
07937    int len;
07938    const char *rr, *contact, *c;
07939 
07940    /* Once a persistant route is set, don't fool with it */
07941    if (p->route && p->route_persistant) {
07942       if (option_debug)
07943          ast_log(LOG_DEBUG, "build_route: Retaining previous route: <%s>\n", p->route->hop);
07944       return;
07945    }
07946 
07947    if (p->route) {
07948       free_old_route(p->route);
07949       p->route = NULL;
07950    }
07951    
07952    p->route_persistant = backwards;
07953    
07954    /* Build a tailq, then assign it to p->route when done.
07955     * If backwards, we add entries from the head so they end up
07956     * in reverse order. However, we do need to maintain a correct
07957     * tail pointer because the contact is always at the end.
07958     */
07959    head = NULL;
07960    tail = head;
07961    /* 1st we pass through all the hops in any Record-Route headers */
07962    for (;;) {
07963       /* Each Record-Route header */
07964       rr = __get_header(req, "Record-Route", &start);
07965       if (*rr == '\0')
07966          break;
07967       for (; (rr = strchr(rr, '<')) ; rr += len) { /* Each route entry */
07968          ++rr;
07969          len = strcspn(rr, ">") + 1;
07970          /* Make a struct route */
07971          if ((thishop = ast_malloc(sizeof(*thishop) + len))) {
07972             /* ast_calloc is not needed because all fields are initialized in this block */
07973             ast_copy_string(thishop->hop, rr, len);
07974             if (option_debug > 1)
07975                ast_log(LOG_DEBUG, "build_route: Record-Route hop: <%s>\n", thishop->hop);
07976             /* Link in */
07977             if (backwards) {
07978                /* Link in at head so they end up in reverse order */
07979                thishop->next = head;
07980                head = thishop;
07981                /* If this was the first then it'll be the tail */
07982                if (!tail)
07983                   tail = thishop;
07984             } else {
07985                thishop->next = NULL;
07986                /* Link in at the end */
07987                if (tail)
07988                   tail->next = thishop;
07989                else
07990                   head = thishop;
07991                tail = thishop;
07992             }
07993          }
07994       }
07995    }
07996 
07997    /* Only append the contact if we are dealing with a strict router */
07998    if (!head || (!ast_strlen_zero(head->hop) && strstr(head->hop,";lr") == NULL) ) {
07999       /* 2nd append the Contact: if there is one */
08000       /* Can be multiple Contact headers, comma separated values - we just take the first */
08001       contact = get_header(req, "Contact");
08002       if (!ast_strlen_zero(contact)) {
08003          if (option_debug > 1)
08004             ast_log(LOG_DEBUG, "build_route: Contact hop: %s\n", contact);
08005          /* Look for <: delimited address */
08006          c = strchr(contact, '<');
08007          if (c) {
08008             /* Take to > */
08009             ++c;
08010             len = strcspn(c, ">") + 1;
08011          } else {
08012             /* No <> - just take the lot */
08013             c = contact;
08014             len = strlen(contact) + 1;
08015          }
08016          if ((thishop = ast_malloc(sizeof(*thishop) + len))) {
08017             /* ast_calloc is not needed because all fields are initialized in this block */
08018             ast_copy_string(thishop->hop, c, len);
08019             thishop->next = NULL;
08020             /* Goes at the end */
08021             if (tail)
08022                tail->next = thishop;
08023             else
08024                head = thishop;
08025          }
08026       }
08027    }
08028 
08029    /* Store as new route */
08030    p->route = head;
08031 
08032    /* For debugging dump what we ended up with */
08033    if (sip_debug_test_pvt(p))
08034       list_route(p->route);
08035 }

static void build_rpid ( struct sip_pvt p  )  [static]

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

Definition at line 6568 of file chan_sip.c.

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

Referenced by initreqprep().

06569 {
06570    int send_pres_tags = TRUE;
06571    const char *privacy=NULL;
06572    const char *screen=NULL;
06573    char buf[256];
06574    const char *clid = default_callerid;
06575    const char *clin = NULL;
06576    const char *fromdomain;
06577 
06578    if (!ast_strlen_zero(p->rpid) || !ast_strlen_zero(p->rpid_from))  
06579       return;
06580 
06581    if (p->owner && p->owner->cid.cid_num)
06582       clid = p->owner->cid.cid_num;
06583    if (p->owner && p->owner->cid.cid_name)
06584       clin = p->owner->cid.cid_name;
06585    if (ast_strlen_zero(clin))
06586       clin = clid;
06587 
06588    switch (p->callingpres) {
06589    case AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED:
06590       privacy = "off";
06591       screen = "no";
06592       break;
06593    case AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN:
06594       privacy = "off";
06595       screen = "yes";
06596       break;
06597    case AST_PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN:
06598       privacy = "off";
06599       screen = "no";
06600       break;
06601    case AST_PRES_ALLOWED_NETWORK_NUMBER:
06602       privacy = "off";
06603       screen = "yes";
06604       break;
06605    case AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED:
06606       privacy = "full";
06607       screen = "no";
06608       break;
06609    case AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN:
06610       privacy = "full";
06611       screen = "yes";
06612       break;
06613    case AST_PRES_PROHIB_USER_NUMBER_FAILED_SCREEN:
06614       privacy = "full";
06615       screen = "no";
06616       break;
06617    case AST_PRES_PROHIB_NETWORK_NUMBER:
06618       privacy = "full";
06619       screen = "yes";
06620       break;
06621    case AST_PRES_NUMBER_NOT_AVAILABLE:
06622       send_pres_tags = FALSE;
06623       break;
06624    default:
06625       ast_log(LOG_WARNING, "Unsupported callingpres (%d)\n", p->callingpres);
06626       if ((p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED)
06627          privacy = "full";
06628       else
06629          privacy = "off";
06630       screen = "no";
06631       break;
06632    }
06633    
06634    fromdomain = S_OR(p->fromdomain, ast_inet_ntoa(p->ourip));
06635 
06636    snprintf(buf, sizeof(buf), "\"%s\" <sip:%s@%s>", clin, clid, fromdomain);
06637    if (send_pres_tags)
06638       snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), ";privacy=%s;screen=%s", privacy, screen);
06639    ast_string_field_set(p, rpid, buf);
06640 
06641    ast_string_field_build(p, rpid_from, "\"%s\" <sip:%s@%s>;tag=%s", clin,
06642                 S_OR(p->fromuser, clid),
06643                 fromdomain, p->tag);
06644 }

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

15768 {
15769    struct sip_user *user;
15770    int format;
15771    struct ast_ha *oldha = NULL;
15772    char *varname = NULL, *varval = NULL;
15773    struct ast_variable *tmpvar = NULL;
15774    struct ast_flags userflags[2] = {{(0)}};
15775    struct ast_flags mask[2] = {{(0)}};
15776 
15777 
15778    if (!(user = ast_calloc(1, sizeof(*user))))
15779       return NULL;
15780       
15781    suserobjs++;
15782    ASTOBJ_INIT(user);
15783    ast_copy_string(user->name, name, sizeof(user->name));
15784    oldha = user->ha;
15785    user->ha = NULL;
15786    ast_copy_flags(&user->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY);
15787    ast_copy_flags(&user->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY);
15788    user->capability = global_capability;
15789    user->allowtransfer = global_allowtransfer;
15790    user->maxcallbitrate = default_maxcallbitrate;
15791    user->autoframing = global_autoframing;
15792    user->prefs = default_prefs;
15793    /* set default context */
15794    strcpy(user->context, default_context);
15795    strcpy(user->language, default_language);
15796    strcpy(user->mohinterpret, default_mohinterpret);
15797    strcpy(user->mohsuggest, default_mohsuggest);
15798    for (; v; v = v->next) {
15799       if (handle_common_options(&userflags[0], &mask[0], v))
15800          continue;
15801 
15802       if (!strcasecmp(v->name, "context")) {
15803          ast_copy_string(user->context, v->value, sizeof(user->context));
15804       } else if (!strcasecmp(v->name, "subscribecontext")) {
15805          ast_copy_string(user->subscribecontext, v->value, sizeof(user->subscribecontext));
15806       } else if (!strcasecmp(v->name, "setvar")) {
15807          varname = ast_strdupa(v->value);
15808          if ((varval = strchr(varname,'='))) {
15809             *varval++ = '\0';
15810             if ((tmpvar = ast_variable_new(varname, varval))) {
15811                tmpvar->next = user->chanvars;
15812                user->chanvars = tmpvar;
15813             }
15814          }
15815       } else if (!strcasecmp(v->name, "permit") ||
15816                !strcasecmp(v->name, "deny")) {
15817          user->ha = ast_append_ha(v->name, v->value, user->ha);
15818       } else if (!strcasecmp(v->name, "allowtransfer")) {
15819          user->allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED;
15820       } else if (!strcasecmp(v->name, "secret")) {
15821          ast_copy_string(user->secret, v->value, sizeof(user->secret)); 
15822       } else if (!strcasecmp(v->name, "md5secret")) {
15823          ast_copy_string(user->md5secret, v->value, sizeof(user->md5secret));
15824       } else if (!strcasecmp(v->name, "callerid")) {
15825          ast_callerid_split(v->value, user->cid_name, sizeof(user->cid_name), user->cid_num, sizeof(user->cid_num));
15826       } else if (!strcasecmp(v->name, "fullname")) {
15827          ast_copy_string(user->cid_name, v->value, sizeof(user->cid_name));
15828       } else if (!strcasecmp(v->name, "cid_number")) {
15829          ast_copy_string(user->cid_num, v->value, sizeof(user->cid_num));
15830       } else if (!strcasecmp(v->name, "callgroup")) {
15831          user->callgroup = ast_get_group(v->value);
15832       } else if (!strcasecmp(v->name, "pickupgroup")) {
15833          user->pickupgroup = ast_get_group(v->value);
15834       } else if (!strcasecmp(v->name, "language")) {
15835          ast_copy_string(user->language, v->value, sizeof(user->language));
15836       } else if (!strcasecmp(v->name, "mohinterpret") 
15837          || !strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) {
15838          ast_copy_string(user->mohinterpret, v->value, sizeof(user->mohinterpret));
15839       } else if (!strcasecmp(v->name, "mohsuggest")) {
15840          ast_copy_string(user->mohsuggest, v->value, sizeof(user->mohsuggest));
15841       } else if (!strcasecmp(v->name, "accountcode")) {
15842          ast_copy_string(user->accountcode, v->value, sizeof(user->accountcode));
15843       } else if (!strcasecmp(v->name, "call-limit")) {
15844          user->call_limit = atoi(v->value);
15845          if (user->call_limit < 0)
15846             user->call_limit = 0;
15847       } else if (!strcasecmp(v->name, "amaflags")) {
15848          format = ast_cdr_amaflags2int(v->value);
15849          if (format < 0) {
15850             ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
15851          } else {
15852             user->amaflags = format;
15853          }
15854       } else if (!strcasecmp(v->name, "allow")) {
15855          ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1);
15856       } else if (!strcasecmp(v->name, "disallow")) {
15857          ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 0);
15858       } else if (!strcasecmp(v->name, "autoframing")) {
15859          user->autoframing = ast_true(v->value);
15860       } else if (!strcasecmp(v->name, "callingpres")) {
15861          user->callingpres = ast_parse_caller_presentation(v->value);
15862          if (user->callingpres == -1)
15863             user->callingpres = atoi(v->value);
15864       } else if (!strcasecmp(v->name, "maxcallbitrate")) {
15865          user->maxcallbitrate = atoi(v->value);
15866          if (user->maxcallbitrate < 0)
15867             user->maxcallbitrate = default_maxcallbitrate;
15868       }
15869       /* We can't just report unknown options here because this may be a
15870        * type=friend entry.  All user options are valid for a peer, but not
15871        * the other way around.  */
15872    }
15873    ast_copy_flags(&user->flags[0], &userflags[0], mask[0].flags);
15874    ast_copy_flags(&user->flags[1], &userflags[1], mask[1].flags);
15875    if (ast_test_flag(&user->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE))
15876       global_allowsubscribe = TRUE; /* No global ban any more */
15877    ast_free_ha(oldha);
15878    return user;
15879 }

static void build_via ( struct sip_pvt p  )  [static]

Build a Via header for a request.

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

01761 {
01762    /* Work around buggy UNIDEN UIP200 firmware */
01763    const char *rport = ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_RFC3581 ? ";rport" : "";
01764 
01765    /* z9hG4bK is a magic cookie.  See RFC 3261 section 8.1.1.7 */
01766    ast_string_field_build(p, via, "SIP/2.0/UDP %s:%d;branch=z9hG4bK%08x%s",
01767           ast_inet_ntoa(p->ourip), ourport, p->branch, rport);
01768 }

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

References append_history, AST_EXTENSION_DEACTIVATED, AST_EXTENSION_REMOVED, ast_extension_state2str(), ast_verbose(), sip_pvt::autokillid, DEFAULT_TRANS_TIMEOUT, FALSE, sip_pvt::laststate, 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().

08226 {
08227    struct sip_pvt *p = data;
08228 
08229    switch(state) {
08230    case AST_EXTENSION_DEACTIVATED:  /* Retry after a while */
08231    case AST_EXTENSION_REMOVED:   /* Extension is gone */
08232       if (p->autokillid > -1)
08233          sip_cancel_destroy(p);  /* Remove subscription expiry for renewals */
08234       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);  /* Delete subscription in 32 secs */
08235       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);
08236       p->stateid = -1;
08237       p->subscribed = NONE;
08238       append_history(p, "Subscribestatus", "%s", state == AST_EXTENSION_REMOVED ? "HintRemoved" : "Deactivated");
08239       break;
08240    default: /* Tell user */
08241       p->laststate = state;
08242       break;
08243    }
08244    if (p->subscribed != NONE) /* Only send state NOTIFY if we know the format */
08245       transmit_state_notify(p, state, 1, FALSE);
08246 
08247    if (option_verbose > 1)
08248       ast_verbose(VERBOSE_PREFIX_1 "Extension Changed %s new state %s for Notify User %s\n", exten, ast_extension_state2str(state), p->username);
08249    return 0;
08250 }

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

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

Referenced by check_user_full(), and register_verify().

08046 {
08047    const char *response = "407 Proxy Authentication Required";
08048    const char *reqheader = "Proxy-Authorization";
08049    const char *respheader = "Proxy-Authenticate";
08050    const char *authtoken;
08051    char a1_hash[256];
08052    char resp_hash[256]="";
08053    char tmp[BUFSIZ * 2];                /* Make a large enough buffer */
08054    char *c;
08055    int  wrongnonce = FALSE;
08056    int  good_response;
08057    const char *usednonce = p->randdata;
08058 
08059    /* table of recognised keywords, and their value in the digest */
08060    enum keys { K_RESP, K_URI, K_USER, K_NONCE, K_LAST };
08061    struct x {
08062       const char *key;
08063       const char *s;
08064    } *i, keys[] = {
08065       [K_RESP] = { "response=", "" },
08066       [K_URI] = { "uri=", "" },
08067       [K_USER] = { "username=", "" },
08068       [K_NONCE] = { "nonce=", "" },
08069       [K_LAST] = { NULL, NULL}
08070    };
08071 
08072    /* Always OK if no secret */
08073    if (ast_strlen_zero(secret) && ast_strlen_zero(md5secret))
08074       return AUTH_SUCCESSFUL;
08075    if (sipmethod == SIP_REGISTER || sipmethod == SIP_SUBSCRIBE) {
08076       /* On a REGISTER, we have to use 401 and its family of headers instead of 407 and its family
08077          of headers -- GO SIP!  Whoo hoo!  Two things that do the same thing but are used in
08078          different circumstances! What a surprise. */
08079       response = "401 Unauthorized";
08080       reqheader = "Authorization";
08081       respheader = "WWW-Authenticate";
08082    }
08083    authtoken =  get_header(req, reqheader);  
08084    if (ignore && !ast_strlen_zero(p->randdata) && ast_strlen_zero(authtoken)) {
08085       /* This is a retransmitted invite/register/etc, don't reconstruct authentication
08086          information */
08087       if (!reliable) {
08088          /* Resend message if this was NOT a reliable delivery.   Otherwise the
08089             retransmission should get it */
08090          transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0);
08091          /* Schedule auto destroy in 32 seconds (according to RFC 3261) */
08092          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
08093       }
08094       return AUTH_CHALLENGE_SENT;
08095    } else if (ast_strlen_zero(p->randdata) || ast_strlen_zero(authtoken)) {
08096       /* We have no auth, so issue challenge and request authentication */
08097       ast_string_field_build(p, randdata, "%08lx", ast_random()); /* Create nonce for challenge */
08098       transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0);
08099       /* Schedule auto destroy in 32 seconds */
08100       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
08101       return AUTH_CHALLENGE_SENT;
08102    } 
08103 
08104    /* --- We have auth, so check it */
08105 
08106    /* Whoever came up with the authentication section of SIP can suck my %&#$&* for not putting
08107          an example in the spec of just what it is you're doing a hash on. */
08108 
08109 
08110    /* Make a copy of the response and parse it */
08111    ast_copy_string(tmp, authtoken, sizeof(tmp));
08112    c = tmp;
08113 
08114    while(c && *(c = ast_skip_blanks(c)) ) { /* lookup for keys */
08115       for (i = keys; i->key != NULL; i++) {
08116          const char *separator = ",";  /* default */
08117 
08118          if (strncasecmp(c, i->key, strlen(i->key)) != 0)
08119             continue;
08120          /* Found. Skip keyword, take text in quotes or up to the separator. */
08121          c += strlen(i->key);
08122          if (*c == '"') { /* in quotes. Skip first and look for last */
08123             c++;
08124             separator = "\"";
08125          }
08126          i->s = c;
08127          strsep(&c, separator);
08128          break;
08129       }
08130       if (i->key == NULL) /* not found, jump after space or comma */
08131          strsep(&c, " ,");
08132    }
08133 
08134    /* Verify that digest username matches  the username we auth as */
08135    if (strcmp(username, keys[K_USER].s)) {
08136       ast_log(LOG_WARNING, "username mismatch, have <%s>, digest has <%s>\n",
08137          username, keys[K_USER].s);
08138       /* Oops, we're trying something here */
08139       return AUTH_USERNAME_MISMATCH;
08140    }
08141 
08142    /* Verify nonce from request matches our nonce.  If not, send 401 with new nonce */
08143    if (strcasecmp(p->randdata, keys[K_NONCE].s)) { /* XXX it was 'n'casecmp ? */
08144       wrongnonce = TRUE;
08145       usednonce = keys[K_NONCE].s;
08146    }
08147 
08148    if (!ast_strlen_zero(md5secret))
08149       ast_copy_string(a1_hash, md5secret, sizeof(a1_hash));
08150    else {
08151       char a1[256];
08152       snprintf(a1, sizeof(a1), "%s:%s:%s", username, global_realm, secret);
08153       ast_md5_hash(a1_hash, a1);
08154    }
08155 
08156    /* compute the expected response to compare with what we received */
08157    {
08158       char a2[256];
08159       char a2_hash[256];
08160       char resp[256];
08161 
08162       snprintf(a2, sizeof(a2), "%s:%s", sip_methods[sipmethod].text,
08163             S_OR(keys[K_URI].s, uri));
08164       ast_md5_hash(a2_hash, a2);
08165       snprintf(resp, sizeof(resp), "%s:%s:%s", a1_hash, usednonce, a2_hash);
08166       ast_md5_hash(resp_hash, resp);
08167    }
08168 
08169    good_response = keys[K_RESP].s &&
08170          !strncasecmp(keys[K_RESP].s, resp_hash, strlen(resp_hash));
08171    if (wrongnonce) {
08172       ast_string_field_build(p, randdata, "%08lx", ast_random());
08173       if (good_response) {
08174          if (sipdebug)
08175             ast_log(LOG_NOTICE, "Correct auth, but based on stale nonce received from '%s'\n", get_header(req, "To"));
08176          /* We got working auth token, based on stale nonce . */
08177          transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, TRUE);
08178       } else {
08179          /* Everything was wrong, so give the device one more try with a new challenge */
08180          if (sipdebug)
08181             ast_log(LOG_NOTICE, "Bad authentication received from '%s'\n", get_header(req, "To"));
08182          transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, FALSE);
08183       }
08184 
08185       /* Schedule auto destroy in 32 seconds */
08186       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
08187       return AUTH_CHALLENGE_SENT;
08188    } 
08189    if (good_response) {
08190       append_history(p, "AuthOK", "Auth challenge succesful for %s", username);
08191       return AUTH_SUCCESSFUL;
08192    }
08193 
08194    /* Ok, we have a bad username/secret pair */
08195    /* Challenge again, and again, and again */
08196    transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0);
08197    sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
08198 
08199    return AUTH_CHALLENGE_SENT;
08200 }

static void check_pendings ( struct sip_pvt p  )  [static]

Check pending actions on SIP call.

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

11642 {
11643    if (ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) {
11644       /* if we can't BYE, then this is really a pending CANCEL */
11645       if (p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA)
11646          transmit_request(p, SIP_CANCEL, p->ocseq, XMIT_RELIABLE, FALSE);
11647          /* Actually don't destroy us yet, wait for the 487 on our original 
11648             INVITE, but do set an autodestruct just in case we never get it. */
11649       else 
11650          transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, TRUE);
11651       ast_clear_flag(&p->flags[0], SIP_PENDINGBYE);   
11652       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
11653    } else if (ast_test_flag(&p->flags[0], SIP_NEEDREINVITE)) {
11654       if (option_debug)
11655          ast_log(LOG_DEBUG, "Sending pending reinvite on '%s'\n", p->callid);
11656       /* Didn't get to reinvite yet, so do it now */
11657       transmit_reinvite_with_sdp(p);
11658       ast_clear_flag(&p->flags[0], SIP_NEEDREINVITE); 
11659    }
11660 }

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

15647 {
15648    struct domain *d;
15649    int result = 0;
15650 
15651    AST_LIST_LOCK(&domain_list);
15652    AST_LIST_TRAVERSE(&domain_list, d, list) {
15653       if (strcasecmp(d->domain, domain))
15654          continue;
15655 
15656       if (len && !ast_strlen_zero(d->context))
15657          ast_copy_string(context, d->context, len);
15658       
15659       result = 1;
15660       break;
15661    }
15662    AST_LIST_UNLOCK(&domain_list);
15663 
15664    return result;
15665 }

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

References check_user_full().

Referenced by handle_request_invite().

09298 {
09299    return check_user_full(p, req, sipmethod, uri, reliable, sin, NULL);
09300 }

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

08986 {
08987    struct sip_user *user = NULL;
08988    struct sip_peer *peer;
08989    char from[256], *c;
08990    char *of;
08991    char rpid_num[50];
08992    const char *rpid;
08993    enum check_auth_result res = AUTH_SUCCESSFUL;
08994    char *t;
08995    char calleridname[50];
08996    int debug=sip_debug_test_addr(sin);
08997    struct ast_variable *tmpvar = NULL, *v = NULL;
08998    char *uri2 = ast_strdupa(uri);
08999 
09000    /* Terminate URI */
09001    t = uri2;
09002    while (*t && *t > 32 && *t != ';')
09003       t++;
09004    *t = '\0';
09005    ast_copy_string(from, get_header(req, "From"), sizeof(from));  /* XXX bug in original code, overwrote string */
09006    if (pedanticsipchecking)
09007       ast_uri_decode(from);
09008    /* XXX here tries to map the username for invite things */
09009    memset(calleridname, 0, sizeof(calleridname));
09010    get_calleridname(from, calleridname, sizeof(calleridname));
09011    if (calleridname[0])
09012       ast_string_field_set(p, cid_name, calleridname);
09013 
09014    rpid = get_header(req, "Remote-Party-ID");
09015    memset(rpid_num, 0, sizeof(rpid_num));
09016    if (!ast_strlen_zero(rpid)) 
09017       p->callingpres = get_rpid_num(rpid, rpid_num, sizeof(rpid_num));
09018 
09019    of = get_in_brackets(from);
09020    if (ast_strlen_zero(p->exten)) {
09021       t = uri2;
09022       if (!strncmp(t, "sip:", 4))
09023          t+= 4;
09024       ast_string_field_set(p, exten, t);
09025       t = strchr(p->exten, '@');
09026       if (t)
09027          *t = '\0';
09028       if (ast_strlen_zero(p->our_contact))
09029          build_contact(p);
09030    }
09031    /* save the URI part of the From header */
09032    ast_string_field_set(p, from, of);
09033    if (strncmp(of, "sip:", 4)) {
09034       ast_log(LOG_NOTICE, "From address missing 'sip:', using it anyway\n");
09035    } else
09036       of += 4;
09037    /* Get just the username part */
09038    if ((c = strchr(of, '@'))) {
09039       char *tmp;
09040       *c = '\0';
09041       if ((c = strchr(of, ':')))
09042          *c = '\0';
09043       tmp = ast_strdupa(of);
09044       /* We need to be able to handle auth-headers looking like
09045          <sip:8164444422;phone-context=+1@1.2.3.4:5060;user=phone;tag=SDadkoa01-gK0c3bdb43>
09046       */
09047       tmp = strsep(&tmp, ";");
09048       if (ast_is_shrinkable_phonenumber(tmp))
09049          ast_shrink_phone_number(tmp);
09050       ast_string_field_set(p, cid_num, tmp);
09051    }
09052    if (ast_strlen_zero(of))
09053       return AUTH_SUCCESSFUL;
09054 
09055    if (!authpeer) /* If we are looking for a peer, don't check the user objects (or realtime) */
09056       user = find_user(of, 1);
09057 
09058    /* Find user based on user name in the from header */
09059    if (user && ast_apply_ha(user->ha, sin)) {
09060       ast_copy_flags(&p->flags[0], &user->flags[0], SIP_FLAGS_TO_COPY);
09061       ast_copy_flags(&p->flags[1], &user->flags[1], SIP_PAGE2_FLAGS_TO_COPY);
09062       /* copy channel vars */
09063       for (v = user->chanvars ; v ; v = v->next) {
09064          if ((tmpvar = ast_variable_new(v->name, v->value))) {
09065             tmpvar->next = p->chanvars; 
09066             p->chanvars = tmpvar;
09067          }
09068       }
09069       p->prefs = user->prefs;
09070       /* Set Frame packetization */
09071       if (p->rtp) {
09072          ast_rtp_codec_setpref(p->rtp, &p->prefs);
09073          p->autoframing = user->autoframing;
09074       }
09075       /* replace callerid if rpid found, and not restricted */
09076       if (!ast_strlen_zero(rpid_num) && ast_test_flag(&p->flags[0], SIP_TRUSTRPID)) {
09077          char *tmp;
09078          if (*calleridname)
09079             ast_string_field_set(p, cid_name, calleridname);
09080          tmp = ast_strdupa(rpid_num);
09081          if (ast_is_shrinkable_phonenumber(tmp))
09082             ast_shrink_phone_number(tmp);
09083          ast_string_field_set(p, cid_num, tmp);
09084       }
09085       
09086       do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT_ROUTE) );
09087 
09088       if (!(res = check_auth(p, req, user->name, user->secret, user->md5secret, sipmethod, uri2, reliable, ast_test_flag(req, SIP_PKT_IGNORE)))) {
09089          sip_cancel_destroy(p);
09090          ast_copy_flags(&p->flags[0], &user->flags[0], SIP_FLAGS_TO_COPY);
09091          ast_copy_flags(&p->flags[1], &user->flags[1], SIP_PAGE2_FLAGS_TO_COPY);
09092          /* Copy SIP extensions profile from INVITE */
09093          if (p->sipoptions)
09094             user->sipoptions = p->sipoptions;
09095 
09096          /* If we have a call limit, set flag */
09097          if (user->call_limit)
09098             ast_set_flag(&p->flags[0], SIP_CALL_LIMIT);
09099          if (!ast_strlen_zero(user->context))
09100             ast_string_field_set(p, context, user->context);
09101          if (!ast_strlen_zero(user->cid_num) && !ast_strlen_zero(p->cid_num)) {
09102             char *tmp = ast_strdupa(user->cid_num);
09103             if (ast_is_shrinkable_phonenumber(tmp))
09104                ast_shrink_phone_number(tmp);
09105             ast_string_field_set(p, cid_num, tmp);
09106          }
09107          if (!ast_strlen_zero(user->cid_name) && !ast_strlen_zero(p->cid_num))
09108             ast_string_field_set(p, cid_name, user->cid_name);
09109          ast_string_field_set(p, username, user->name);
09110          ast_string_field_set(p, peername, user->name);
09111          ast_string_field_set(p, peersecret, user->secret);
09112          ast_string_field_set(p, peermd5secret, user->md5secret);
09113          ast_string_field_set(p, subscribecontext, user->subscribecontext);
09114          ast_string_field_set(p, accountcode, user->accountcode);
09115          ast_string_field_set(p, language, user->language);
09116          ast_string_field_set(p, mohsuggest, user->mohsuggest);
09117          ast_string_field_set(p, mohinterpret, user->mohinterpret);
09118          p->allowtransfer = user->allowtransfer;
09119          p->amaflags = user->amaflags;
09120          p->callgroup = user->callgroup;
09121          p->pickupgroup = user->pickupgroup;
09122          if (user->callingpres)  /* User callingpres setting will override RPID header */
09123             p->callingpres = user->callingpres;
09124          
09125          /* Set default codec settings for this call */
09126          p->capability = user->capability;      /* User codec choice */
09127          p->jointcapability = user->capability;    /* Our codecs */
09128          if (p->peercapability)           /* AND with peer's codecs */
09129             p->jointcapability &= p->peercapability;
09130          if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) ||
09131              (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO))
09132             p->noncodeccapability |= AST_RTP_DTMF;
09133          else
09134             p->noncodeccapability &= ~AST_RTP_DTMF;
09135          p->jointnoncodeccapability = p->noncodeccapability;
09136          if (p->t38.peercapability)
09137             p->t38.jointcapability &= p->t38.peercapability;
09138          p->maxcallbitrate = user->maxcallbitrate;
09139          /* If we do not support video, remove video from call structure */
09140          if ((!ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) || !(p->capability & AST_FORMAT_VIDEO_MASK)) && p->vrtp) {
09141             ast_rtp_destroy(p->vrtp);
09142             p->vrtp = NULL;
09143          }
09144       }
09145       if (user && debug)
09146          ast_verbose("Found user '%s'\n", user->name);
09147    } else {
09148       if (user) {
09149          if (!authpeer && debug)
09150             ast_verbose("Found user '%s', but fails host access\n", user->name);
09151          ASTOBJ_UNREF(user,sip_destroy_user);
09152       }
09153       user = NULL;
09154    }
09155 
09156    if (!user) {
09157       /* If we didn't find a user match, check for peers */
09158       if (sipmethod == SIP_SUBSCRIBE)
09159          /* For subscribes, match on peer name only */
09160          peer = find_peer(of, NULL, 1);
09161       else
09162          /* Look for peer based on the IP address we received data from */
09163          /* If peer is registered from this IP address or have this as a default
09164             IP address, this call is from the peer 
09165          */
09166          peer = find_peer(NULL, &p->recv, 1);
09167 
09168       if (peer) {
09169          /* Set Frame packetization */
09170          if (p->rtp) {
09171             ast_rtp_codec_setpref(p->rtp, &peer->prefs);
09172             p->autoframing = peer->autoframing;
09173          }
09174          if (debug)
09175             ast_verbose("Found peer '%s'\n", peer->name);
09176 
09177          /* Take the peer */
09178          ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY);
09179          ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY);
09180 
09181          /* Copy SIP extensions profile to peer */
09182          if (p->sipoptions)
09183             peer->sipoptions = p->sipoptions;
09184 
09185          /* replace callerid if rpid found, and not restricted */
09186          if (!ast_strlen_zero(rpid_num) && ast_test_flag(&p->flags[0], SIP_TRUSTRPID)) {
09187             char *tmp = ast_strdupa(rpid_num);
09188             if (*calleridname)
09189                ast_string_field_set(p, cid_name, calleridname);
09190             if (ast_is_shrinkable_phonenumber(tmp))
09191                ast_shrink_phone_number(tmp);
09192             ast_string_field_set(p, cid_num, tmp);
09193          }
09194          do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT_ROUTE));
09195 
09196          ast_string_field_set(p, peersecret, peer->secret);
09197          ast_string_field_set(p, peermd5secret, peer->md5secret);
09198          ast_string_field_set(p, subscribecontext, peer->subscribecontext);
09199          ast_string_field_set(p, mohinterpret, peer->mohinterpret);
09200          ast_string_field_set(p, mohsuggest, peer->mohsuggest);
09201          if (peer->callingpres)  /* Peer calling pres setting will override RPID */
09202             p->callingpres = peer->callingpres;
09203          if (peer->maxms && peer->lastms)
09204             p->timer_t1 = peer->lastms;
09205          if (ast_test_flag(&peer->flags[0], SIP_INSECURE_INVITE)) {
09206             /* Pretend there is no required authentication */
09207             ast_string_field_free(p, peersecret);
09208             ast_string_field_free(p, peermd5secret);
09209          }
09210          if (!(res = check_auth(p, req, peer->name, p->peersecret, p->peermd5secret, sipmethod, uri2, reliable, ast_test_flag(req, SIP_PKT_IGNORE)))) {
09211             ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY);
09212             ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY);
09213             /* If we have a call limit, set flag */
09214             if (peer->call_limit)
09215                ast_set_flag(&p->flags[0], SIP_CALL_LIMIT);
09216             ast_string_field_set(p, peername, peer->name);
09217             ast_string_field_set(p, authname, peer->name);
09218 
09219             /* copy channel vars */
09220             for (v = peer->chanvars ; v ; v = v->next) {
09221                if ((tmpvar = ast_variable_new(v->name, v->value))) {
09222                   tmpvar->next = p->chanvars; 
09223                   p->chanvars = tmpvar;
09224                }
09225             }
09226             if (authpeer) {
09227                (*authpeer) = ASTOBJ_REF(peer);  /* Add a ref to the object here, to keep it in memory a bit longer if it is realtime */
09228             }
09229 
09230             if (!ast_strlen_zero(peer->username)) {
09231                ast_string_field_set(p, username, peer->username);
09232                /* Use the default username for authentication on outbound calls */
09233                /* XXX this takes the name from the caller... can we override ? */
09234                ast_string_field_set(p, authname, peer->username);
09235             }
09236             if (!ast_strlen_zero(peer->cid_num) && !ast_strlen_zero(p->cid_num)) {
09237                char *tmp = ast_strdupa(peer->cid_num);
09238                if (ast_is_shrinkable_phonenumber(tmp))
09239                   ast_shrink_phone_number(tmp);
09240                ast_string_field_set(p, cid_num, tmp);
09241             }
09242             if (!ast_strlen_zero(peer->cid_name) && !ast_strlen_zero(p->cid_name)) 
09243                ast_string_field_set(p, cid_name, peer->cid_name);
09244             ast_string_field_set(p, fullcontact, peer->fullcontact);
09245             if (!ast_strlen_zero(peer->context))
09246                ast_string_field_set(p, context, peer->context);
09247             ast_string_field_set(p, peersecret, peer->secret);
09248             ast_string_field_set(p, peermd5secret, peer->md5secret);
09249             ast_string_field_set(p, language, peer->language);
09250             ast_string_field_set(p, accountcode, peer->accountcode);
09251             p->amaflags = peer->amaflags;
09252             p->callgroup = peer->callgroup;
09253             p->pickupgroup = peer->pickupgroup;
09254             p->capability = peer->capability;
09255             p->prefs = peer->prefs;
09256             p->jointcapability = peer->capability;
09257             if (p->peercapability)
09258                p->jointcapability &= p->peercapability;
09259             p->maxcallbitrate = peer->maxcallbitrate;
09260             if ((!ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) || !(p->capability & AST_FORMAT_VIDEO_MASK)) && p->vrtp) {
09261                ast_rtp_destroy(p->vrtp);
09262                p->vrtp = NULL;
09263             }
09264             if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) ||
09265                 (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO))
09266                p->noncodeccapability |= AST_RTP_DTMF;
09267             else
09268                p->noncodeccapability &= ~AST_RTP_DTMF;
09269             p->jointnoncodeccapability = p->noncodeccapability;
09270             if (p->t38.peercapability)
09271                p->t38.jointcapability &= p->t38.peercapability;
09272          }
09273          ASTOBJ_UNREF(peer, sip_destroy_peer);
09274       } else { 
09275          if (debug)
09276             ast_verbose("Found no matching peer or user for '%s:%d'\n", ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port));
09277 
09278          /* do we allow guests? */
09279          if (!global_allowguest) {
09280             if (global_alwaysauthreject)
09281                res = AUTH_FAKE_AUTH; /* reject with fake authorization request */
09282             else
09283                res = AUTH_SECRET_FAILED; /* we don't want any guests, authentication will fail */
09284          }
09285       }
09286 
09287    }
09288 
09289    if (user)
09290       ASTOBJ_UNREF(user, sip_destroy_user);
09291    return res;
09292 }

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 8851 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, LOG_WARNING, sip_pvt::sa, sip_debug_test_pvt(), sip_nat_mode(), SIP_NAT_ROUTE, sip_real_dst(), and STANDARD_SIP_PORT.

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

08852 {
08853    char via[256];
08854    char *c, *pt;
08855    struct hostent *hp;
08856    struct ast_hostent ahp;
08857 
08858    ast_copy_string(via, get_header(req, "Via"), sizeof(via));
08859 
08860    /* Work on the leftmost value of the topmost Via header */
08861    c = strchr(via, ',');
08862    if (c)
08863       *c = '\0';
08864 
08865    /* Check for rport */
08866    c = strstr(via, ";rport");
08867    if (c && (c[6] != '=')) /* rport query, not answer */
08868       ast_set_flag(&p->flags[0], SIP_NAT_ROUTE);
08869 
08870    c = strchr(via, ';');
08871    if (c) 
08872       *c = '\0';
08873 
08874    c = strchr(via, ' ');
08875    if (c) {
08876       *c = '\0';
08877       c = ast_skip_blanks(c+1);
08878       if (strcasecmp(via, "SIP/2.0/UDP")) {
08879          ast_log(LOG_WARNING, "Don't know how to respond via '%s'\n", via);
08880          return;
08881       }
08882       pt = strchr(c, ':');
08883       if (pt)
08884          *pt++ = '\0';  /* remember port pointer */
08885       hp = ast_gethostbyname(c, &ahp);
08886       if (!hp) {
08887          ast_log(LOG_WARNING, "'%s' is not a valid host\n", c);
08888          return;
08889       }
08890       memset(&p->sa, 0, sizeof(p->sa));
08891       p->sa.sin_family = AF_INET;
08892       memcpy(&p->sa.sin_addr, hp->h_addr, sizeof(p->sa.sin_addr));
08893       p->sa.sin_port = htons(pt ? atoi(pt) : STANDARD_SIP_PORT);
08894 
08895       if (sip_debug_test_pvt(p)) {
08896          const struct sockaddr_in *dst = sip_real_dst(p);
08897          ast_verbose("Sending to %s : %d (%s)\n", ast_inet_ntoa(dst->sin_addr), ntohs(dst->sin_port), sip_nat_mode(p));
08898       }
08899    }
08900 }

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

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

09740 {
09741    char *oldcontext, *newcontext, *stalecontext, *stringp, newlist[AST_MAX_CONTEXT];
09742 
09743    while ((oldcontext = strsep(&old, "&"))) {
09744       stalecontext = '\0';
09745       ast_copy_string(newlist, new, sizeof(newlist));
09746       stringp = newlist;
09747       while ((newcontext = strsep(&stringp, "&"))) {
09748          if (strcmp(newcontext, oldcontext) == 0) {
09749             /* This is not the context you're looking for */
09750             stalecontext = '\0';
09751             break;
09752          } else if (strcmp(newcontext, oldcontext)) {
09753             stalecontext = oldcontext;
09754          }
09755          
09756       }
09757       if (stalecontext)
09758          ast_context_destroy(ast_context_find(stalecontext), "SIP");
09759    }
09760 }

static int clear_realm_authentication ( struct sip_auth authlist  )  [static]

Clear realm authentication list (at reload).

Definition at line 15739 of file chan_sip.c.

References free, and sip_auth::next.

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

15740 {
15741    struct sip_auth *a = authlist;
15742    struct sip_auth *b;
15743 
15744    while (a) {
15745       b = a;
15746       a = a->next;
15747       free(b);
15748    }
15749 
15750    return 1;
15751 }

static void clear_sip_domains ( void   )  [static]

Clear our domain list (at reload).

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

15669 {
15670    struct domain *d;
15671 
15672    AST_LIST_LOCK(&domain_list);
15673    while ((d = AST_LIST_REMOVE_HEAD(&domain_list, list)))
15674       free(d);
15675    AST_LIST_UNLOCK(&domain_list);
15676 }

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

References complete_sip_peer().

10553 {
10554    if (pos == 3)
10555       return complete_sip_peer(word, state, 0);
10556 
10557    return NULL;
10558 }

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

Do completion on peer name.

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

10527 {
10528    char *result = NULL;
10529    int wordlen = strlen(word);
10530    int which = 0;
10531 
10532    ASTOBJ_CONTAINER_TRAVERSE(&peerl, !result, do {
10533       /* locking of the object is not required because only the name and flags are being compared */
10534       if (!strncasecmp(word, iterator->name, wordlen) &&
10535             (!flags2 || ast_test_flag(&iterator->flags[1], flags2)) &&
10536             ++which > state)
10537          result = ast_strdup(iterator->name);
10538    } while(0) );
10539    return result;
10540 }

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

References complete_sip_peer(), and SIP_PAGE2_RTCACHEFRIENDS.

10621 {
10622    if (pos == 4)
10623       return complete_sip_peer(word, state, SIP_PAGE2_RTCACHEFRIENDS);
10624    return NULL;
10625 }

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

References complete_sip_user(), and SIP_PAGE2_RTCACHEFRIENDS.

10629 {
10630    if (pos == 4)
10631       return complete_sip_user(word, state, SIP_PAGE2_RTCACHEFRIENDS);
10632 
10633    return NULL;
10634 }

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

References complete_sip_peer().

10544 {
10545    if (pos == 3)
10546       return complete_sip_peer(word, state, 0);
10547 
10548    return NULL;
10549 }

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

References complete_sip_user().

10582 {
10583    if (pos == 3)
10584       return complete_sip_user(word, state, 0);
10585 
10586    return NULL;
10587 }

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

Do completion on user name.

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

10562 {
10563    char *result = NULL;
10564    int wordlen = strlen(word);
10565    int which = 0;
10566 
10567    ASTOBJ_CONTAINER_TRAVERSE(&userl, !result, do {
10568       /* locking of the object is not required because only the name and flags are being compared */
10569       if (!strncasecmp(word, iterator->name, wordlen)) {
10570          if (flags2 && !ast_test_flag(&iterator->flags[1], flags2))
10571             continue;
10572          if (++which > state) {
10573             result = ast_strdup(iterator->name);
10574          }
10575       }
10576    } while(0) );
10577    return result;
10578 }

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

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

10508 {
10509    int which=0;
10510    struct sip_pvt *cur;
10511    char *c = NULL;
10512    int wordlen = strlen(word);
10513 
10514    ast_mutex_lock(&iflock);
10515    for (cur = iflist; cur; cur = cur->next) {
10516       if (!strncasecmp(word, cur->callid, wordlen) && ++which > state) {
10517          c = ast_strdup(cur->callid);
10518          break;
10519       }
10520    }
10521    ast_mutex_unlock(&iflock);
10522    return c;
10523 }

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

Support routine for 'sip notify' CLI.

Definition at line 10590 of file chan_sip.c.

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

10591 {
10592    char *c = NULL;
10593 
10594    if (pos == 2) {
10595       int which = 0;
10596       char *cat = NULL;
10597       int wordlen = strlen(word);
10598 
10599       /* do completion for notify type */
10600 
10601       if (!notify_types)
10602          return NULL;
10603       
10604       while ( (cat = ast_category_browse(notify_types, cat)) ) {
10605          if (!strncasecmp(word, cat, wordlen) && ++which > state) {
10606             c = ast_strdup(cat);
10607             break;
10608          }
10609       }
10610       return c;
10611    }
10612 
10613    if (pos > 2)
10614       return complete_sip_peer(word, state, 0);
10615 
10616    return NULL;
10617 }

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

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

Referenced by respprep().

05380 {
05381    int start = 0;
05382    int copied = 0;
05383    for (;;) {
05384       const char *tmp = __get_header(orig, field, &start);
05385 
05386       if (ast_strlen_zero(tmp))
05387          break;
05388       /* Add what we're responding to */
05389       add_header(req, field, tmp);
05390       copied++;
05391    }
05392    return copied ? 0 : -1;
05393 }

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

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

Referenced by reqprep(), and respprep().

05369 {
05370    const char *tmp = get_header(orig, field);
05371 
05372    if (!ast_strlen_zero(tmp)) /* Add what we're responding to */
05373       return add_header(req, field, tmp);
05374    ast_log(LOG_NOTICE, "No field '%s' present to copy\n", field);
05375    return -1;
05376 }

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

06414 {
06415    long offset;
06416    int x;
06417    offset = ((void *)dst) - ((void *)src);
06418    /* First copy stuff */
06419    memcpy(dst, src, sizeof(*dst));
06420    /* Now fix pointer arithmetic */
06421    for (x=0; x < src->headers; x++)
06422       dst->header[x] += offset;
06423    for (x=0; x < src->lines; x++)
06424       dst->line[x] += offset;
06425    dst->rlPart1 += offset;
06426    dst->rlPart2 += offset;
06427 }

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

05402 {
05403    int copied = 0;
05404    int start = 0;
05405 
05406    for (;;) {
05407       char new[256];
05408       const char *oh = __get_header(orig, field, &start);
05409 
05410       if (ast_strlen_zero(oh))
05411          break;
05412 
05413       if (!copied) { /* Only check for empty rport in topmost via header */
05414          char leftmost[256], *others, *rport;
05415 
05416          /* Only work on leftmost value */
05417          ast_copy_string(leftmost, oh, sizeof(leftmost));
05418          others = strchr(leftmost, ',');
05419          if (others)
05420              *others++ = '\0';
05421 
05422          /* Find ;rport;  (empty request) */
05423          rport = strstr(leftmost, ";rport");
05424          if (rport && *(rport+6) == '=') 
05425             rport = NULL;     /* We already have a parameter to rport */
05426 
05427          /* Check rport if NAT=yes or NAT=rfc3581 (which is the default setting)  */
05428          if (rport && ((ast_test_flag(&p->flags[0], SIP_NAT) == SIP_NAT_ALWAYS) || (ast_test_flag(&p->flags[0], SIP_NAT) == SIP_NAT_RFC3581))) {
05429             /* We need to add received port - rport */
05430             char *end;
05431 
05432             rport = strstr(leftmost, ";rport");
05433 
05434             if (rport) {
05435                end = strchr(rport + 1, ';');
05436                if (end)
05437                   memmove(rport, end, strlen(end) + 1);
05438                else
05439                   *rport = '\0';
05440             }
05441 
05442             /* Add rport to first VIA header if requested */
05443             snprintf(new, sizeof(new), "%s;received=%s;rport=%d%s%s",
05444                leftmost, ast_inet_ntoa(p->recv.sin_addr),
05445                ntohs(p->recv.sin_port),
05446                others ? "," : "", others ? others : "");
05447          } else {
05448             /* We should *always* add a received to the topmost via */
05449             snprintf(new, sizeof(new), "%s;received=%s%s%s",
05450                leftmost, ast_inet_ntoa(p->recv.sin_addr),
05451                others ? "," : "", others ? others : "");
05452          }
05453          oh = new;   /* the header to copy */
05454       }  /* else add the following via headers untouched */
05455       add_header(req, field, oh);
05456       copied++;
05457    }
05458    if (!copied) {
05459       ast_log(LOG_NOTICE, "No header field '%s' present to copy\n", field);
05460       return -1;
05461    }
05462    return 0;
05463 }

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 2699 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, LOG_WARNING, portno, sip_pvt::recv, sip_pvt::sa, sip_destroy_peer(), STANDARD_SIP_PORT, sip_pvt::timer_t1, and sip_peer::tohost.

02700 {
02701    struct hostent *hp;
02702    struct ast_hostent ahp;
02703    struct sip_peer *p;
02704    char *port;
02705    int portno;
02706    char host[MAXHOSTNAMELEN], *hostn;
02707    char peer[256];
02708 
02709    ast_copy_string(peer, opeer, sizeof(peer));
02710    port = strchr(peer, ':');
02711    if (port)
02712       *port++ = '\0';
02713    dialog->sa.sin_family = AF_INET;
02714    dialog->timer_t1 = 500; /* Default SIP retransmission timer T1 (RFC 3261) */
02715    p = find_peer(peer, NULL, 1);
02716 
02717    if (p) {
02718       int res = create_addr_from_peer(dialog, p);
02719       ASTOBJ_UNREF(p, sip_destroy_peer);
02720       return res;
02721    }
02722    hostn = peer;
02723    portno = port ? atoi(port) : STANDARD_SIP_PORT;
02724    if (srvlookup) {
02725       char service[MAXHOSTNAMELEN];
02726       int tportno;
02727       int ret;
02728 
02729       snprintf(service, sizeof(service), "_sip._udp.%s", peer);
02730       ret = ast_get_srv(NULL, host, sizeof(host), &tportno, service);
02731       if (ret > 0) {
02732          hostn = host;
02733          portno = tportno;
02734       }
02735    }
02736    hp = ast_gethostbyname(hostn, &ahp);
02737    if (!hp) {
02738       ast_log(LOG_WARNING, "No such host: %s\n", peer);
02739       return -1;
02740    }
02741    ast_string_field_set(dialog, tohost, peer);
02742    memcpy(&dialog->sa.sin_addr, hp->h_addr, sizeof(dialog->sa.sin_addr));
02743    dialog->sa.sin_port = htons(portno);
02744    dialog->recv = dialog->sa;
02745    return 0;
02746 }

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

02595 {
02596    if ((peer->addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr) &&
02597        (!peer->maxms || ((peer->lastms >= 0)  && (peer->lastms <= peer->maxms)))) {
02598       dialog->sa = (peer->addr.sin_addr.s_addr) ? peer->addr : peer->defaddr;
02599       dialog->recv = dialog->sa;
02600    } else 
02601       return -1;
02602 
02603    ast_copy_flags(&dialog->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY);
02604    ast_copy_flags(&dialog->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY);
02605    dialog->capability = peer->capability;
02606    if ((!ast_test_flag(&dialog->flags[1], SIP_PAGE2_VIDEOSUPPORT) || !(dialog->capability & AST_FORMAT_VIDEO_MASK)) && dialog->vrtp) {
02607       ast_rtp_destroy(dialog->vrtp);
02608       dialog->vrtp = NULL;
02609    }
02610    dialog->prefs = peer->prefs;
02611    if (ast_test_flag(&dialog->flags[1], SIP_PAGE2_T38SUPPORT)) {
02612       dialog->t38.capability = global_t38_capability;
02613       if (dialog->udptl) {
02614          if (ast_udptl_get_error_correction_scheme(dialog->udptl) == UDPTL_ERROR_CORRECTION_FEC )
02615             dialog->t38.capability |= T38FAX_UDP_EC_FEC;
02616          else if (ast_udptl_get_error_correction_scheme(dialog->udptl) == UDPTL_ERROR_CORRECTION_REDUNDANCY )
02617             dialog->t38.capability |= T38FAX_UDP_EC_REDUNDANCY;
02618          else if (ast_udptl_get_error_correction_scheme(dialog->udptl) == UDPTL_ERROR_CORRECTION_NONE )
02619             dialog->t38.capability |= T38FAX_UDP_EC_NONE;
02620          dialog->t38.capability |= T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF;
02621          if (option_debug > 1)
02622             ast_log(LOG_DEBUG,"Our T38 capability (%d)\n", dialog->t38.capability);
02623       }
02624       dialog->t38.jointcapability = dialog->t38.capability;
02625    } else if (dialog->udptl) {
02626       ast_udptl_destroy(dialog->udptl);
02627       dialog->udptl = NULL;
02628    }
02629    do_setnat(dialog, ast_test_flag(&dialog->flags[0], SIP_NAT) & SIP_NAT_ROUTE );
02630 
02631    if (dialog->rtp) {
02632       ast_rtp_setdtmf(dialog->rtp, ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833);
02633       ast_rtp_setdtmfcompensate(dialog->rtp, ast_test_flag(&dialog->flags[1], SIP_PAGE2_RFC2833_COMPENSATE));
02634       ast_rtp_set_rtptimeout(dialog->rtp, peer->rtptimeout);
02635       ast_rtp_set_rtpholdtimeout(dialog->rtp, peer->rtpholdtimeout);
02636       ast_rtp_set_rtpkeepalive(dialog->rtp, peer->rtpkeepalive);
02637       /* Set Frame packetization */
02638       ast_rtp_codec_setpref(dialog->rtp, &dialog->prefs);
02639       dialog->autoframing = peer->autoframing;
02640    }
02641    if (dialog->vrtp) {
02642       ast_rtp_setdtmf(dialog->vrtp, 0);
02643       ast_rtp_setdtmfcompensate(dialog->vrtp, 0);
02644       ast_rtp_set_rtptimeout(dialog->vrtp, peer->rtptimeout);
02645       ast_rtp_set_rtpholdtimeout(dialog->vrtp, peer->rtpholdtimeout);
02646       ast_rtp_set_rtpkeepalive(dialog->vrtp, peer->rtpkeepalive);
02647    }
02648 
02649    ast_string_field_set(dialog, peername, peer->username);
02650    ast_string_field_set(dialog, authname, peer->username);
02651    ast_string_field_set(dialog, username, peer->username);
02652    ast_string_field_set(dialog, peersecret, peer->secret);
02653    ast_string_field_set(dialog, peermd5secret, peer->md5secret);
02654    ast_string_field_set(dialog, mohsuggest, peer->mohsuggest);
02655    ast_string_field_set(dialog, mohinterpret, peer->mohinterpret);
02656    ast_string_field_set(dialog, tohost, peer->tohost);
02657    ast_string_field_set(dialog, fullcontact, peer->fullcontact);
02658    if (!dialog->initreq.headers && !ast_strlen_zero(peer->fromdomain)) {
02659       char *tmpcall;
02660       char *c;
02661       tmpcall = ast_strdupa(dialog->callid);
02662       c = strchr(tmpcall, '@');
02663       if (c) {
02664          *c = '\0';
02665          ast_string_field_build(dialog, callid, "%s@%s", tmpcall, peer->fromdomain);
02666       }
02667    }
02668    if (ast_strlen_zero(dialog->tohost))
02669       ast_string_field_set(dialog, tohost, ast_inet_ntoa(dialog->sa.sin_addr));
02670    if (!ast_strlen_zero(peer->fromdomain))
02671       ast_string_field_set(dialog, fromdomain, peer->fromdomain);
02672    if (!ast_strlen_zero(peer->fromuser))
02673       ast_string_field_set(dialog, fromuser, peer->fromuser);
02674    dialog->maxtime = peer->maxms;
02675    dialog->callgroup = peer->callgroup;
02676    dialog->pickupgroup = peer->pickupgroup;
02677    dialog->allowtransfer = peer->allowtransfer;
02678    /* Set timer T1 to RTT for this peer (if known by qualify=) */
02679    /* Minimum is settable or default to 100 ms */
02680    if (peer->maxms && peer->lastms)
02681       dialog->timer_t1 = peer->lastms < global_t1min ? global_t1min : peer->lastms;
02682    if ((ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) ||
02683        (ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_AUTO))
02684       dialog->noncodeccapability |= AST_RTP_DTMF;
02685    else
02686       dialog->noncodeccapability &= ~AST_RTP_DTMF;
02687    ast_string_field_set(dialog, context, peer->context);
02688    dialog->rtptimeout = peer->rtptimeout;
02689    if (peer->call_limit)
02690       ast_set_flag(&dialog->flags[0], SIP_CALL_LIMIT);
02691    dialog->maxcallbitrate = peer->maxcallbitrate;
02692    
02693    return 0;
02694 }

static void destroy_association ( struct sip_peer peer  )  [static]

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

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

07568 {
07569    if (!ast_test_flag(&global_flags[1], SIP_PAGE2_IGNOREREGEXPIRE)) {
07570       if (ast_test_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT))
07571          ast_update_realtime("sippeers", "name", peer->name, "fullcontact", "", "ipaddr", "", "port", "", "regseconds", "0", "username", "", "regserver", "", NULL);
07572       else 
07573          ast_db_del("SIP/Registry", peer->name);
07574    }
07575 }

static int determine_firstline_parts ( struct sip_request req  )  [static]

Parse first line of incoming SIP request.

Definition at line 6455 of file chan_sip.c.

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

Referenced by parse_request().

06456 {
06457    char *e = ast_skip_blanks(req->header[0]);   /* there shouldn't be any */
06458 
06459    if (!*e)
06460       return -1;
06461    req->rlPart1 = e; /* method or protocol */
06462    e = ast_skip_nonblanks(e);
06463    if (*e)
06464       *e++ = '\0';
06465    /* Get URI or status code */
06466    e = ast_skip_blanks(e);
06467    if ( !*e )
06468       return -1;
06469    ast_trim_blanks(e);
06470 
06471    if (!strcasecmp(req->rlPart1, "SIP/2.0") ) { /* We have a response */
06472       if (strlen(e) < 3)   /* status code is 3 digits */
06473          return -1;
06474       req->rlPart2 = e;
06475    } else { /* We have a request */
06476       if ( *e == '<' ) { /* XXX the spec says it must not be in <> ! */
06477          ast_log(LOG_WARNING, "bogus uri in <> %s\n", e);
06478          e++;
06479          if (!*e)
06480             return -1; 
06481       }
06482       req->rlPart2 = e; /* URI */
06483       e = ast_skip_nonblanks(e);
06484       if (*e)
06485          *e++ = '\0';
06486       e = ast_skip_blanks(e);
06487       if (strcasecmp(e, "SIP/2.0") ) {
06488          ast_log(LOG_WARNING, "Bad request protocol %s\n", e);
06489          return -1;
06490       }
06491    }
06492    return 1;
06493 }

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 15024 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, and VERBOSE_PREFIX_1.

15025 {
15026    int res;
15027    struct sip_pvt *sip;
15028    struct sip_peer *peer = NULL;
15029    time_t t;
15030    int fastrestart = FALSE;
15031    int lastpeernum = -1;
15032    int curpeernum;
15033    int reloading;
15034 
15035    /* Add an I/O event to our SIP UDP socket */
15036    if (sipsock > -1) 
15037       sipsock_read_id = ast_io_add(io, sipsock, sipsock_read, AST_IO_IN, NULL);
15038    
15039    /* From here on out, we die whenever asked */
15040    for(;;) {
15041       /* Check for a reload request */
15042       ast_mutex_lock(&sip_reload_lock);
15043       reloading = sip_reloading;
15044       sip_reloading = FALSE;
15045       ast_mutex_unlock(&sip_reload_lock);
15046       if (reloading) {
15047          if (option_verbose > 0)
15048             ast_verbose(VERBOSE_PREFIX_1 "Reloading SIP\n");
15049          sip_do_reload(sip_reloadreason);
15050 
15051          /* Change the I/O fd of our UDP socket */
15052          if (sipsock > -1)
15053             sipsock_read_id = ast_io_change(io, sipsock_read_id, sipsock, NULL, 0, NULL);
15054       }
15055       /* Check for interfaces needing to be killed */
15056       ast_mutex_lock(&iflock);
15057 restartsearch:    
15058       t = time(NULL);
15059       /* don't scan the interface list if it hasn't been a reasonable period
15060          of time since the last time we did it (when MWI is being sent, we can
15061          get back to this point every millisecond or less)
15062       */
15063       for (sip = iflist; !fastrestart && sip; sip = sip->next) {
15064          ast_mutex_lock(&sip->lock);
15065          /* Check RTP timeouts and kill calls if we have a timeout set and do not get RTP */
15066          if (sip->rtp && sip->owner &&
15067              (sip->owner->_state == AST_STATE_UP) &&
15068              !sip->redirip.sin_addr.s_addr) {
15069             if (sip->lastrtptx &&
15070                 ast_rtp_get_rtpkeepalive(sip->rtp) &&
15071                 (t > sip->lastrtptx + ast_rtp_get_rtpkeepalive(sip->rtp))) {
15072                /* Need to send an empty RTP packet */
15073                sip->lastrtptx = time(NULL);
15074                ast_rtp_sendcng(sip->rtp, 0);
15075             }
15076             if (sip->lastrtprx &&
15077                (ast_rtp_get_rtptimeout(sip->rtp) || ast_rtp_get_rtpholdtimeout(sip->rtp)) &&
15078                 (t > sip->lastrtprx + ast_rtp_get_rtptimeout(sip->rtp))) {
15079                /* Might be a timeout now -- see if we're on hold */
15080                struct sockaddr_in sin;
15081                ast_rtp_get_peer(sip->rtp, &sin);
15082                if (sin.sin_addr.s_addr || 
15083                    (ast_rtp_get_rtpholdtimeout(sip->rtp) &&
15084                     (t > sip->lastrtprx + ast_rtp_get_rtpholdtimeout(sip->rtp)))) {
15085                   /* Needs a hangup */
15086                   if (ast_rtp_get_rtptimeout(sip->rtp)) {
15087                      while (sip->owner && ast_channel_trylock(sip->owner)) {
15088                         ast_mutex_unlock(&sip->lock);
15089                         usleep(1);
15090                         ast_mutex_lock(&sip->lock);
15091                      }
15092                      if (sip->owner) {
15093                         if (!(ast_rtp_get_bridged(sip->rtp))) {
15094                            ast_log(LOG_NOTICE,
15095                               "Disconnecting call '%s' for lack of RTP activity in %ld seconds\n",
15096                               sip->owner->name,
15097                               (long) (t - sip->lastrtprx));
15098                            /* Issue a softhangup */
15099                            ast_softhangup_nolock(sip->owner, AST_SOFTHANGUP_DEV);
15100                         } else
15101                            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));
15102                         ast_channel_unlock(sip->owner);
15103                         /* forget the timeouts for this call, since a hangup
15104                            has already been requested and we don't want to
15105                            repeatedly request hangups
15106                         */
15107                         ast_rtp_set_rtptimeout(sip->rtp, 0);
15108                         ast_rtp_set_rtpholdtimeout(sip->rtp, 0);
15109                         if (sip->vrtp) {
15110                            ast_rtp_set_rtptimeout(sip->vrtp, 0);
15111                            ast_rtp_set_rtpholdtimeout(sip->vrtp, 0);
15112                         }
15113                      }
15114                   }
15115                }
15116             }
15117          }
15118          /* If we have sessions that needs to be destroyed, do it now */
15119          if (ast_test_flag(&sip->flags[0], SIP_NEEDDESTROY) && !sip->packets &&
15120              !sip->owner) {
15121             ast_mutex_unlock(&sip->lock);
15122             __sip_destroy(sip, 1);
15123             goto restartsearch;
15124          }
15125          ast_mutex_unlock(&sip->lock);
15126       }
15127       ast_mutex_unlock(&iflock);
15128 
15129       pthread_testcancel();
15130       /* Wait for sched or io */
15131       res = ast_sched_wait(sched);
15132       if ((res < 0) || (res > 1000))
15133          res = 1000;
15134       /* If we might need to send more mailboxes, don't wait long at all.*/
15135       if (fastrestart)
15136          res = 1;
15137       res = ast_io_wait(io, res);
15138       if (option_debug && res > 20)
15139          ast_log(LOG_DEBUG, "chan_sip: ast_io_wait ran %d all at once\n", res);
15140       ast_mutex_lock(&monlock);
15141       if (res >= 0)  {
15142          res = ast_sched_runq(sched);
15143          if (option_debug && res >= 20)
15144             ast_log(LOG_DEBUG, "chan_sip: ast_sched_runq ran %d all at once\n", res);
15145       }
15146 
15147       /* Send MWI notifications to peers - static and cached realtime peers */
15148       t = time(NULL);
15149       fastrestart = FALSE;
15150       curpeernum = 0;
15151       peer = NULL;
15152       /* Find next peer that needs mwi */
15153       ASTOBJ_CONTAINER_TRAVERSE(&peerl, !peer, do {
15154          if ((curpeernum > lastpeernum) && does_peer_need_mwi(iterator)) {
15155             fastrestart = TRUE;
15156             lastpeernum = curpeernum;
15157             peer = ASTOBJ_REF(iterator);
15158          };
15159          curpeernum++;
15160       } while (0)
15161       );
15162       /* Send MWI to the peer */
15163       if (peer) {
15164          ASTOBJ_WRLOCK(peer);
15165          sip_send_mwi_to_peer(peer);
15166          ASTOBJ_UNLOCK(peer);
15167          ASTOBJ_UNREF(peer,sip_destroy_peer);
15168       } else {
15169          /* Reset where we come from */
15170          lastpeernum = -1;
15171       }
15172       ast_mutex_unlock(&monlock);
15173    }
15174    /* Never reached */
15175    return NULL;
15176    
15177 }

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

11089 {
11090    char digest[1024];
11091 
11092    if (!p->options && !(p->options = ast_calloc(1, sizeof(*p->options))))
11093       return -2;
11094 
11095    p->authtries++;
11096    if (option_debug > 1)
11097       ast_log(LOG_DEBUG, "Auth attempt %d on %s\n", p->authtries, sip_methods[sipmethod].text);
11098    memset(digest, 0, sizeof(digest));
11099    if (reply_digest(p, req, header, sipmethod, digest, sizeof(digest) )) {
11100       /* No way to authenticate */
11101       return -1;
11102    }
11103    /* Now we have a reply digest */
11104    p->options->auth = digest;
11105    p->options->authheader = respheader;
11106    return transmit_invite(p, sipmethod, sipmethod == SIP_INVITE, init); 
11107 }

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

11068 {
11069    char digest[1024];
11070    p->authtries++;
11071    memset(digest,0,sizeof(digest));
11072    if (reply_digest(p, req, header, SIP_REGISTER, digest, sizeof(digest))) {
11073       /* There's nothing to use for authentication */
11074       /* No digest challenge in request */
11075       if (sip_debug_test_pvt(p) && p->registry)
11076          ast_verbose("No authentication challenge, sending blank registration to domain/host name %s\n", p->registry->hostname);
11077          /* No old challenge */
11078       return -1;
11079    }
11080    if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY))
11081       append_history(p, "RegistryAuth", "Try: %d", p->authtries);
11082    if (sip_debug_test_pvt(p) && p->registry)
11083       ast_verbose("Responding to challenge, registration to domain/host name %s\n", p->registry->hostname);
11084    return transmit_register(p->registry, SIP_REGISTER, digest, respheader); 
11085 }

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

Set nat mode on the various data sockets.

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

02571 {
02572    const char *mode = natflags ? "On" : "Off";
02573 
02574    if (p->rtp) {
02575       if (option_debug)
02576          ast_log(LOG_DEBUG, "Setting NAT on RTP to %s\n", mode);
02577       ast_rtp_setnat(p->rtp, natflags);
02578    }
02579    if (p->vrtp) {
02580       if (option_debug)
02581          ast_log(LOG_DEBUG, "Setting NAT on VRTP to %s\n", mode);
02582       ast_rtp_setnat(p->vrtp, natflags);
02583    }
02584    if (p->udptl) {
02585       if (option_debug)
02586          ast_log(LOG_DEBUG, "Setting NAT on UDPTL to %s\n", mode);
02587       ast_udptl_setnat(p->udptl, natflags);
02588    }
02589 }

static int does_peer_need_mwi ( struct sip_peer peer  )  [static]

Check whether peer needs a new MWI notification check.

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

15004 {
15005    time_t t = time(NULL);
15006 
15007    if (ast_test_flag(&peer->flags[1], SIP_PAGE2_SUBSCRIBEMWIONLY) &&
15008        !peer->mwipvt) { /* We don't have a subscription */
15009       peer->lastmsgcheck = t; /* Reset timer */
15010       return FALSE;
15011    }
15012 
15013    if (!ast_strlen_zero(peer->mailbox) && (t - peer->lastmsgcheck) > global_mwitime)
15014       return TRUE;
15015 
15016    return FALSE;
15017 }

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

Print domain mode to cli.

Definition at line 9928 of file chan_sip.c.

References SIP_DOMAIN_AUTO, and SIP_DOMAIN_CONFIG.

Referenced by sip_show_domains().

09929 {
09930    switch (mode) {
09931    case SIP_DOMAIN_AUTO:
09932       return "[Automatic]";
09933    case SIP_DOMAIN_CONFIG:
09934       return "[Configured]";
09935    }
09936 
09937    return "";
09938 }

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

Convert DTMF mode to printable string.

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

09709 {
09710    switch (mode) {
09711    case SIP_DTMF_RFC2833:
09712       return "rfc2833";
09713    case SIP_DTMF_INFO:
09714       return "info";
09715    case SIP_DTMF_INBAND:
09716       return "inband";
09717    case SIP_DTMF_AUTO:
09718       return "auto";
09719    }
09720    return "<error>";
09721 }

static int expire_register ( void *  data  )  [static]

Expire registration of SIP peer.

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

07579 {
07580    struct sip_peer *peer = data;
07581    
07582    if (!peer)     /* Hmmm. We have no peer. Weird. */
07583       return 0;
07584 
07585    memset(&peer->addr, 0, sizeof(peer->addr));
07586 
07587    destroy_association(peer); /* remove registration data from storage */
07588    
07589    manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name);
07590    register_peer_exten(peer, FALSE);   /* Remove regexten */
07591    peer->expire = -1;
07592    ast_device_state_changed("SIP/%s", peer->name);
07593 
07594    /* Do we need to release this peer from memory? 
07595       Only for realtime peers and autocreated peers
07596    */
07597    if (ast_test_flag(&peer->flags[1], SIP_PAGE2_SELFDESTRUCT) ||
07598        ast_test_flag(&peer->flags[1], SIP_PAGE2_RTAUTOCLEAR)) {
07599       peer = ASTOBJ_CONTAINER_UNLINK(&peerl, peer);   /* Remove from peer list */
07600       ASTOBJ_UNREF(peer, sip_destroy_peer);     /* Remove from memory */
07601    }
07602 
07603    return 0;
07604 }

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

Check Contact: URI of SIP message.

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

06546 {
06547    char stripped[BUFSIZ];
06548    char *c;
06549 
06550    ast_copy_string(stripped, get_header(req, "Contact"), sizeof(stripped));
06551    c = get_in_brackets(stripped);
06552    c = strsep(&c, ";"); /* trim ; and beyond */
06553    if (!ast_strlen_zero(c))
06554       ast_string_field_set(p, uri, c);
06555 }

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

References aliases.

03970 {
03971    /*! \brief Structure for conversion between compressed SIP and "normal" SIP */
03972    static const struct cfalias {
03973       char * const fullname;
03974       char * const shortname;
03975    } aliases[] = {
03976       { "Content-Type",  "c" },
03977       { "Content-Encoding",    "e" },
03978       { "From",       "f" },
03979       { "Call-ID",       "i" },
03980       { "Contact",       "m" },
03981       { "Content-Length",   "l" },
03982       { "Subject",       "s" },
03983       { "To",         "t" },
03984       { "Supported",     "k" },
03985       { "Refer-To",      "r" },
03986       { "Referred-By",   "b" },
03987       { "Allow-Events",  "u" },
03988       { "Event",      "o" },
03989       { "Via",     "v" },
03990       { "Accept-Contact",      "a" },
03991       { "Reject-Contact",      "j" },
03992       { "Request-Disposition", "d" },
03993       { "Session-Expires",     "x" },
03994       { "Identity",            "y" },
03995       { "Identity-Info",       "n" },
03996    };
03997    int x;
03998 
03999    for (x=0; x<sizeof(aliases) / sizeof(aliases[0]); x++) 
04000       if (!strcasecmp(aliases[x].fullname, name))
04001          return aliases[x].shortname;
04002 
04003    return _default;
04004 }

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

04329 {
04330    struct sip_pvt *p = NULL;
04331    char *tag = "";   /* note, tag is never NULL */
04332    char totag[128];
04333    char fromtag[128];
04334    const char *callid = get_header(req, "Call-ID");
04335    const char *from = get_header(req, "From");
04336    const char *to = get_header(req, "To");
04337    const char *cseq = get_header(req, "Cseq");
04338 
04339    /* Call-ID, to, from and Cseq are required by RFC 3261. (Max-forwards and via too - ignored now) */
04340    /* get_header always returns non-NULL so we must use ast_strlen_zero() */
04341    if (ast_strlen_zero(callid) || ast_strlen_zero(to) ||
04342          ast_strlen_zero(from) || ast_strlen_zero(cseq))
04343       return NULL;   /* Invalid packet */
04344 
04345    if (pedanticsipchecking) {
04346       /* In principle Call-ID's uniquely identify a call, but with a forking SIP proxy
04347          we need more to identify a branch - so we have to check branch, from
04348          and to tags to identify a call leg.
04349          For Asterisk to behave correctly, you need to turn on pedanticsipchecking
04350          in sip.conf
04351          */
04352       if (gettag(req, "To", totag, sizeof(totag)))
04353          ast_set_flag(req, SIP_PKT_WITH_TOTAG); /* Used in handle_request/response */
04354       gettag(req, "From", fromtag, sizeof(fromtag));
04355 
04356       tag = (req->method == SIP_RESPONSE) ? totag : fromtag;
04357 
04358       if (option_debug > 4 )
04359          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);
04360    }
04361 
04362    ast_mutex_lock(&iflock);
04363    for (p = iflist; p; p = p->next) {
04364       /* In pedantic, we do not want packets with bad syntax to be connected to a PVT */
04365       int found = FALSE;
04366       if (ast_strlen_zero(p->callid))
04367          continue;
04368       if (req->method == SIP_REGISTER)
04369          found = (!strcmp(p->callid, callid));
04370       else 
04371          found = (!strcmp(p->callid, callid) && 
04372          (!pedanticsipchecking || !tag || ast_strlen_zero(p->theirtag) || !strcmp(p->theirtag, tag))) ;
04373 
04374       if (option_debug > 4)
04375          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);
04376 
04377       /* If we get a new request within an existing to-tag - check the to tag as well */
04378       if (pedanticsipchecking && found  && req->method != SIP_RESPONSE) {  /* SIP Request */
04379          if (p->tag[0] == '\0' && totag[0]) {
04380             /* We have no to tag, but they have. Wrong dialog */
04381             found = FALSE;
04382          } else if (totag[0]) {        /* Both have tags, compare them */
04383             if (strcmp(totag, p->tag)) {
04384                found = FALSE;    /* This is not our packet */
04385             }
04386          }
04387          if (!found && option_debug > 4)
04388             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);
04389       }
04390 
04391 
04392       if (found) {
04393          /* Found the call */
04394          ast_mutex_unlock(&iflock);
04395          ast_mutex_lock(&p->lock);
04396          return p;
04397       }
04398    }
04399    ast_mutex_unlock(&iflock);
04400 
04401    /* See if the method is capable of creating a dialog */
04402    if (sip_methods[intended_method].can_create == CAN_CREATE_DIALOG) {
04403       if (intended_method == SIP_REFER) {
04404          /* We do support REFER, but not outside of a dialog yet */
04405          transmit_response_using_temp(callid, sin, 1, intended_method, req, "603 Declined (no dialog)");
04406       } else if (intended_method == SIP_NOTIFY) {
04407          /* We do not support out-of-dialog NOTIFY either,
04408             like voicemail notification, so cancel that early */
04409          transmit_response_using_temp(callid, sin, 1, intended_method, req, "489 Bad event");
04410       } else {
04411          /* Ok, time to create a new SIP dialog object, a pvt */
04412          if ((p = sip_alloc(callid, sin, 1, intended_method)))  {
04413             /* Ok, we've created a dialog, let's go and process it */
04414             ast_mutex_lock(&p->lock);
04415          } else {
04416             /* We have a memory or file/socket error (can't allocate RTP sockets or something) so we're not
04417                getting a dialog from sip_alloc. 
04418    
04419                Without a dialog we can't retransmit and handle ACKs and all that, but at least
04420                send an error message.
04421    
04422                Sorry, we apologize for the inconvienience
04423             */
04424             transmit_response_using_temp(callid, sin, 1, intended_method, req, "500 Server internal error");
04425             if (option_debug > 3)
04426                ast_log(LOG_DEBUG, "Failed allocating SIP dialog, sending 500 Server internal error and giving up\n");
04427          }
04428       }
04429       return p;
04430    } else if( sip_methods[intended_method].can_create == CAN_CREATE_DIALOG_UNSUPPORTED_METHOD) {
04431       /* A method we do not support, let's take it on the volley */
04432       transmit_response_using_temp(callid, sin, 1, intended_method, req, "501 Method Not Implemented");
04433    } else if (intended_method != SIP_RESPONSE && intended_method != SIP_ACK) {
04434       /* This is a request outside of a dialog that we don't know about 
04435          ...never reply to an ACK!
04436       */
04437       transmit_response_using_temp(callid, sin, 1, intended_method, req, "481 Call leg/transaction does not exist");
04438    }
04439    /* We do not respond to responses for dialogs that we don't know about, we just drop
04440       the session quickly */
04441 
04442    return p;
04443 }

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

References s.

Referenced by get_in_brackets().

02212 {
02213         char last_char = '\0';
02214         const char *s;
02215         for (s = start; *s && s != lim; last_char = *s++) {
02216                 if (*s == '"' && last_char != '\\')
02217                         break;
02218         }
02219         return s;
02220 }

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

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

02483 {
02484    struct sip_peer *p = NULL;
02485 
02486    if (peer)
02487       p = ASTOBJ_CONTAINER_FIND(&peerl, peer);
02488    else
02489       p = ASTOBJ_CONTAINER_FIND_FULL(&peerl, sin, name, sip_addr_hashfunc, 1, sip_addrcmp);
02490 
02491    if (!p && realtime)
02492       p = realtime_peer(peer, sin);
02493 
02494    return p;
02495 }

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

Find authentication for a specific realm.

Definition at line 15754 of file chan_sip.c.

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

Referenced by build_reply_digest().

15755 {
15756    struct sip_auth *a;
15757 
15758    for (a = authlist; a; a = a->next) {
15759       if (!strcasecmp(a->realm, realm))
15760          break;
15761    }
15762 
15763    return a;
15764 }

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

04650 {
04651    const char *content_type;
04652    const char *search;
04653    char *boundary;
04654    unsigned int x;
04655    int boundaryisquoted = FALSE;
04656 
04657    content_type = get_header(req, "Content-Type");
04658 
04659    /* if the body contains only SDP, this is easy */
04660    if (!strcasecmp(content_type, "application/sdp")) {
04661       req->sdp_start = 0;
04662       req->sdp_end = req->lines;
04663       return 1;
04664    }
04665 
04666    /* if it's not multipart/mixed, there cannot be an SDP */
04667    if (strncasecmp(content_type, "multipart/mixed", 15))
04668       return 0;
04669 
04670    /* if there is no boundary marker, it's invalid */
04671    if (!(search = strcasestr(content_type, ";boundary=")))
04672       return 0;
04673 
04674    search += 10;
04675    if (ast_strlen_zero(search))
04676       return 0;
04677 
04678    /* If the boundary is quoted with ", remove quote */
04679    if (*search == '\"')  {
04680       search++;
04681       boundaryisquoted = TRUE;
04682    }
04683 
04684    /* make a duplicate of the string, with two extra characters
04685       at the beginning */
04686    boundary = ast_strdupa(search - 2);
04687    boundary[0] = boundary[1] = '-';
04688 
04689    /* Remove final quote */
04690    if (boundaryisquoted)
04691       boundary[strlen(boundary) - 1] = '\0';
04692 
04693    /* search for the boundary marker, but stop when there are not enough
04694       lines left for it, the Content-Type header and at least one line of
04695       body */
04696    for (x = 0; x < (req->lines - 2); x++) {
04697       if (!strncasecmp(req->line[x], boundary, strlen(boundary)) &&
04698           !strcasecmp(req->line[x + 1], "Content-Type: application/sdp")) {
04699          x += 2;
04700          req->sdp_start = x;
04701 
04702          /* search for the end of the body part */
04703          for ( ; x < req->lines; x++) {
04704             if (!strncasecmp(req->line[x], boundary, strlen(boundary)))
04705                break;
04706          }
04707          req->sdp_end = x;
04708          return 1;
04709       }
04710    }
04711 
04712    return 0;
04713 }

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

find_sip_method: Find SIP method from header

Definition at line 1655 of file chan_sip.c.

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

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

01656 {
01657    int i, res = 0;
01658    
01659    if (ast_strlen_zero(msg))
01660       return 0;
01661    for (i = 1; i < (sizeof(sip_methods) / sizeof(sip_methods[0])) && !res; i++) {
01662       if (method_match(i, msg))
01663          res = sip_methods[i].id;
01664    }
01665    return res;
01666 }

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

Find subscription type in array.

Definition at line 10422 of file chan_sip.c.

References subscription_types, and type.

Referenced by transmit_state_notify().

10423 {
10424    int i;
10425 
10426    for (i = 1; (i < (sizeof(subscription_types) / sizeof(subscription_types[0]))); i++) {
10427       if (subscription_types[i].type == subtype) {
10428          return &subscription_types[i];
10429       }
10430    }
10431    return &subscription_types[0];
10432 }

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

References ASTOBJ_CONTAINER_FIND, realtime_user(), and userl.

02562 {
02563    struct sip_user *u = ASTOBJ_CONTAINER_FIND(&userl, name);
02564    if (!u && realtime)
02565       u = realtime_user(name);
02566    return u;
02567 }

static void free_old_route ( struct sip_route route  )  [static]

Remove route from route list.

Definition at line 7910 of file chan_sip.c.

References free, and sip_route::next.

Referenced by __sip_destroy(), and build_route().

07911 {
07912    struct sip_route *next;
07913 
07914    while (route) {
07915       next = route->next;
07916       free(route);
07917       route = next;
07918    }
07919 }

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

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

11415 {
11416    if (ast_strlen_zero(data)) {
11417       ast_log(LOG_WARNING, "CHECKSIPDOMAIN requires an argument - A domain name\n");
11418       return -1;
11419    }
11420    if (check_sip_domain(data, NULL, 0))
11421       ast_copy_string(buf, data, len);
11422    else
11423       buf[0] = '\0';
11424    return 0;
11425 }

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

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

11351 {
11352    struct sip_pvt *p;
11353    const char *content = NULL;
11354    AST_DECLARE_APP_ARGS(args,
11355       AST_APP_ARG(header);
11356       AST_APP_ARG(number);
11357    );
11358    int i, number, start = 0;
11359 
11360    if (ast_strlen_zero(data)) {
11361       ast_log(LOG_WARNING, "This function requires a header name.\n");
11362       return -1;
11363    }
11364 
11365    ast_channel_lock(chan);
11366    if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) {
11367       ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n");
11368       ast_channel_unlock(chan);
11369       return -1;
11370    }
11371 
11372    AST_STANDARD_APP_ARGS(args, data);
11373    if (!args.number) {
11374       number = 1;
11375    } else {
11376       sscanf(args.number, "%d", &number);
11377       if (number < 1)
11378          number = 1;
11379    }
11380 
11381    p = chan->tech_pvt;
11382 
11383    /* If there is no private structure, this channel is no longer alive */
11384    if (!p) {
11385       ast_channel_unlock(chan);
11386       return -1;
11387    }
11388 
11389    for (i = 0; i < number; i++)
11390       content = __get_header(&p->initreq, args.header, &start);
11391 
11392    if (ast_strlen_zero(content)) {
11393       ast_channel_unlock(chan);
11394       return -1;
11395    }
11396 
11397    ast_copy_string(buf, content, len);
11398    ast_channel_unlock(chan);
11399 
11400    return 0;
11401 }

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

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

11530 {
11531    struct sip_pvt *p;
11532 
11533    *buf = 0;
11534    
11535    if (!data) {
11536       ast_log(LOG_WARNING, "This function requires a parameter name.\n");
11537       return -1;
11538    }
11539 
11540    ast_channel_lock(chan);
11541    if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) {
11542       ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n");
11543       ast_channel_unlock(chan);
11544       return -1;
11545    }
11546 
11547    p = chan->tech_pvt;
11548 
11549    /* If there is no private structure, this channel is no longer alive */
11550    if (!p) {
11551       ast_channel_unlock(chan);
11552       return -1;
11553    }
11554 
11555    if (!strcasecmp(data, "peerip")) {
11556       ast_copy_string(buf, p->sa.sin_addr.s_addr ? ast_inet_ntoa(p->sa.sin_addr) : "", len);
11557    } else  if (!strcasecmp(data, "recvip")) {
11558       ast_copy_string(buf, p->recv.sin_addr.s_addr ? ast_inet_ntoa(p->recv.sin_addr) : "", len);
11559    } else  if (!strcasecmp(data, "from")) {
11560       ast_copy_string(buf, p->from, len);
11561    } else  if (!strcasecmp(data, "uri")) {
11562       ast_copy_string(buf, p->uri, len);
11563    } else  if (!strcasecmp(data, "useragent")) {
11564       ast_copy_string(buf, p->useragent, len);
11565    } else  if (!strcasecmp(data, "peername")) {
11566       ast_copy_string(buf, p->peername, len);
11567    } else if (!strcasecmp(data, "t38passthrough")) {
11568       if (p->t38.state == T38_DISABLED)
11569          ast_copy_string(buf, "0", sizeof("0"));
11570       else    /* T38 is offered or enabled in this call */
11571          ast_copy_string(buf, "1", sizeof("1"));
11572    } else {
11573       ast_channel_unlock(chan);
11574       return -1;
11575    }
11576    ast_channel_unlock(chan);
11577 
11578    return 0;
11579 }

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

11440 {
11441    struct sip_peer *peer;
11442    char *colname;
11443 
11444    if ((colname = strchr(data, ':')))  /*! \todo Will be deprecated after 1.4 */
11445       *colname++ = '\0';
11446    else if ((colname = strchr(data, '|')))
11447       *colname++ = '\0';
11448    else
11449       colname = "ip";
11450 
11451    if (!(peer = find_peer(data, NULL, 1)))
11452       return -1;
11453 
11454    if (!strcasecmp(colname, "ip")) {
11455       ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "", len);
11456    } else  if (!strcasecmp(colname, "status")) {
11457       peer_status(peer, buf, len);
11458    } else  if (!strcasecmp(colname, "language")) {
11459       ast_copy_string(buf, peer->language, len);
11460    } else  if (!strcasecmp(colname, "regexten")) {
11461       ast_copy_string(buf, peer->regexten, len);
11462    } else  if (!strcasecmp(colname, "limit")) {
11463       snprintf(buf, len, "%d", peer->call_limit);
11464    } else  if (!strcasecmp(colname, "curcalls")) {
11465       snprintf(buf, len, "%d", peer->inUse);
11466    } else  if (!strcasecmp(colname, "accountcode")) {
11467       ast_copy_string(buf, peer->accountcode, len);
11468    } else  if (!strcasecmp(colname, "useragent")) {
11469       ast_copy_string(buf, peer->useragent, len);
11470    } else  if (!strcasecmp(colname, "mailbox")) {
11471       ast_copy_string(buf, peer->mailbox, len);
11472    } else  if (!strcasecmp(colname, "context")) {
11473       ast_copy_string(buf, peer->context, len);
11474    } else  if (!strcasecmp(colname, "expire")) {
11475       snprintf(buf, len, "%d", peer->expire);
11476    } else  if (!strcasecmp(colname, "dynamic")) {
11477       ast_copy_string(buf, (ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC) ? "yes" : "no"), len);
11478    } else  if (!strcasecmp(colname, "callerid_name")) {
11479       ast_copy_string(buf, peer->cid_name, len);
11480    } else  if (!strcasecmp(colname, "callerid_num")) {
11481       ast_copy_string(buf, peer->cid_num, len);
11482    } else  if (!strcasecmp(colname, "codecs")) {
11483       ast_getformatname_multiple(buf, len -1, peer->capability);
11484    } else  if (!strncasecmp(colname, "codec[", 6)) {
11485       char *codecnum;
11486       int index = 0, codec = 0;
11487       
11488       codecnum = colname + 6; /* move past the '[' */
11489       codecnum = strsep(&codecnum, "]"); /* trim trailing ']' if any */
11490       index = atoi(codecnum);
11491       if((codec = ast_codec_pref_index(&peer->prefs, index))) {
11492          ast_copy_string(buf, ast_getformatname(codec), len);
11493       }
11494    }
11495 
11496    ASTOBJ_UNREF(peer, sip_destroy_peer);
11497 
11498    return 0;
11499 }

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

Generate 32 byte random string for callid's etc.

Definition at line 4162 of file chan_sip.c.

References ast_random().

Referenced by build_callid_pvt(), and build_callid_registry().

04163 {
04164    long val[4];
04165    int x;
04166 
04167    for (x=0; x<4; x++)
04168       val[x] = ast_random();
04169    snprintf(buf, size, "%08lx%08lx%08lx%08lx", val[0], val[1], val[2], val[3]);
04170 
04171    return buf;
04172 }

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 8796 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, LOG_WARNING, ast_channel::macrocontext, option_debug, sip_pvt::owner, pbx_builtin_getvar_helper(), sip_pvt::refer, sip_refer::refer_call, sip_refer::refer_contact, sip_refer::refer_to, sip_refer::refer_to_domain, sip_refer::referred_by, S_OR, and sip_debug_test_pvt().

Referenced by handle_request_bye().

08797 {
08798    char tmp[256] = "", *c, *a;
08799    struct sip_request *req = oreq ? oreq : &p->initreq;
08800    struct sip_refer *referdata = p->refer;
08801    const char *transfer_context = NULL;
08802    
08803    ast_copy_string(tmp, get_header(req, "Also"), sizeof(tmp));
08804    c = get_in_brackets(tmp);
08805 
08806    if (pedanticsipchecking)
08807       ast_uri_decode(c);
08808    
08809    if (strncmp(c, "sip:", 4)) {
08810       ast_log(LOG_WARNING, "Huh?  Not a SIP header in Also: transfer (%s)?\n", c);
08811       return -1;
08812    }
08813    c += 4;
08814    if ((a = strchr(c, ';')))  /* Remove arguments */
08815       *a = '\0';
08816    
08817    if ((a = strchr(c, '@'))) {   /* Separate Domain */
08818       *a++ = '\0';
08819       ast_copy_string(referdata->refer_to_domain, a, sizeof(referdata->refer_to_domain));
08820    }
08821    
08822    if (sip_debug_test_pvt(p))
08823       ast_verbose("Looking for %s in %s\n", c, p->context);
08824 
08825    if (p->owner)  /* Mimic behaviour in res_features.c */
08826       transfer_context = pbx_builtin_getvar_helper(p->owner, "TRANSFER_CONTEXT");
08827 
08828    /* By default, use the context in the channel sending the REFER */
08829    if (ast_strlen_zero(transfer_context)) {
08830       transfer_context = S_OR(p->owner->macrocontext,
08831                S_OR(p->context, default_context));
08832    }
08833    if (ast_exists_extension(NULL, transfer_context, c, 1, NULL)) {
08834       /* This is a blind transfer */
08835       if (option_debug)
08836          ast_log(LOG_DEBUG,"SIP Bye-also transfer to Extension %s@%s \n", c, transfer_context);
08837       ast_copy_string(referdata->refer_to, c, sizeof(referdata->refer_to));
08838       ast_copy_string(referdata->referred_by, "", sizeof(referdata->referred_by));
08839       ast_copy_string(referdata->refer_contact, "", sizeof(referdata->refer_contact));
08840       referdata->refer_call = NULL;
08841       /* Set new context */
08842       ast_string_field_set(p, context, transfer_context);
08843       return 0;
08844    } else if (ast_canmatch_extension(NULL, p->context, c, 1, NULL)) {
08845       return 1;
08846    }
08847 
08848    return -1;
08849 }

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

Get a specific line from the message body.

Definition at line 3953 of file chan_sip.c.

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

Referenced by handle_request_info().

03954 {
03955    int x;
03956    int len = strlen(name);
03957    char *r;
03958 
03959    for (x = 0; x < req->lines; x++) {
03960       r = get_body_by_line(req->line[x], name, len);
03961       if (r[0] != '\0')
03962          return r;
03963    }
03964 
03965    return "";
03966 }

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

Referenced by get_body(), and get_sdp_iterate().

03920 {
03921    if (strncasecmp(line, name, nameLen) == 0 && line[nameLen] == '=')
03922       return ast_skip_blanks(line + nameLen + 1);
03923 
03924    return "";
03925 }

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

Get caller id name from SIP headers.

Definition at line 8903 of file chan_sip.c.

Referenced by check_user_full().

08904 {
08905    const char *end = strchr(input,'<');   /* first_bracket */
08906    const char *tmp = strchr(input,'"');   /* first quote */
08907    int bytes = 0;
08908    int maxbytes = outputsize - 1;
08909 
08910    if (!end || end == input)  /* we require a part in brackets */
08911       return NULL;
08912 
08913    end--; /* move just before "<" */
08914 
08915    if (tmp && tmp <= end) {
08916       /* The quote (tmp) precedes the bracket (end+1).
08917        * Find the matching quote and return the content.
08918        */
08919       end = strchr(tmp+1, '"');
08920       if (!end)
08921          return NULL;
08922       bytes = (int) (end - tmp);
08923       /* protect the output buffer */
08924       if (bytes > maxbytes)
08925          bytes = maxbytes;
08926       ast_copy_string(output, tmp + 1, bytes);
08927    } else {
08928       /* No quoted string, or it is inside brackets. */
08929       /* clear the empty characters in the begining*/
08930       input = ast_skip_blanks(input);
08931       /* clear the empty characters in the end */
08932       while(*end && *end < 33 && end > input)
08933          end--;
08934       if (end >= input) {
08935          bytes = (int) (end - input) + 2;
08936          /* protect the output buffer */
08937          if (bytes > maxbytes)
08938             bytes = maxbytes;
08939          ast_copy_string(output, input, bytes);
08940       } else
08941          return NULL;
08942    }
08943    return output;
08944 }

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 8470 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, LOG_WARNING, sip_request::method, option_debug, sip_request::rlPart2, sip_debug_test_pvt(), SIP_INVITE, sip_methods, SIP_PAGE2_ALLOWOVERLAP, SIP_REFER, strsep(), and cfsip_methods::text.

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

08471 {
08472    char tmp[256] = "", *uri, *a;
08473    char tmpf[256] = "", *from;
08474    struct sip_request *req;
08475    char *colon;
08476    
08477    req = oreq;
08478    if (!req)
08479       req = &p->initreq;
08480 
08481    /* Find the request URI */
08482    if (req->rlPart2)
08483       ast_copy_string(tmp, req->rlPart2, sizeof(tmp));
08484    
08485    if (pedanticsipchecking)
08486       ast_uri_decode(tmp);
08487 
08488    uri = get_in_brackets(tmp);
08489 
08490    if (strncmp(uri, "sip:", 4)) {
08491       ast_log(LOG_WARNING, "Huh?  Not a SIP header (%s)?\n", uri);
08492       return -1;
08493    }
08494    uri += 4;
08495 
08496    /* Now find the From: caller ID and name */
08497    ast_copy_string(tmpf, get_header(req, "From"), sizeof(tmpf));
08498    if (!ast_strlen_zero(tmpf)) {
08499       if (pedanticsipchecking)
08500          ast_uri_decode(tmpf);
08501       from = get_in_brackets(tmpf);
08502    } else {
08503       from = NULL;
08504    }
08505    
08506    if (!ast_strlen_zero(from)) {
08507       if (strncmp(from, "sip:", 4)) {
08508          ast_log(LOG_WARNING, "Huh?  Not a SIP header (%s)?\n", from);
08509          return -1;
08510       }
08511       from += 4;
08512       if ((a = strchr(from, '@')))
08513          *a++ = '\0';
08514       else
08515          a = from;   /* just a domain */
08516       from = strsep(&from, ";"); /* Remove userinfo options */
08517       a = strsep(&a, ";");    /* Remove URI options */
08518       ast_string_field_set(p, fromdomain, a);
08519    }
08520 
08521    /* Skip any options and find the domain */
08522 
08523    /* Get the target domain */
08524    if ((a = strchr(uri, '@'))) {
08525       *a++ = '\0';
08526    } else { /* No username part */
08527       a = uri;
08528       uri = "s";  /* Set extension to "s" */
08529    }
08530    colon = strchr(a, ':'); /* Remove :port */
08531    if (colon)
08532       *colon = '\0';
08533 
08534    uri = strsep(&uri, ";");   /* Remove userinfo options */
08535    a = strsep(&a, ";");    /* Remove URI options */
08536 
08537    ast_string_field_set(p, domain, a);
08538 
08539    if (!AST_LIST_EMPTY(&domain_list)) {
08540       char domain_context[AST_MAX_EXTENSION];
08541 
08542       domain_context[0] = '\0';
08543       if (!check_sip_domain(p->domain, domain_context, sizeof(domain_context))) {
08544          if (!allow_external_domains && (req->method == SIP_INVITE || req->method == SIP_REFER)) {
08545             if (option_debug)
08546                ast_log(LOG_DEBUG, "Got SIP %s to non-local domain '%s'; refusing request.\n", sip_methods[req->method].text, p->domain);
08547             return -2;
08548          }
08549       }
08550       /* If we have a context defined, overwrite the original context */
08551       if (!ast_strlen_zero(domain_context))
08552          ast_string_field_set(p, context, domain_context);
08553    }
08554 
08555    if (sip_debug_test_pvt(p))
08556       ast_verbose("Looking for %s in %s (domain %s)\n", uri, p->context, p->domain);
08557 
08558    /* Check the dialplan for the username part of the request URI,
08559       the domain will be stored in the SIPDOMAIN variable
08560       Return 0 if we have a matching extension */
08561    if (ast_exists_extension(NULL, p->context, uri, 1, from) ||
08562       !strcmp(uri, ast_pickup_ext())) {
08563       if (!oreq)
08564          ast_string_field_set(p, exten, uri);
08565       return 0;
08566    }
08567 
08568    /* Return 1 for pickup extension or overlap dialling support (if we support it) */
08569    if((ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP) && 
08570        ast_canmatch_extension(NULL, p->context, uri, 1, from)) ||
08571        !strncmp(uri, ast_pickup_ext(), strlen(uri))) {
08572       return 1;
08573    }
08574    
08575    return -1;
08576 }

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

Get header from SIP request.

Definition at line 4042 of file chan_sip.c.

References __get_header().

04043 {
04044    int start = 0;
04045    return __get_header(req, name, &start);
04046 }

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

02234 {
02235    const char *parse = tmp;
02236    char *first_bracket;
02237 
02238    /*
02239     * Skip any quoted text until we find the part in brackets.
02240          * On any error give up and return the full string.
02241          */
02242         while ( (first_bracket = strchr(parse, '<')) ) {
02243                 char *first_quote = strchr(parse, '"');
02244 
02245       if (!first_quote || first_quote > first_bracket)
02246          break; /* no need to look at quoted part */
02247       /* the bracket is within quotes, so ignore it */
02248       parse = find_closing_quote(first_quote + 1, NULL);
02249       if (!*parse) { /* not found, return full string ? */
02250          /* XXX or be robust and return in-bracket part ? */
02251          ast_log(LOG_WARNING, "No closing quote found in '%s'\n", tmp);
02252          break;
02253       }
02254       parse++;
02255    }
02256    if (first_bracket) {
02257       char *second_bracket = strchr(first_bracket + 1, '>');
02258       if (second_bracket) {
02259          *second_bracket = '\0';
02260          tmp = first_bracket + 1;
02261       } else {
02262          ast_log(LOG_WARNING, "No closing bracket found in '%s'\n", tmp);
02263       }
02264    }
02265    return tmp;
02266 }

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

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

Referenced by handle_request_notify(), and receive_message().

09304 {
09305    int x;
09306    int y;
09307 
09308    buf[0] = '\0';
09309    y = len - strlen(buf) - 5;
09310    if (y < 0)
09311       y = 0;
09312    for (x=0;x<req->lines;x++) {
09313       strncat(buf, req->line[x], y); /* safe */
09314       y -= strlen(req->line[x]) + 1;
09315       if (y < 0)
09316          y = 0;
09317       if (y != 0)
09318          strcat(buf, "\n"); /* safe */
09319    }
09320    return 0;
09321 }

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

Get referring dnis.

Definition at line 8441 of file chan_sip.c.

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

Referenced by handle_request_invite().

08442 {
08443    char tmp[256], *c, *a;
08444    struct sip_request *req;
08445    
08446    req = oreq;
08447    if (!req)
08448       req = &p->initreq;
08449    ast_copy_string(tmp, get_header(req, "Diversion"), sizeof(tmp));
08450    if (ast_strlen_zero(tmp))
08451       return 0;
08452    c = get_in_brackets(tmp);
08453    if (strncmp(c, "sip:", 4)) {
08454       ast_log(LOG_WARNING, "Huh?  Not an RDNIS SIP header (%s)?\n", c);
08455       return -1;
08456    }
08457    c += 4;
08458    a = c;
08459    strsep(&a, "@;"); /* trim anything after @ or ; */
08460    if (sip_debug_test_pvt(p))
08461       ast_verbose("RDNIS is %s\n", c);
08462    ast_string_field_set(p, rdnis, c);
08463 
08464    return 0;
08465 }

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

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

Referenced by handle_request_refer().

08636 {
08637 
08638    const char *p_referred_by = NULL;
08639    char *h_refer_to = NULL; 
08640    char *h_referred_by = NULL;
08641    char *refer_to;
08642    const char *p_refer_to;
08643    char *referred_by_uri = NULL;
08644    char *ptr;
08645    struct sip_request *req = NULL;
08646    const char *transfer_context = NULL;
08647    struct sip_refer *referdata;
08648 
08649 
08650    req = outgoing_req;
08651    referdata = transferer->refer;
08652 
08653    if (!req)
08654       req = &transferer->initreq;
08655 
08656    p_refer_to = get_header(req, "Refer-To");
08657    if (ast_strlen_zero(p_refer_to)) {
08658       ast_log(LOG_WARNING, "Refer-To Header missing. Skipping transfer.\n");
08659       return -2;  /* Syntax error */
08660    }
08661    h_refer_to = ast_strdupa(p_refer_to);
08662    refer_to = get_in_brackets(h_refer_to);
08663    if (pedanticsipchecking)
08664       ast_uri_decode(refer_to);
08665 
08666    if (strncasecmp(refer_to, "sip:", 4)) {
08667       ast_log(LOG_WARNING, "Can't transfer to non-sip: URI.  (Refer-to: %s)?\n", refer_to);
08668       return -3;
08669    }
08670    refer_to += 4;       /* Skip sip: */
08671 
08672    /* Get referred by header if it exists */
08673    p_referred_by = get_header(req, "Referred-By");
08674    if (!ast_strlen_zero(p_referred_by)) {
08675       char *lessthan;
08676       h_referred_by = ast_strdupa(p_referred_by);
08677       if (pedanticsipchecking)
08678          ast_uri_decode(h_referred_by);
08679 
08680       /* Store referrer's caller ID name */
08681       ast_copy_string(referdata->referred_by_name, h_referred_by, sizeof(referdata->referred_by_name));
08682       if ((lessthan = strchr(referdata->referred_by_name, '<'))) {
08683          *(lessthan - 1) = '\0'; /* Space */
08684       }
08685 
08686       referred_by_uri = get_in_brackets(h_referred_by);
08687       if(strncasecmp(referred_by_uri, "sip:", 4)) {
08688          ast_log(LOG_WARNING, "Huh?  Not a sip: header (Referred-by: %s). Skipping.\n", referred_by_uri);
08689          referred_by_uri = (char *) NULL;
08690       } else {
08691          referred_by_uri += 4;      /* Skip sip: */
08692       }
08693    }
08694 
08695    /* Check for arguments in the refer_to header */
08696    if ((ptr = strchr(refer_to, '?'))) { /* Search for arguments */
08697       *ptr++ = '\0';
08698       if (!strncasecmp(ptr, "REPLACES=", 9)) {
08699          char *to = NULL, *from = NULL;
08700 
08701          /* This is an attended transfer */
08702          referdata->attendedtransfer = 1;
08703          ast_copy_string(referdata->replaces_callid, ptr+9, sizeof(referdata->replaces_callid));
08704          ast_uri_decode(referdata->replaces_callid);
08705          if ((ptr = strchr(referdata->replaces_callid, ';')))  /* Find options */ {
08706             *ptr++ = '\0';
08707          }
08708 
08709          if (ptr) {
08710             /* Find the different tags before we destroy the string */
08711             to = strcasestr(ptr, "to-tag=");
08712             from = strcasestr(ptr, "from-tag=");
08713          }
08714 
08715          /* Grab the to header */
08716          if (to) {
08717             ptr = to + 7;
08718             if ((to = strchr(ptr, '&')))
08719                *to = '\0';
08720             if ((to = strchr(ptr, ';')))
08721                *to = '\0';
08722             ast_copy_string(referdata->replaces_callid_totag, ptr, sizeof(referdata->replaces_callid_totag));
08723          }
08724 
08725          if (from) {
08726             ptr = from + 9;
08727             if ((to = strchr(ptr, '&')))
08728                *to = '\0';
08729             if ((to = strchr(ptr, ';')))
08730                *to = '\0';
08731             ast_copy_string(referdata->replaces_callid_fromtag, ptr, sizeof(referdata->replaces_callid_fromtag));
08732          }
08733 
08734          if (option_debug > 1) {
08735             if (!pedanticsipchecking)
08736                ast_log(LOG_DEBUG,"Attended transfer: Will use Replace-Call-ID : %s (No check of from/to tags)\n", referdata->replaces_callid );
08737             else
08738                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>" );
08739          }
08740       }
08741    }
08742    
08743    if ((ptr = strchr(refer_to, '@'))) {   /* Separate domain */
08744       char *urioption;
08745 
08746       *ptr++ = '\0';
08747       if ((urioption = strchr(ptr, ';')))
08748          *urioption++ = '\0';
08749       /* Save the domain for the dial plan */
08750       ast_copy_string(referdata->refer_to_domain, ptr, sizeof(referdata->refer_to_domain));
08751       if (urioption)
08752          ast_copy_string(referdata->refer_to_urioption, urioption, sizeof(referdata->refer_to_urioption));
08753    }
08754 
08755    if ((ptr = strchr(refer_to, ';')))  /* Remove options */
08756       *ptr = '\0';
08757    ast_copy_string(referdata->refer_to, refer_to, sizeof(referdata->refer_to));
08758    
08759    if (referred_by_uri) {
08760       if ((ptr = strchr(referred_by_uri, ';')))    /* Remove options */
08761          *ptr = '\0';
08762       ast_copy_string(referdata->referred_by, referred_by_uri, sizeof(referdata->referred_by));
08763    } else {
08764       referdata->referred_by[0] = '\0';
08765    }
08766 
08767    /* Determine transfer context */
08768    if (transferer->owner)  /* Mimic behaviour in res_features.c */
08769       transfer_context = pbx_builtin_getvar_helper(transferer->owner, "TRANSFER_CONTEXT");
08770 
08771    /* By default, use the context in the channel sending the REFER */
08772    if (ast_strlen_zero(transfer_context)) {
08773       transfer_context = S_OR(transferer->owner->macrocontext,
08774                S_OR(transferer->context, default_context));
08775    }
08776 
08777    ast_copy_string(referdata->refer_to_context, transfer_context, sizeof(referdata->refer_to_context));
08778    
08779    /* Either an existing extension or the parking extension */
08780    if (ast_exists_extension(NULL, transfer_context, refer_to, 1, NULL) ) {
08781       if (sip_debug_test_pvt(transferer)) {
08782          ast_verbose("SIP transfer to extension %s@%s by %s\n", refer_to, transfer_context, referred_by_uri);
08783       }
08784       /* We are ready to transfer to the extension */
08785       return 0;
08786    } 
08787    if (sip_debug_test_pvt(transferer))
08788       ast_verbose("Failed SIP Transfer to non-existing extension %s in context %s\n n", refer_to, transfer_context);
08789 
08790    /* Failure, we can't find this extension */
08791    return -1;
08792 }

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

References AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED.

Referenced by check_user_full().

08951 {
08952    char *start;
08953    char *end;
08954 
08955    start = strchr(input,':');
08956    if (!start) {
08957       output[0] = '\0';
08958       return 0;
08959    }
08960    start++;
08961 
08962    /* we found "number" */
08963    ast_copy_string(output,start,maxlen);
08964    output[maxlen-1] = '\0';
08965 
08966    end = strchr(output,'@');
08967    if (end)
08968       *end = '\0';
08969    else
08970       output[0] = '\0';
08971    if (strstr(input,"privacy=full") || strstr(input,"privacy=uri"))
08972       return AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED;
08973 
08974    return 0;
08975 }

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

Get a line from an SDP message body.

Definition at line 3945 of file chan_sip.c.

References get_sdp_iterate().

03946 {
03947    int dummy = 0;
03948 
03949    return get_sdp_iterate(&dummy, req, name);
03950 }

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

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

03932 {
03933    int len = strlen(name);
03934 
03935    while (*start < req->sdp_end) {
03936       const char *r = get_body_by_line(req->line[(*start)++], name, len);
03937       if (r[0] != '\0')
03938          return r;
03939    }
03940 
03941    return "";
03942 }

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

References ast_channel_trylock, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), 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().

08584 {
08585    struct sip_pvt *sip_pvt_ptr;
08586 
08587    ast_mutex_lock(&iflock);
08588 
08589    if (option_debug > 3 && totag)
08590       ast_log(LOG_DEBUG, "Looking for callid %s (fromtag %s totag %s)\n", callid, fromtag ? fromtag : "<no fromtag>", totag ? totag : "<no totag>");
08591 
08592    /* Search interfaces and find the match */
08593    for (sip_pvt_ptr = iflist; sip_pvt_ptr; sip_pvt_ptr = sip_pvt_ptr->next) {
08594       if (!strcmp(sip_pvt_ptr->callid, callid)) {
08595          int match = 1;
08596          char *ourtag = sip_pvt_ptr->tag;
08597 
08598          /* Go ahead and lock it (and its owner) before returning */
08599          ast_mutex_lock(&sip_pvt_ptr->lock);
08600 
08601          /* Check if tags match. If not, this is not the call we want
08602             (With a forking SIP proxy, several call legs share the
08603             call id, but have different tags)
08604          */
08605          if (pedanticsipchecking && (strcmp(fromtag, sip_pvt_ptr->theirtag) || strcmp(totag, ourtag)))
08606             match = 0;
08607 
08608          if (!match) {
08609             ast_mutex_unlock(&sip_pvt_ptr->lock);
08610             continue;
08611          }
08612 
08613          if (option_debug > 3 && totag)             
08614             ast_log(LOG_DEBUG, "Matched %s call - their tag is %s Our tag is %s\n",
08615                ast_test_flag(&sip_pvt_ptr->flags[0], SIP_OUTGOING) ? "OUTGOING": "INCOMING",
08616                sip_pvt_ptr->theirtag, sip_pvt_ptr->tag);
08617 
08618          /* deadlock avoidance... */
08619          while (sip_pvt_ptr->owner && ast_channel_trylock(sip_pvt_ptr->owner)) {
08620             ast_mutex_unlock(&sip_pvt_ptr->lock);
08621             usleep(1);
08622             ast_mutex_lock(&sip_pvt_ptr->lock);
08623          }
08624          break;
08625       }
08626    }
08627    ast_mutex_unlock(&iflock);
08628    if (option_debug > 3 && !sip_pvt_ptr)
08629       ast_log(LOG_DEBUG, "Found no match for callid %s to-tag %s from-tag %s\n", callid, totag, fromtag);
08630    return sip_pvt_ptr;
08631 }

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

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

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

12848 {
12849    const char *thetag;
12850 
12851    if (!tagbuf)
12852       return NULL;
12853    tagbuf[0] = '\0';    /* reset the buffer */
12854    thetag = get_header(req, header);
12855    thetag = strcasestr(thetag, ";tag=");
12856    if (thetag) {
12857       thetag += 5;
12858       ast_copy_string(tagbuf, thetag, tagbufsize);
12859       return strsep(&tagbuf, ";");
12860    }
12861    return NULL;
12862 }

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

References ast_clear_flag, ast_false(), ast_log(), ast_set2_flag, ast_set_flag, ast_true(), ast_variable::lineno, LOG_WARNING, ast_variable::name, 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().

15477 {
15478    int res = 1;
15479    static int dep_insecure_very = 0;
15480    static int dep_insecure_yes = 0;
15481 
15482    if (!strcasecmp(v->name, "trustrpid")) {
15483       ast_set_flag(&mask[0], SIP_TRUSTRPID);
15484       ast_set2_flag(&flags[0], ast_true(v->value), SIP_TRUSTRPID);
15485    } else if (!strcasecmp(v->name, "sendrpid")) {
15486       ast_set_flag(&mask[0], SIP_SENDRPID);
15487       ast_set2_flag(&flags[0], ast_true(v->value), SIP_SENDRPID);
15488    } else if (!strcasecmp(v->name, "g726nonstandard")) {
15489       ast_set_flag(&mask[0], SIP_G726_NONSTANDARD);
15490       ast_set2_flag(&flags[0], ast_true(v->value), SIP_G726_NONSTANDARD);
15491    } else if (!strcasecmp(v->name, "useclientcode")) {
15492       ast_set_flag(&mask[0], SIP_USECLIENTCODE);
15493       ast_set2_flag(&flags[0], ast_true(v->value), SIP_USECLIENTCODE);
15494    } else if (!strcasecmp(v->name, "dtmfmode")) {
15495       ast_set_flag(&mask[0], SIP_DTMF);
15496       ast_clear_flag(&flags[0], SIP_DTMF);
15497       if (!strcasecmp(v->value, "inband"))
15498          ast_set_flag(&flags[0], SIP_DTMF_INBAND);
15499       else if (!strcasecmp(v->value, "rfc2833"))
15500          ast_set_flag(&flags[0], SIP_DTMF_RFC2833);
15501       else if (!strcasecmp(v->value, "info"))
15502          ast_set_flag(&flags[0], SIP_DTMF_INFO);
15503       else if (!strcasecmp(v->value, "auto"))
15504          ast_set_flag(&flags[0], SIP_DTMF_AUTO);
15505       else {
15506          ast_log(LOG_WARNING, "Unknown dtmf mode '%s' on line %d, using rfc2833\n", v->value, v->lineno);
15507          ast_set_flag(&flags[0], SIP_DTMF_RFC2833);
15508       }
15509    } else if (!strcasecmp(v->name, "nat")) {
15510       ast_set_flag(&mask[0], SIP_NAT);
15511       ast_clear_flag(&flags[0], SIP_NAT);
15512       if (!strcasecmp(v->value, "never"))
15513          ast_set_flag(&flags[0], SIP_NAT_NEVER);
15514       else if (!strcasecmp(v->value, "route"))
15515          ast_set_flag(&flags[0], SIP_NAT_ROUTE);
15516       else if (ast_true(v->value))
15517          ast_set_flag(&flags[0], SIP_NAT_ALWAYS);
15518       else
15519          ast_set_flag(&flags[0], SIP_NAT_RFC3581);
15520    } else if (!strcasecmp(v->name, "canreinvite")) {
15521       ast_set_flag(&mask[0], SIP_REINVITE);
15522       ast_clear_flag(&flags[0], SIP_REINVITE);
15523       if (ast_true(v->value)) {
15524          ast_set_flag(&flags[0], SIP_CAN_REINVITE | SIP_CAN_REINVITE_NAT);
15525       } else if (!ast_false(v->value)) {
15526          char buf[64];
15527          char *word, *next = buf;
15528 
15529          ast_copy_string(buf, v->value, sizeof(buf));
15530          while ((word = strsep(&next, ","))) {
15531             if (!strcasecmp(word, "update")) {
15532                ast_set_flag(&flags[0], SIP_REINVITE_UPDATE | SIP_CAN_REINVITE);
15533             } else if (!strcasecmp(word, "nonat")) {
15534                ast_set_flag(&flags[0], SIP_CAN_REINVITE);
15535                ast_clear_flag(&flags[0], SIP_CAN_REINVITE_NAT);
15536             } else {
15537                ast_log(LOG_WARNING, "Unknown canreinvite mode '%s' on line %d\n", v->value, v->lineno);
15538             }
15539          }
15540       }
15541    } else if (!strcasecmp(v->name, "insecure")) {
15542       ast_set_flag(&mask[0], SIP_INSECURE_PORT | SIP_INSECURE_INVITE);
15543       ast_clear_flag(&flags[0], SIP_INSECURE_PORT | SIP_INSECURE_INVITE);
15544       if (!strcasecmp(v->value, "very")) {
15545          ast_set_flag(&flags[0], SIP_INSECURE_PORT | SIP_INSECURE_INVITE);
15546          if (!dep_insecure_very) {
15547             ast_log(LOG_WARNING, "insecure=very at line %d is deprecated; use insecure=port,invite instead\n", v->lineno);
15548             dep_insecure_very = 1;
15549          }
15550       }
15551       else if (ast_true(v->value)) {
15552          ast_set_flag(&flags[0], SIP_INSECURE_PORT);
15553          if (!dep_insecure_yes) {
15554             ast_log(LOG_WARNING, "insecure=%s at line %d is deprecated; use insecure=port instead\n", v->value, v->lineno);
15555             dep_insecure_yes = 1;
15556          }
15557       }
15558       else if (!ast_false(v->value)) {
15559          char buf[64];
15560          char *word, *next;
15561 
15562          ast_copy_string(buf, v->value, sizeof(buf));
15563          next = buf;
15564          while ((word = strsep(&next, ","))) {
15565             if (!strcasecmp(word, "port"))
15566                ast_set_flag(&flags[0], SIP_INSECURE_PORT);
15567             else if (!strcasecmp(word, "invite"))
15568                ast_set_flag(&flags[0], SIP_INSECURE_INVITE);
15569             else
15570                ast_log(LOG_WARNING, "Unknown insecure mode '%s' on line %d\n", v->value, v->lineno);
15571          }
15572       }
15573    } else if (!strcasecmp(v->name, "progressinband")) {
15574       ast_set_flag(&mask[0], SIP_PROG_INBAND);
15575       ast_clear_flag(&flags[0], SIP_PROG_INBAND);
15576       if (ast_true(v->value))
15577          ast_set_flag(&flags[0], SIP_PROG_INBAND_YES);
15578       else if (strcasecmp(v->value, "never"))
15579          ast_set_flag(&flags[0], SIP_PROG_INBAND_NO);
15580    } else if (!strcasecmp(v->name, "promiscredir")) {
15581       ast_set_flag(&mask[0], SIP_PROMISCREDIR);
15582       ast_set2_flag(&flags[0], ast_true(v->value), SIP_PROMISCREDIR);
15583    } else if (!strcasecmp(v->name, "videosupport")) {
15584       ast_set_flag(&mask[1], SIP_PAGE2_VIDEOSUPPORT);
15585       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_VIDEOSUPPORT);
15586    } else if (!strcasecmp(v->name, "allowoverlap")) {
15587       ast_set_flag(&mask[1], SIP_PAGE2_ALLOWOVERLAP);
15588       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_ALLOWOVERLAP);
15589    } else if (!strcasecmp(v->name, "allowsubscribe")) {
15590       ast_set_flag(&mask[1], SIP_PAGE2_ALLOWSUBSCRIBE);
15591       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_ALLOWSUBSCRIBE);
15592    } else if (!strcasecmp(v->name, "t38pt_udptl")) {
15593       ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT_UDPTL);
15594       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_T38SUPPORT_UDPTL);
15595 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS
15596    } else if (!strcasecmp(v->name, "t38pt_rtp")) {
15597       ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT_RTP);
15598       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_T38SUPPORT_RTP);
15599    } else if (!strcasecmp(v->name, "t38pt_tcp")) {
15600       ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT_TCP);
15601       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_T38SUPPORT_TCP);
15602 #endif
15603    } else if (!strcasecmp(v->name, "rfc2833compensate")) {
15604       ast_set_flag(&mask[1], SIP_PAGE2_RFC2833_COMPENSATE);
15605       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_RFC2833_COMPENSATE);
15606    } else if (!strcasecmp(v->name, "buggymwi")) {
15607       ast_set_flag(&mask[1], SIP_PAGE2_BUGGY_MWI);
15608       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_BUGGY_MWI);
15609    } else
15610       res = 0;
15611 
15612    return res;
15613 }

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

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

Referenced by handle_request_invite().

13021 {
13022    struct ast_frame *f;
13023    int earlyreplace = 0;
13024    int oneleggedreplace = 0;     /* Call with no bridge, propably IVR or voice message */
13025    struct ast_channel *c = p->owner;   /* Our incoming call */
13026    struct ast_channel *replacecall = p->refer->refer_call->owner; /* The channel we're about to take over */
13027    struct ast_channel *targetcall;     /* The bridge to the take-over target */
13028 
13029    /* Check if we're in ring state */
13030    if (replacecall->_state == AST_STATE_RING)
13031       earlyreplace = 1;
13032 
13033    /* Check if we have a bridge */
13034    if (!(targetcall = ast_bridged_channel(replacecall))) {
13035       /* We have no bridge */
13036       if (!earlyreplace) {
13037          if (option_debug > 1)
13038             ast_log(LOG_DEBUG, " Attended transfer attempted to replace call with no bridge (maybe ringing). Channel %s!\n", replacecall->name);
13039          oneleggedreplace = 1;
13040       }
13041    } 
13042    if (option_debug > 3 && targetcall && targetcall->_state == AST_STATE_RINGING)
13043          ast_log(LOG_DEBUG, "SIP transfer: Target channel is in ringing state\n");
13044 
13045    if (option_debug > 3) {
13046       if (targetcall) 
13047          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); 
13048       else
13049          ast_log(LOG_DEBUG, "SIP transfer: Invite Replace incoming channel should replace and hang up channel %s (one call leg)\n", replacecall->name); 
13050    }
13051 
13052    if (ignore) {
13053       ast_log(LOG_NOTICE, "Ignoring this INVITE with replaces in a stupid way.\n");
13054       /* We should answer something here. If we are here, the
13055          call we are replacing exists, so an accepted 
13056          can't harm */
13057       transmit_response_with_sdp(p, "200 OK", req, XMIT_RELIABLE);
13058       /* Do something more clever here */
13059       ast_channel_unlock(c);
13060       ast_mutex_unlock(&p->refer->refer_call->lock);
13061       return 1;
13062    } 
13063    if (!c) {
13064       /* What to do if no channel ??? */
13065       ast_log(LOG_ERROR, "Unable to create new channel.  Invite/replace failed.\n");
13066       transmit_response_reliable(p, "503 Service Unavailable", req);
13067       append_history(p, "Xfer", "INVITE/Replace Failed. No new channel.");
13068       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
13069       ast_mutex_unlock(&p->refer->refer_call->lock);
13070       return 1;
13071    }
13072    append_history(p, "Xfer", "INVITE/Replace received");
13073    /* We have three channels to play with
13074       channel c: New incoming call
13075       targetcall: Call from PBX to target
13076       p->refer->refer_call: SIP pvt dialog from transferer to pbx.
13077       replacecall: The owner of the previous
13078       We need to masq C into refer_call to connect to 
13079       targetcall;
13080       If we are talking to internal audio stream, target call is null.
13081    */
13082 
13083    /* Fake call progress */
13084    transmit_response(p, "100 Trying", req);
13085    ast_setstate(c, AST_STATE_RING);
13086 
13087    /* Masquerade the new call into the referred call to connect to target call 
13088       Targetcall is not touched by the masq */
13089 
13090    /* Answer the incoming call and set channel to UP state */
13091    transmit_response_with_sdp(p, "200 OK", req, XMIT_RELIABLE);
13092    ast_setstate(c, AST_STATE_UP);
13093    
13094    /* Stop music on hold and other generators */
13095    ast_quiet_chan(replacecall);
13096    ast_quiet_chan(targetcall);
13097    if (option_debug > 3)
13098       ast_log(LOG_DEBUG, "Invite/Replaces: preparing to masquerade %s into %s\n", c->name, replacecall->name);
13099    /* Unlock clone, but not original (replacecall) */
13100    ast_channel_unlock(c);
13101 
13102    /* Unlock PVT */
13103    ast_mutex_unlock(&p->refer->refer_call->lock);
13104 
13105    /* Make sure that the masq does not free our PVT for the old call */
13106    ast_set_flag(&p->refer->refer_call->flags[0], SIP_DEFER_BYE_ON_TRANSFER);  /* Delay hangup */
13107       
13108    /* Prepare the masquerade - if this does not happen, we will be gone */
13109    if(ast_channel_masquerade(replacecall, c))
13110       ast_log(LOG_ERROR, "Failed to masquerade C into Replacecall\n");
13111    else if (option_debug > 3)
13112       ast_log(LOG_DEBUG, "Invite/Replaces: Going to masquerade %s into %s\n", c->name, replacecall->name);
13113 
13114    /* The masquerade will happen as soon as someone reads a frame from the channel */
13115 
13116    /* C should now be in place of replacecall */
13117    /* ast_read needs to lock channel */
13118    ast_channel_unlock(c);
13119    
13120    if (earlyreplace || oneleggedreplace ) {
13121       /* Force the masq to happen */
13122       if ((f = ast_read(replacecall))) {  /* Force the masq to happen */
13123          ast_frfree(f);
13124          f = NULL;
13125          if (option_debug > 3)
13126             ast_log(LOG_DEBUG, "Invite/Replace:  Could successfully read frame from RING channel!\n");
13127       } else {
13128          ast_log(LOG_WARNING, "Invite/Replace:  Could not read frame from RING channel \n");
13129       }
13130       c->hangupcause = AST_CAUSE_SWITCH_CONGESTION;
13131       ast_channel_unlock(replacecall);
13132    } else { /* Bridged call, UP channel */
13133       if ((f = ast_read(replacecall))) {  /* Force the masq to happen */
13134          /* Masq ok */
13135          ast_frfree(f);
13136          f = NULL;
13137          if (option_debug > 2)
13138             ast_log(LOG_DEBUG, "Invite/Replace:  Could successfully read frame from channel! Masq done.\n");
13139       } else {
13140          ast_log(LOG_WARNING, "Invite/Replace:  Could not read frame from channel. Transfer failed\n");
13141       }
13142       ast_channel_unlock(replacecall);
13143    }
13144    ast_mutex_unlock(&p->refer->refer_call->lock);
13145 
13146    ast_setstate(c, AST_STATE_DOWN);
13147    if (option_debug > 3) {
13148       struct ast_channel *test;
13149       ast_log(LOG_DEBUG, "After transfer:----------------------------\n");
13150       ast_log(LOG_DEBUG, " -- C:        %s State %s\n", c->name, ast_state2str(c->_state));
13151       if (replacecall)
13152          ast_log(LOG_DEBUG, " -- replacecall:        %s State %s\n", replacecall->name, ast_state2str(replacecall->_state));
13153       if (p->owner) {
13154          ast_log(LOG_DEBUG, " -- P->owner: %s State %s\n", p->owner->name, ast_state2str(p->owner->_state));
13155          test = ast_bridged_channel(p->owner);
13156          if (test)
13157             ast_log(LOG_DEBUG, " -- Call bridged to P->owner: %s State %s\n", test->name, ast_state2str(test->_state));
13158          else
13159             ast_log(LOG_DEBUG, " -- No call bridged to C->owner \n");
13160       } else 
13161          ast_log(LOG_DEBUG, " -- No channel yet \n");
13162       ast_log(LOG_DEBUG, "End After transfer:----------------------------\n");
13163    }
13164 
13165    ast_channel_unlock(p->owner); /* Unlock new owner */
13166    ast_mutex_unlock(&p->lock);   /* Unlock SIP structure */
13167 
13168    /* The call should be down with no ast_channel, so hang it up */
13169    c->tech_pvt = NULL;
13170    ast_hangup(c);
13171    return 0;
13172 }

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 14638 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, LOG_WARNING, 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.

14639 {
14640    /* Called with p->lock held, as well as p->owner->lock if appropriate, keeping things
14641       relatively static */
14642    const char *cmd;
14643    const char *cseq;
14644    const char *useragent;
14645    int seqno;
14646    int len;
14647    int ignore = FALSE;
14648    int respid;
14649    int res = 0;
14650    int debug = sip_debug_test_pvt(p);
14651    char *e;
14652    int error = 0;
14653 
14654    /* Get Method and Cseq */
14655    cseq = get_header(req, "Cseq");
14656    cmd = req->header[0];
14657 
14658    /* Must have Cseq */
14659    if (ast_strlen_zero(cmd) || ast_strlen_zero(cseq)) {
14660       ast_log(LOG_ERROR, "Missing Cseq. Dropping this SIP message, it's incomplete.\n");
14661       error = 1;
14662    }
14663    if (!error && sscanf(cseq, "%d%n", &seqno, &len) != 1) {
14664       ast_log(LOG_ERROR, "No seqno in '%s'. Dropping incomplete message.\n", cmd);
14665       error = 1;
14666    }
14667    if (error) {
14668       if (!p->initreq.headers)   /* New call */
14669          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); /* Make sure we destroy this dialog */
14670       return -1;
14671    }
14672    /* Get the command XXX */
14673 
14674    cmd = req->rlPart1;
14675    e = req->rlPart2;
14676 
14677    /* Save useragent of the client */
14678    useragent = get_header(req, "User-Agent");
14679    if (!ast_strlen_zero(useragent))
14680       ast_string_field_set(p, useragent, useragent);
14681 
14682    /* Find out SIP method for incoming request */
14683    if (req->method == SIP_RESPONSE) {  /* Response to our request */
14684       /* Response to our request -- Do some sanity checks */   
14685       if (!p->initreq.headers) {
14686          if (option_debug)
14687             ast_log(LOG_DEBUG, "That's odd...  Got a response on a call we dont know about. Cseq %d Cmd %s\n", seqno, cmd);
14688          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
14689          return 0;
14690       } else if (p->ocseq && (p->ocseq < seqno)) {
14691          if (option_debug)
14692             ast_log(LOG_DEBUG, "Ignoring out of order response %d (expecting %d)\n", seqno, p->ocseq);
14693          return -1;
14694       } else if (p->ocseq && (p->ocseq != seqno)) {
14695          /* ignore means "don't do anything with it" but still have to 
14696             respond appropriately  */
14697          ignore = TRUE;
14698          ast_set_flag(req, SIP_PKT_IGNORE);
14699          ast_set_flag(req, SIP_PKT_IGNORE_RESP);
14700          append_history(p, "Ignore", "Ignoring this retransmit\n");
14701       } else if (e) {
14702          e = ast_skip_blanks(e);
14703          if (sscanf(e, "%d %n", &respid, &len) != 1) {
14704             ast_log(LOG_WARNING, "Invalid response: '%s'\n", e);
14705          } else {
14706             if (respid <= 0) {
14707                ast_log(LOG_WARNING, "Invalid SIP response code: '%d'\n", respid);
14708                return 0;
14709             }
14710             /* More SIP ridiculousness, we have to ignore bogus contacts in 100 etc responses */
14711             if ((respid == 200) || ((respid >= 300) && (respid <= 399)))
14712                extract_uri(p, req);
14713             handle_response(p, respid, e + len, req, ignore, seqno);
14714          }
14715       }
14716       return 0;
14717    }
14718 
14719    /* New SIP request coming in 
14720       (could be new request in existing SIP dialog as well...) 
14721     */         
14722    
14723    p->method = req->method;   /* Find out which SIP method they are using */
14724    if (option_debug > 3)
14725       ast_log(LOG_DEBUG, "**** Received %s (%d) - Command in SIP %s\n", sip_methods[p->method].text, sip_methods[p->method].id, cmd); 
14726 
14727    if (p->icseq && (p->icseq > seqno)) {
14728       if (option_debug)
14729          ast_log(LOG_DEBUG, "Ignoring too old SIP packet packet %d (expecting >= %d)\n", seqno, p->icseq);
14730       if (req->method != SIP_ACK)
14731          transmit_response(p, "503 Server error", req);  /* We must respond according to RFC 3261 sec 12.2 */
14732       return -1;
14733    } else if (p->icseq &&
14734          p->icseq == seqno &&
14735          req->method != SIP_ACK &&
14736          (p->method != SIP_CANCEL || ast_test_flag(&p->flags[0], SIP_ALREADYGONE))) {
14737       /* ignore means "don't do anything with it" but still have to 
14738          respond appropriately.  We do this if we receive a repeat of
14739          the last sequence number  */
14740       ignore = 2;
14741       ast_set_flag(req, SIP_PKT_IGNORE);
14742       ast_set_flag(req, SIP_PKT_IGNORE_REQ);
14743       if (option_debug > 2)
14744          ast_log(LOG_DEBUG, "Ignoring SIP message because of retransmit (%s Seqno %d, ours %d)\n", sip_methods[p->method].text, p->icseq, seqno);
14745    }
14746       
14747    if (seqno >= p->icseq)
14748       /* Next should follow monotonically (but not necessarily 
14749          incrementally -- thanks again to the genius authors of SIP --
14750          increasing */
14751       p->icseq = seqno;
14752 
14753    /* Find their tag if we haven't got it */
14754    if (ast_strlen_zero(p->theirtag)) {
14755       char tag[128];
14756 
14757       gettag(req, "From", tag, sizeof(tag));
14758       ast_string_field_set(p, theirtag, tag);
14759    }
14760    snprintf(p->lastmsg, sizeof(p->lastmsg), "Rx: %s", cmd);
14761 
14762    if (pedanticsipchecking) {
14763       /* If this is a request packet without a from tag, it's not
14764          correct according to RFC 3261  */
14765       /* Check if this a new request in a new dialog with a totag already attached to it,
14766          RFC 3261 - section 12.2 - and we don't want to mess with recovery  */
14767       if (!p->initreq.headers && ast_test_flag(req, SIP_PKT_WITH_TOTAG)) {
14768          /* If this is a first request and it got a to-tag, it is not for us */
14769          if (!ast_test_flag(req, SIP_PKT_IGNORE) && req->method == SIP_INVITE) {
14770             transmit_response_reliable(p, "481 Call/Transaction Does Not Exist", req);
14771             /* Will cease to exist after ACK */
14772          } else if (req->method != SIP_ACK) {
14773             transmit_response(p, "481 Call/Transaction Does Not Exist", req);
14774             sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
14775          }
14776          return res;
14777       }
14778    }
14779 
14780    if (!e && (p->method == SIP_INVITE || p->method == SIP_SUBSCRIBE || p->method == SIP_REGISTER || p->method == SIP_NOTIFY)) {
14781       transmit_response(p, "400 Bad request", req);
14782       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
14783       return -1;
14784    }
14785 
14786    /* Handle various incoming SIP methods in requests */
14787    switch (p->method) {
14788    case SIP_OPTIONS:
14789       res = handle_request_options(p, req);
14790       break;
14791    case SIP_INVITE:
14792       res = handle_request_invite(p, req, debug, seqno, sin, recount, e);
14793       break;
14794    case SIP_REFER:
14795       res = handle_request_refer(p, req, debug, ignore, seqno, nounlock);
14796       break;
14797    case SIP_CANCEL:
14798       res = handle_request_cancel(p, req);
14799       break;
14800    case SIP_BYE:
14801       res = handle_request_bye(p, req);
14802       break;
14803    case SIP_MESSAGE:
14804       res = handle_request_message(p, req);
14805       break;
14806    case SIP_SUBSCRIBE:
14807       res = handle_request_subscribe(p, req, sin, seqno, e);
14808       break;
14809    case SIP_REGISTER:
14810       res = handle_request_register(p, req, sin, e);
14811       break;
14812    case SIP_INFO:
14813       if (ast_test_flag(req, SIP_PKT_DEBUG))
14814          ast_verbose("Receiving INFO!\n");
14815       if (!ignore) 
14816          handle_request_info(p, req);
14817       else  /* if ignoring, transmit response */
14818          transmit_response(p, "200 OK", req);
14819       break;
14820    case SIP_NOTIFY:
14821       res = handle_request_notify(p, req, sin, seqno, e);
14822       break;
14823    case SIP_ACK:
14824       /* Make sure we don't ignore this */
14825       if (seqno == p->pendinginvite) {
14826          p->invitestate = INV_TERMINATED;
14827          p->pendinginvite = 0;
14828          __sip_ack(p, seqno, FLAG_RESPONSE, 0);
14829          if (find_sdp(req)) {
14830             if (process_sdp(p, req))
14831                return -1;
14832          } 
14833          check_pendings(p);
14834       }
14835       /* Got an ACK that we did not match. Ignore silently */
14836       if (!p->lastinvite && ast_strlen_zero(p->randdata))
14837          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
14838       break;
14839    default:
14840       transmit_response_with_allow(p, "501 Method Not Implemented", req, 0);
14841       ast_log(LOG_NOTICE, "Unknown SIP command '%s' from '%s'\n", 
14842          cmd, ast_inet_ntoa(p->sa.sin_addr));
14843       /* If this is some new method, and we don't have a call, destroy it now */
14844       if (!p->initreq.headers)
14845          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
14846       break;
14847    }
14848    return res;
14849 }

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

Handle incoming BYE request.

Definition at line 14217 of file chan_sip.c.

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

Referenced by handle_request().

14218 {
14219    struct ast_channel *c=NULL;
14220    int res;
14221    struct ast_channel *bridged_to;
14222    
14223    /* If we have an INCOMING invite that we haven't answered, terminate that transaction */
14224    if (p->pendinginvite && !ast_test_flag(&p->flags[0], SIP_OUTGOING) && !ast_test_flag(req, SIP_PKT_IGNORE) && !p->owner) 
14225       transmit_response_reliable(p, "487 Request Terminated", &p->initreq);
14226 
14227    p->invitestate = INV_TERMINATED;
14228 
14229    copy_request(&p->initreq, req);
14230    check_via(p, req);
14231    sip_alreadygone(p);
14232 
14233    /* Get RTCP quality before end of call */
14234    if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY) || p->owner) {
14235       char *audioqos, *videoqos;
14236       if (p->rtp) {
14237          audioqos = ast_rtp_get_quality(p->rtp, NULL);
14238          if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY))
14239             append_history(p, "RTCPaudio", "Quality:%s", audioqos);
14240          if (p->owner)
14241             pbx_builtin_setvar_helper(p->owner, "RTPAUDIOQOS", audioqos);
14242       }
14243       if (p->vrtp) {
14244          videoqos = ast_rtp_get_quality(p->vrtp, NULL);
14245          if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY))
14246             append_history(p, "RTCPvideo", "Quality:%s", videoqos);
14247          if (p->owner)
14248             pbx_builtin_setvar_helper(p->owner, "RTPVIDEOQOS", videoqos);
14249       }
14250    }
14251 
14252    stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */
14253 
14254    if (!ast_strlen_zero(get_header(req, "Also"))) {
14255       ast_log(LOG_NOTICE, "Client '%s' using deprecated BYE/Also transfer method.  Ask vendor to support REFER instead\n",
14256          ast_inet_ntoa(p->recv.sin_addr));
14257       if (ast_strlen_zero(p->context))
14258          ast_string_field_set(p, context, default_context);
14259       res = get_also_info(p, req);
14260       if (!res) {
14261          c = p->owner;
14262          if (c) {
14263             bridged_to = ast_bridged_channel(c);
14264             if (bridged_to) {
14265                /* Don't actually hangup here... */
14266                ast_queue_control(c, AST_CONTROL_UNHOLD);
14267                ast_async_goto(bridged_to, p->context, p->refer->refer_to,1);
14268             } else
14269                ast_queue_hangup(p->owner);
14270          }
14271       } else {
14272          ast_log(LOG_WARNING, "Invalid transfer information from '%s'\n", ast_inet_ntoa(p->recv.sin_addr));
14273          if (p->owner)
14274             ast_queue_hangup(p->owner);
14275       }
14276    } else if (p->owner) {
14277       ast_queue_hangup(p->owner);
14278       if (option_debug > 2)
14279          ast_log(LOG_DEBUG, "Received bye, issuing owner hangup\n");
14280    } else {
14281       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
14282       if (option_debug > 2)
14283          ast_log(LOG_DEBUG, "Received bye, no owner, selfdestruct soon.\n");
14284    }
14285    transmit_response(p, "200 OK", req);
14286 
14287    return 1;
14288 }

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

Handle incoming CANCEL request.

Definition at line 14129 of file chan_sip.c.

References ast_channel::_state, ast_log(), ast_queue_hangup(), AST_STATE_UP, check_via(), DEFAULT_TRANS_TIMEOUT, sip_pvt::initreq, INV_CANCELLED, sip_pvt::invitestate, sip_request::len, LOG_DEBUG, option_debug, sip_pvt::owner, sip_dual::req, sip_alreadygone(), sip_scheddestroy(), stop_media_flows(), transmit_response(), and transmit_response_reliable().

Referenced by handle_request().

14130 {
14131       
14132    check_via(p, req);
14133    sip_alreadygone(p);
14134    p->invitestate = INV_CANCELLED;
14135    
14136    if (p->owner && p->owner->_state == AST_STATE_UP) {
14137       /* This call is up, cancel is ignored, we need a bye */
14138       transmit_response(p, "200 OK", req);
14139       if (option_debug)
14140          ast_log(LOG_DEBUG, "Got CANCEL on an answered call. Ignoring... \n");
14141       return 0;
14142    }
14143    stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */
14144 
14145    if (p->owner)
14146       ast_queue_hangup(p->owner);
14147    else
14148       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
14149    if (p->initreq.len > 0) {
14150       transmit_response_reliable(p, "487 Request Terminated", &p->initreq);
14151       transmit_response(p, "200 OK", req);
14152       return 1;
14153    } else {
14154       transmit_response(p, "481 Call Leg Does Not Exist", req);
14155       return 0;
14156    }
14157 }

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 10775 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(), LOG_WARNING, sip_pvt::owner, sip_scheddestroy(), SIP_USECLIENTCODE, sipdebug, and transmit_response().

Referenced by handle_request().

10776 {
10777    char buf[1024];
10778    unsigned int event;
10779    const char *c = get_header(req, "Content-Type");
10780 
10781    /* Need to check the media/type */
10782    if (!strcasecmp(c, "application/dtmf-relay") ||
10783        !strcasecmp(c, "application/vnd.nortelnetworks.digits")) {
10784       unsigned int duration = 0;
10785 
10786       /* Try getting the "signal=" part */
10787       if (ast_strlen_zero(c = get_body(req, "Signal")) && ast_strlen_zero(c = get_body(req, "d"))) {
10788          ast_log(LOG_WARNING, "Unable to retrieve DTMF signal from INFO message from %s\n", p->callid);
10789          transmit_response(p, "200 OK", req); /* Should return error */
10790          return;
10791       } else {
10792          ast_copy_string(buf, c, sizeof(buf));
10793       }
10794 
10795       if (!ast_strlen_zero((c = get_body(req, "Duration"))))
10796          duration = atoi(c);
10797       if (!duration)
10798          duration = 100; /* 100 ms */
10799 
10800       if (!p->owner) {  /* not a PBX call */
10801          transmit_response(p, "481 Call leg/transaction does not exist", req);
10802          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
10803          return;
10804       }
10805 
10806       if (ast_strlen_zero(buf)) {
10807          transmit_response(p, "200 OK", req);
10808          return;
10809       }
10810 
10811       if (buf[0] == '*')
10812          event = 10;
10813       else if (buf[0] == '#')
10814          event = 11;
10815       else if ((buf[0] >= 'A') && (buf[0] <= 'D'))
10816          event = 12 + buf[0] - 'A';
10817       else
10818          event = atoi(buf);
10819       if (event == 16) {
10820          /* send a FLASH event */
10821          struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_FLASH, };
10822          ast_queue_frame(p->owner, &f);
10823          if (sipdebug)
10824             ast_verbose("* DTMF-relay event received: FLASH\n");
10825       } else {
10826          /* send a DTMF event */
10827          struct ast_frame f = { AST_FRAME_DTMF, };
10828          if (event < 10) {
10829             f.subclass = '0' + event;
10830          } else if (event < 11) {
10831             f.subclass = '*';
10832          } else if (event < 12) {
10833             f.subclass = '#';
10834          } else if (event < 16) {
10835             f.subclass = 'A' + (event - 12);
10836          }
10837          f.len = duration;
10838          ast_queue_frame(p->owner, &f);
10839          if (sipdebug)
10840             ast_verbose("* DTMF-relay event received: %c\n", f.subclass);
10841       }
10842       transmit_response(p, "200 OK", req);
10843       return;
10844    } else if (!strcasecmp(c, "application/media_control+xml")) {
10845       /* Eh, we'll just assume it's a fast picture update for now */
10846       if (p->owner)
10847          ast_queue_control(p->owner, AST_CONTROL_VIDUPDATE);
10848       transmit_response(p, "200 OK", req);
10849       return;
10850    } else if (!ast_strlen_zero(c = get_header(req, "X-ClientCode"))) {
10851       /* Client code (from SNOM phone) */
10852       if (ast_test_flag(&p->flags[0], SIP_USECLIENTCODE)) {
10853          if (p->owner && p->owner->cdr)
10854             ast_cdr_setuserfield(p->owner, c);
10855          if (p->owner && ast_bridged_channel(p->owner) && ast_bridged_channel(p->owner)->cdr)
10856             ast_cdr_setuserfield(ast_bridged_channel(p->owner), c);
10857          transmit_response(p, "200 OK", req);
10858       } else {
10859          transmit_response(p, "403 Unauthorized", req);
10860       }
10861       return;
10862    }
10863    /* Other type of INFO message, not really understood by Asterisk */
10864    /* if (get_msg_text(buf, sizeof(buf), req)) { */
10865 
10866    ast_log(LOG_WARNING, "Unable to parse INFO message from %s. Content %s\n", p->callid, buf);
10867    transmit_response(p, "415 Unsupported media type", req);
10868    return;
10869 }

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 
) [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 13181 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, 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, LOG_WARNING, make_our_tag(), option_debug, sip_pvt::owner, parse_ok_contact(), parse_sip_options(), sip_pvt::pendinginvite, process_sdp(), sip_pvt::refer, sip_refer::refer_call, sip_pvt::rtp, S_OR, sip_alreadygone(), sip_cancel_destroy(), SIP_DTMF, SIP_DTMF_RFC2833, sip_handle_t38_reinvite(), SIP_INVITE, sip_new(), SIP_NO_HISTORY, SIP_OPT_REPLACES, SIP_OUTGOING, SIP_PAGE2_ALLOWOVERLAP, SIP_PAGE2_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, and XMIT_RELIABLE.

Referenced by handle_request().

13182 {
13183    int res = 1;
13184    int gotdest;
13185    const char *p_replaces;
13186    char *replace_id = NULL;
13187    const char *required;
13188    unsigned int required_profile = 0;
13189    struct ast_channel *c = NULL;    /* New channel */
13190 
13191    /* Find out what they support */
13192    if (!p->sipoptions) {
13193       const char *supported = get_header(req, "Supported");
13194       if (!ast_strlen_zero(supported))
13195          parse_sip_options(p, supported);
13196    }
13197 
13198    /* Find out what they require */
13199    required = get_header(req, "Require");
13200    if (!ast_strlen_zero(required)) {
13201       required_profile = parse_sip_options(NULL, required);
13202       if (required_profile && required_profile != SIP_OPT_REPLACES) {
13203          /* At this point we only support REPLACES */
13204          transmit_response_with_unsupported(p, "420 Bad extension (unsupported)", req, required);
13205          ast_log(LOG_WARNING,"Received SIP INVITE with unsupported required extension: %s\n", required);
13206          p->invitestate = INV_COMPLETED;
13207          if (!p->lastinvite)
13208             sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
13209          return -1;
13210       }
13211    }
13212 
13213    /* Check if this is a loop */
13214    if (ast_test_flag(&p->flags[0], SIP_OUTGOING) && p->owner && (p->owner->_state != AST_STATE_UP)) {
13215       /* This is a call to ourself.  Send ourselves an error code and stop
13216          processing immediately, as SIP really has no good mechanism for
13217          being able to call yourself */
13218       /* If pedantic is on, we need to check the tags. If they're different, this is
13219          in fact a forked call through a SIP proxy somewhere. */
13220       transmit_response(p, "482 Loop Detected", req);
13221       p->invitestate = INV_COMPLETED;
13222       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
13223       return 0;
13224    }
13225    
13226    if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->pendinginvite) {
13227       /* We already have a pending invite. Sorry. You are on hold. */
13228       transmit_response(p, "491 Request Pending", req);
13229       if (option_debug)
13230          ast_log(LOG_DEBUG, "Got INVITE on call where we already have pending INVITE, deferring that - %s\n", p->callid);
13231       /* Don't destroy dialog here */
13232       return 0;
13233    }
13234 
13235    p_replaces = get_header(req, "Replaces");
13236    if (!ast_strlen_zero(p_replaces)) {
13237       /* We have a replaces header */
13238       char *ptr;
13239       char *fromtag = NULL;
13240       char *totag = NULL;
13241       char *start, *to;
13242       int error = 0;
13243 
13244       if (p->owner) {
13245          if (option_debug > 2)
13246             ast_log(LOG_DEBUG, "INVITE w Replaces on existing call? Refusing action. [%s]\n", p->callid);
13247          transmit_response(p, "400 Bad request", req);   /* The best way to not not accept the transfer */
13248          /* Do not destroy existing call */
13249          return -1;
13250       }
13251 
13252       if (sipdebug && option_debug > 2)
13253          ast_log(LOG_DEBUG, "INVITE part of call transfer. Replaces [%s]\n", p_replaces);
13254       /* Create a buffer we can manipulate */
13255       replace_id = ast_strdupa(p_replaces);
13256       ast_uri_decode(replace_id);
13257 
13258       if (!p->refer && !sip_refer_allocate(p)) {
13259          transmit_response(p, "500 Server Internal Error", req);
13260          append_history(p, "Xfer", "INVITE/Replace Failed. Out of memory.");
13261          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
13262          p->invitestate = INV_COMPLETED;
13263          return -1;
13264       }
13265 
13266       /*  Todo: (When we find phones that support this)
13267          if the replaces header contains ";early-only"
13268          we can only replace the call in early
13269          stage, not after it's up.
13270 
13271          If it's not in early mode, 486 Busy.
13272       */
13273       
13274       /* Skip leading whitespace */
13275       replace_id = ast_skip_blanks(replace_id);
13276 
13277       start = replace_id;
13278       while ( (ptr = strsep(&start, ";")) ) {
13279          ptr = ast_skip_blanks(ptr); /* XXX maybe unnecessary ? */
13280          if ( (to = strcasestr(ptr, "to-tag=") ) )
13281             totag = to + 7;   /* skip the keyword */
13282          else if ( (to = strcasestr(ptr, "from-tag=") ) ) {
13283             fromtag = to + 9; /* skip the keyword */
13284             fromtag = strsep(&fromtag, "&"); /* trim what ? */
13285          }
13286       }
13287 
13288       if (sipdebug && option_debug > 3) 
13289          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>");
13290 
13291 
13292       /* Try to find call that we are replacing 
13293          If we have a Replaces  header, we need to cancel that call if we succeed with this call 
13294       */
13295       if ((p->refer->refer_call = get_sip_pvt_byid_locked(replace_id, totag, fromtag)) == NULL) {
13296          ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-existent call id (%s)!\n", replace_id);
13297          transmit_response(p, "481 Call Leg Does Not Exist (Replaces)", req);
13298          error = 1;
13299       }
13300 
13301       /* At this point, bot the pvt and the owner of the call to be replaced is locked */
13302 
13303       /* The matched call is the call from the transferer to Asterisk .
13304          We want to bridge the bridged part of the call to the 
13305          incoming invite, thus taking over the refered call */
13306 
13307       if (p->refer->refer_call == p) {
13308          ast_log(LOG_NOTICE, "INVITE with replaces into it's own call id (%s == %s)!\n", replace_id, p->callid);
13309          p->refer->refer_call = NULL;
13310          transmit_response(p, "400 Bad request", req);   /* The best way to not not accept the transfer */
13311          error = 1;
13312       }
13313 
13314       if (!error && !p->refer->refer_call->owner) {
13315          /* Oops, someting wrong anyway, no owner, no call */
13316          ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-existing call id (%s)!\n", replace_id);
13317          /* Check for better return code */
13318          transmit_response(p, "481 Call Leg Does Not Exist (Replace)", req);
13319          error = 1;
13320       }
13321 
13322       if (!error && p->refer->refer_call->owner->_state != AST_STATE_RING && p->refer->refer_call->owner->_state != AST_STATE_UP ) {
13323          ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-ringing or active call id (%s)!\n", replace_id);
13324          transmit_response(p, "603 Declined (Replaces)", req);
13325          error = 1;
13326       }
13327 
13328       if (error) {   /* Give up this dialog */
13329          append_history(p, "Xfer", "INVITE/Replace Failed.");
13330          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
13331          ast_mutex_unlock(&p->lock);
13332          if (p->refer->refer_call) {
13333             ast_mutex_unlock(&p->refer->refer_call->lock);
13334             ast_channel_unlock(p->refer->refer_call->owner);
13335          }
13336          p->invitestate = INV_COMPLETED;
13337          return -1;
13338       }
13339    }
13340 
13341 
13342    /* Check if this is an INVITE that sets up a new dialog or
13343       a re-invite in an existing dialog */
13344 
13345    if (!ast_test_flag(req, SIP_PKT_IGNORE)) {
13346       int newcall = (p->initreq.headers ? TRUE : FALSE);
13347 
13348       sip_cancel_destroy(p);
13349       /* This also counts as a pending invite */
13350       p->pendinginvite = seqno;
13351       check_via(p, req);
13352 
13353       copy_request(&p->initreq, req);     /* Save this INVITE as the transaction basis */
13354       if (!p->owner) {  /* Not a re-invite */
13355          if (debug)
13356             ast_verbose("Using INVITE request as basis request - %s\n", p->callid);
13357          if (newcall)
13358             append_history(p, "Invite", "New call: %s", p->callid);
13359          parse_ok_contact(p, req);
13360       } else { /* Re-invite on existing call */
13361          ast_clear_flag(&p->flags[0], SIP_OUTGOING);  /* This is now an inbound dialog */
13362          /* Handle SDP here if we already have an owner */
13363          if (find_sdp(req)) {
13364             if (process_sdp(p, req)) {
13365                transmit_response(p, "488 Not acceptable here", req);
13366                if (!p->lastinvite)
13367                   sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
13368                return -1;
13369             }
13370          } else {
13371             p->jointcapability = p->capability;
13372             if (option_debug)
13373                ast_log(LOG_DEBUG, "Hm....  No sdp for the moment\n");
13374          }
13375          if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) /* This is a response, note what it was for */
13376             append_history(p, "ReInv", "Re-invite received");
13377       }
13378    } else if (debug)
13379       ast_verbose("Ignoring this INVITE request\n");
13380 
13381    
13382    if (!p->lastinvite && !ast_test_flag(req, SIP_PKT_IGNORE) && !p->owner) {
13383       /* This is a new invite */
13384       /* Handle authentication if this is our first invite */
13385       res = check_user(p, req, SIP_INVITE, e, XMIT_RELIABLE, sin);
13386       if (res == AUTH_CHALLENGE_SENT) {
13387          p->invitestate = INV_COMPLETED;     /* Needs to restart in another INVITE transaction */
13388          return 0;
13389       }
13390       if (res < 0) { /* Something failed in authentication */
13391          if (res == AUTH_FAKE_AUTH) {
13392             ast_log(LOG_NOTICE, "Sending fake auth rejection for user %s\n", get_header(req, "From"));
13393             transmit_fake_auth_response(p, req, 1);
13394          } else {
13395             ast_log(LOG_NOTICE, "Failed to authenticate user %s\n", get_header(req, "From"));
13396             transmit_response_reliable(p, "403 Forbidden", req);
13397          }
13398          p->invitestate = INV_COMPLETED;  
13399          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
13400          ast_string_field_free(p, theirtag);
13401          return 0;
13402       }
13403 
13404       /* We have a succesful authentication, process the SDP portion if there is one */
13405       if (find_sdp(req)) {
13406          if (process_sdp(p, req)) {
13407             /* Unacceptable codecs */
13408             transmit_response_reliable(p, "488 Not acceptable here", req);
13409             p->invitestate = INV_COMPLETED;  
13410             sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
13411             if (option_debug)
13412                ast_log(LOG_DEBUG, "No compatible codecs for this SIP call.\n");
13413             return -1;
13414          }
13415       } else { /* No SDP in invite, call control session */
13416          p->jointcapability = p->capability;
13417          if (option_debug > 1)
13418             ast_log(LOG_DEBUG, "No SDP in Invite, third party call control\n");
13419       }
13420 
13421       /* Queue NULL frame to prod ast_rtp_bridge if appropriate */
13422       /* This seems redundant ... see !p-owner above */
13423       if (p->owner)
13424          ast_queue_frame(p->owner, &ast_null_frame);
13425 
13426 
13427       /* Initialize the context if it hasn't been already */
13428       if (ast_strlen_zero(p->context))
13429          ast_string_field_set(p, context, default_context);
13430 
13431 
13432       /* Check number of concurrent calls -vs- incoming limit HERE */
13433       if (option_debug)
13434          ast_log(LOG_DEBUG, "Checking SIP call limits for device %s\n", p->username);
13435       if ((res = update_call_counter(p, INC_CALL_LIMIT))) {
13436          if (res < 0) {
13437             ast_log(LOG_NOTICE, "Failed to place call for user %s, too many calls\n", p->username);
13438             transmit_response_reliable(p, "480 Temporarily Unavailable (Call limit) ", req);
13439             sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
13440             p->invitestate = INV_COMPLETED;  
13441          }
13442          return 0;
13443       }
13444       gotdest = get_destination(p, NULL); /* Get destination right away */
13445       get_rdnis(p, NULL);        /* Get redirect information */
13446       extract_uri(p, req);       /* Get the Contact URI */
13447       build_contact(p);       /* Build our contact header */
13448 
13449       if (p->rtp) {
13450          ast_rtp_setdtmf(p->rtp, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833);
13451          ast_rtp_setdtmfcompensate(p->rtp, ast_test_flag(&p->flags[1], SIP_PAGE2_RFC2833_COMPENSATE));
13452       }
13453 
13454       if (!replace_id && gotdest) { /* No matching extension found */
13455          if (gotdest == 1 && ast_test_flag(&p->flags[1], SIP_PAGE2_ALLOWOVERLAP))
13456             transmit_response_reliable(p, "484 Address Incomplete", req);
13457          else
13458             transmit_response_reliable(p, "404 Not Found", req);
13459          p->invitestate = INV_COMPLETED;  
13460          update_call_counter(p, DEC_CALL_LIMIT);
13461          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
13462          return 0;
13463       } else {
13464          /* If no extension was specified, use the s one */
13465          /* Basically for calling to IP/Host name only */
13466          if (ast_strlen_zero(p->exten))
13467             ast_string_field_set(p, exten, "s");
13468          /* Initialize our tag */   
13469 
13470          make_our_tag(p->tag, sizeof(p->tag));
13471          /* First invitation - create the channel */
13472          c = sip_new(p, AST_STATE_DOWN, S_OR(p->username, NULL));
13473          *recount = 1;
13474 
13475          /* Save Record-Route for any later requests we make on this dialogue */
13476          build_route(p, req, 0);
13477 
13478          if (c) {
13479             /* Pre-lock the call */
13480             ast_channel_lock(c);
13481          }
13482       }
13483    } else {
13484       if (option_debug > 1 && sipdebug) {
13485          if (!ast_test_flag(req, SIP_PKT_IGNORE))
13486             ast_log(LOG_DEBUG, "Got a SIP re-invite for call %s\n", p->callid);
13487          else
13488             ast_log(LOG_DEBUG, "Got a SIP re-transmit of INVITE for call %s\n", p->callid);
13489       }
13490       c = p->owner;
13491    }
13492 
13493    if (!ast_test_flag(req, SIP_PKT_IGNORE) && p)
13494       p->lastinvite = seqno;
13495 
13496    if (replace_id) {    /* Attended transfer or call pickup - we're the target */
13497       /* Go and take over the target call */
13498       if (sipdebug && option_debug > 3)
13499          ast_log(LOG_DEBUG, "Sending this call to the invite/replcaes handler %s\n", p->callid);
13500       return handle_invite_replaces(p, req, debug, ast_test_flag(req, SIP_PKT_IGNORE), seqno, sin);
13501    }
13502 
13503 
13504    if (c) { /* We have a call  -either a new call or an old one (RE-INVITE) */
13505       switch(c->_state) {
13506       case AST_STATE_DOWN:
13507          if (option_debug > 1)
13508             ast_log(LOG_DEBUG, "%s: New call is still down.... Trying... \n", c->name);
13509          transmit_response(p, "100 Trying", req);
13510          p->invitestate = INV_PROCEEDING;
13511          ast_setstate(c, AST_STATE_RING);
13512          if (strcmp(p->exten, ast_pickup_ext())) { /* Call to extension -start pbx on this call */
13513             enum ast_pbx_result res;
13514 
13515             res = ast_pbx_start(c);
13516 
13517             switch(res) {
13518             case AST_PBX_FAILED:
13519                ast_log(LOG_WARNING, "Failed to start PBX :(\n");
13520                p->invitestate = INV_COMPLETED;
13521                if (ast_test_flag(req, SIP_PKT_IGNORE))
13522                   transmit_response(p, "503 Unavailable", req);
13523                else
13524                   transmit_response_reliable(p, "503 Unavailable", req);
13525                break;
13526             case AST_PBX_CALL_LIMIT:
13527                ast_log(LOG_WARNING, "Failed to start PBX (call limit reached) \n");
13528                p->invitestate = INV_COMPLETED;
13529                if (ast_test_flag(req, SIP_PKT_IGNORE))
13530                   transmit_response(p, "480 Temporarily Unavailable", req);
13531                else
13532                   transmit_response_reliable(p, "480 Temporarily Unavailable", req);
13533                break;
13534             case AST_PBX_SUCCESS:
13535                /* nothing to do */
13536                break;
13537             }
13538 
13539             if (res) {
13540 
13541                /* Unlock locks so ast_hangup can do its magic */
13542                ast_mutex_unlock(&c->lock);
13543                ast_mutex_unlock(&p->lock);
13544                ast_hangup(c);
13545                ast_mutex_lock(&p->lock);
13546                c = NULL;
13547             }
13548          } else { /* Pickup call in call group */
13549             ast_channel_unlock(c);
13550             if (ast_pickup_call(c)) {
13551                ast_log(LOG_NOTICE, "Nothing to pick up for %s\n", p->callid);
13552                if (ast_test_flag(req, SIP_PKT_IGNORE))
13553                   transmit_response(p, "503 Unavailable", req);   /* OEJ - Right answer? */
13554                else
13555                   transmit_response_reliable(p, "503 Unavailable", req);
13556                sip_alreadygone(p);
13557                /* Unlock locks so ast_hangup can do its magic */
13558                ast_mutex_unlock(&p->lock);
13559                c->hangupcause = AST_CAUSE_CALL_REJECTED;
13560             } else {
13561                ast_mutex_unlock(&p->lock);
13562                ast_setstate(c, AST_STATE_DOWN);
13563                c->hangupcause = AST_CAUSE_NORMAL_CLEARING;
13564             }
13565             p->invitestate = INV_COMPLETED;
13566             ast_hangup(c);
13567             ast_mutex_lock(&p->lock);
13568             c = NULL;
13569          }
13570          break;
13571       case AST_STATE_RING:
13572          transmit_response(p, "100 Trying", req);
13573          p->invitestate = INV_PROCEEDING;
13574          break;
13575       case AST_STATE_RINGING:
13576          transmit_response(p, "180 Ringing", req);
13577          p->invitestate = INV_PROCEEDING;
13578          break;
13579       case AST_STATE_UP:
13580          if (option_debug > 1)
13581             ast_log(LOG_DEBUG, "%s: This call is UP.... \n", c->name);
13582 
13583          if (p->t38.state == T38_PEER_REINVITE) {
13584             struct ast_channel *bridgepeer = NULL;
13585             struct sip_pvt *bridgepvt = NULL;
13586             
13587             if ((bridgepeer = ast_bridged_channel(p->owner))) {
13588                /* 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*/
13589                /*! XXX: we should also check here does the other side supports t38 at all !!! XXX */
13590                if (bridgepeer->tech == &sip_tech || bridgepeer->tech == &sip_tech_info) {
13591                   bridgepvt = (struct sip_pvt*)bridgepeer->tech_pvt;
13592                   if (bridgepvt->t38.state == T38_DISABLED) {
13593                      if (bridgepvt->udptl) { /* If everything is OK with other side's udptl struct */
13594                         /* Send re-invite to the bridged channel */
13595                         sip_handle_t38_reinvite(bridgepeer, p, 1);
13596                      } else { /* Something is wrong with peers udptl struct */
13597                         ast_log(LOG_WARNING, "Strange... The other side of the bridge don't have udptl struct\n");
13598                         ast_mutex_lock(&bridgepvt->lock);
13599                         bridgepvt->t38.state = T38_DISABLED;
13600                         ast_mutex_unlock(&bridgepvt->lock);
13601                         if (option_debug > 1)
13602                            ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", bridgepvt->t38.state, bridgepeer->name);
13603                         if (ast_test_flag(req, SIP_PKT_IGNORE))
13604                            transmit_response(p, "488 Not acceptable here", req);
13605                         else
13606                            transmit_response_reliable(p, "488 Not acceptable here", req);
13607                      
13608                      }
13609                   } else {
13610                      /* The other side is already setup for T.38 most likely so we need to acknowledge this too */
13611                      transmit_response_with_t38_sdp(p, "200 OK", req, XMIT_CRITICAL);
13612                      p->t38.state = T38_ENABLED;
13613                      if (option_debug)
13614                         ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>");
13615                   }
13616                } else {
13617                   /* Other side is not a SIP channel */
13618                   if (ast_test_flag(req, SIP_PKT_IGNORE))
13619                      transmit_response(p, "488 Not acceptable here", req);
13620                   else
13621                      transmit_response_reliable(p, "488 Not acceptable here", req);
13622                   p->t38.state = T38_DISABLED;
13623                   if (option_debug > 1)
13624                      ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>");
13625 
13626                   if (!p->lastinvite) /* Only destroy if this is *not* a re-invite */
13627                      sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
13628                }
13629             } else {
13630                /* we are not bridged in a call */
13631                transmit_response_with_t38_sdp(p, "200 OK", req, XMIT_CRITICAL);
13632                p->t38.state = T38_ENABLED;
13633                if (option_debug)
13634                   ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>");
13635             }
13636          } else if (p->t38.state == T38_DISABLED) { /* Channel doesn't have T38 offered or enabled */
13637             int sendok = TRUE;
13638 
13639             /* If we are bridged to a channel that has T38 enabled than this is a case of RTP re-invite after T38 session */
13640             /* so handle it here (re-invite other party to RTP) */
13641             struct ast_channel *bridgepeer = NULL;
13642             struct sip_pvt *bridgepvt = NULL;
13643             if ((bridgepeer = ast_bridged_channel(p->owner))) {
13644                if (bridgepeer->tech == &sip_tech || bridgepeer->tech == &sip_tech_info) {
13645                   bridgepvt = (struct sip_pvt*)bridgepeer->tech_pvt;
13646                   /* Does the bridged peer have T38 ? */
13647                   if (bridgepvt->t38.state == T38_ENABLED) {
13648                      ast_log(LOG_WARNING, "RTP re-invite after T38 session not handled yet !\n");
13649                      /* Insted of this we should somehow re-invite the other side of the bridge to RTP */
13650                      if (ast_test_flag(req, SIP_PKT_IGNORE))
13651                         transmit_response(p, "488 Not Acceptable Here (unsupported)", req);
13652                      else
13653                         transmit_response_reliable(p, "488 Not Acceptable Here (unsupported)", req);
13654                      sendok = FALSE;
13655                   } 
13656                   /* No bridged peer with T38 enabled*/
13657                }
13658             } 
13659             /* Respond to normal re-invite */
13660             if (sendok)
13661                transmit_response_with_sdp(p, "200 OK", req, XMIT_CRITICAL);
13662 
13663          }
13664          p->invitestate = INV_TERMINATED;
13665          break;
13666       default:
13667          ast_log(LOG_WARNING, "Don't know how to handle INVITE in state %d\n", c->_state);
13668          transmit_response(p, "100 Trying", req);
13669          break;
13670       }
13671    } else {
13672       if (p && (p->autokillid == -1)) {
13673          const char *msg;
13674 
13675          if (!p->jointcapability)
13676             msg = "488 Not Acceptable Here (codec error)";
13677          else {
13678             ast_log(LOG_NOTICE, "Unable to create/find SIP channel for this INVITE\n");
13679             msg = "503 Unavailable";
13680          }
13681          if (ast_test_flag(req, SIP_PKT_IGNORE))
13682             transmit_response(p, msg, req);
13683          else
13684             transmit_response_reliable(p, msg, req);
13685          p->invitestate = INV_COMPLETED;
13686          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
13687       }
13688    }
13689    return res;
13690 }

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

Handle incoming MESSAGE request.

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

14292 {
14293    if (!ast_test_flag(req, SIP_PKT_IGNORE)) {
14294       if (ast_test_flag(req, SIP_PKT_DEBUG))
14295          ast_verbose("Receiving message!\n");
14296       receive_message(p, req);
14297    } else
14298       transmit_response(p, "202 Accepted", req);
14299    return 1;
14300 }

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

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

Referenced by handle_request().

12866 {
12867    /* This is mostly a skeleton for future improvements */
12868    /* Mostly created to return proper answers on notifications on outbound REFER's */
12869    int res = 0;
12870    const char *event = get_header(req, "Event");
12871    char *eventid = NULL;
12872    char *sep;
12873 
12874    if( (sep = strchr(event, ';')) ) {  /* XXX bug here - overwriting string ? */
12875       *sep++ = '\0';
12876       eventid = sep;
12877    }
12878    
12879    if (option_debug > 1 && sipdebug)
12880       ast_log(LOG_DEBUG, "Got NOTIFY Event: %s\n", event);
12881 
12882    if (strcmp(event, "refer")) {
12883       /* We don't understand this event. */
12884       /* Here's room to implement incoming voicemail notifications :-) */
12885       transmit_response(p, "489 Bad event", req);
12886       res = -1;
12887    } else {
12888       /* Save nesting depth for now, since there might be other events we will
12889          support in the future */
12890 
12891       /* Handle REFER notifications */
12892 
12893       char buf[1024];
12894       char *cmd, *code;
12895       int respcode;
12896       int success = TRUE;
12897 
12898       /* EventID for each transfer... EventID is basically the REFER cseq 
12899 
12900        We are getting notifications on a call that we transfered
12901        We should hangup when we are getting a 200 OK in a sipfrag
12902        Check if we have an owner of this event */
12903       
12904       /* Check the content type */
12905       if (strncasecmp(get_header(req, "Content-Type"), "message/sipfrag", strlen("message/sipfrag"))) {
12906          /* We need a sipfrag */
12907          transmit_response(p, "400 Bad request", req);
12908          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
12909          return -1;
12910       }
12911 
12912       /* Get the text of the attachment */
12913       if (get_msg_text(buf, sizeof(buf), req)) {
12914          ast_log(LOG_WARNING, "Unable to retrieve attachment from NOTIFY %s\n", p->callid);
12915          transmit_response(p, "400 Bad request", req);
12916          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
12917          return -1;
12918       }
12919 
12920       /*
12921       From the RFC...
12922       A minimal, but complete, implementation can respond with a single
12923          NOTIFY containing either the body:
12924                SIP/2.0 100 Trying
12925       
12926          if the subscription is pending, the body:
12927                SIP/2.0 200 OK
12928          if the reference was successful, the body:
12929                SIP/2.0 503 Service Unavailable
12930          if the reference failed, or the body:
12931                SIP/2.0 603 Declined
12932 
12933          if the REFER request was accepted before approval to follow the
12934          reference could be obtained and that approval was subsequently denied
12935          (see Section 2.4.7).
12936       
12937       If there are several REFERs in the same dialog, we need to
12938       match the ID of the event header...
12939       */
12940       if (option_debug > 2)
12941          ast_log(LOG_DEBUG, "* SIP Transfer NOTIFY Attachment: \n---%s\n---\n", buf);
12942       cmd = ast_skip_blanks(buf);
12943       code = cmd;
12944       /* We are at SIP/2.0 */
12945       while(*code && (*code > 32)) {   /* Search white space */
12946          code++;
12947       }
12948       *code++ = '\0';
12949       code = ast_skip_blanks(code);
12950       sep = code;
12951       sep++;
12952       while(*sep && (*sep > 32)) {  /* Search white space */
12953          sep++;
12954       }
12955       *sep++ = '\0';       /* Response string */
12956       respcode = atoi(code);
12957       switch (respcode) {
12958       case 100:   /* Trying: */
12959       case 101:   /* dialog establishment */
12960          /* Don't do anything yet */
12961          break;
12962       case 183:   /* Ringing: */
12963          /* Don't do anything yet */
12964          break;
12965       case 200:   /* OK: The new call is up, hangup this call */
12966          /* Hangup the call that we are replacing */
12967          break;
12968       case 301: /* Moved permenantly */
12969       case 302: /* Moved temporarily */
12970          /* Do we get the header in the packet in this case? */
12971          success = FALSE;
12972          break;
12973       case 503:   /* Service Unavailable: The new call failed */
12974             /* Cancel transfer, continue the call */
12975          success = FALSE;
12976          break;
12977       case 603:   /* Declined: Not accepted */
12978             /* Cancel transfer, continue the current call */
12979          success = FALSE;
12980          break;
12981       }
12982       if (!success) {
12983          ast_log(LOG_NOTICE, "Transfer failed. Sorry. Nothing further to do with this call\n");
12984       }
12985       
12986       /* Confirm that we received this packet */
12987       transmit_response(p, "200 OK", req);
12988    };
12989 
12990    if (!p->lastinvite)
12991       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
12992 
12993    return res;
12994 }

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

Handle incoming OPTIONS request.

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

12998 {
12999    int res;
13000 
13001    res = get_destination(p, req);
13002    build_contact(p);
13003    /* XXX Should we authenticate OPTIONS? XXX */
13004    if (ast_strlen_zero(p->context))
13005       ast_string_field_set(p, context, default_context);
13006    if (res < 0)
13007       transmit_response_with_allow(p, "404 Not Found", req, 0);
13008    else 
13009       transmit_response_with_allow(p, "200 OK", req, 0);
13010    /* Destroy if this OPTIONS was the opening request, but not if
13011       it's in the middle of a normal call flow. */
13012    if (!p->lastinvite)
13013       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
13014 
13015    return res;
13016 }

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

13857 {
13858    struct sip_dual current;   /* Chan1: Call between asterisk and transferer */
13859                /* Chan2: Call between asterisk and transferee */
13860 
13861    int res = 0;
13862 
13863    if (ast_test_flag(req, SIP_PKT_DEBUG))
13864       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");
13865 
13866    if (!p->owner) {
13867       /* This is a REFER outside of an existing SIP dialog */
13868       /* We can't handle that, so decline it */
13869       if (option_debug > 2)
13870          ast_log(LOG_DEBUG, "Call %s: Declined REFER, outside of dialog...\n", p->callid);
13871       transmit_response(p, "603 Declined (No dialog)", req);
13872       if (!ast_test_flag(req, SIP_PKT_IGNORE)) {
13873          append_history(p, "Xfer", "Refer failed. Outside of dialog.");
13874          sip_alreadygone(p);
13875          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
13876       }
13877       return 0;
13878    }  
13879 
13880 
13881    /* Check if transfer is allowed from this device */
13882    if (p->allowtransfer == TRANSFER_CLOSED ) {
13883       /* Transfer not allowed, decline */
13884       transmit_response(p, "603 Declined (policy)", req);
13885       append_history(p, "Xfer", "Refer failed. Allowtransfer == closed.");
13886       /* Do not destroy SIP session */
13887       return 0;
13888    }
13889 
13890    if(!ignore && ast_test_flag(&p->flags[0], SIP_GOTREFER)) {
13891       /* Already have a pending REFER */  
13892       transmit_response(p, "491 Request pending", req);
13893       append_history(p, "Xfer", "Refer failed. Request pending.");
13894       return 0;
13895    }
13896 
13897    /* Allocate memory for call transfer data */
13898    if (!p->refer && !sip_refer_allocate(p)) {
13899       transmit_response(p, "500 Internal Server Error", req);
13900       append_history(p, "Xfer", "Refer failed. Memory allocation error.");
13901       return -3;
13902    }
13903 
13904    res = get_refer_info(p, req); /* Extract headers */
13905 
13906    p->refer->status = REFER_SENT;
13907 
13908    if (res != 0) {
13909       switch (res) {
13910       case -2: /* Syntax error */
13911          transmit_response(p, "400 Bad Request (Refer-to missing)", req);
13912          append_history(p, "Xfer", "Refer failed. Refer-to missing.");
13913          if (ast_test_flag(req, SIP_PKT_DEBUG) && option_debug)
13914             ast_log(LOG_DEBUG, "SIP transfer to black hole can't be handled (no refer-to: )\n");
13915          break;
13916       case -3:
13917          transmit_response(p, "603 Declined (Non sip: uri)", req);
13918          append_history(p, "Xfer", "Refer failed. Non SIP uri");
13919          if (ast_test_flag(req, SIP_PKT_DEBUG) && option_debug)
13920             ast_log(LOG_DEBUG, "SIP transfer to non-SIP uri denied\n");
13921          break;
13922       default:
13923          /* Refer-to extension not found, fake a failed transfer */
13924          transmit_response(p, "202 Accepted", req);
13925          append_history(p, "Xfer", "Refer failed. Bad extension.");
13926          transmit_notify_with_sipfrag(p, seqno, "404 Not found", TRUE);
13927          ast_clear_flag(&p->flags[0], SIP_GOTREFER);  
13928          if (ast_test_flag(req, SIP_PKT_DEBUG) && option_debug)
13929             ast_log(LOG_DEBUG, "SIP transfer to bad extension: %s\n", p->refer->refer_to);
13930          break;
13931       } 
13932       return 0;
13933    }
13934    if (ast_strlen_zero(p->context))
13935       ast_string_field_set(p, context, default_context);
13936 
13937    /* If we do not support SIP domains, all transfers are local */
13938    if (allow_external_domains && check_sip_domain(p->refer->refer_to_domain, NULL, 0)) {
13939       p->refer->localtransfer = 1;
13940       if (sipdebug && option_debug > 2)
13941          ast_log(LOG_DEBUG, "This SIP transfer is local : %s\n", p->refer->refer_to_domain);
13942    } else if (AST_LIST_EMPTY(&domain_list)) {
13943       /* This PBX don't bother with SIP domains, so all transfers are local */
13944       p->refer->localtransfer = 1;
13945    } else
13946       if (sipdebug && option_debug > 2)
13947          ast_log(LOG_DEBUG, "This SIP transfer is to a remote SIP extension (remote domain %s)\n", p->refer->refer_to_domain);
13948    
13949    /* Is this a repeat of a current request? Ignore it */
13950    /* Don't know what else to do right now. */
13951    if (ignore) 
13952       return res;
13953 
13954    /* If this is a blind transfer, we have the following
13955       channels to work with:
13956       - chan1, chan2: The current call between transferer and transferee (2 channels)
13957       - target_channel: A new call from the transferee to the target (1 channel)
13958       We need to stay tuned to what happens in order to be able
13959       to bring back the call to the transferer */
13960 
13961    /* If this is a attended transfer, we should have all call legs within reach:
13962       - chan1, chan2: The call between the transferer and transferee (2 channels)
13963       - target_channel, targetcall_pvt: The call between the transferer and the target (2 channels)
13964    We want to bridge chan2 with targetcall_pvt!
13965    
13966       The replaces call id in the refer message points
13967       to the call leg between Asterisk and the transferer.
13968       So we need to connect the target and the transferee channel
13969       and hangup the two other channels silently 
13970    
13971       If the target is non-local, the call ID could be on a remote
13972       machine and we need to send an INVITE with replaces to the
13973       target. We basically handle this as a blind transfer
13974       and let the sip_call function catch that we need replaces
13975       header in the INVITE.
13976    */
13977 
13978 
13979    /* Get the transferer's channel */
13980    current.chan1 = p->owner;
13981 
13982    /* Find the other part of the bridge (2) - transferee */
13983    current.chan2 = ast_bridged_channel(current.chan1);
13984    
13985    if (sipdebug && option_debug > 2)
13986       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>");
13987 
13988    if (!current.chan2 && !p->refer->attendedtransfer) {
13989       /* No bridged channel, propably IVR or echo or similar... */
13990       /* Guess we should masquerade or something here */
13991       /* Until we figure it out, refuse transfer of such calls */
13992       if (sipdebug && option_debug > 2)
13993          ast_log(LOG_DEBUG,"Refused SIP transfer on non-bridged channel.\n");
13994       p->refer->status = REFER_FAILED;
13995       append_history(p, "Xfer", "Refer failed. Non-bridged channel.");
13996       transmit_response(p, "603 Declined", req);
13997       return -1;
13998    }
13999 
14000    if (current.chan2) {
14001       if (sipdebug && option_debug > 3)
14002          ast_log(LOG_DEBUG, "Got SIP transfer, applying to bridged peer '%s'\n", current.chan2->name);
14003 
14004       ast_queue_control(current.chan1, AST_CONTROL_UNHOLD);
14005    }
14006 
14007    ast_set_flag(&p->flags[0], SIP_GOTREFER); 
14008 
14009    /* Attended transfer: Find all call legs and bridge transferee with target*/
14010    if (p->refer->attendedtransfer) {
14011       if ((res = local_attended_transfer(p, &current, req, seqno)))
14012          return res; /* We're done with the transfer */
14013       /* Fall through for remote transfers that we did not find locally */
14014       if (sipdebug && option_debug > 3)
14015          ast_log(LOG_DEBUG, "SIP attended transfer: Still not our call - generating INVITE with replaces\n");
14016       /* Fallthrough if we can't find the call leg internally */
14017    }
14018 
14019 
14020    /* Parking a call */
14021    if (p->refer->localtransfer && !strcmp(p->refer->refer_to, ast_parking_ext())) {
14022       /* Must release c's lock now, because it will not longer be accessible after the transfer! */
14023       *nounlock = 1;
14024       ast_channel_unlock(current.chan1);
14025       copy_request(&current.req, req);
14026       ast_clear_flag(&p->flags[0], SIP_GOTREFER);  
14027       p->refer->status = REFER_200OK;
14028       append_history(p, "Xfer", "REFER to call parking.");
14029       if (sipdebug && option_debug > 3)
14030          ast_log(LOG_DEBUG, "SIP transfer to parking: trying to park %s. Parked by %s\n", current.chan2->name, current.chan1->name);
14031       sip_park(current.chan2, current.chan1, req, seqno);
14032       return res;
14033    } 
14034 
14035    /* Blind transfers and remote attended xfers */
14036    transmit_response(p, "202 Accepted", req);
14037 
14038    if (current.chan1 && current.chan2) {
14039       if (option_debug > 2)
14040          ast_log(LOG_DEBUG, "chan1->name: %s\n", current.chan1->name);
14041       pbx_builtin_setvar_helper(current.chan1, "BLINDTRANSFER", current.chan2->name);
14042    }
14043    if (current.chan2) {
14044       pbx_builtin_setvar_helper(current.chan2, "BLINDTRANSFER", current.chan1->name);
14045       pbx_builtin_setvar_helper(current.chan2, "SIPDOMAIN", p->refer->refer_to_domain);
14046       pbx_builtin_setvar_helper(current.chan2, "SIPTRANSFER", "yes");
14047       /* One for the new channel */
14048       pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER", "yes");
14049       /* Attended transfer to remote host, prepare headers for the INVITE */
14050       if (p->refer->referred_by) 
14051          pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER_REFERER", p->refer->referred_by);
14052    }
14053    /* Generate a Replaces string to be used in the INVITE during attended transfer */
14054    if (p->refer->replaces_callid && !ast_strlen_zero(p->refer->replaces_callid)) {
14055       char tempheader[BUFSIZ];
14056       snprintf(tempheader, sizeof(tempheader), "%s%s%s%s%s", p->refer->replaces_callid, 
14057             p->refer->replaces_callid_totag ? ";to-tag=" : "", 
14058             p->refer->replaces_callid_totag, 
14059             p->refer->replaces_callid_fromtag ? ";from-tag=" : "",
14060             p->refer->replaces_callid_fromtag);
14061       if (current.chan2)
14062          pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER_REPLACES", tempheader);
14063    }
14064    /* Must release lock now, because it will not longer
14065          be accessible after the transfer! */
14066    *nounlock = 1;
14067    ast_channel_unlock(current.chan1);
14068    ast_channel_unlock(current.chan2);
14069 
14070    /* Connect the call */
14071 
14072    /* FAKE ringing if not attended transfer */
14073    if (!p->refer->attendedtransfer)
14074       transmit_notify_with_sipfrag(p, seqno, "183 Ringing", FALSE); 
14075       
14076    /* For blind transfer, this will lead to a new call */
14077    /* For attended transfer to remote host, this will lead to
14078          a new SIP call with a replaces header, if the dial plan allows it 
14079    */
14080    if (!current.chan2) {
14081       /* We have no bridge, so we're talking with Asterisk somehow */
14082       /* We need to masquerade this call */
14083       /* What to do to fix this situation:
14084          * Set up the new call in a new channel 
14085          * Let the new channel masq into this channel
14086          Please add that code here :-)
14087       */
14088       p->refer->status = REFER_FAILED;
14089       transmit_notify_with_sipfrag(p, seqno, "503 Service Unavailable (can't handle one-legged xfers)", TRUE);
14090       ast_clear_flag(&p->flags[0], SIP_GOTREFER);  
14091       append_history(p, "Xfer", "Refer failed (only bridged calls).");
14092       return -1;
14093    }
14094    ast_set_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER);   /* Delay hangup */
14095 
14096    /* For blind transfers, move the call to the new extensions. For attended transfers on multiple
14097       servers - generate an INVITE with Replaces. Either way, let the dial plan decided  */
14098    res = ast_async_goto(current.chan2, p->refer->refer_to_context, p->refer->refer_to, 1);
14099 
14100    if (!res) {
14101       /* Success  - we have a new channel */
14102       if (option_debug > 2)
14103          ast_log(LOG_DEBUG, "%s transfer succeeded. Telling transferer.\n", p->refer->attendedtransfer? "Attended" : "Blind");
14104       transmit_notify_with_sipfrag(p, seqno, "200 Ok", TRUE);
14105       if (p->refer->localtransfer)
14106          p->refer->status = REFER_200OK;
14107       if (p->owner)
14108          p->owner->hangupcause = AST_CAUSE_NORMAL_CLEARING;
14109       append_history(p, "Xfer", "Refer succeeded.");
14110       ast_clear_flag(&p->flags[0], SIP_GOTREFER);  
14111       /* Do not hangup call, the other side do that when we say 200 OK */
14112       /* We could possibly implement a timer here, auto congestion */
14113       res = 0;
14114    } else {
14115       ast_clear_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Don't delay hangup */
14116       if (option_debug > 2)
14117          ast_log(LOG_DEBUG, "%s transfer failed. Resuming original call.\n", p->refer->attendedtransfer? "Attended" : "Blind");
14118       append_history(p, "Xfer", "Refer failed.");
14119       /* Failure of some kind */
14120       p->refer->status = REFER_FAILED;
14121       transmit_notify_with_sipfrag(p, seqno, "503 Service Unavailable", TRUE);
14122       ast_clear_flag(&p->flags[0], SIP_GOTREFER);  
14123       res = -1;
14124    }
14125    return res;
14126 }

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

References append_history, ast_inet_ntoa(), ast_log(), ast_test_flag, ast_verbose(), AUTH_NOT_FOUND, 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().

14595 {
14596    enum check_auth_result res;
14597 
14598    /* Use this as the basis */
14599    if (ast_test_flag(req, SIP_PKT_DEBUG))
14600       ast_verbose("Using latest REGISTER request as basis request\n");
14601    copy_request(&p->initreq, req);
14602    check_via(p, req);
14603    if ((res = register_verify(p, sin, req, e)) < 0) {
14604       const char *reason = "";
14605 
14606       switch (res) {
14607       case AUTH_SECRET_FAILED:
14608          reason = "Wrong password";
14609          break;
14610       case AUTH_USERNAME_MISMATCH:
14611          reason = "Username/auth name mismatch";
14612          break;
14613       case AUTH_NOT_FOUND:
14614          reason = "No matching peer found";
14615          break;
14616       case AUTH_UNKNOWN_DOMAIN:
14617          reason = "Not a local domain";
14618          break;
14619       default:
14620          break;
14621       }
14622       ast_log(LOG_NOTICE, "Registration from '%s' failed for '%s' - %s\n",
14623          get_header(req, "To"), ast_inet_ntoa(sin->sin_addr),
14624          reason);
14625    }
14626    if (res < 1) {
14627       /* Destroy the session, but keep us around for just a bit in case they don't
14628          get our 200 OK */
14629       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
14630    }
14631    append_history(p, "RegRequest", "%s : Account %s", res ? "Failed": "Succeeded", get_header(req, "To"));
14632    return res;
14633 }

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

References append_history, AST_EXTENSION_REMOVED, ast_extension_state(), ast_extension_state2str(), ast_extension_state_add(), ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_strdupa, ast_string_field_build, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_verbose(), ASTOBJ_UNLOCK, ASTOBJ_UNREF, ASTOBJ_WRLOCK, AUTH_CHALLENGE_SENT, AUTH_FAKE_AUTH, sip_pvt::autokillid, build_contact(), cb_extensionstate(), check_user_full(), check_via(), context, copy_request(), CPIM_PIDF_XML, DIALOG_INFO_XML, sip_pvt::dialogver, event, sip_pvt::expiry, FALSE, sip_pvt::flags, get_destination(), get_header(), sip_request::headers, iflist, sip_pvt::initreq, sip_pvt::lastinvite, sip_pvt::laststate, sip_pvt::lock, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, sip_peer::mailbox, make_our_tag(), sip_request::method, 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().

14304 {
14305    int gotdest;
14306    int res = 0;
14307    int firststate = AST_EXTENSION_REMOVED;
14308    struct sip_peer *authpeer = NULL;
14309    const char *eventheader = get_header(req, "Event");   /* Get Event package name */
14310    const char *accept = get_header(req, "Accept");
14311    int resubscribe = (p->subscribed != NONE);
14312    char *temp, *event;
14313 
14314    if (p->initreq.headers) {  
14315       /* We already have a dialog */
14316       if (p->initreq.method != SIP_SUBSCRIBE) {
14317          /* This is a SUBSCRIBE within another SIP dialog, which we do not support */
14318          /* For transfers, this could happen, but since we haven't seen it happening, let us just refuse this */
14319          transmit_response(p, "403 Forbidden (within dialog)", req);
14320          /* Do not destroy session, since we will break the call if we do */
14321          if (option_debug)
14322             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);
14323          return 0;
14324       } else if (ast_test_flag(req, SIP_PKT_DEBUG)) {
14325          if (option_debug) {
14326             if (resubscribe)
14327                ast_log(LOG_DEBUG, "Got a re-subscribe on existing subscription %s\n", p->callid);
14328             else
14329                ast_log(LOG_DEBUG, "Got a new subscription %s (possibly with auth)\n", p->callid);
14330          }
14331       }
14332    }
14333 
14334    /* Check if we have a global disallow setting on subscriptions. 
14335       if so, we don't have to check peer/user settings after auth, which saves a lot of processing
14336    */
14337    if (!global_allowsubscribe) {
14338       transmit_response(p, "403 Forbidden (policy)", req);
14339       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
14340       return 0;
14341    }
14342 
14343    if (!ast_test_flag(req, SIP_PKT_IGNORE) && !resubscribe) {  /* Set up dialog, new subscription */
14344       /* Use this as the basis */
14345       if (ast_test_flag(req, SIP_PKT_DEBUG))
14346          ast_verbose("Creating new subscription\n");
14347 
14348       copy_request(&p->initreq, req);
14349       check_via(p, req);
14350    } else if (ast_test_flag(req, SIP_PKT_DEBUG) && ast_test_flag(req, SIP_PKT_IGNORE))
14351       ast_verbose("Ignoring this SUBSCRIBE request\n");
14352 
14353    /* Find parameters to Event: header value and remove them for now */
14354    if (ast_strlen_zero(eventheader)) {
14355       transmit_response(p, "489 Bad Event", req);
14356       if (option_debug > 1)
14357          ast_log(LOG_DEBUG, "Received SIP subscribe for unknown event package: <none>\n");
14358       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
14359       return 0;
14360    }
14361 
14362    if ( (strchr(eventheader, ';'))) {
14363       event = ast_strdupa(eventheader);   /* Since eventheader is a const, we can't change it */
14364       temp = strchr(event, ';');       
14365       *temp = '\0';           /* Remove any options for now */
14366                      /* We might need to use them later :-) */
14367    } else
14368       event = (char *) eventheader;    /* XXX is this legal ? */
14369 
14370    /* Handle authentication */
14371    res = check_user_full(p, req, SIP_SUBSCRIBE, e, 0, sin, &authpeer);
14372    /* if an authentication response was sent, we are done here */
14373    if (res == AUTH_CHALLENGE_SENT) {
14374       if (authpeer)
14375          ASTOBJ_UNREF(authpeer, sip_destroy_peer);
14376       return 0;
14377    }
14378    if (res < 0) {
14379       if (res == AUTH_FAKE_AUTH) {
14380          ast_log(LOG_NOTICE, "Sending fake auth rejection for user %s\n", get_header(req, "From"));
14381          transmit_fake_auth_response(p, req, 1);
14382       } else {
14383          ast_log(LOG_NOTICE, "Failed to authenticate user %s for SUBSCRIBE\n", get_header(req, "From"));
14384          transmit_response_reliable(p, "403 Forbidden", req);
14385       }
14386       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
14387       if (authpeer)
14388          ASTOBJ_UNREF(authpeer, sip_destroy_peer);
14389       return 0;
14390    }
14391 
14392    /* Check if this user/peer is allowed to subscribe at all */
14393    if (!ast_test_flag(&p->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)) {
14394       transmit_response(p, "403 Forbidden (policy)", req);
14395       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
14396       if (authpeer)
14397          ASTOBJ_UNREF(authpeer, sip_destroy_peer);
14398       return 0;
14399    }
14400 
14401    /* Get destination right away */
14402    gotdest = get_destination(p, NULL);
14403 
14404    /* Initialize the context if it hasn't been already;
14405       note this is done _after_ handling any domain lookups,
14406       because the context specified there is for calls, not
14407       subscriptions
14408    */
14409    if (!ast_strlen_zero(p->subscribecontext))
14410       ast_string_field_set(p, context, p->subscribecontext);
14411    else if (ast_strlen_zero(p->context))
14412       ast_string_field_set(p, context, default_context);
14413 
14414    /* Get full contact header - this needs to be used as a request URI in NOTIFY's */
14415    parse_ok_contact(p, req);
14416 
14417    build_contact(p);
14418    if (gotdest) {
14419       transmit_response(p, "404 Not Found", req);
14420       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
14421       if (authpeer)
14422          ASTOBJ_UNREF(authpeer, sip_destroy_peer);
14423       return 0;
14424    }
14425 
14426    /* Initialize tag for new subscriptions */   
14427    if (ast_strlen_zero(p->tag))
14428       make_our_tag(p->tag, sizeof(p->tag));
14429 
14430    if (!strcmp(event, "presence") || !strcmp(event, "dialog")) { /* Presence, RFC 3842 */
14431       if (authpeer)  /* No need for authpeer here */
14432          ASTOBJ_UNREF(authpeer, sip_destroy_peer);
14433 
14434       /* Header from Xten Eye-beam Accept: multipart/related, application/rlmi+xml, application/pidf+xml, application/xpidf+xml */
14435       /* Polycom phones only handle xpidf+xml, even if they say they can
14436          handle pidf+xml as well
14437       */
14438       if (strstr(p->useragent, "Polycom")) {
14439          p->subscribed = XPIDF_XML;
14440       } else if (strstr(accept, "application/pidf+xml")) {
14441          p->subscribed = PIDF_XML;         /* RFC 3863 format */
14442       } else if (strstr(accept, "application/dialog-info+xml")) {
14443          p->subscribed = DIALOG_INFO_XML;
14444          /* IETF draft: draft-ietf-sipping-dialog-package-05.txt */
14445       } else if (strstr(accept, "application/cpim-pidf+xml")) {
14446          p->subscribed = CPIM_PIDF_XML;    /* RFC 3863 format */
14447       } else if (strstr(accept, "application/xpidf+xml")) {
14448          p->subscribed = XPIDF_XML;        /* Early pre-RFC 3863 format with MSN additions (Microsoft Messenger) */
14449       } else if (ast_strlen_zero(accept)) {
14450          if (p->subscribed == NONE) { /* if the subscribed field is not already set, and there is no accept header... */
14451             transmit_response(p, "489 Bad Event", req);
14452   
14453             ast_log(LOG_WARNING,"SUBSCRIBE failure: no Accept header: pvt: stateid: %d, laststate: %d, dialogver: %d, subscribecont: '%s', subscribeuri: '%s'\n",
14454                p->stateid, p->laststate, p->dialogver, p->subscribecontext, p->subscribeuri);
14455             ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
14456             return 0;
14457          }
14458          /* if p->subscribed is non-zero, then accept is not obligatory; according to rfc 3265 section 3.1.3, at least.
14459             so, we'll just let it ride, keeping the value from a previous subscription, and not abort the subscription */
14460       } else {
14461          /* Can't find a format for events that we know about */
14462          char mybuf[200];
14463          snprintf(mybuf,sizeof(mybuf),"489 Bad Event (format %s)", accept);
14464          transmit_response(p, mybuf, req);
14465  
14466          ast_log(LOG_WARNING,"SUBSCRIBE failure: unrecognized format: '%s' pvt: subscribed: %d, stateid: %d, laststate: %d, dialogver: %d, subscribecont: '%s', subscribeuri: '%s'\n",
14467             accept, (int)p->subscribed, p->stateid, p->laststate, p->dialogver, p->subscribecontext, p->subscribeuri);
14468          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
14469          return 0;
14470       }
14471    } else if (!strcmp(event, "message-summary")) { 
14472       if (!ast_strlen_zero(accept) && strcmp(accept, "application/simple-message-summary")) {
14473          /* Format requested that we do not support */
14474          transmit_response(p, "406 Not Acceptable", req);
14475          if (option_debug > 1)
14476             ast_log(LOG_DEBUG, "Received SIP mailbox subscription for unknown format: %s\n", accept);
14477          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
14478          if (authpeer)  /* No need for authpeer here */
14479             ASTOBJ_UNREF(authpeer, sip_destroy_peer);
14480          return 0;
14481       }
14482       /* Looks like they actually want a mailbox status 
14483         This version of Asterisk supports mailbox subscriptions
14484         The subscribed URI needs to exist in the dial plan
14485         In most devices, this is configurable to the voicemailmain extension you use
14486       */
14487       if (!authpeer || ast_strlen_zero(authpeer->mailbox)) {
14488          transmit_response(p, "404 Not found (no mailbox)", req);
14489          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
14490          ast_log(LOG_NOTICE, "Received SIP subscribe for peer without mailbox: %s\n", authpeer->name);
14491          if (authpeer)  /* No need for authpeer here */
14492             ASTOBJ_UNREF(authpeer, sip_destroy_peer);
14493          return 0;
14494       }
14495 
14496       p->subscribed = MWI_NOTIFICATION;
14497       if (authpeer->mwipvt && authpeer->mwipvt != p)  /* Destroy old PVT if this is a new one */
14498          /* We only allow one subscription per peer */
14499          sip_destroy(authpeer->mwipvt);
14500       authpeer->mwipvt = p;      /* Link from peer to pvt */
14501       p->relatedpeer = authpeer; /* Link from pvt to peer */
14502    } else { /* At this point, Asterisk does not understand the specified event */
14503       transmit_response(p, "489 Bad Event", req);
14504       if (option_debug > 1)
14505          ast_log(LOG_DEBUG, "Received SIP subscribe for unknown event package: %s\n", event);
14506       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
14507       if (authpeer)  /* No need for authpeer here */
14508          ASTOBJ_UNREF(authpeer, sip_destroy_peer);
14509       return 0;
14510    }
14511 
14512    if (p->subscribed != MWI_NOTIFICATION && !resubscribe)
14513       p->stateid = ast_extension_state_add(p->context, p->exten, cb_extensionstate, p);
14514 
14515    if (!ast_test_flag(req, SIP_PKT_IGNORE) && p)
14516       p->lastinvite = seqno;
14517    if (p && !ast_test_flag(&p->flags[0], SIP_NEEDDESTROY)) {
14518       p->expiry = atoi(get_header(req, "Expires"));
14519 
14520       /* check if the requested expiry-time is within the approved limits from sip.conf */
14521       if (p->expiry > max_expiry)
14522          p->expiry = max_expiry;
14523       if (p->expiry < min_expiry && p->expiry > 0)
14524          p->expiry = min_expiry;
14525 
14526       if (sipdebug || option_debug > 1) {
14527          if (p->subscribed == MWI_NOTIFICATION && p->relatedpeer)
14528             ast_log(LOG_DEBUG, "Adding subscription for mailbox notification - peer %s Mailbox %s\n", p->relatedpeer->name, p->relatedpeer->mailbox);
14529          else
14530             ast_log(LOG_DEBUG, "Adding subscription for extension %s context %s for peer %s\n", p->exten, p->context, p->username);
14531       }
14532       if (p->autokillid > -1)
14533          sip_cancel_destroy(p);  /* Remove subscription expiry for renewals */
14534       if (p->expiry > 0)
14535          sip_scheddestroy(p, (p->expiry + 10) * 1000);   /* Set timer for destruction of call at expiration */
14536 
14537       if (p->subscribed == MWI_NOTIFICATION) {
14538          transmit_response(p, "200 OK", req);
14539          if (p->relatedpeer) {   /* Send first notification */
14540             ASTOBJ_WRLOCK(p->relatedpeer);
14541             sip_send_mwi_to_peer(p->relatedpeer);
14542             ASTOBJ_UNLOCK(p->relatedpeer);
14543          }
14544       } else {
14545          struct sip_pvt *p_old;
14546 
14547          if ((firststate = ast_extension_state(NULL, p->context, p->exten)) < 0) {
14548 
14549             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));
14550             transmit_response(p, "404 Not found", req);
14551             ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
14552             return 0;
14553          }
14554 
14555          transmit_response(p, "200 OK", req);
14556          transmit_state_notify(p, firststate, 1, FALSE); /* Send first notification */
14557          append_history(p, "Subscribestatus", "%s", ast_extension_state2str(firststate));
14558          /* hide the 'complete' exten/context in the refer_to field for later display */
14559          ast_string_field_build(p, subscribeuri, "%s@%s", p->exten, p->context);
14560 
14561          /* remove any old subscription from this peer for the same exten/context,
14562          as the peer has obviously forgotten about it and it's wasteful to wait
14563          for it to expire and send NOTIFY messages to the peer only to have them
14564          ignored (or generate errors)
14565          */
14566          ast_mutex_lock(&iflock);
14567          for (p_old = iflist; p_old; p_old = p_old->next) {
14568             if (p_old == p)
14569                continue;
14570             if (p_old->initreq.method != SIP_SUBSCRIBE)
14571                continue;
14572             if (p_old->subscribed == NONE)
14573                continue;
14574             ast_mutex_lock(&p_old->lock);
14575             if (!strcmp(p_old->username, p->username)) {
14576                if (!strcmp(p_old->exten, p->exten) &&
14577                    !strcmp(p_old->context, p->context)) {
14578                   ast_set_flag(&p_old->flags[0], SIP_NEEDDESTROY);
14579                   ast_mutex_unlock(&p_old->lock);
14580                   break;
14581                }
14582             }
14583             ast_mutex_unlock(&p_old->lock);
14584          }
14585          ast_mutex_unlock(&iflock);
14586       }
14587       if (!p->expiry)
14588          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
14589    }
14590    return 1;
14591 }

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 12205 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, LOG_WARNING, 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.

12206 {
12207    struct ast_channel *owner;
12208    int sipmethod;
12209    int res = 1;
12210    const char *c = get_header(req, "Cseq");
12211    const char *msg = strchr(c, ' ');
12212 
12213    if (!msg)
12214       msg = "";
12215    else
12216       msg++;
12217    sipmethod = find_sip_method(msg);
12218 
12219    owner = p->owner;
12220    if (owner) 
12221       owner->hangupcause = hangup_sip2cause(resp);
12222 
12223    /* Acknowledge whatever it is destined for */
12224    if ((resp >= 100) && (resp <= 199))
12225       __sip_semi_ack(p, seqno, 0, sipmethod);
12226    else
12227       __sip_ack(p, seqno, 0, sipmethod);
12228 
12229    /* Get their tag if we haven't already */
12230    if (ast_strlen_zero(p->theirtag) || (resp >= 200)) {
12231       char tag[128];
12232 
12233       gettag(req, "To", tag, sizeof(tag));
12234       ast_string_field_set(p, theirtag, tag);
12235    }
12236    if (p->relatedpeer && p->method == SIP_OPTIONS) {
12237       /* We don't really care what the response is, just that it replied back. 
12238          Well, as long as it's not a 100 response...  since we might
12239          need to hang around for something more "definitive" */
12240       if (resp != 100)
12241          handle_response_peerpoke(p, resp, req);
12242    } else if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
12243       switch(resp) {
12244       case 100:   /* 100 Trying */
12245       case 101:   /* 101 Dialog establishment */
12246          if (sipmethod == SIP_INVITE) 
12247             handle_response_invite(p, resp, rest, req, seqno);
12248          break;
12249       case 183:   /* 183 Session Progress */
12250          if (sipmethod == SIP_INVITE) 
12251             handle_response_invite(p, resp, rest, req, seqno);
12252          break;
12253       case 180:   /* 180 Ringing */
12254          if (sipmethod == SIP_INVITE) 
12255             handle_response_invite(p, resp, rest, req, seqno);
12256          break;
12257       case 200:   /* 200 OK */
12258          p->authtries = 0; /* Reset authentication counter */
12259          if (sipmethod == SIP_MESSAGE || sipmethod == SIP_INFO) {
12260             /* We successfully transmitted a message 
12261                or a video update request in INFO */
12262             /* Nothing happens here - the message is inside a dialog */
12263          } else if (sipmethod == SIP_INVITE) {
12264             handle_response_invite(p, resp, rest, req, seqno);
12265          } else if (sipmethod == SIP_NOTIFY) {
12266             /* They got the notify, this is the end */
12267             if (p->owner) {
12268                if (!p->refer) {
12269                   ast_log(LOG_WARNING, "Notify answer on an owned channel? - %s\n", p->owner->name);
12270                   ast_queue_hangup(p->owner);
12271                } else if (option_debug > 3) 
12272                   ast_log(LOG_DEBUG, "Got OK on REFER Notify message\n");
12273             } else {
12274                if (p->subscribed == NONE) 
12275                   ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12276             }
12277          } else if (sipmethod == SIP_REGISTER) 
12278             res = handle_response_register(p, resp, rest, req, ignore, seqno);
12279          else if (sipmethod == SIP_BYE)      /* Ok, we're ready to go */
12280             ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12281          break;
12282       case 202:   /* Transfer accepted */
12283          if (sipmethod == SIP_REFER) 
12284             handle_response_refer(p, resp, rest, req, seqno);
12285          break;
12286       case 401: /* Not www-authorized on SIP method */
12287          if (sipmethod == SIP_INVITE)
12288             handle_response_invite(p, resp, rest, req, seqno);
12289          else if (sipmethod == SIP_REFER)
12290             handle_response_refer(p, resp, rest, req, seqno);
12291          else if (p->registry && sipmethod == SIP_REGISTER)
12292             res = handle_response_register(p, resp, rest, req, ignore, seqno);
12293          else {
12294             ast_log(LOG_WARNING, "Got authentication request (401) on unknown %s to '%s'\n", sip_methods[sipmethod].text, get_header(req, "To"));
12295             ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12296          }
12297          break;
12298       case 403: /* Forbidden - we failed authentication */
12299          if (sipmethod == SIP_INVITE)
12300             handle_response_invite(p, resp, rest, req, seqno);
12301          else if (p->registry && sipmethod == SIP_REGISTER) 
12302             res = handle_response_register(p, resp, rest, req, ignore, seqno);
12303          else {
12304             ast_log(LOG_WARNING, "Forbidden - maybe wrong password on authentication for %s\n", msg);
12305             ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12306          }
12307          break;
12308       case 404: /* Not found */
12309          if (p->registry && sipmethod == SIP_REGISTER)
12310             res = handle_response_register(p, resp, rest, req, ignore, seqno);
12311          else if (sipmethod == SIP_INVITE)
12312             handle_response_invite(p, resp, rest, req, seqno);
12313          else if (owner)
12314             ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
12315          break;
12316       case 407: /* Proxy auth required */
12317          if (sipmethod == SIP_INVITE)
12318             handle_response_invite(p, resp, rest, req, seqno);
12319          else if (sipmethod == SIP_REFER)
12320             handle_response_refer(p, resp, rest, req, seqno);
12321          else if (p->registry && sipmethod == SIP_REGISTER)
12322             res = handle_response_register(p, resp, rest, req, ignore, seqno);
12323          else if (sipmethod == SIP_BYE) {
12324             if (ast_strlen_zero(p->authname))
12325                ast_log(LOG_WARNING, "Asked to authenticate %s, to %s:%d but we have no matching peer!\n",
12326                      msg, ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port));
12327                ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12328             if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, "Proxy-Authenticate", "Proxy-Authorization", sipmethod, 0)) {
12329                ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From"));
12330                ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12331             }
12332          } else   /* We can't handle this, giving up in a bad way */
12333             ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12334 
12335          break;
12336       case 481: /* Call leg does not exist */
12337          if (sipmethod == SIP_INVITE) {
12338             handle_response_invite(p, resp, rest, req, seqno);
12339          } else if (sipmethod == SIP_REFER) {
12340             handle_response_refer(p, resp, rest, req, seqno);
12341          } else if (sipmethod == SIP_BYE) {
12342             /* The other side has no transaction to bye,
12343             just assume it's all right then */
12344             ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid);
12345          } else if (sipmethod == SIP_CANCEL) {
12346             /* The other side has no transaction to cancel,
12347             just assume it's all right then */
12348             ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid);
12349          } else {
12350             ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid);
12351             /* Guessing that this is not an important request */
12352          }
12353          break;
12354       case 487:
12355          if (sipmethod == SIP_INVITE)
12356             handle_response_invite(p, resp, rest, req, seqno);
12357          break;
12358       case 488: /* Not acceptable here - codec error */
12359          if (sipmethod == SIP_INVITE)
12360             handle_response_invite(p, resp, rest, req, seqno);
12361          break;
12362       case 491: /* Pending */
12363          if (sipmethod == SIP_INVITE)
12364             handle_response_invite(p, resp, rest, req, seqno);
12365          else {
12366             if (option_debug)
12367                ast_log(LOG_DEBUG, "Got 491 on %s, unspported. Call ID %s\n", sip_methods[sipmethod].text, p->callid);
12368             ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12369          }
12370          break;
12371       case 501: /* Not Implemented */
12372          if (sipmethod == SIP_INVITE)
12373             handle_response_invite(p, resp, rest, req, seqno);
12374          else if (sipmethod == SIP_REFER)
12375             handle_response_refer(p, resp, rest, req, seqno);
12376          else
12377             ast_log(LOG_WARNING, "Host '%s' does not implement '%s'\n", ast_inet_ntoa(p->sa.sin_addr), msg);
12378          break;
12379       case 603:   /* Declined transfer */
12380          if (sipmethod == SIP_REFER) {
12381             handle_response_refer(p, resp, rest, req, seqno);
12382             break;
12383          }
12384          /* Fallthrough */
12385       default:
12386          if ((resp >= 300) && (resp < 700)) {
12387             /* Fatal response */
12388             if ((option_verbose > 2) && (resp != 487))
12389                ast_verbose(VERBOSE_PREFIX_3 "Got SIP response %d \"%s\" back from %s\n", resp, rest, ast_inet_ntoa(p->sa.sin_addr));
12390    
12391             if (sipmethod == SIP_INVITE)
12392                stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */
12393 
12394             /* XXX Locking issues?? XXX */
12395             switch(resp) {
12396             case 300: /* Multiple Choices */
12397             case 301: /* Moved permenantly */
12398             case 302: /* Moved temporarily */
12399             case 305: /* Use Proxy */
12400                parse_moved_contact(p, req);
12401                /* Fall through */
12402             case 486: /* Busy here */
12403             case 600: /* Busy everywhere */
12404             case 603: /* Decline */
12405                if (p->owner)
12406                   ast_queue_control(p->owner, AST_CONTROL_BUSY);
12407                break;
12408             case 482: /*
12409                \note SIP is incapable of performing a hairpin call, which
12410                is yet another failure of not having a layer 2 (again, YAY
12411                 IETF for thinking ahead).  So we treat this as a call
12412                 forward and hope we end up at the right place... */
12413                if (option_debug)
12414                   ast_log(LOG_DEBUG, "Hairpin detected, setting up call forward for what it's worth\n");
12415                if (p->owner)
12416                   ast_string_field_build(p->owner, call_forward,
12417                                "Local/%s@%s", p->username, p->context);
12418                /* Fall through */
12419             case 480: /* Temporarily Unavailable */
12420             case 404: /* Not Found */
12421             case 410: /* Gone */
12422             case 400: /* Bad Request */
12423             case 500: /* Server error */
12424                if (sipmethod == SIP_REFER) {
12425                   handle_response_refer(p, resp, rest, req, seqno);
12426                   break;
12427                }
12428                /* Fall through */
12429             case 503: /* Service Unavailable */
12430             case 504: /* Server Timeout */
12431                if (owner)
12432                   ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
12433                break;
12434             default:
12435                /* Send hangup */ 
12436                if (owner && sipmethod != SIP_MESSAGE && sipmethod != SIP_INFO)
12437                   ast_queue_hangup(p->owner);
12438                break;
12439             }
12440             /* ACK on invite */
12441             if (sipmethod == SIP_INVITE) 
12442                transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
12443             if (sipmethod != SIP_MESSAGE && sipmethod != SIP_INFO) 
12444                sip_alreadygone(p);
12445             if (!p->owner)
12446                ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12447          } else if ((resp >= 100) && (resp < 200)) {
12448             if (sipmethod == SIP_INVITE) {
12449                if (!ast_test_flag(req, SIP_PKT_IGNORE))
12450                   sip_cancel_destroy(p);
12451                if (find_sdp(req))
12452                   process_sdp(p, req);
12453                if (p->owner) {
12454                   /* Queue a progress frame */
12455                   ast_queue_control(p->owner, AST_CONTROL_PROGRESS);
12456                }
12457             }
12458          } else
12459             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));
12460       }
12461    } else { 
12462       /* Responses to OUTGOING SIP requests on INCOMING calls 
12463          get handled here. As well as out-of-call message responses */
12464       if (ast_test_flag(req, SIP_PKT_DEBUG))
12465          ast_verbose("SIP Response message for INCOMING dialog %s arrived\n", msg);
12466 
12467       if (sipmethod == SIP_INVITE && resp == 200) {
12468          /* Tags in early session is replaced by the tag in 200 OK, which is 
12469          the final reply to our INVITE */
12470          char tag[128];
12471 
12472          gettag(req, "To", tag, sizeof(tag));
12473          ast_string_field_set(p, theirtag, tag);
12474       }
12475 
12476       switch(resp) {
12477       case 200:
12478          if (sipmethod == SIP_INVITE) {
12479             handle_response_invite(p, resp, rest, req, seqno);
12480          } else if (sipmethod == SIP_CANCEL) {
12481             if (option_debug)
12482                ast_log(LOG_DEBUG, "Got 200 OK on CANCEL\n");
12483 
12484             /* Wait for 487, then destroy */
12485          } else if (sipmethod == SIP_NOTIFY) {
12486             /* They got the notify, this is the end */
12487             if (p->owner) {
12488                if (p->refer) {
12489                   if (option_debug)
12490                      ast_log(LOG_DEBUG, "Got 200 OK on NOTIFY for transfer\n");
12491                } else
12492                   ast_log(LOG_WARNING, "Notify answer on an owned channel?\n");
12493                /* ast_queue_hangup(p->owner); Disabled */
12494             } else {
12495                if (!p->subscribed && !p->refer)
12496                   ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12497             }
12498          } else if (sipmethod == SIP_BYE)
12499             ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12500          else if (sipmethod == SIP_MESSAGE || sipmethod == SIP_INFO)
12501             /* We successfully transmitted a message or
12502                a video update request in INFO */
12503             ;
12504          else if (sipmethod == SIP_BYE) 
12505             /* Ok, we're ready to go */
12506             ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12507          break;
12508       case 202:   /* Transfer accepted */
12509          if (sipmethod == SIP_REFER) 
12510             handle_response_refer(p, resp, rest, req, seqno);
12511          break;
12512       case 401:   /* www-auth */
12513       case 407:
12514          if (sipmethod == SIP_REFER)
12515             handle_response_refer(p, resp, rest, req, seqno);
12516          else if (sipmethod == SIP_INVITE) 
12517             handle_response_invite(p, resp, rest, req, seqno);
12518          else if (sipmethod == SIP_BYE) {
12519             char *auth, *auth2;
12520 
12521             auth = (resp == 407 ? "Proxy-Authenticate" : "WWW-Authenticate");
12522             auth2 = (resp == 407 ? "Proxy-Authorization" : "Authorization");
12523             if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, auth, auth2, sipmethod, 0)) {
12524                ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From"));
12525                ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12526             }
12527          }
12528          break;
12529       case 481:   /* Call leg does not exist */
12530          if (sipmethod == SIP_INVITE) {
12531             /* Re-invite failed */
12532             handle_response_invite(p, resp, rest, req, seqno);
12533          } else if (sipmethod == SIP_BYE) {
12534             ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12535          } else if (sipdebug) {
12536             ast_log  (LOG_DEBUG, "Remote host can't match request %s to call '%s'. Giving up\n", sip_methods[sipmethod].text, p->callid);
12537          }
12538          break;
12539       case 501: /* Not Implemented */
12540          if (sipmethod == SIP_INVITE) 
12541             handle_response_invite(p, resp, rest, req, seqno);
12542          else if (sipmethod == SIP_REFER) 
12543             handle_response_refer(p, resp, rest, req, seqno);
12544          break;
12545       case 603:   /* Declined transfer */
12546          if (sipmethod == SIP_REFER) {
12547             handle_response_refer(p, resp, rest, req, seqno);
12548             break;
12549          }
12550          /* Fallthrough */
12551       default: /* Errors without handlers */
12552          if ((resp >= 100) && (resp < 200)) {
12553             if (sipmethod == SIP_INVITE) {   /* re-invite */
12554                if (!ast_test_flag(req, SIP_PKT_IGNORE))
12555                   sip_cancel_destroy(p);
12556             }
12557          }
12558          if ((resp >= 300) && (resp < 700)) {
12559             if ((option_verbose > 2) && (resp != 487))
12560                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));
12561             switch(resp) {
12562             case 488: /* Not acceptable here - codec error */
12563             case 603: /* Decline */
12564             case 500: /* Server error */
12565             case 503: /* Service Unavailable */
12566             case 504: /* Server timeout */
12567 
12568                if (sipmethod == SIP_INVITE) {   /* re-invite failed */
12569                   sip_cancel_destroy(p);
12570                }
12571                break;
12572             }
12573          }
12574          break;
12575       }
12576    }
12577 }

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

References ast_channel::_state, 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, LOG_WARNING, 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, and XMIT_UNRELIABLE.

Referenced by handle_response().

11664 {
11665    int outgoing = ast_test_flag(&p->flags[0], SIP_OUTGOING);
11666    int res = 0;
11667    int reinvite = (p->owner && p->owner->_state == AST_STATE_UP);
11668    struct ast_channel *bridgepeer = NULL;
11669    
11670    if (option_debug > 3) {
11671       if (reinvite)
11672          ast_log(LOG_DEBUG, "SIP response %d to RE-invite on %s call %s\n", resp, outgoing ? "outgoing" : "incoming", p->callid);
11673       else
11674          ast_log(LOG_DEBUG, "SIP response %d to standard invite\n", resp);
11675    }
11676 
11677    if (ast_test_flag(&p->flags[0], SIP_ALREADYGONE)) { /* This call is already gone */
11678       if (option_debug)
11679          ast_log(LOG_DEBUG, "Got response on call that is already terminated: %s (ignoring)\n", p->callid);
11680       return;
11681    }
11682 
11683    /* Acknowledge sequence number - This only happens on INVITE from SIP-call */
11684    if (p->initid > -1) {
11685       /* Don't auto congest anymore since we've gotten something useful back */
11686       ast_sched_del(sched, p->initid);
11687       p->initid = -1;
11688    }
11689 
11690    /* RFC3261 says we must treat every 1xx response (but not 100)
11691       that we don't recognize as if it was 183.
11692    */
11693    if (resp > 100 && resp < 200 && resp!=101 && resp != 180 && resp != 183)
11694       resp = 183;
11695 
11696    /* Any response between 100 and 199 is PROCEEDING */
11697    if (resp >= 100 && resp < 200 && p->invitestate == INV_CALLING)
11698       p->invitestate = INV_PROCEEDING;
11699  
11700    /* Final response, not 200 ? */
11701    if (resp >= 300 && (p->invitestate == INV_CALLING || p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA ))
11702       p->invitestate = INV_COMPLETED;
11703       
11704 
11705    switch (resp) {
11706    case 100:   /* Trying */
11707    case 101:   /* Dialog establishment */
11708       if (!ast_test_flag(req, SIP_PKT_IGNORE))
11709          sip_cancel_destroy(p);
11710       check_pendings(p);
11711       break;
11712 
11713    case 180:   /* 180 Ringing */
11714       if (!ast_test_flag(req, SIP_PKT_IGNORE))
11715          sip_cancel_destroy(p);
11716       if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) {
11717          ast_queue_control(p->owner, AST_CONTROL_RINGING);
11718          if (p->owner->_state != AST_STATE_UP) {
11719             ast_setstate(p->owner, AST_STATE_RINGING);
11720          }
11721       }
11722       if (find_sdp(req)) {
11723          p->invitestate = INV_EARLY_MEDIA;
11724          res = process_sdp(p, req);
11725          if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) {
11726             /* Queue a progress frame only if we have SDP in 180 */
11727             ast_queue_control(p->owner, AST_CONTROL_PROGRESS);
11728          }
11729       }
11730       check_pendings(p);
11731       break;
11732 
11733    case 183:   /* Session progress */
11734       if (!ast_test_flag(req, SIP_PKT_IGNORE))
11735          sip_cancel_destroy(p);
11736       /* Ignore 183 Session progress without SDP */
11737       if (find_sdp(req)) {
11738          p->invitestate = INV_EARLY_MEDIA;
11739          res = process_sdp(p, req);
11740          if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) {
11741             /* Queue a progress frame */
11742             ast_queue_control(p->owner, AST_CONTROL_PROGRESS);
11743          }
11744       }
11745       check_pendings(p);
11746       break;
11747 
11748    case 200:   /* 200 OK on invite - someone's answering our call */
11749       if (!ast_test_flag(req, SIP_PKT_IGNORE))
11750          sip_cancel_destroy(p);
11751       p->authtries = 0;
11752       if (find_sdp(req)) {
11753          if ((res = process_sdp(p, req)) && !ast_test_flag(req, SIP_PKT_IGNORE))
11754             if (!reinvite)
11755                /* This 200 OK's SDP is not acceptable, so we need to ack, then hangup */
11756                /* For re-invites, we try to recover */
11757                ast_set_flag(&p->flags[0], SIP_PENDINGBYE);  
11758       }
11759 
11760       /* Parse contact header for continued conversation */
11761       /* When we get 200 OK, we know which device (and IP) to contact for this call */
11762       /* This is important when we have a SIP proxy between us and the phone */
11763       if (outgoing) {
11764          update_call_counter(p, DEC_CALL_RINGING);
11765          parse_ok_contact(p, req);
11766          if(set_address_from_contact(p)) {
11767             /* Bad contact - we don't know how to reach this device */
11768             /* We need to ACK, but then send a bye */
11769             /* OEJ: Possible issue that may need a check:
11770                If we have a proxy route between us and the device,
11771                should we care about resolving the contact
11772                or should we just send it?
11773             */
11774             if (!ast_test_flag(req, SIP_PKT_IGNORE))
11775                ast_set_flag(&p->flags[0], SIP_PENDINGBYE);  
11776          } 
11777 
11778          /* Save Record-Route for any later requests we make on this dialogue */
11779          build_route(p, req, 1);
11780       }
11781       
11782       if (p->owner && (p->owner->_state == AST_STATE_UP) && (bridgepeer = ast_bridged_channel(p->owner))) { /* if this is a re-invite */
11783          struct sip_pvt *bridgepvt = NULL;
11784 
11785          if (!bridgepeer->tech) {
11786             ast_log(LOG_WARNING, "Ooooh.. no tech!  That's REALLY bad\n");
11787             break;
11788          }
11789          if (bridgepeer->tech == &sip_tech || bridgepeer->tech == &sip_tech_info) {
11790             bridgepvt = (struct sip_pvt*)(bridgepeer->tech_pvt);
11791             if (bridgepvt->udptl) {
11792                if (p->t38.state == T38_PEER_REINVITE) {
11793                   sip_handle_t38_reinvite(bridgepeer, p, 0);
11794                   ast_rtp_set_rtptimers_onhold(p->rtp);
11795                   if (p->vrtp)
11796                      ast_rtp_set_rtptimers_onhold(p->vrtp); /* Turn off RTP timers while we send fax */
11797                } else if (p->t38.state == T38_DISABLED && bridgepeer && (bridgepvt->t38.state == T38_ENABLED)) {
11798                   ast_log(LOG_WARNING, "RTP re-inivte after T38 session not handled yet !\n");
11799                   /* Insted of this we should somehow re-invite the other side of the bridge to RTP */
11800                   /* XXXX Should we really destroy this session here, without any response at all??? */
11801                   sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
11802                }
11803             } else {
11804                if (option_debug > 1)
11805                   ast_log(LOG_DEBUG, "Strange... The other side of the bridge does not have a udptl struct\n");
11806                ast_mutex_lock(&bridgepvt->lock);
11807                bridgepvt->t38.state = T38_DISABLED;
11808                ast_mutex_unlock(&bridgepvt->lock);
11809                if (option_debug)
11810                   ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", bridgepvt->t38.state, bridgepeer->tech->type);
11811                p->t38.state = T38_DISABLED;
11812                if (option_debug > 1)
11813                   ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>");
11814             }
11815          } else {
11816             /* Other side is not a SIP channel */
11817             if (option_debug > 1)
11818                ast_log(LOG_DEBUG, "Strange... The other side of the bridge is not a SIP channel\n");
11819             p->t38.state = T38_DISABLED;
11820             if (option_debug > 1)
11821                ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>");
11822          }
11823       }
11824       if ((p->t38.state == T38_LOCAL_REINVITE) || (p->t38.state == T38_LOCAL_DIRECT)) {
11825          /* If there was T38 reinvite and we are supposed to answer with 200 OK than this should set us to T38 negotiated mode */
11826          p->t38.state = T38_ENABLED;
11827          if (option_debug)
11828             ast_log(LOG_DEBUG, "T38 changed state to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>");
11829       }
11830 
11831       if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) {
11832          if (!reinvite) {
11833             ast_queue_control(p->owner, AST_CONTROL_ANSWER);
11834          } else { /* RE-invite */
11835             ast_queue_frame(p->owner, &ast_null_frame);
11836          }
11837       } else {
11838           /* It's possible we're getting an 200 OK after we've tried to disconnect
11839               by sending CANCEL */
11840          /* First send ACK, then send bye */
11841          if (!ast_test_flag(req, SIP_PKT_IGNORE))
11842             ast_set_flag(&p->flags[0], SIP_PENDINGBYE);  
11843       }
11844       /* If I understand this right, the branch is different for a non-200 ACK only */
11845       p->invitestate = INV_TERMINATED;
11846       transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, TRUE);
11847       check_pendings(p);
11848       break;
11849    case 407: /* Proxy authentication */
11850    case 401: /* Www auth */
11851       /* First we ACK */
11852       transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
11853       if (p->options)
11854          p->options->auth_type = (resp == 401 ? WWW_AUTH : PROXY_AUTH);
11855 
11856       /* Then we AUTH */
11857       ast_string_field_free(p, theirtag); /* forget their old tag, so we don't match tags when getting response */
11858       if (!ast_test_flag(req, SIP_PKT_IGNORE)) {
11859          char *authenticate = (resp == 401 ? "WWW-Authenticate" : "Proxy-Authenticate");
11860          char *authorization = (resp == 401 ? "Authorization" : "Proxy-Authorization");
11861          if (p->authtries < MAX_AUTHTRIES)
11862             p->invitestate = INV_CALLING;
11863          if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, authenticate, authorization, SIP_INVITE, 1)) {
11864             ast_log(LOG_NOTICE, "Failed to authenticate on INVITE to '%s'\n", get_header(&p->initreq, "From"));
11865             ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
11866             sip_alreadygone(p);
11867             if (p->owner)
11868                ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
11869          }
11870       }
11871       break;
11872 
11873    case 403: /* Forbidden */
11874       /* First we ACK */
11875       transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
11876       ast_log(LOG_WARNING, "Received response: \"Forbidden\" from '%s'\n", get_header(&p->initreq, "From"));
11877       if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner)
11878          ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
11879       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
11880       sip_alreadygone(p);
11881       break;
11882 
11883    case 404: /* Not found */
11884       transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
11885       if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE))
11886          ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
11887       sip_alreadygone(p);
11888       break;
11889 
11890    case 481: /* Call leg does not exist */
11891       /* Could be REFER caused INVITE with replaces */
11892       ast_log(LOG_WARNING, "Re-invite to non-existing call leg on other UA. SIP dialog '%s'. Giving up.\n", p->callid);
11893       transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
11894       if (p->owner)
11895          ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
11896       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
11897       break;
11898    case 487: /* Cancelled transaction */
11899       /* We have sent CANCEL on an outbound INVITE 
11900          This transaction is already scheduled to be killed by sip_hangup().
11901       */
11902       transmit_request(p, SIP_ACK, seqno, 0, 0);
11903       if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE))
11904          ast_queue_hangup(p->owner);
11905       else if (!ast_test_flag(req, SIP_PKT_IGNORE))
11906          update_call_counter(p, DEC_CALL_LIMIT);
11907       break;
11908    case 488: /* Not acceptable here */
11909       transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
11910       if (reinvite && p->udptl) {
11911          /* If this is a T.38 call, we should go back to 
11912             audio. If this is an audio call - something went
11913             terribly wrong since we don't renegotiate codecs,
11914             only IP/port .
11915          */
11916          p->t38.state = T38_DISABLED;
11917          /* Try to reset RTP timers */
11918          ast_rtp_set_rtptimers_onhold(p->rtp);
11919          ast_log(LOG_ERROR, "Got error on T.38 re-invite. Bad configuration. Peer needs to have T.38 disabled.\n");
11920 
11921          /*! \bug Is there any way we can go back to the audio call on both
11922             sides here? 
11923          */
11924          /* While figuring that out, hangup the call */
11925          if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE))
11926             ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
11927          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
11928       } else {
11929          /* We can't set up this call, so give up */
11930          if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE))
11931             ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
11932          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
11933       }
11934       break;
11935    case 491: /* Pending */
11936       /* we really should have to wait a while, then retransmit */
11937          /* We should support the retry-after at some point */
11938       /* At this point, we treat this as a congestion */
11939       transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
11940       if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE))
11941          ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
11942       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
11943       break;
11944 
11945    case 501: /* Not implemented */
11946       transmit_request(p, SIP_ACK, seqno, 0, 0);
11947       if (p->owner)
11948          ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
11949       break;
11950    }
11951 }

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

Handle qualification responses (OPTIONS).

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

12146 {
12147    struct sip_peer *peer = p->relatedpeer;
12148    int statechanged, is_reachable, was_reachable;
12149    int pingtime = ast_tvdiff_ms(ast_tvnow(), peer->ps);
12150 
12151    /*
12152     * Compute the response time to a ping (goes in peer->lastms.)
12153     * -1 means did not respond, 0 means unknown,
12154     * 1..maxms is a valid response, >maxms means late response.
12155     */
12156    if (pingtime < 1) /* zero = unknown, so round up to 1 */
12157       pingtime = 1;
12158 
12159    /* Now determine new state and whether it has changed.
12160     * Use some helper variables to simplify the writing
12161     * of the expressions.
12162     */
12163    was_reachable = peer->lastms > 0 && peer->lastms <= peer->maxms;
12164    is_reachable = pingtime <= peer->maxms;
12165    statechanged = peer->lastms == 0 /* yes, unknown before */
12166       || was_reachable != is_reachable;
12167 
12168    peer->lastms = pingtime;
12169    peer->call = NULL;
12170    if (statechanged) {
12171       const char *s = is_reachable ? "Reachable" : "Lagged";
12172 
12173       ast_log(LOG_NOTICE, "Peer '%s' is now %s. (%dms / %dms)\n",
12174          peer->name, s, pingtime, peer->maxms);
12175       ast_device_state_changed("SIP/%s", peer->name);
12176       manager_event(EVENT_FLAG_SYSTEM, "PeerStatus",
12177          "Peer: SIP/%s\r\nPeerStatus: %s\r\nTime: %d\r\n",
12178          peer->name, s, pingtime);
12179    }
12180 
12181    if (peer->pokeexpire > -1)
12182       ast_sched_del(sched, peer->pokeexpire);
12183    ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12184 
12185    /* Try again eventually */
12186    peer->pokeexpire = ast_sched_add(sched,
12187       is_reachable ? DEFAULT_FREQ_OK : DEFAULT_FREQ_NOTOK,
12188       sip_poke_peer_s, peer);
12189 }

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

Definition at line 11956 of file chan_sip.c.

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

Referenced by handle_response().

11957 {
11958    char *auth = "Proxy-Authenticate";
11959    char *auth2 = "Proxy-Authorization";
11960 
11961    /* If no refer structure exists, then do nothing */
11962    if (!p->refer)
11963       return;
11964 
11965    switch (resp) {
11966    case 202:   /* Transfer accepted */
11967       /* We need  to do something here */
11968       /* The transferee is now sending INVITE to target */
11969       p->refer->status = REFER_ACCEPTED;
11970       /* Now wait for next message */
11971       if (option_debug > 2)
11972          ast_log(LOG_DEBUG, "Got 202 accepted on transfer\n");
11973       /* We should hang along, waiting for NOTIFY's here */
11974       break;
11975 
11976    case 401:   /* Not www-authorized on SIP method */
11977    case 407:   /* Proxy auth */
11978       if (ast_strlen_zero(p->authname)) {
11979          ast_log(LOG_WARNING, "Asked to authenticate REFER to %s:%d but we have no matching peer or realm auth!\n",
11980             ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port));
11981          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
11982       }
11983       if (resp == 401) {
11984          auth = "WWW-Authenticate";
11985          auth2 = "Authorization";
11986       }
11987       if ((p->authtries > 1) || do_proxy_auth(p, req, auth, auth2, SIP_REFER, 0)) {
11988          ast_log(LOG_NOTICE, "Failed to authenticate on REFER to '%s'\n", get_header(&p->initreq, "From"));
11989          p->refer->status = REFER_NOAUTH;
11990          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
11991       }
11992       break;
11993    case 481: /* Call leg does not exist */
11994 
11995       /* A transfer with Replaces did not work */
11996       /* OEJ: We should Set flag, cancel the REFER, go back
11997       to original call - but right now we can't */
11998       ast_log(LOG_WARNING, "Remote host can't match REFER request to call '%s'. Giving up.\n", p->callid);
11999       if (p->owner)
12000          ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
12001       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
12002       break;
12003 
12004    case 500:   /* Server error */
12005    case 501:   /* Method not implemented */
12006       /* Return to the current call onhold */
12007       /* Status flag needed to be reset */
12008       ast_log(LOG_NOTICE, "SIP transfer to %s failed, call miserably fails. \n", p->refer->refer_to);
12009       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
12010       p->refer->status = REFER_FAILED;
12011       break;
12012    case 603:   /* Transfer declined */
12013       ast_log(LOG_NOTICE, "SIP transfer to %s declined, call miserably fails. \n", p->refer->refer_to);
12014       p->refer->status = REFER_FAILED;
12015       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
12016       break;
12017    }
12018 }

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

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

Referenced by handle_response().

12022 {
12023    int expires, expires_ms;
12024    struct sip_registry *r;
12025    r=p->registry;
12026 
12027    switch (resp) {
12028    case 401:   /* Unauthorized */
12029       if ((p->authtries == MAX_AUTHTRIES) || do_register_auth(p, req, "WWW-Authenticate", "Authorization")) {
12030          ast_log(LOG_NOTICE, "Failed to authenticate on REGISTER to '%s@%s' (Tries %d)\n", p->registry->username, p->registry->hostname, p->authtries);
12031          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12032          }
12033       break;
12034    case 403:   /* Forbidden */
12035       ast_log(LOG_WARNING, "Forbidden - wrong password on authentication for REGISTER for '%s' to '%s'\n", p->registry->username, p->registry->hostname);
12036       if (global_regattempts_max)
12037          p->registry->regattempts = global_regattempts_max+1;
12038       ast_sched_del(sched, r->timeout);
12039       r->timeout = -1;
12040       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12041       break;
12042    case 404:   /* Not found */
12043       ast_log(LOG_WARNING, "Got 404 Not found on SIP register to service %s@%s, giving up\n", p->registry->username,p->registry->hostname);
12044       if (global_regattempts_max)
12045          p->registry->regattempts = global_regattempts_max+1;
12046       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12047       r->call = NULL;
12048       ast_sched_del(sched, r->timeout);
12049       r->timeout = -1;
12050       break;
12051    case 407:   /* Proxy auth */
12052       if ((p->authtries == MAX_AUTHTRIES) || do_register_auth(p, req, "Proxy-Authenticate", "Proxy-Authorization")) {
12053          ast_log(LOG_NOTICE, "Failed to authenticate on REGISTER to '%s' (tries '%d')\n", get_header(&p->initreq, "From"), p->authtries);
12054          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12055       }
12056       break;
12057    case 479:   /* SER: Not able to process the URI - address is wrong in register*/
12058       ast_log(LOG_WARNING, "Got error 479 on register to %s@%s, giving up (check config)\n", p->registry->username,p->registry->hostname);
12059       if (global_regattempts_max)
12060          p->registry->regattempts = global_regattempts_max+1;
12061       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12062       r->call = NULL;
12063       ast_sched_del(sched, r->timeout);
12064       r->timeout = -1;
12065       break;
12066    case 200:   /* 200 OK */
12067       if (!r) {
12068          ast_log(LOG_WARNING, "Got 200 OK on REGISTER that isn't a register\n");
12069          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12070          return 0;
12071       }
12072 
12073       r->regstate = REG_STATE_REGISTERED;
12074       r->regtime = time(NULL);      /* Reset time of last succesful registration */
12075       manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelDriver: SIP\r\nDomain: %s\r\nStatus: %s\r\n", r->hostname, regstate2str(r->regstate));
12076       r->regattempts = 0;
12077       if (option_debug)
12078          ast_log(LOG_DEBUG, "Registration successful\n");
12079       if (r->timeout > -1) {
12080          if (option_debug)
12081             ast_log(LOG_DEBUG, "Cancelling timeout %d\n", r->timeout);
12082          ast_sched_del(sched, r->timeout);
12083       }
12084       r->timeout=-1;
12085       r->call = NULL;
12086       p->registry = NULL;
12087       /* Let this one hang around until we have all the responses */
12088       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
12089       /* ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); */
12090 
12091       /* set us up for re-registering */
12092       /* figure out how long we got registered for */
12093       if (r->expire > -1)
12094          ast_sched_del(sched, r->expire);
12095       /* according to section 6.13 of RFC, contact headers override
12096          expires headers, so check those first */
12097       expires = 0;
12098 
12099       /* XXX todo: try to save the extra call */
12100       if (!ast_strlen_zero(get_header(req, "Contact"))) {
12101          const char *contact = NULL;
12102          const char *tmptmp = NULL;
12103          int start = 0;
12104          for(;;) {
12105             contact = __get_header(req, "Contact", &start);
12106             /* this loop ensures we get a contact header about our register request */
12107             if(!ast_strlen_zero(contact)) {
12108                if( (tmptmp=strstr(contact, p->our_contact))) {
12109                   contact=tmptmp;
12110                   break;
12111                }
12112             } else
12113                break;
12114          }
12115          tmptmp = strcasestr(contact, "expires=");
12116          if (tmptmp) {
12117             if (sscanf(tmptmp + 8, "%d;", &expires) != 1)
12118                expires = 0;
12119          }
12120 
12121       }
12122       if (!expires) 
12123          expires=atoi(get_header(req, "expires"));
12124       if (!expires)
12125          expires=default_expiry;
12126 
12127       expires_ms = expires * 1000;
12128       if (expires <= EXPIRY_GUARD_LIMIT)
12129          expires_ms -= MAX((expires_ms * EXPIRY_GUARD_PCT),EXPIRY_GUARD_MIN);
12130       else
12131          expires_ms -= EXPIRY_GUARD_SECS * 1000;
12132       if (sipdebug)
12133          ast_log(LOG_NOTICE, "Outbound Registration: Expiry for %s is %d sec (Scheduling reregistration in %d s)\n", r->hostname, expires, expires_ms/1000); 
12134 
12135       r->refresh= (int) expires_ms / 1000;
12136 
12137       /* Schedule re-registration before we expire */
12138       r->expire=ast_sched_add(sched, expires_ms, sip_reregister, r); 
12139       ASTOBJ_UNREF(r, sip_registry_destroy);
12140    }
12141    return 1;
12142 }

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

03229 {
03230    switch (cause) {
03231       case AST_CAUSE_UNALLOCATED:      /* 1 */
03232       case AST_CAUSE_NO_ROUTE_DESTINATION:   /* 3 IAX2: Can't find extension in context */
03233       case AST_CAUSE_NO_ROUTE_TRANSIT_NET:   /* 2 */
03234          return "404 Not Found";
03235       case AST_CAUSE_CONGESTION:    /* 34 */
03236       case AST_CAUSE_SWITCH_CONGESTION:   /* 42 */
03237          return "503 Service Unavailable";
03238       case AST_CAUSE_NO_USER_RESPONSE: /* 18 */
03239          return "408 Request Timeout";
03240       case AST_CAUSE_NO_ANSWER:     /* 19 */
03241          return "480 Temporarily unavailable";
03242       case AST_CAUSE_CALL_REJECTED:    /* 21 */
03243          return "403 Forbidden";
03244       case AST_CAUSE_NUMBER_CHANGED:      /* 22 */
03245          return "410 Gone";
03246       case AST_CAUSE_NORMAL_UNSPECIFIED:  /* 31 */
03247          return "480 Temporarily unavailable";
03248       case AST_CAUSE_INVALID_NUMBER_FORMAT:
03249          return "484 Address incomplete";
03250       case AST_CAUSE_USER_BUSY:
03251          return "486 Busy here";
03252       case AST_CAUSE_FAILURE:
03253          return "500 Server internal failure";
03254       case AST_CAUSE_FACILITY_REJECTED:   /* 29 */
03255          return "501 Not Implemented";
03256       case AST_CAUSE_CHAN_NOT_IMPLEMENTED:
03257          return "503 Service Unavailable";
03258       /* Used in chan_iax2 */
03259       case AST_CAUSE_DESTINATION_OUT_OF_ORDER:
03260          return "502 Bad Gateway";
03261       case AST_CAUSE_BEARERCAPABILITY_NOTAVAIL: /* Can't find codec to connect to host */
03262          return "488 Not Acceptable Here";
03263          
03264       case AST_CAUSE_NOTDEFINED:
03265       default:
03266          if (option_debug)
03267             ast_log(LOG_DEBUG, "AST hangup cause %d (no match found in SIP)\n", cause);
03268          return NULL;
03269    }
03270 
03271    /* Never reached */
03272    return 0;
03273 }

static int hangup_sip2cause ( int  cause  )  [static]

Convert SIP hangup causes to Asterisk hangup causes.

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

03117 {
03118    /* Possible values taken from causes.h */
03119 
03120    switch(cause) {
03121       case 401:   /* Unauthorized */
03122          return AST_CAUSE_CALL_REJECTED;
03123       case 403:   /* Not found */
03124          return AST_CAUSE_CALL_REJECTED;
03125       case 404:   /* Not found */
03126          return AST_CAUSE_UNALLOCATED;
03127       case 405:   /* Method not allowed */
03128          return AST_CAUSE_INTERWORKING;
03129       case 407:   /* Proxy authentication required */
03130          return AST_CAUSE_CALL_REJECTED;
03131       case 408:   /* No reaction */
03132          return AST_CAUSE_NO_USER_RESPONSE;
03133       case 409:   /* Conflict */
03134          return AST_CAUSE_NORMAL_TEMPORARY_FAILURE;
03135       case 410:   /* Gone */
03136          return AST_CAUSE_UNALLOCATED;
03137       case 411:   /* Length required */
03138          return AST_CAUSE_INTERWORKING;
03139       case 413:   /* Request entity too large */
03140          return AST_CAUSE_INTERWORKING;
03141       case 414:   /* Request URI too large */
03142          return AST_CAUSE_INTERWORKING;
03143       case 415:   /* Unsupported media type */
03144          return AST_CAUSE_INTERWORKING;
03145       case 420:   /* Bad extension */
03146          return AST_CAUSE_NO_ROUTE_DESTINATION;
03147       case 480:   /* No answer */
03148          return AST_CAUSE_NO_ANSWER;
03149       case 481:   /* No answer */
03150          return AST_CAUSE_INTERWORKING;
03151       case 482:   /* Loop detected */
03152          return AST_CAUSE_INTERWORKING;
03153       case 483:   /* Too many hops */
03154          return AST_CAUSE_NO_ANSWER;
03155       case 484:   /* Address incomplete */
03156          return AST_CAUSE_INVALID_NUMBER_FORMAT;
03157       case 485:   /* Ambigous */
03158          return AST_CAUSE_UNALLOCATED;
03159       case 486:   /* Busy everywhere */
03160          return AST_CAUSE_BUSY;
03161       case 487:   /* Request terminated */
03162          return AST_CAUSE_INTERWORKING;
03163       case 488:   /* No codecs approved */
03164          return AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;
03165       case 491:   /* Request pending */
03166          return AST_CAUSE_INTERWORKING;
03167       case 493:   /* Undecipherable */
03168          return AST_CAUSE_INTERWORKING;
03169       case 500:   /* Server internal failure */
03170          return AST_CAUSE_FAILURE;
03171       case 501:   /* Call rejected */
03172          return AST_CAUSE_FACILITY_REJECTED;
03173       case 502:   
03174          return AST_CAUSE_DESTINATION_OUT_OF_ORDER;
03175       case 503:   /* Service unavailable */
03176          return AST_CAUSE_CONGESTION;
03177       case 504:   /* Gateway timeout */
03178          return AST_CAUSE_RECOVERY_ON_TIMER_EXPIRE;
03179       case 505:   /* SIP version not supported */
03180          return AST_CAUSE_INTERWORKING;
03181       case 600:   /* Busy everywhere */
03182          return AST_CAUSE_USER_BUSY;
03183       case 603:   /* Decline */
03184          return AST_CAUSE_CALL_REJECTED;
03185       case 604:   /* Does not exist anywhere */
03186          return AST_CAUSE_UNALLOCATED;
03187       case 606:   /* Not acceptable */
03188          return AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;
03189       default:
03190          return AST_CAUSE_NORMAL;
03191    }
03192    /* Never reached */
03193    return 0;
03194 }

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

Initialize SIP request.

Definition at line 5571 of file chan_sip.c.

References sip_methods, and cfsip_methods::text.

05572 {
05573    /* Initialize a request */
05574    memset(req, 0, sizeof(*req));
05575         req->method = sipmethod;
05576    req->header[0] = req->data;
05577    snprintf(req->header[0], sizeof(req->data), "%s %s SIP/2.0\r\n", sip_methods[sipmethod].text, recip);
05578    req->len = strlen(req->header[0]);
05579    req->headers++;
05580    return 0;
05581 }

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

Initialize SIP response, based on SIP request.

Definition at line 5558 of file chan_sip.c.

References SIP_RESPONSE.

05559 {
05560    /* Initialize a response */
05561    memset(resp, 0, sizeof(*resp));
05562    resp->method = SIP_RESPONSE;
05563    resp->header[0] = resp->data;
05564    snprintf(resp->header[0], sizeof(resp->data), "SIP/2.0 %s\r\n", msg);
05565    resp->len = strlen(resp->header[0]);
05566    resp->headers++;
05567    return 0;
05568 }

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

01620 {
01621    if (p->initreq.headers && option_debug) {
01622       ast_log(LOG_DEBUG, "Initializing already initialized SIP dialog %s (presumably reinvite)\n", p->callid);
01623    }
01624    /* Use this as the basis */
01625    copy_request(&p->initreq, req);
01626    parse_request(&p->initreq);
01627    if (ast_test_flag(req, SIP_PKT_DEBUG))
01628       ast_verbose("%d headers, %d lines\n", p->initreq.headers, p->initreq.lines);
01629 }

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

Initiate new SIP request to peer/user.

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

06648 {
06649    char invite_buf[256] = "";
06650    char *invite = invite_buf;
06651    size_t invite_max = sizeof(invite_buf);
06652    char from[256];
06653    char to[256];
06654    char tmp[BUFSIZ/2];
06655    char tmp2[BUFSIZ/2];
06656    const char *l = NULL, *n = NULL;
06657    const char *urioptions = "";
06658 
06659    if (ast_test_flag(&p->flags[0], SIP_USEREQPHONE)) {
06660       const char *s = p->username;  /* being a string field, cannot be NULL */
06661 
06662       /* Test p->username against allowed characters in AST_DIGIT_ANY
06663          If it matches the allowed characters list, then sipuser = ";user=phone"
06664          If not, then sipuser = ""
06665       */
06666       /* + is allowed in first position in a tel: uri */
06667       if (*s == '+')
06668          s++;
06669       for (; *s; s++) {
06670          if (!strchr(AST_DIGIT_ANYNUM, *s) )
06671             break;
06672       }
06673       /* If we have only digits, add ;user=phone to the uri */
06674       if (*s)
06675          urioptions = ";user=phone";
06676    }
06677 
06678 
06679    snprintf(p->lastmsg, sizeof(p->lastmsg), "Init: %s", sip_methods[sipmethod].text);
06680 
06681    if (p->owner) {
06682       l = p->owner->cid.cid_num;
06683       n = p->owner->cid.cid_name;
06684    }
06685    /* if we are not sending RPID and user wants his callerid restricted */
06686    if (!ast_test_flag(&p->flags[0], SIP_SENDRPID) &&
06687        ((p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED)) {
06688       l = CALLERID_UNKNOWN;
06689       n = l;
06690    }
06691    if (ast_strlen_zero(l))
06692       l = default_callerid;
06693    if (ast_strlen_zero(n))
06694       n = l;
06695    /* Allow user to be overridden */
06696    if (!ast_strlen_zero(p->fromuser))
06697       l = p->fromuser;
06698    else /* Save for any further attempts */
06699       ast_string_field_set(p, fromuser, l);
06700 
06701    /* Allow user to be overridden */
06702    if (!ast_strlen_zero(p->fromname))
06703       n = p->fromname;
06704    else /* Save for any further attempts */
06705       ast_string_field_set(p, fromname, n);
06706 
06707    if (pedanticsipchecking) {
06708       ast_uri_encode(n, tmp, sizeof(tmp), 0);
06709       n = tmp;
06710       ast_uri_encode(l, tmp2, sizeof(tmp2), 0);
06711       l = tmp2;
06712    }
06713 
06714    if (ourport != STANDARD_SIP_PORT && ast_strlen_zero(p->fromdomain))
06715       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);
06716    else
06717       snprintf(from, sizeof(from), "\"%s\" <sip:%s@%s>;tag=%s", n, l, S_OR(p->fromdomain, ast_inet_ntoa(p->ourip)), p->tag);
06718 
06719    /* If we're calling a registered SIP peer, use the fullcontact to dial to the peer */
06720    if (!ast_strlen_zero(p->fullcontact)) {
06721       /* If we have full contact, trust it */
06722       ast_build_string(&invite, &invite_max, "%s", p->fullcontact);
06723    } else {
06724       /* Otherwise, use the username while waiting for registration */
06725       ast_build_string(&invite, &invite_max, "sip:");
06726       if (!ast_strlen_zero(p->username)) {
06727          n = p->username;
06728          if (pedanticsipchecking) {
06729             ast_uri_encode(n, tmp, sizeof(tmp), 0);
06730             n = tmp;
06731          }
06732          ast_build_string(&invite, &invite_max, "%s@", n);
06733       }
06734       ast_build_string(&invite, &invite_max, "%s", p->tohost);
06735       if (ntohs(p->sa.sin_port) != STANDARD_SIP_PORT)
06736          ast_build_string(&invite, &invite_max, ":%d", ntohs(p->sa.sin_port));
06737       ast_build_string(&invite, &invite_max, "%s", urioptions);
06738    }
06739 
06740    /* If custom URI options have been provided, append them */
06741    if (p->options && p->options->uri_options)
06742       ast_build_string(&invite, &invite_max, ";%s", p->options->uri_options);
06743    
06744    ast_string_field_set(p, uri, invite_buf);
06745 
06746    if (sipmethod == SIP_NOTIFY && !ast_strlen_zero(p->theirtag)) { 
06747       /* If this is a NOTIFY, use the From: tag in the subscribe (RFC 3265) */
06748       snprintf(to, sizeof(to), "<sip:%s>;tag=%s", p->uri, p->theirtag);
06749    } else if (p->options && p->options->vxml_url) {
06750       /* If there is a VXML URL append it to the SIP URL */
06751       snprintf(to, sizeof(to), "<%s>;%s", p->uri, p->options->vxml_url);
06752    } else 
06753       snprintf(to, sizeof(to), "<%s>", p->uri);
06754    
06755    init_req(req, sipmethod, p->uri);
06756    snprintf(tmp, sizeof(tmp), "%d %s", ++p->ocseq, sip_methods[sipmethod].text);
06757 
06758    add_header(req, "Via", p->via);
06759    /* SLD: FIXME?: do Route: here too?  I think not cos this is the first request.
06760     * OTOH, then we won't have anything in p->route anyway */
06761    /* Build Remote Party-ID and From */
06762    if (ast_test_flag(&p->flags[0], SIP_SENDRPID) && (sipmethod == SIP_INVITE)) {
06763       build_rpid(p);
06764       add_header(req, "From", p->rpid_from);
06765    } else 
06766       add_header(req, "From", from);
06767    add_header(req, "To", to);
06768    ast_string_field_set(p, exten, l);
06769    build_contact(p);
06770    add_header(req, "Contact", p->our_contact);
06771    add_header(req, "Call-ID", p->callid);
06772    add_header(req, "CSeq", tmp);
06773    if (!ast_strlen_zero(global_useragent))
06774       add_header(req, "User-Agent", global_useragent);
06775    add_header(req, "Max-Forwards", DEFAULT_MAX_FORWARDS);
06776    if (!ast_strlen_zero(p->rpid))
06777       add_header(req, "Remote-Party-ID", p->rpid);
06778 }

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

Convert Insecure setting to printable string.

Definition at line 9724 of file chan_sip.c.

Referenced by _sip_show_peer().

09725 {
09726    if (port && invite)
09727       return "port,invite";
09728    else if (port)
09729       return "port";
09730    else if (invite)
09731       return "invite";
09732    else
09733       return "no";
09734 }

static void list_route ( struct sip_route route  )  [static]

List all routes - mostly for debugging.

Definition at line 7922 of file chan_sip.c.

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

Referenced by build_route().

07923 {
07924    if (!route)
07925       ast_verbose("list_route: no route\n");
07926    else {
07927       for (;route; route = route->next)
07928          ast_verbose("list_route: hop: <%s>\n", route->hop);
07929    }
07930 }

static int load_module ( void   )  [static]

PBX load module - initialization.

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

17401 {
17402    ASTOBJ_CONTAINER_INIT(&userl);   /* User object list */
17403    ASTOBJ_CONTAINER_INIT(&peerl);   /* Peer object list */
17404    ASTOBJ_CONTAINER_INIT(&regl); /* Registry object list */
17405 
17406    if (!(sched = sched_context_create())) {
17407       ast_log(LOG_ERROR, "Unable to create scheduler context\n");
17408       return AST_MODULE_LOAD_FAILURE;
17409    }
17410 
17411    if (!(io = io_context_create())) {
17412       ast_log(LOG_ERROR, "Unable to create I/O context\n");
17413       sched_context_destroy(sched);
17414       return AST_MODULE_LOAD_FAILURE;
17415    }
17416 
17417    sip_reloadreason = CHANNEL_MODULE_LOAD;
17418 
17419    if(reload_config(sip_reloadreason)) /* Load the configuration from sip.conf */
17420       return AST_MODULE_LOAD_DECLINE;
17421 
17422    /* Make sure we can register our sip channel type */
17423    if (ast_channel_register(&sip_tech)) {
17424       ast_log(LOG_ERROR, "Unable to register channel type 'SIP'\n");
17425       io_context_destroy(io);
17426       sched_context_destroy(sched);
17427       return AST_MODULE_LOAD_FAILURE;
17428    }
17429 
17430    /* Register all CLI functions for SIP */
17431    ast_cli_register_multiple(cli_sip, sizeof(cli_sip)/ sizeof(struct ast_cli_entry));
17432 
17433    /* Tell the RTP subdriver that we're here */
17434    ast_rtp_proto_register(&sip_rtp);
17435 
17436    /* Tell the UDPTL subdriver that we're here */
17437    ast_udptl_proto_register(&sip_udptl);
17438 
17439    /* Register dialplan applications */
17440    ast_register_application(app_dtmfmode, sip_dtmfmode, synopsis_dtmfmode, descrip_dtmfmode);
17441    ast_register_application(app_sipaddheader, sip_addheader, synopsis_sipaddheader, descrip_sipaddheader);
17442 
17443    /* Register dialplan functions */
17444    ast_custom_function_register(&sip_header_function);
17445    ast_custom_function_register(&sippeer_function);
17446    ast_custom_function_register(&sipchaninfo_function);
17447    ast_custom_function_register(&checksipdomain_function);
17448 
17449    /* Register manager commands */
17450    ast_manager_register2("SIPpeers", EVENT_FLAG_SYSTEM, manager_sip_show_peers,
17451          "List SIP peers (text format)", mandescr_show_peers);
17452    ast_manager_register2("SIPshowpeer", EVENT_FLAG_SYSTEM, manager_sip_show_peer,
17453          "Show SIP peer (text format)", mandescr_show_peer);
17454 
17455    sip_poke_all_peers();   
17456    sip_send_all_registers();
17457    
17458    /* And start the monitor for the first time */
17459    restart_monitor();
17460 
17461    return AST_MODULE_LOAD_SUCCESS;
17462 }

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

13695 {
13696    struct sip_dual target;    /* Chan 1: Call from tranferer to Asterisk */
13697                /* Chan 2: Call from Asterisk to target */
13698    int res = 0;
13699    struct sip_pvt *targetcall_pvt;
13700 
13701    /* Check if the call ID of the replaces header does exist locally */
13702    if (!(targetcall_pvt = get_sip_pvt_byid_locked(transferer->refer->replaces_callid, transferer->refer->replaces_callid_totag, 
13703       transferer->refer->replaces_callid_fromtag))) {
13704       if (transferer->refer->localtransfer) {
13705          /* We did not find the refered call. Sorry, can't accept then */
13706          transmit_response(transferer, "202 Accepted", req);
13707          /* Let's fake a response from someone else in order
13708             to follow the standard */
13709          transmit_notify_with_sipfrag(transferer, seqno, "481 Call leg/transaction does not exist", TRUE);
13710          append_history(transferer, "Xfer", "Refer failed");
13711          ast_clear_flag(&transferer->flags[0], SIP_GOTREFER);  
13712          transferer->refer->status = REFER_FAILED;
13713          return -1;
13714       }
13715       /* Fall through for remote transfers that we did not find locally */
13716       if (option_debug > 2)
13717          ast_log(LOG_DEBUG, "SIP attended transfer: Not our call - generating INVITE with replaces\n");
13718       return 0;
13719    }
13720 
13721    /* Ok, we can accept this transfer */
13722    transmit_response(transferer, "202 Accepted", req);
13723    append_history(transferer, "Xfer", "Refer accepted");
13724    if (!targetcall_pvt->owner) { /* No active channel */
13725       if (option_debug > 3)
13726          ast_log(LOG_DEBUG, "SIP attended transfer: Error: No owner of target call\n");
13727       /* Cancel transfer */
13728       transmit_notify_with_sipfrag(transferer, seqno, "503 Service Unavailable", TRUE);
13729       append_history(transferer, "Xfer", "Refer failed");
13730       ast_clear_flag(&transferer->flags[0], SIP_GOTREFER);
13731       transferer->refer->status = REFER_FAILED;
13732       ast_mutex_unlock(&targetcall_pvt->lock);
13733       ast_channel_unlock(current->chan1);
13734       ast_channel_unlock(targetcall_pvt->owner);
13735       return -1;
13736    }
13737 
13738    /* We have a channel, find the bridge */
13739    target.chan1 = targetcall_pvt->owner;           /* Transferer to Asterisk */
13740    target.chan2 = ast_bridged_channel(targetcall_pvt->owner);  /* Asterisk to target */
13741 
13742    if (!target.chan2 || !(target.chan2->_state == AST_STATE_UP || target.chan2->_state == AST_STATE_RINGING) ) {
13743       /* Wrong state of new channel */
13744       if (option_debug > 3) {
13745          if (target.chan2) 
13746             ast_log(LOG_DEBUG, "SIP attended transfer: Error: Wrong state of target call: %s\n", ast_state2str(target.chan2->_state));
13747          else if (target.chan1->_state != AST_STATE_RING)
13748             ast_log(LOG_DEBUG, "SIP attended transfer: Error: No target channel\n");
13749          else
13750             ast_log(LOG_DEBUG, "SIP attended transfer: Attempting transfer in ringing state\n");
13751       }
13752    }
13753 
13754    /* Transfer */
13755    if (option_debug > 3 && sipdebug) {
13756       if (current->chan2)  /* We have two bridges */
13757          ast_log(LOG_DEBUG, "SIP attended transfer: trying to bridge %s and %s\n", target.chan1->name, current->chan2->name);
13758       else        /* One bridge, propably transfer of IVR/voicemail etc */
13759          ast_log(LOG_DEBUG, "SIP attended transfer: trying to make %s take over (masq) %s\n", target.chan1->name, current->chan1->name);
13760    }
13761 
13762    ast_set_flag(&transferer->flags[0], SIP_DEFER_BYE_ON_TRANSFER);   /* Delay hangup */
13763 
13764    /* Perform the transfer */
13765    res = attempt_transfer(current, &target);
13766    ast_mutex_unlock(&targetcall_pvt->lock);
13767    if (res) {
13768       /* Failed transfer */
13769       /* Could find better message, but they will get the point */
13770       transmit_notify_with_sipfrag(transferer, seqno, "486 Busy", TRUE);
13771       append_history(transferer, "Xfer", "Refer failed");
13772       if (targetcall_pvt->owner)
13773          ast_channel_unlock(targetcall_pvt->owner);
13774       /* Right now, we have to hangup, sorry. Bridge is destroyed */
13775       ast_hangup(transferer->owner);
13776    } else {
13777       /* Transfer succeeded! */
13778 
13779       /* Tell transferer that we're done. */
13780       transmit_notify_with_sipfrag(transferer, seqno, "200 OK", TRUE);
13781       append_history(transferer, "Xfer", "Refer succeeded");
13782       transferer->refer->status = REFER_200OK;
13783       if (targetcall_pvt->owner) {
13784          if (option_debug)
13785             ast_log(LOG_DEBUG, "SIP attended transfer: Unlocking channel %s\n", targetcall_pvt->owner->name);
13786          ast_channel_unlock(targetcall_pvt->owner);
13787       }
13788    }
13789    return 1;
13790 }

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

References t.

Referenced by sipsock_read().

04525 {
04526    int h = 0, t = 0; 
04527    int lws = 0; 
04528 
04529    for (; h < len;) { 
04530       /* Eliminate all CRs */ 
04531       if (msgbuf[h] == '\r') { 
04532          h++; 
04533          continue; 
04534       } 
04535       /* Check for end-of-line */ 
04536       if (msgbuf[h] == '\n') { 
04537          /* Check for end-of-message */ 
04538          if (h + 1 == len) 
04539             break; 
04540          /* Check for a continuation line */ 
04541          if (msgbuf[h + 1] == ' ' || msgbuf[h + 1] == '\t') { 
04542             /* Merge continuation line */ 
04543             h++; 
04544             continue; 
04545          } 
04546          /* Propagate LF and start new line */ 
04547          msgbuf[t++] = msgbuf[h++]; 
04548          lws = 0;
04549          continue; 
04550       } 
04551       if (msgbuf[h] == ' ' || msgbuf[h] == '\t') { 
04552          if (lws) { 
04553             h++; 
04554             continue; 
04555          } 
04556          msgbuf[t++] = msgbuf[h++]; 
04557          lws = 1; 
04558          continue; 
04559       } 
04560       msgbuf[t++] = msgbuf[h++]; 
04561       if (lws) 
04562          lws = 0; 
04563    } 
04564    msgbuf[t] = '\0'; 
04565    return t; 
04566 }

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

Make our SIP dialog tag.

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

04197 {
04198    snprintf(tagbuf, len, "as%08lx", ast_random());
04199 }

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

Show SIP peers in the manager API.

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

09970 {
09971    const char *a[4];
09972    const char *peer;
09973    int ret;
09974 
09975    peer = astman_get_header(m,"Peer");
09976    if (ast_strlen_zero(peer)) {
09977       astman_send_error(s, m, "Peer: <name> missing.\n");
09978       return 0;
09979    }
09980    a[0] = "sip";
09981    a[1] = "show";
09982    a[2] = "peer";
09983    a[3] = peer;
09984 
09985    ret = _sip_show_peer(1, -1, s, m, 4, a);
09986    astman_append(s, "\r\n\r\n" );
09987    return ret;
09988 }

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

Show SIP peers in the manager API.

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

09521 {
09522    const char *id = astman_get_header(m,"ActionID");
09523    const char *a[] = {"sip", "show", "peers"};
09524    char idtext[256] = "";
09525    int total = 0;
09526 
09527    if (!ast_strlen_zero(id))
09528       snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
09529 
09530    astman_send_ack(s, m, "Peer status list will follow");
09531    /* List the peers in separate manager events */
09532    _sip_show_peers(-1, &total, s, m, 3, a);
09533    /* Send final confirmation */
09534    astman_append(s,
09535    "Event: PeerlistComplete\r\n"
09536    "ListItems: %d\r\n"
09537    "%s"
09538    "\r\n", total, idtext);
09539    return 0;
09540 }

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

References len, sip_methods, and text.

Referenced by __sip_semi_ack(), and find_sip_method().

01646 {
01647    int len = strlen(sip_methods[id].text);
01648    int l_name = name ? strlen(name) : 0;
01649    /* true if the string is long enough, and ends with whitespace, and matches */
01650    return (l_name >= len && name[len] < 33 &&
01651       !strncasecmp(sip_methods[id].text, name, len));
01652 }

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

Convert NAT setting to text string.

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

09424 {
09425    switch(nat) {
09426    case SIP_NAT_NEVER:
09427       return "No";
09428    case SIP_NAT_ROUTE:
09429       return "Route";
09430    case SIP_NAT_ALWAYS:
09431       return "Always";
09432    case SIP_NAT_RFC3581:
09433       return "RFC3581";
09434    default:
09435       return "Unknown";
09436    }
09437 }

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

Copy SIP request, parse it.

Definition at line 2138 of file chan_sip.c.

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

Referenced by send_request(), and send_response().

02139 {
02140    memset(dst, 0, sizeof(*dst));
02141    memcpy(dst->data, src->data, sizeof(dst->data));
02142    dst->len = src->len;
02143    parse_request(dst);
02144 }

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

Parse 302 Moved temporalily response.

Definition at line 11598 of file chan_sip.c.

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

Referenced by handle_response().

11599 {
11600    char tmp[BUFSIZ];
11601    char *s, *e;
11602    char *domain;
11603 
11604    ast_copy_string(tmp, get_header(req, "Contact"), sizeof(tmp));
11605    s = get_in_brackets(tmp);
11606    s = strsep(&s, ";"); /* strip ; and beyond */
11607    if (ast_test_flag(&p->flags[0], SIP_PROMISCREDIR)) {
11608       if (!strncasecmp(s, "sip:", 4))
11609          s += 4;
11610       e = strchr(s, '/');
11611       if (e)
11612          *e = '\0';
11613       if (option_debug)
11614          ast_log(LOG_DEBUG, "Found promiscuous redirection to 'SIP/%s'\n", s);
11615       if (p->owner)
11616          ast_string_field_build(p->owner, call_forward, "SIP/%s", s);
11617    } else {
11618       e = strchr(tmp, '@');
11619       if (e) {
11620          *e++ = '\0';
11621          domain = e;
11622       } else {
11623          /* No username part */
11624          domain = tmp;
11625       }
11626       e = strchr(tmp, '/');
11627       if (e)
11628          *e = '\0';
11629       if (!strncasecmp(s, "sip:", 4))
11630          s += 4;
11631       if (option_debug > 1)
11632          ast_log(LOG_DEBUG, "Received 302 Redirect to extension '%s' (domain %s)\n", s, domain);
11633       if (p->owner) {
11634          pbx_builtin_setvar_helper(p->owner, "SIPDOMAIN", domain);
11635          ast_string_field_set(p->owner, call_forward, s);
11636       }
11637    }
11638 }

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

07678 {
07679    char contact[BUFSIZ]; 
07680    char *c;
07681 
07682    /* Look for brackets */
07683    ast_copy_string(contact, get_header(req, "Contact"), sizeof(contact));
07684    c = get_in_brackets(contact);
07685 
07686    /* Save full contact to call pvt for later bye or re-invite */
07687    ast_string_field_set(pvt, fullcontact, c);
07688 
07689    /* Save URI for later ACKs, BYE or RE-invites */
07690    ast_string_field_set(pvt, okcontacturi, c);
07691 
07692    /* We should return false for URI:s we can't handle,
07693       like sips:, tel:, mailto:,ldap: etc */
07694    return TRUE;      
07695 }

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

07761 {
07762    char contact[BUFSIZ]; 
07763    char data[BUFSIZ];
07764    const char *expires = get_header(req, "Expires");
07765    int expiry = atoi(expires);
07766    char *curi, *n, *pt;
07767    int port;
07768    const char *useragent;
07769    struct hostent *hp;
07770    struct ast_hostent ahp;
07771    struct sockaddr_in oldsin;
07772 
07773    ast_copy_string(contact, get_header(req, "Contact"), sizeof(contact));
07774 
07775    if (ast_strlen_zero(expires)) {  /* No expires header */
07776       expires = strcasestr(contact, ";expires=");
07777       if (expires) {
07778          /* XXX bug here, we overwrite the string */
07779          expires = strsep((char **) &expires, ";"); /* trim ; and beyond */
07780          if (sscanf(expires + 9, "%d", &expiry) != 1)
07781             expiry = default_expiry;
07782       } else {
07783          /* Nothing has been specified */
07784          expiry = default_expiry;
07785       }
07786    }
07787 
07788    /* Look for brackets */
07789    curi = contact;
07790    if (strchr(contact, '<') == NULL)   /* No <, check for ; and strip it */
07791       strsep(&curi, ";");  /* This is Header options, not URI options */
07792    curi = get_in_brackets(contact);
07793 
07794    /* if they did not specify Contact: or Expires:, they are querying
07795       what we currently have stored as their contact address, so return
07796       it
07797    */
07798    if (ast_strlen_zero(curi) && ast_strlen_zero(expires)) {
07799       /* If we have an active registration, tell them when the registration is going to expire */
07800       if (peer->expire > -1 && !ast_strlen_zero(peer->fullcontact))
07801          pvt->expiry = ast_sched_when(sched, peer->expire);
07802       return PARSE_REGISTER_QUERY;
07803    } else if (!strcasecmp(curi, "*") || !expiry) { /* Unregister this peer */
07804       /* This means remove all registrations and return OK */
07805       memset(&peer->addr, 0, sizeof(peer->addr));
07806       if (peer->expire > -1)
07807          ast_sched_del(sched, peer->expire);
07808       peer->expire = -1;
07809 
07810       destroy_association(peer);
07811       
07812       register_peer_exten(peer, 0); /* Add extension from regexten= setting in sip.conf */
07813       peer->fullcontact[0] = '\0';
07814       peer->useragent[0] = '\0';
07815       peer->sipoptions = 0;
07816       peer->lastms = 0;
07817 
07818       if (option_verbose > 2)
07819          ast_verbose(VERBOSE_PREFIX_3 "Unregistered SIP '%s'\n", peer->name);
07820          manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unregistered\r\n", peer->name);
07821       return PARSE_REGISTER_UPDATE;
07822    }
07823 
07824    /* Store whatever we got as a contact from the client */
07825    ast_copy_string(peer->fullcontact, curi, sizeof(peer->fullcontact));
07826 
07827    /* For the 200 OK, we should use the received contact */
07828    ast_string_field_build(pvt, our_contact, "<%s>", curi);
07829 
07830    /* Make sure it's a SIP URL */
07831    if (strncasecmp(curi, "sip:", 4)) {
07832       ast_log(LOG_NOTICE, "'%s' is not a valid SIP contact (missing sip:) trying to use anyway\n", curi);
07833    } else
07834       curi += 4;
07835    /* Ditch q */
07836    curi = strsep(&curi, ";");
07837    /* Grab host */
07838    n = strchr(curi, '@');
07839    if (!n) {
07840       n = curi;
07841       curi = NULL;
07842    } else
07843       *n++ = '\0';
07844    pt = strchr(n, ':');
07845    if (pt) {
07846       *pt++ = '\0';
07847       port = atoi(pt);
07848    } else
07849       port = STANDARD_SIP_PORT;
07850    oldsin = peer->addr;
07851    if (!ast_test_flag(&peer->flags[0], SIP_NAT_ROUTE)) {
07852       /* XXX This could block for a long time XXX */
07853       hp = ast_gethostbyname(n, &ahp);
07854       if (!hp)  {
07855          ast_log(LOG_WARNING, "Invalid host '%s'\n", n);
07856          return PARSE_REGISTER_FAILED;
07857       }
07858       peer->addr.sin_family = AF_INET;
07859       memcpy(&peer->addr.sin_addr, hp->h_addr, sizeof(peer->addr.sin_addr));
07860       peer->addr.sin_port = htons(port);
07861    } else {
07862       /* Don't trust the contact field.  Just use what they came to us
07863          with */
07864       peer->addr = pvt->recv;
07865    }
07866 
07867    /* Save SIP options profile */
07868    peer->sipoptions = pvt->sipoptions;
07869 
07870    if (curi)   /* Overwrite the default username from config at registration */
07871       ast_copy_string(peer->username, curi, sizeof(peer->username));
07872    else
07873       peer->username[0] = '\0';
07874 
07875    if (peer->expire > -1) {
07876       ast_sched_del(sched, peer->expire);
07877       peer->expire = -1;
07878    }
07879    if (expiry > max_expiry)
07880       expiry = max_expiry;
07881    if (expiry < min_expiry)
07882       expiry = min_expiry;
07883    peer->expire = ast_test_flag(&peer->flags[0], SIP_REALTIME) ? -1 :
07884       ast_sched_add(sched, (expiry + 10) * 1000, expire_register, peer);
07885    pvt->expiry = expiry;
07886    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);
07887    if (!ast_test_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT)) 
07888       ast_db_put("SIP/Registry", peer->name, data);
07889    manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Registered\r\n", peer->name);
07890 
07891    /* Is this a new IP address for us? */
07892    if (inaddrcmp(&peer->addr, &oldsin)) {
07893       sip_poke_peer(peer);
07894       if (option_verbose > 2)
07895          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);
07896       register_peer_exten(peer, 1);
07897    }
07898    
07899    /* Save User agent */
07900    useragent = get_header(req, "User-Agent");
07901    if (strcasecmp(useragent, peer->useragent)) {   /* XXX copy if they are different ? */
07902       ast_copy_string(peer->useragent, useragent, sizeof(peer->useragent));
07903       if (option_verbose > 3)
07904          ast_verbose(VERBOSE_PREFIX_3 "Saved useragent \"%s\" for peer %s\n", peer->useragent, peer->name);  
07905    }
07906    return PARSE_REGISTER_UPDATE;
07907 }

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

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

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

04572 {
04573    /* Divide fields by NULL's */
04574    char *c;
04575    int f = 0;
04576 
04577    c = req->data;
04578 
04579    /* First header starts immediately */
04580    req->header[f] = c;
04581    while(*c) {
04582       if (*c == '\n') {
04583          /* We've got a new header */
04584          *c = 0;
04585 
04586          if (sipdebug && option_debug > 3)
04587             ast_log(LOG_DEBUG, "Header %d: %s (%d)\n", f, req->header[f], (int) strlen(req->header[f]));
04588          if (ast_strlen_zero(req->header[f])) {
04589             /* Line by itself means we're now in content */
04590             c++;
04591             break;
04592          }
04593          if (f >= SIP_MAX_HEADERS - 1) {
04594             ast_log(LOG_WARNING, "Too many SIP headers. Ignoring.\n");
04595          } else
04596             f++;
04597          req->header[f] = c + 1;
04598       } else if (*c == '\r') {
04599          /* Ignore but eliminate \r's */
04600          *c = 0;
04601       }
04602       c++;
04603    }
04604    /* Check for last header */
04605    if (!ast_strlen_zero(req->header[f])) {
04606       if (sipdebug && option_debug > 3)
04607          ast_log(LOG_DEBUG, "Header %d: %s (%d)\n", f, req->header[f], (int) strlen(req->header[f]));
04608       f++;
04609    }
04610    req->headers = f;
04611    /* Now we process any mime content */
04612    f = 0;
04613    req->line[f] = c;
04614    while(*c) {
04615       if (*c == '\n') {
04616          /* We've got a new line */
04617          *c = 0;
04618          if (sipdebug && option_debug > 3)
04619             ast_log(LOG_DEBUG, "Line: %s (%d)\n", req->line[f], (int) strlen(req->line[f]));
04620          if (f >= SIP_MAX_LINES - 1) {
04621             ast_log(LOG_WARNING, "Too many SDP lines. Ignoring.\n");
04622          } else
04623             f++;
04624          req->line[f] = c + 1;
04625       } else if (*c == '\r') {
04626          /* Ignore and eliminate \r's */
04627          *c = 0;
04628       }
04629       c++;
04630    }
04631    /* Check for last line */
04632    if (!ast_strlen_zero(req->line[f])) 
04633       f++;
04634    req->lines = f;
04635    if (*c) 
04636       ast_log(LOG_WARNING, "Odd content, extra stuff left over ('%s')\n", c);
04637    /* Split up the first line parts */
04638    determine_firstline_parts(req);
04639 }

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

Parse supported header in incoming packet.

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

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

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

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

09443 {
09444    int res = 0;
09445    if (peer->maxms) {
09446       if (peer->lastms < 0) {
09447          ast_copy_string(status, "UNREACHABLE", statuslen);
09448       } else if (peer->lastms > peer->maxms) {
09449          snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms);
09450          res = 1;
09451       } else if (peer->lastms) {
09452          snprintf(status, statuslen, "OK (%d ms)", peer->lastms);
09453          res = 1;
09454       } else {
09455          ast_copy_string(status, "UNKNOWN", statuslen);
09456       }
09457    } else { 
09458       ast_copy_string(status, "Unmonitored", statuslen);
09459       /* Checking if port is 0 */
09460       res = -1;
09461    }
09462    return res;
09463 }

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

09911 {
09912    int x, codec;
09913 
09914    for(x = 0; x < 32 ; x++) {
09915       codec = ast_codec_pref_index(pref, x);
09916       if (!codec)
09917          break;
09918       ast_cli(fd, "%s", ast_getformatname(codec));
09919       ast_cli(fd, ":%d", pref->framing[x]);
09920       if (x < 31 && ast_codec_pref_index(pref, x + 1))
09921          ast_cli(fd, ",");
09922    }
09923    if (!x)
09924       ast_cli(fd, "none");
09925 }

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

Print call group and pickup group.

Definition at line 9701 of file chan_sip.c.

References ast_cli(), and ast_print_group().

Referenced by _sip_show_peer(), and sip_show_user().

09702 {
09703    char buf[256];
09704    ast_cli(fd, crlf ? "%s\r\n" : "%s\n", ast_print_group(buf, sizeof(buf), group) );
09705 }

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

References append_history, 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, sip_request::data, debug, EVENT_FLAG_CALL, FALSE, sip_pvt::flags, format, get_sdp(), get_sdp_iterate(), hp, sip_pvt::jointcapability, t38properties::jointcapability, sip_pvt::jointnoncodeccapability, sip_pvt::lastinvite, sip_pvt::lastrtprx, sip_pvt::lastrtptx, len, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, LOG_WARNING, LONG_MAX, LONG_MIN, manager_event(), 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_CALL_ONHOLD_INACTIVE, SIP_PAGE2_CALL_ONHOLD_ONEDIR, SIP_PAGE2_RFC2833_COMPENSATE, sip_peer_hold(), 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.

04721 {
04722    const char *m;    /* SDP media offer */
04723    const char *c;
04724    const char *a;
04725    char host[258];
04726    int len = -1;
04727    int portno = -1;     /*!< RTP Audio port number */
04728    int vportno = -1;    /*!< RTP Video port number */
04729    int udptlportno = -1;
04730    int peert38capability = 0;
04731    char s[256];
04732    int old = 0;
04733 
04734    /* Peer capability is the capability in the SDP, non codec is RFC2833 DTMF (101) */ 
04735    int peercapability = 0, peernoncodeccapability = 0;
04736    int vpeercapability = 0, vpeernoncodeccapability = 0;
04737    struct sockaddr_in sin;    /*!< media socket address */
04738    struct sockaddr_in vsin;   /*!< Video socket address */
04739 
04740    const char *codecs;
04741    struct hostent *hp;     /*!< RTP Audio host IP */
04742    struct hostent *vhp = NULL;   /*!< RTP video host IP */
04743    struct ast_hostent audiohp;
04744    struct ast_hostent videohp;
04745    int codec;
04746    int destiterator = 0;
04747    int iterator;
04748    int sendonly = -1;
04749    int numberofports;
04750    struct ast_rtp *newaudiortp, *newvideortp;   /* Buffers for codec handling */
04751    int newjointcapability;          /* Negotiated capability */
04752    int newpeercapability;
04753    int newnoncodeccapability;
04754    int numberofmediastreams = 0;
04755    int debug = sip_debug_test_pvt(p);
04756       
04757    int found_rtpmap_codecs[32];
04758    int last_rtpmap_codec=0;
04759 
04760    if (!p->rtp) {
04761       ast_log(LOG_ERROR, "Got SDP but have no RTP session allocated.\n");
04762       return -1;
04763    }
04764 
04765    /* Initialize the temporary RTP structures we use to evaluate the offer from the peer */
04766    newaudiortp = alloca(ast_rtp_alloc_size());
04767    memset(newaudiortp, 0, ast_rtp_alloc_size());
04768    ast_rtp_new_init(newaudiortp);
04769    ast_rtp_pt_clear(newaudiortp);
04770 
04771    newvideortp = alloca(ast_rtp_alloc_size());
04772    memset(newvideortp, 0, ast_rtp_alloc_size());
04773    ast_rtp_new_init(newvideortp);
04774    ast_rtp_pt_clear(newvideortp);
04775 
04776    /* Update our last rtprx when we receive an SDP, too */
04777    p->lastrtprx = p->lastrtptx = time(NULL); /* XXX why both ? */
04778 
04779 
04780    /* Try to find first media stream */
04781    m = get_sdp(req, "m");
04782    destiterator = req->sdp_start;
04783    c = get_sdp_iterate(&destiterator, req, "c");
04784    if (ast_strlen_zero(m) || ast_strlen_zero(c)) {
04785       ast_log(LOG_WARNING, "Insufficient information for SDP (m = '%s', c = '%s')\n", m, c);
04786       return -1;
04787    }
04788 
04789    /* Check for IPv4 address (not IPv6 yet) */
04790    if (sscanf(c, "IN IP4 %256s", host) != 1) {
04791       ast_log(LOG_WARNING, "Invalid host in c= line, '%s'\n", c);
04792       return -1;
04793    }
04794 
04795    /* XXX This could block for a long time, and block the main thread! XXX */
04796    hp = ast_gethostbyname(host, &audiohp);
04797    if (!hp) {
04798       ast_log(LOG_WARNING, "Unable to lookup host in c= line, '%s'\n", c);
04799       return -1;
04800    }
04801    vhp = hp;   /* Copy to video address as default too */
04802    
04803    iterator = req->sdp_start;
04804    ast_set_flag(&p->flags[0], SIP_NOVIDEO);  
04805 
04806 
04807    /* Find media streams in this SDP offer */
04808    while ((m = get_sdp_iterate(&iterator, req, "m"))[0] != '\0') {
04809       int x;
04810       int audio = FALSE;
04811 
04812       numberofports = 1;
04813       if ((sscanf(m, "audio %d/%d RTP/AVP %n", &x, &numberofports, &len) == 2) ||
04814           (sscanf(m, "audio %d RTP/AVP %n", &x, &len) == 1)) {
04815          audio = TRUE;
04816          numberofmediastreams++;
04817          /* Found audio stream in this media definition */
04818          portno = x;
04819          /* Scan through the RTP payload types specified in a "m=" line: */
04820          for (codecs = m + len; !ast_strlen_zero(codecs); codecs = ast_skip_blanks(codecs + len)) {
04821             if (sscanf(codecs, "%d%n", &codec, &len) != 1) {
04822                ast_log(LOG_WARNING, "Error in codec string '%s'\n", codecs);
04823                return -1;
04824             }
04825             if (debug)
04826                ast_verbose("Found RTP audio format %d\n", codec);
04827             ast_rtp_set_m_type(newaudiortp, codec);
04828          }
04829       } else if ((sscanf(m, "video %d/%d RTP/AVP %n", &x, &numberofports, &len) == 2) ||
04830           (sscanf(m, "video %d RTP/AVP %n", &x, &len) == 1)) {
04831          /* If it is not audio - is it video ? */
04832          ast_clear_flag(&p->flags[0], SIP_NOVIDEO);   
04833          numberofmediastreams++;
04834          vportno = x;
04835          /* Scan through the RTP payload types specified in a "m=" line: */
04836          for (codecs = m + len; !ast_strlen_zero(codecs); codecs = ast_skip_blanks(codecs + len)) {
04837             if (sscanf(codecs, "%d%n", &codec, &len) != 1) {
04838                ast_log(LOG_WARNING, "Error in codec string '%s'\n", codecs);
04839                return -1;
04840             }
04841             if (debug)
04842                ast_verbose("Found RTP video format %d\n", codec);
04843             ast_rtp_set_m_type(newvideortp, codec);
04844          }
04845       } else if (p->udptl && ( (sscanf(m, "image %d udptl t38%n", &x, &len) == 1) || 
04846        (sscanf(m, "image %d UDPTL t38%n", &x, &len) == 1) )) {
04847          if (debug)
04848             ast_verbose("Got T.38 offer in SDP in dialog %s\n", p->callid);
04849          udptlportno = x;
04850          numberofmediastreams++;
04851          
04852          if (p->owner && p->lastinvite) {
04853             p->t38.state = T38_PEER_REINVITE; /* T38 Offered in re-invite from remote party */
04854             if (option_debug > 1)
04855                ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>" );
04856          } else {
04857             p->t38.state = T38_PEER_DIRECT; /* T38 Offered directly from peer in first invite */
04858             if (option_debug > 1)
04859                ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>");
04860          }
04861       } else 
04862          ast_log(LOG_WARNING, "Unsupported SDP media type in offer: %s\n", m);
04863       if (numberofports > 1)
04864          ast_log(LOG_WARNING, "SDP offered %d ports for media, not supported by Asterisk. Will try anyway...\n", numberofports);
04865       
04866 
04867       /* Check for Media-description-level-address for audio */
04868       c = get_sdp_iterate(&destiterator, req, "c");
04869       if (!ast_strlen_zero(c)) {
04870          if (sscanf(c, "IN IP4 %256s", host) != 1) {
04871             ast_log(LOG_WARNING, "Invalid secondary host in c= line, '%s'\n", c);
04872          } else {
04873             /* XXX This could block for a long time, and block the main thread! XXX */
04874             if (audio) {
04875                if ( !(hp = ast_gethostbyname(host, &audiohp))) {
04876                   ast_log(LOG_WARNING, "Unable to lookup RTP Audio host in secondary c= line, '%s'\n", c);
04877                   return -2;
04878                }
04879             } else if (!(vhp = ast_gethostbyname(host, &videohp))) {
04880                ast_log(LOG_WARNING, "Unable to lookup RTP video host in secondary c= line, '%s'\n", c);
04881                return -2;
04882             }
04883          }
04884 
04885       }
04886    }
04887    if (portno == -1 && vportno == -1 && udptlportno == -1)
04888       /* No acceptable offer found in SDP  - we have no ports */
04889       /* Do not change RTP or VRTP if this is a re-invite */
04890       return -2;
04891 
04892    if (numberofmediastreams > 2)
04893       /* We have too many fax, audio and/or video media streams, fail this offer */
04894       return -3;
04895 
04896    /* RTP addresses and ports for audio and video */
04897    sin.sin_family = AF_INET;
04898    vsin.sin_family = AF_INET;
04899    memcpy(&sin.sin_addr, hp->h_addr, sizeof(sin.sin_addr));
04900    if (vhp)
04901       memcpy(&vsin.sin_addr, vhp->h_addr, sizeof(vsin.sin_addr));
04902 
04903    /* Setup UDPTL port number */
04904    if (p->udptl) {
04905       if (udptlportno > 0) {
04906          sin.sin_port = htons(udptlportno);
04907          ast_udptl_set_peer(p->udptl, &sin);
04908          if (debug)
04909             ast_log(LOG_DEBUG,"Peer T.38 UDPTL is at port %s:%d\n",ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
04910       } else {
04911          ast_udptl_stop(p->udptl);
04912          if (debug)
04913             ast_log(LOG_DEBUG, "Peer doesn't provide T.38 UDPTL\n");
04914       }
04915    }
04916 
04917       
04918    if (p->rtp) {
04919       if (portno > 0) {
04920          sin.sin_port = htons(portno);
04921          ast_rtp_set_peer(p->rtp, &sin);
04922          if (debug)
04923             ast_verbose("Peer audio RTP is at port %s:%d\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
04924       } else {
04925          if (udptlportno > 0) {
04926             if (debug)
04927                ast_verbose("Got T.38 Re-invite without audio. Keeping RTP active during T.38 session. Callid %s\n", p->callid);
04928          } else {
04929             ast_rtp_stop(p->rtp);
04930             if (debug)
04931                ast_verbose("Peer doesn't provide audio. Callid %s\n", p->callid);
04932          }
04933       }
04934    }
04935    /* Setup video port number */
04936    if (vportno != -1)
04937       vsin.sin_port = htons(vportno);
04938 
04939    /* Next, scan through each "a=rtpmap:" line, noting each
04940     * specified RTP payload type (with corresponding MIME subtype):
04941     */
04942    /* XXX This needs to be done per media stream, since it's media stream specific */
04943    iterator = req->sdp_start;
04944    while ((a = get_sdp_iterate(&iterator, req, "a"))[0] != '\0') {
04945       char* mimeSubtype = ast_strdupa(a); /* ensures we have enough space */
04946       if (option_debug > 1) {
04947          int breakout = FALSE;
04948       
04949          /* If we're debugging, check for unsupported sdp options */
04950          if (!strncasecmp(a, "rtcp:", (size_t) 5)) {
04951             if (debug)
04952                ast_verbose("Got unsupported a:rtcp in SDP offer \n");
04953             breakout = TRUE;
04954          } else if (!strncasecmp(a, "fmtp:", (size_t) 5)) {
04955             /* Format parameters:  Not supported */
04956             /* Note: This is used for codec parameters, like bitrate for
04957                G722 and video formats for H263 and H264 
04958                See RFC2327 for an example */
04959             if (debug)
04960                ast_verbose("Got unsupported a:fmtp in SDP offer \n");
04961             breakout = TRUE;
04962          } else if (!strncasecmp(a, "framerate:", (size_t) 10)) {
04963             /* Video stuff:  Not supported */
04964             if (debug)
04965                ast_verbose("Got unsupported a:framerate in SDP offer \n");
04966             breakout = TRUE;
04967          } else if (!strncasecmp(a, "maxprate:", (size_t) 9)) {
04968             /* Video stuff:  Not supported */
04969             if (debug)
04970                ast_verbose("Got unsupported a:maxprate in SDP offer \n");
04971             breakout = TRUE;
04972          } else if (!strncasecmp(a, "crypto:", (size_t) 7)) {
04973             /* SRTP stuff, not yet supported */
04974             if (debug)
04975                ast_verbose("Got unsupported a:crypto in SDP offer \n");
04976             breakout = TRUE;
04977          }
04978          if (breakout)  /* We have a match, skip to next header */
04979             continue;
04980       }
04981       if (!strcasecmp(a, "sendonly")) {
04982          if (sendonly == -1)
04983             sendonly = 1;
04984          continue;
04985       } else if (!strcasecmp(a, "inactive")) {
04986          if (sendonly == -1)
04987             sendonly = 2;
04988          continue;
04989       }  else if (!strcasecmp(a, "sendrecv")) {
04990          if (sendonly == -1)
04991             sendonly = 0;
04992          continue;
04993       } else if (strlen(a) > 5 && !strncasecmp(a, "ptime", 5)) {
04994          char *tmp = strrchr(a, ':');
04995          long int framing = 0;
04996          if (tmp) {
04997             tmp++;
04998             framing = strtol(tmp, NULL, 10);
04999             if (framing == LONG_MIN || framing == LONG_MAX) {
05000                framing = 0;
05001                if (option_debug)
05002                   ast_log(LOG_DEBUG, "Can't read framing from SDP: %s\n", a);
05003             }
05004          }
05005          if (framing && last_rtpmap_codec) {
05006             if (p->autoframing) {
05007                struct ast_codec_pref *pref = ast_rtp_codec_getpref(p->rtp);
05008                int codec_n;
05009                int format = 0;
05010                for (codec_n = 0; codec_n < last_rtpmap_codec; codec_n++) {
05011                   format = ast_rtp_codec_getformat(found_rtpmap_codecs[codec_n]);
05012                   if (!format)   /* non-codec or not found */
05013                      continue;
05014                   if (option_debug)
05015                      ast_log(LOG_DEBUG, "Setting framing for %d to %ld\n", format, framing);
05016                   ast_codec_pref_setsize(pref, format, framing);
05017                }
05018                ast_rtp_codec_setpref(p->rtp, pref);
05019             }
05020          }
05021          memset(&found_rtpmap_codecs, 0, sizeof(found_rtpmap_codecs));
05022          last_rtpmap_codec = 0;
05023          continue;
05024       } else if (sscanf(a, "rtpmap: %u %[^/]/", &codec, mimeSubtype) == 2) {
05025          /* We have a rtpmap to handle */
05026          if (debug)
05027             ast_verbose("Found description format %s for ID %d\n", mimeSubtype, codec);
05028          found_rtpmap_codecs[last_rtpmap_codec] = codec;
05029          last_rtpmap_codec++;
05030 
05031          /* Note: should really look at the 'freq' and '#chans' params too */
05032          ast_rtp_set_rtpmap_type(newaudiortp, codec, "audio", mimeSubtype,
05033                ast_test_flag(&p->flags[0], SIP_G726_NONSTANDARD) ? AST_RTP_OPT_G726_NONSTANDARD : 0);
05034          if (p->vrtp)
05035             ast_rtp_set_rtpmap_type(newvideortp, codec, "video", mimeSubtype, 0);
05036       }
05037    }
05038    
05039    if (udptlportno != -1) {
05040       int found = 0, x;
05041       
05042       old = 0;
05043       
05044       /* Scan trough the a= lines for T38 attributes and set apropriate fileds */
05045       iterator = req->sdp_start;
05046       while ((a = get_sdp_iterate(&iterator, req, "a"))[0] != '\0') {
05047          if ((sscanf(a, "T38FaxMaxBuffer:%d", &x) == 1)) {
05048             found = 1;
05049             if (option_debug > 2)
05050                ast_log(LOG_DEBUG, "MaxBufferSize:%d\n",x);
05051          } else if ((sscanf(a, "T38MaxBitRate:%d", &x) == 1)) {
05052             found = 1;
05053             if (option_debug > 2)
05054                ast_log(LOG_DEBUG,"T38MaxBitRate: %d\n",x);
05055             switch (x) {
05056             case 14400:
05057                peert38capability |= T38FAX_RATE_14400 | T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400;
05058                break;
05059             case 12000:
05060                peert38capability |= T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400;
05061                break;
05062             case 9600:
05063                peert38capability |= T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400;
05064                break;
05065             case 7200:
05066                peert38capability |= T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400;
05067                break;
05068             case 4800:
05069                peert38capability |= T38FAX_RATE_4800 | T38FAX_RATE_2400;
05070                break;
05071             case 2400:
05072                peert38capability |= T38FAX_RATE_2400;
05073                break;
05074             }
05075          } else if ((sscanf(a, "T38FaxVersion:%d", &x) == 1)) {
05076             found = 1;
05077             if (option_debug > 2)
05078                ast_log(LOG_DEBUG, "FaxVersion: %d\n",x);
05079             if (x == 0)
05080                peert38capability |= T38FAX_VERSION_0;
05081             else if (x == 1)
05082                peert38capability |= T38FAX_VERSION_1;
05083          } else if ((sscanf(a, "T38FaxMaxDatagram:%d", &x) == 1)) {
05084             found = 1;
05085             if (option_debug > 2)
05086                ast_log(LOG_DEBUG, "FaxMaxDatagram: %d\n",x);
05087             ast_udptl_set_far_max_datagram(p->udptl, x);
05088             ast_udptl_set_local_max_datagram(p->udptl, x);
05089          } else if ((sscanf(a, "T38FaxFillBitRemoval:%d", &x) == 1)) {
05090             found = 1;
05091             if (option_debug > 2)
05092                ast_log(LOG_DEBUG, "FillBitRemoval: %d\n",x);
05093             if (x == 1)
05094                peert38capability |= T38FAX_FILL_BIT_REMOVAL;
05095          } else if ((sscanf(a, "T38FaxTranscodingMMR:%d", &x) == 1)) {
05096             found = 1;
05097             if (option_debug > 2)
05098                ast_log(LOG_DEBUG, "Transcoding MMR: %d\n",x);
05099             if (x == 1)
05100                peert38capability |= T38FAX_TRANSCODING_MMR;
05101          }
05102          if ((sscanf(a, "T38FaxTranscodingJBIG:%d", &x) == 1)) {
05103             found = 1;
05104             if (option_debug > 2)
05105                ast_log(LOG_DEBUG, "Transcoding JBIG: %d\n",x);
05106             if (x == 1)
05107                peert38capability |= T38FAX_TRANSCODING_JBIG;
05108          } else if ((sscanf(a, "T38FaxRateManagement:%255s", s) == 1)) {
05109             found = 1;
05110             if (option_debug > 2)
05111                ast_log(LOG_DEBUG, "RateManagement: %s\n", s);
05112             if (!strcasecmp(s, "localTCF"))
05113                peert38capability |= T38FAX_RATE_MANAGEMENT_LOCAL_TCF;
05114             else if (!strcasecmp(s, "transferredTCF"))
05115                peert38capability |= T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF;
05116          } else if ((sscanf(a, "T38FaxUdpEC:%255s", s) == 1)) {
05117             found = 1;
05118             if (option_debug > 2)
05119                ast_log(LOG_DEBUG, "UDP EC: %s\n", s);
05120             if (!strcasecmp(s, "t38UDPRedundancy")) {
05121                peert38capability |= T38FAX_UDP_EC_REDUNDANCY;
05122                ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_REDUNDANCY);
05123             } else if (!strcasecmp(s, "t38UDPFEC")) {
05124                peert38capability |= T38FAX_UDP_EC_FEC;
05125                ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_FEC);
05126             } else {
05127                peert38capability |= T38FAX_UDP_EC_NONE;
05128                ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_NONE);
05129             }
05130          }
05131       }
05132       if (found) { /* Some cisco equipment returns nothing beside c= and m= lines in 200 OK T38 SDP */
05133          p->t38.peercapability = peert38capability;
05134          p->t38.jointcapability = (peert38capability & 255); /* Put everything beside supported speeds settings */
05135          peert38capability &= (T38FAX_RATE_14400 | T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400);
05136          p->t38.jointcapability |= (peert38capability & p->t38.capability); /* Put the lower of our's and peer's speed */
05137       }
05138       if (debug)
05139          ast_log(LOG_DEBUG, "Our T38 capability = (%d), peer T38 capability (%d), joint T38 capability (%d)\n",
05140             p->t38.capability,
05141             p->t38.peercapability,
05142             p->t38.jointcapability);
05143    } else {
05144       p->t38.state = T38_DISABLED;
05145       if (option_debug > 2)
05146          ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>");
05147    }
05148 
05149    /* Now gather all of the codecs that we are asked for: */
05150    ast_rtp_get_current_formats(newaudiortp, &peercapability, &peernoncodeccapability);
05151    ast_rtp_get_current_formats(newvideortp, &vpeercapability, &vpeernoncodeccapability);
05152 
05153    newjointcapability = p->capability & (peercapability | vpeercapability);
05154    newpeercapability = (peercapability | vpeercapability);
05155    newnoncodeccapability = p->noncodeccapability & peernoncodeccapability;
05156       
05157       
05158    if (debug) {
05159       /* shame on whoever coded this.... */
05160       char s1[BUFSIZ], s2[BUFSIZ], s3[BUFSIZ], s4[BUFSIZ];
05161 
05162       ast_verbose("Capabilities: us - %s, peer - audio=%s/video=%s, combined - %s\n",
05163              ast_getformatname_multiple(s1, BUFSIZ, p->capability),
05164              ast_getformatname_multiple(s2, BUFSIZ, newpeercapability),
05165              ast_getformatname_multiple(s3, BUFSIZ, vpeercapability),
05166              ast_getformatname_multiple(s4, BUFSIZ, newjointcapability));
05167 
05168       ast_verbose("Non-codec capabilities (dtmf): us - %s, peer - %s, combined - %s\n",
05169              ast_rtp_lookup_mime_multiple(s1, BUFSIZ, p->noncodeccapability, 0, 0),
05170              ast_rtp_lookup_mime_multiple(s2, BUFSIZ, peernoncodeccapability, 0, 0),
05171              ast_rtp_lookup_mime_multiple(s3, BUFSIZ, newnoncodeccapability, 0, 0));
05172    }
05173    if (!newjointcapability) {
05174       /* If T.38 was not negotiated either, totally bail out... */
05175       if (!p->t38.jointcapability) {
05176          ast_log(LOG_NOTICE, "No compatible codecs, not accepting this offer!\n");
05177          /* Do NOT Change current setting */
05178          return -1;
05179       } else {
05180          if (option_debug > 2)
05181             ast_log(LOG_DEBUG, "Have T.38 but no audio codecs, accepting offer anyway\n");
05182          return 0;
05183       }
05184    }
05185 
05186    /* We are now ready to change the sip session and p->rtp and p->vrtp with the offered codecs, since
05187       they are acceptable */
05188    p->jointcapability = newjointcapability;          /* Our joint codec profile for this call */
05189    p->peercapability = newpeercapability;            /* The other sides capability in latest offer */
05190    p->jointnoncodeccapability = newnoncodeccapability;   /* DTMF capabilities */
05191 
05192    ast_rtp_pt_copy(p->rtp, newaudiortp);
05193    if (p->vrtp)
05194       ast_rtp_pt_copy(p->vrtp, newvideortp);
05195 
05196    if (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO) {
05197       ast_clear_flag(&p->flags[0], SIP_DTMF);
05198       if (newnoncodeccapability & AST_RTP_DTMF) {
05199          /* XXX Would it be reasonable to drop the DSP at this point? XXX */
05200          ast_set_flag(&p->flags[0], SIP_DTMF_RFC2833);
05201          /* Since RFC2833 is now negotiated we need to change some properties of the RTP stream */
05202          ast_rtp_setdtmf(p->rtp, 1);
05203          ast_rtp_setdtmfcompensate(p->rtp, ast_test_flag(&p->flags[1], SIP_PAGE2_RFC2833_COMPENSATE));
05204       } else {
05205          ast_set_flag(&p->flags[0], SIP_DTMF_INBAND);
05206       }
05207    }
05208 
05209    /* Setup audio port number */
05210    if (p->rtp && sin.sin_port) {
05211       ast_rtp_set_peer(p->rtp, &sin);
05212       if (debug)
05213          ast_verbose("Peer audio RTP is at port %s:%d\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
05214    }
05215 
05216    /* Setup video port number */
05217    if (p->vrtp && vsin.sin_port) {
05218       ast_rtp_set_peer(p->vrtp, &vsin);
05219       if (debug) 
05220          ast_verbose("Peer video RTP is at port %s:%d\n", ast_inet_ntoa(vsin.sin_addr), ntohs(vsin.sin_port));
05221    }
05222 
05223    /* Ok, we're going with this offer */
05224    if (option_debug > 1) {
05225       char buf[BUFSIZ];
05226       ast_log(LOG_DEBUG, "We're settling with these formats: %s\n", ast_getformatname_multiple(buf, BUFSIZ, p->jointcapability));
05227    }
05228 
05229    if (!p->owner)    /* There's no open channel owning us so we can return here. For a re-invite or so, we proceed */
05230       return 0;
05231 
05232    if (option_debug > 3)
05233       ast_log(LOG_DEBUG, "We have an owner, now see if we need to change this call\n");
05234 
05235    if (!(p->owner->nativeformats & p->jointcapability) && (p->jointcapability & AST_FORMAT_AUDIO_MASK)) {
05236       if (debug) {
05237          char s1[BUFSIZ], s2[BUFSIZ];
05238          ast_log(LOG_DEBUG, "Oooh, we need to change our audio formats since our peer supports only %s and not %s\n", 
05239             ast_getformatname_multiple(s1, BUFSIZ, p->jointcapability),
05240             ast_getformatname_multiple(s2, BUFSIZ, p->owner->nativeformats));
05241       }
05242       p->owner->nativeformats = ast_codec_choose(&p->prefs, p->jointcapability, 1) | (p->capability & vpeercapability);
05243       ast_set_read_format(p->owner, p->owner->readformat);
05244       ast_set_write_format(p->owner, p->owner->writeformat);
05245    }
05246    
05247    if (sin.sin_addr.s_addr && (!sendonly || sendonly == -1)) {
05248       ast_queue_control(p->owner, AST_CONTROL_UNHOLD);
05249       /* Activate a re-invite */
05250       ast_queue_frame(p->owner, &ast_null_frame);
05251    } else if (!sin.sin_addr.s_addr || sendonly) {
05252       ast_queue_control_data(p->owner, AST_CONTROL_HOLD, 
05253                    S_OR(p->mohsuggest, NULL),
05254                    !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
05255       if (sendonly)
05256          ast_rtp_stop(p->rtp);
05257       /* RTCP needs to go ahead, even if we're on hold!!! */
05258       /* Activate a re-invite */
05259       ast_queue_frame(p->owner, &ast_null_frame);
05260    }
05261 
05262    /* Manager Hold and Unhold events must be generated, if necessary */
05263    if (sin.sin_addr.s_addr && (!sendonly || sendonly == -1)) {
05264       if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) {
05265          append_history(p, "Unhold", "%s", req->data);
05266          if (global_callevents)
05267             manager_event(EVENT_FLAG_CALL, "Unhold",
05268                "Channel: %s\r\n"
05269                "Uniqueid: %s\r\n",
05270                p->owner->name, 
05271                p->owner->uniqueid);
05272          if (global_notifyhold)
05273             sip_peer_hold(p, 0);
05274       } 
05275       ast_clear_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD);  /* Clear both flags */
05276    } else if (!sin.sin_addr.s_addr || sendonly ) {
05277       /* No address for RTP, we're on hold */
05278       append_history(p, "Hold", "%s", req->data);
05279 
05280       if (global_callevents && !ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) {
05281          manager_event(EVENT_FLAG_CALL, "Hold",
05282             "Channel: %s\r\n"
05283             "Uniqueid: %s\r\n",
05284             p->owner->name, 
05285             p->owner->uniqueid);
05286       }
05287       if (sendonly == 1)   /* One directional hold (sendonly/recvonly) */
05288          ast_set_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD_ONEDIR);
05289       else if (sendonly == 2) /* Inactive stream */
05290          ast_set_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD_INACTIVE);
05291       if (global_notifyhold)
05292          sip_peer_hold(p, 1);
05293    }
05294    
05295    return 0;
05296 }

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

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

02408 {
02409    struct sip_peer *peer;
02410    struct ast_variable *var = NULL;
02411    struct ast_variable *tmp;
02412    char ipaddr[INET_ADDRSTRLEN];
02413 
02414    /* First check on peer name */
02415    if (newpeername) 
02416       var = ast_load_realtime("sippeers", "name", newpeername, NULL);
02417    else if (sin) {   /* Then check on IP address for dynamic peers */
02418       ast_copy_string(ipaddr, ast_inet_ntoa(sin->sin_addr), sizeof(ipaddr));
02419       var = ast_load_realtime("sippeers", "host", ipaddr, NULL);  /* First check for fixed IP hosts */
02420       if (!var)
02421          var = ast_load_realtime("sippeers", "ipaddr", ipaddr, NULL);   /* Then check for registred hosts */
02422    }
02423 
02424    if (!var)
02425       return NULL;
02426 
02427    for (tmp = var; tmp; tmp = tmp->next) {
02428       /* If this is type=user, then skip this object. */
02429       if (!strcasecmp(tmp->name, "type") &&
02430           !strcasecmp(tmp->value, "user")) {
02431          ast_variables_destroy(var);
02432          return NULL;
02433       } else if (!newpeername && !strcasecmp(tmp->name, "name")) {
02434          newpeername = tmp->value;
02435       }
02436    }
02437    
02438    if (!newpeername) {  /* Did not find peer in realtime */
02439       ast_log(LOG_WARNING, "Cannot Determine peer name ip=%s\n", ipaddr);
02440       ast_variables_destroy(var);
02441       return NULL;
02442    }
02443 
02444    /* Peer found in realtime, now build it in memory */
02445    peer = build_peer(newpeername, var, NULL, !ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS));
02446    if (!peer) {
02447       ast_variables_destroy(var);
02448       return NULL;
02449    }
02450 
02451    if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) {
02452       /* Cache peer */
02453       ast_copy_flags(&peer->flags[1],&global_flags[1], SIP_PAGE2_RTAUTOCLEAR|SIP_PAGE2_RTCACHEFRIENDS);
02454       if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTAUTOCLEAR)) {
02455          if (peer->expire > -1) {
02456             ast_sched_del(sched, peer->expire);
02457          }
02458          peer->expire = ast_sched_add(sched, (global_rtautoclear) * 1000, expire_register, (void *)peer);
02459       }
02460       ASTOBJ_CONTAINER_LINK(&peerl,peer);
02461    } else {
02462       ast_set_flag(&peer->flags[0], SIP_REALTIME);
02463    }
02464    ast_variables_destroy(var);
02465 
02466    return peer;
02467 }

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

02293 {
02294    char port[10];
02295    char ipaddr[INET_ADDRSTRLEN];
02296    char regseconds[20];
02297 
02298    char *sysname = ast_config_AST_SYSTEM_NAME;
02299    char *syslabel = NULL;
02300 
02301    time_t nowtime = time(NULL) + expirey;
02302    const char *fc = fullcontact ? "fullcontact" : NULL;
02303    
02304    snprintf(regseconds, sizeof(regseconds), "%d", (int)nowtime);  /* Expiration time */
02305    ast_copy_string(ipaddr, ast_inet_ntoa(sin->sin_addr), sizeof(ipaddr));
02306    snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port));
02307    
02308    if (ast_strlen_zero(sysname)) /* No system name, disable this */
02309       sysname = NULL;
02310    else if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTSAVE_SYSNAME))
02311       syslabel = "regserver";
02312 
02313    if (fc)
02314       ast_update_realtime("sippeers", "name", peername, "ipaddr", ipaddr,
02315          "port", port, "regseconds", regseconds,
02316          "username", username, fc, fullcontact, syslabel, sysname, NULL); /* note fc and syslabel _can_ be NULL */
02317    else
02318       ast_update_realtime("sippeers", "name", peername, "ipaddr", ipaddr,
02319          "port", port, "regseconds", regseconds,
02320          "username", username, syslabel, sysname, NULL); /* note syslabel _can_ be NULL */
02321 }

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

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

02518 {
02519    struct ast_variable *var;
02520    struct ast_variable *tmp;
02521    struct sip_user *user = NULL;
02522 
02523    var = ast_load_realtime("sipusers", "name", username, NULL);
02524 
02525    if (!var)
02526       return NULL;
02527 
02528    for (tmp = var; tmp; tmp = tmp->next) {
02529       if (!strcasecmp(tmp->name, "type") &&
02530          !strcasecmp(tmp->value, "peer")) {
02531          ast_variables_destroy(var);
02532          return NULL;
02533       }
02534    }
02535 
02536    user = build_user(username, var, !ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS));
02537    
02538    if (!user) {   /* No user found */
02539       ast_variables_destroy(var);
02540       return NULL;
02541    }
02542 
02543    if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) {
02544       ast_set_flag(&user->flags[1], SIP_PAGE2_RTCACHEFRIENDS);
02545       suserobjs++;
02546       ASTOBJ_CONTAINER_LINK(&userl,user);
02547    } else {
02548       /* Move counter from s to r... */
02549       suserobjs--;
02550       ruserobjs++;
02551       ast_set_flag(&user->flags[0], SIP_REALTIME);
02552    }
02553    ast_variables_destroy(var);
02554    return user;
02555 }

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 9327 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(), LOG_WARNING, sip_pvt::owner, sip_debug_test_pvt(), sip_scheddestroy(), and transmit_response().

Referenced by handle_request_message().

09328 {
09329    char buf[1024];
09330    struct ast_frame f;
09331    const char *content_type = get_header(req, "Content-Type");
09332 
09333    if (strcmp(content_type, "text/plain")) { /* No text/plain attachment */
09334       transmit_response(p, "415 Unsupported Media Type", req); /* Good enough, or? */
09335       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
09336       return;
09337    }
09338 
09339    if (get_msg_text(buf, sizeof(buf), req)) {
09340       ast_log(LOG_WARNING, "Unable to retrieve text from %s\n", p->callid);
09341       transmit_response(p, "202 Accepted", req);
09342       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
09343       return;
09344    }
09345 
09346    if (p->owner) {
09347       if (sip_debug_test_pvt(p))
09348          ast_verbose("Message received: '%s'\n", buf);
09349       memset(&f, 0, sizeof(f));
09350       f.frametype = AST_FRAME_TEXT;
09351       f.subclass = 0;
09352       f.offset = 0;
09353       f.data = buf;
09354       f.datalen = strlen(buf);
09355       ast_queue_frame(p->owner, &f);
09356       transmit_response(p, "202 Accepted", req); /* We respond 202 accepted, since we relay the message */
09357    } else { /* Message outside of a call, we do not support that */
09358       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);
09359       transmit_response(p, "405 Method Not Allowed", req); /* Good enough, or? */
09360    }
09361    sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
09362    return;
09363 }

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

Convert transfer status to string.

Definition at line 1604 of file chan_sip.c.

References referstatusstrings, and text.

Referenced by __sip_show_channels().

01605 {
01606    int i = (sizeof(referstatusstrings) / sizeof(referstatusstrings[0]));
01607    int x;
01608 
01609    for (x = 0; x < i; x++) {
01610       if (referstatusstrings[x].status ==  rstatus)
01611          return (char *) referstatusstrings[x].text;
01612    }
01613    return "";
01614 }

static void reg_source_db ( struct sip_peer peer  )  [static]

Get registration details from Asterisk DB.

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

07618 {
07619    char data[256];
07620    struct in_addr in;
07621    int expiry;
07622    int port;
07623    char *scan, *addr, *port_str, *expiry_str, *username, *contact;
07624 
07625    if (ast_test_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT)) 
07626       return;
07627    if (ast_db_get("SIP/Registry", peer->name, data, sizeof(data)))
07628       return;
07629 
07630    scan = data;
07631    addr = strsep(&scan, ":");
07632    port_str = strsep(&scan, ":");
07633    expiry_str = strsep(&scan, ":");
07634    username = strsep(&scan, ":");
07635    contact = scan;   /* Contact include sip: and has to be the last part of the database entry as long as we use : as a separator */
07636 
07637    if (!inet_aton(addr, &in))
07638       return;
07639 
07640    if (port_str)
07641       port = atoi(port_str);
07642    else
07643       return;
07644 
07645    if (expiry_str)
07646       expiry = atoi(expiry_str);
07647    else
07648       return;
07649 
07650    if (username)
07651       ast_copy_string(peer->username, username, sizeof(peer->username));
07652    if (contact)
07653       ast_copy_string(peer->fullcontact, contact, sizeof(peer->fullcontact));
07654 
07655    if (option_debug > 1)
07656       ast_log(LOG_DEBUG, "SIP Seeding peer from astdb: '%s' at %s@%s:%d for %d\n",
07657              peer->name, peer->username, ast_inet_ntoa(in), port, expiry);
07658 
07659    memset(&peer->addr, 0, sizeof(peer->addr));
07660    peer->addr.sin_family = AF_INET;
07661    peer->addr.sin_addr = in;
07662    peer->addr.sin_port = htons(port);
07663    if (sipsock < 0) {
07664       /* SIP isn't up yet, so schedule a poke only, pretty soon */
07665       if (peer->pokeexpire > -1)
07666          ast_sched_del(sched, peer->pokeexpire);
07667       peer->pokeexpire = ast_sched_add(sched, ast_random() % 5000 + 1, sip_poke_peer_s, peer);
07668    } else
07669       sip_poke_peer(peer);
07670    if (peer->expire > -1)
07671       ast_sched_del(sched, peer->expire);
07672    peer->expire = ast_sched_add(sched, (expiry + 10) * 1000, expire_register, peer);
07673    register_peer_exten(peer, TRUE);
07674 }

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

Automatically add peer extension to dial plan.

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

02325 {
02326    char multi[256];
02327    char *stringp, *ext, *context;
02328 
02329    /* XXX note that global_regcontext is both a global 'enable' flag and
02330     * the name of the global regexten context, if not specified
02331     * individually.
02332     */
02333    if (ast_strlen_zero(global_regcontext))
02334       return;
02335 
02336    ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi));
02337    stringp = multi;
02338    while ((ext = strsep(&stringp, "&"))) {
02339       if ((context = strchr(ext, '@'))) {
02340          *context++ = '\0';   /* split ext@context */
02341          if (!ast_context_find(context)) {
02342             ast_log(LOG_WARNING, "Context %s must exist in regcontext= in sip.conf!\n", context);
02343             continue;
02344          }
02345       } else {
02346          context = global_regcontext;
02347       }
02348       if (onoff)
02349          ast_add_extension(context, 1, ext, 1, NULL, NULL, "Noop",
02350              ast_strdup(peer->name), ast_free, "SIP");
02351       else
02352          ast_context_remove_extension(context, ext, 1, NULL);
02353    }
02354 }

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 8266 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_NOT_FOUND, 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_DEBUG, LOG_ERROR, LOG_NOTICE, LOG_WARNING, manager_event(), sip_peer::md5secret, name, option_debug, 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.

08268 {
08269    enum check_auth_result res = AUTH_NOT_FOUND;
08270    struct sip_peer *peer;
08271    char tmp[256];
08272    char *name, *c;
08273    char *t;
08274    char *domain;
08275 
08276    /* Terminate URI */
08277    t = uri;
08278    while(*t && (*t > 32) && (*t != ';'))
08279       t++;
08280    *t = '\0';
08281    
08282    ast_copy_string(tmp, get_header(req, "To"), sizeof(tmp));
08283    if (pedanticsipchecking)
08284       ast_uri_decode(tmp);
08285 
08286    c = get_in_brackets(tmp);
08287    c = strsep(&c, ";"); /* Ditch ;user=phone */
08288 
08289    if (!strncmp(c, "sip:", 4)) {
08290       name = c + 4;
08291    } else {
08292       name = c;
08293       ast_log(LOG_NOTICE, "Invalid to address: '%s' from %s (missing sip:) trying to use anyway...\n", c, ast_inet_ntoa(sin->sin_addr));
08294    }
08295 
08296    /* Strip off the domain name */
08297    if ((c = strchr(name, '@'))) {
08298       *c++ = '\0';
08299       domain = c;
08300       if ((c = strchr(domain, ':')))   /* Remove :port */
08301          *c = '\0';
08302       if (!AST_LIST_EMPTY(&domain_list)) {
08303          if (!check_sip_domain(domain, NULL, 0)) {
08304             transmit_response(p, "404 Not found (unknown domain)", &p->initreq);
08305             return AUTH_UNKNOWN_DOMAIN;
08306          }
08307       }
08308    }
08309 
08310    ast_string_field_set(p, exten, name);
08311    build_contact(p);
08312    peer = find_peer(name, NULL, 1);
08313    if (!(peer && ast_apply_ha(peer->ha, sin))) {
08314       /* Peer fails ACL check */
08315       if (peer)
08316          ASTOBJ_UNREF(peer, sip_destroy_peer);
08317       peer = NULL;
08318    }
08319    if (peer) {
08320       /* Set Frame packetization */
08321       if (p->rtp) {
08322          ast_rtp_codec_setpref(p->rtp, &peer->prefs);
08323          p->autoframing = peer->autoframing;
08324       }
08325       if (!ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)) {
08326          ast_log(LOG_ERROR, "Peer '%s' is trying to register, but not configured as host=dynamic\n", peer->name);
08327       } else {
08328          ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_NAT);
08329          transmit_response(p, "100 Trying", req);
08330          if (!(res = check_auth(p, req, peer->name, peer->secret, peer->md5secret, SIP_REGISTER, uri, XMIT_UNRELIABLE, ast_test_flag(req, SIP_PKT_IGNORE)))) {
08331             sip_cancel_destroy(p);
08332 
08333             /* We have a succesful registration attemp with proper authentication,
08334                now, update the peer */
08335             switch (parse_register_contact(p, peer, req)) {
08336             case PARSE_REGISTER_FAILED:
08337                ast_log(LOG_WARNING, "Failed to parse contact info\n");
08338                transmit_response_with_date(p, "400 Bad Request", req);
08339                peer->lastmsgssent = -1;
08340                res = 0;
08341                break;
08342             case PARSE_REGISTER_QUERY:
08343                transmit_response_with_date(p, "200 OK", req);
08344                peer->lastmsgssent = -1;
08345                res = 0;
08346                break;
08347             case PARSE_REGISTER_UPDATE:
08348                update_peer(peer, p->expiry);
08349                /* Say OK and ask subsystem to retransmit msg counter */
08350                transmit_response_with_date(p, "200 OK", req);
08351                if (!ast_test_flag((&peer->flags[1]), SIP_PAGE2_SUBSCRIBEMWIONLY))
08352                   peer->lastmsgssent = -1;
08353                res = 0;
08354                break;
08355             }
08356          } 
08357       }
08358    }
08359    if (!peer && autocreatepeer) {
08360       /* Create peer if we have autocreate mode enabled */
08361       peer = temp_peer(name);
08362       if (peer) {
08363          ASTOBJ_CONTAINER_LINK(&peerl, peer);
08364          sip_cancel_destroy(p);
08365          switch (parse_register_contact(p, peer, req)) {
08366          case PARSE_REGISTER_FAILED:
08367             ast_log(LOG_WARNING, "Failed to parse contact info\n");
08368             transmit_response_with_date(p, "400 Bad Request", req);
08369             peer->lastmsgssent = -1;
08370             res = 0;
08371             break;
08372          case PARSE_REGISTER_QUERY:
08373             transmit_response_with_date(p, "200 OK", req);
08374             peer->lastmsgssent = -1;
08375             res = 0;
08376             break;
08377          case PARSE_REGISTER_UPDATE:
08378             /* Say OK and ask subsystem to retransmit msg counter */
08379             transmit_response_with_date(p, "200 OK", req);
08380             manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Registered\r\n", peer->name);
08381             peer->lastmsgssent = -1;
08382             res = 0;
08383             break;
08384          }
08385       }
08386    }
08387    if (!res) {
08388       ast_device_state_changed("SIP/%s", peer->name);
08389    }
08390    if (res < 0) {
08391       switch (res) {
08392       case AUTH_SECRET_FAILED:
08393          /* Wrong password in authentication. Go away, don't try again until you fixed it */
08394          transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq);
08395          break;
08396       case AUTH_USERNAME_MISMATCH:
08397          /* Username and digest username does not match. 
08398             Asterisk uses the From: username for authentication. We need the
08399             users to use the same authentication user name until we support
08400             proper authentication by digest auth name */
08401          transmit_response(p, "403 Authentication user name does not match account name", &p->initreq);
08402          break;
08403       case AUTH_NOT_FOUND:
08404          if (global_alwaysauthreject) {
08405             transmit_fake_auth_response(p, &p->initreq, 1);
08406          } else {
08407             /* URI not found */
08408             transmit_response(p, "404 Not found", &p->initreq);
08409          }
08410          break;
08411       default:
08412          break;
08413       }
08414       if (option_debug > 1) {
08415          const char *reason = "";
08416 
08417          switch (res) {
08418          case AUTH_SECRET_FAILED:
08419             reason = "Bad password";
08420             break;
08421          case AUTH_USERNAME_MISMATCH:
08422             reason = "Bad digest user";
08423             break;
08424          case AUTH_NOT_FOUND:
08425             reason = "Peer not found";
08426             break;
08427          default:
08428             break;
08429          }
08430          ast_log(LOG_DEBUG, "SIP REGISTER attempt failed for %s : %s\n",
08431             peer->name, reason);
08432       }
08433    }
08434    if (peer)
08435       ASTOBJ_UNREF(peer, sip_destroy_peer);
08436 
08437    return res;
08438 }

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

Convert registration state status to string.

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

07119 {
07120    switch(regstate) {
07121    case REG_STATE_FAILED:
07122       return "Failed";
07123    case REG_STATE_UNREGISTERED:
07124       return "Unregistered";
07125    case REG_STATE_REGSENT:
07126       return "Request Sent";
07127    case REG_STATE_AUTHSENT:
07128       return "Auth. Sent";
07129    case REG_STATE_REGISTERED:
07130       return "Registered";
07131    case REG_STATE_REJECTED:
07132       return "Rejected";
07133    case REG_STATE_TIMEOUT:
07134       return "Timeout";
07135    case REG_STATE_NOAUTH:
07136       return "No Authentication";
07137    default:
07138       return "Unknown";
07139    }
07140 }

static int reload ( void   )  [static]

Part of Asterisk module interface.

Definition at line 17286 of file chan_sip.c.

References sip_reload().

17287 {
17288    return sip_reload(0, 0, NULL);
17289 }

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 16197 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_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.

16198 {
16199    struct ast_config *cfg, *ucfg;
16200    struct ast_variable *v;
16201    struct sip_peer *peer;
16202    struct sip_user *user;
16203    struct ast_hostent ahp;
16204    char *cat, *stringp, *context, *oldregcontext;
16205    char newcontexts[AST_MAX_CONTEXT], oldcontexts[AST_MAX_CONTEXT];
16206    struct hostent *hp;
16207    int format;
16208    struct ast_flags dummy[2];
16209    int auto_sip_domains = FALSE;
16210    struct sockaddr_in old_bindaddr = bindaddr;
16211    int registry_count = 0, peer_count = 0, user_count = 0;
16212    unsigned int temp_tos = 0;
16213    struct ast_flags debugflag = {0};
16214 
16215    cfg = ast_config_load(config);
16216 
16217    /* We *must* have a config file otherwise stop immediately */
16218    if (!cfg) {
16219       ast_log(LOG_NOTICE, "Unable to load config %s\n", config);
16220       return -1;
16221    }
16222    
16223    /* Initialize copy of current global_regcontext for later use in removing stale contexts */
16224    ast_copy_string(oldcontexts, global_regcontext, sizeof(oldcontexts));
16225    oldregcontext = oldcontexts;
16226 
16227    /* Clear all flags before setting default values */
16228    /* Preserve debugging settings for console */
16229    ast_copy_flags(&debugflag, &global_flags[1], SIP_PAGE2_DEBUG_CONSOLE);
16230    ast_clear_flag(&global_flags[0], AST_FLAGS_ALL);
16231    ast_clear_flag(&global_flags[1], AST_FLAGS_ALL);
16232    ast_copy_flags(&global_flags[1], &debugflag, SIP_PAGE2_DEBUG_CONSOLE);
16233 
16234    /* Reset IP addresses  */
16235    memset(&bindaddr, 0, sizeof(bindaddr));
16236    memset(&localaddr, 0, sizeof(localaddr));
16237    memset(&externip, 0, sizeof(externip));
16238    memset(&default_prefs, 0 , sizeof(default_prefs));
16239    outboundproxyip.sin_port = htons(STANDARD_SIP_PORT);
16240    outboundproxyip.sin_family = AF_INET;  /* Type of address: IPv4 */
16241    ourport = STANDARD_SIP_PORT;
16242    srvlookup = DEFAULT_SRVLOOKUP;
16243    global_tos_sip = DEFAULT_TOS_SIP;
16244    global_tos_audio = DEFAULT_TOS_AUDIO;
16245    global_tos_video = DEFAULT_TOS_VIDEO;
16246    externhost[0] = '\0';         /* External host name (for behind NAT DynDNS support) */
16247    externexpire = 0;       /* Expiration for DNS re-issuing */
16248    externrefresh = 10;
16249    memset(&outboundproxyip, 0, sizeof(outboundproxyip));
16250 
16251    /* Reset channel settings to default before re-configuring */
16252    allow_external_domains = DEFAULT_ALLOW_EXT_DOM;          /* Allow external invites */
16253    global_regcontext[0] = '\0';
16254    expiry = DEFAULT_EXPIRY;
16255    global_notifyringing = DEFAULT_NOTIFYRINGING;
16256    global_limitonpeers = FALSE;
16257    global_directrtpsetup = FALSE;      /* Experimental feature, disabled by default */
16258    global_notifyhold = FALSE;
16259    global_alwaysauthreject = 0;
16260    global_allowsubscribe = FALSE;
16261    ast_copy_string(global_useragent, DEFAULT_USERAGENT, sizeof(global_useragent));
16262    ast_copy_string(default_notifymime, DEFAULT_NOTIFYMIME, sizeof(default_notifymime));
16263    if (ast_strlen_zero(ast_config_AST_SYSTEM_NAME))
16264       ast_copy_string(global_realm, DEFAULT_REALM, sizeof(global_realm));
16265    else
16266       ast_copy_string(global_realm, ast_config_AST_SYSTEM_NAME, sizeof(global_realm));
16267    ast_copy_string(default_callerid, DEFAULT_CALLERID, sizeof(default_callerid));
16268    compactheaders = DEFAULT_COMPACTHEADERS;
16269    global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT;
16270    global_regattempts_max = 0;
16271    pedanticsipchecking = DEFAULT_PEDANTIC;
16272    global_mwitime = DEFAULT_MWITIME;
16273    autocreatepeer = DEFAULT_AUTOCREATEPEER;
16274    global_autoframing = 0;
16275    global_allowguest = DEFAULT_ALLOWGUEST;
16276    global_rtptimeout = 0;
16277    global_rtpholdtimeout = 0;
16278    global_rtpkeepalive = 0;
16279    global_allowtransfer = TRANSFER_OPENFORALL;  /* Merrily accept all transfers by default */
16280    global_rtautoclear = 120;
16281    ast_set_flag(&global_flags[1], SIP_PAGE2_ALLOWSUBSCRIBE);   /* Default for peers, users: TRUE */
16282    ast_set_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP);     /* Default for peers, users: TRUE */
16283    ast_set_flag(&global_flags[1], SIP_PAGE2_RTUPDATE);
16284 
16285    /* Initialize some reasonable defaults at SIP reload (used both for channel and as default for peers and users */
16286    ast_copy_string(default_context, DEFAULT_CONTEXT, sizeof(default_context));
16287    default_subscribecontext[0] = '\0';
16288    default_language[0] = '\0';
16289    default_fromdomain[0] = '\0';
16290    default_qualify = DEFAULT_QUALIFY;
16291    default_maxcallbitrate = DEFAULT_MAX_CALL_BITRATE;
16292    ast_copy_string(default_mohinterpret, DEFAULT_MOHINTERPRET, sizeof(default_mohinterpret));
16293    ast_copy_string(default_mohsuggest, DEFAULT_MOHSUGGEST, sizeof(default_mohsuggest));
16294    ast_copy_string(default_vmexten, DEFAULT_VMEXTEN, sizeof(default_vmexten));
16295    ast_set_flag(&global_flags[0], SIP_DTMF_RFC2833);        /*!< Default DTMF setting: RFC2833 */
16296    ast_set_flag(&global_flags[0], SIP_NAT_RFC3581);         /*!< NAT support if requested by device with rport */
16297    ast_set_flag(&global_flags[0], SIP_CAN_REINVITE);        /*!< Allow re-invites */
16298 
16299    /* Debugging settings, always default to off */
16300    dumphistory = FALSE;
16301    recordhistory = FALSE;
16302    ast_clear_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONFIG);
16303 
16304    /* Misc settings for the channel */
16305    global_relaxdtmf = FALSE;
16306    global_callevents = FALSE;
16307    global_t1min = DEFAULT_T1MIN;    
16308 
16309    global_matchexterniplocally = FALSE;
16310 
16311    /* Copy the default jb config over global_jbconf */
16312    memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf));
16313 
16314    ast_clear_flag(&global_flags[1], SIP_PAGE2_VIDEOSUPPORT);
16315 
16316    /* Read the [general] config section of sip.conf (or from realtime config) */
16317    for (v = ast_variable_browse(cfg, "general"); v; v = v->next) {
16318       if (handle_common_options(&global_flags[0], &dummy[0], v))
16319          continue;
16320       /* handle jb conf */
16321       if (!ast_jb_read_conf(&global_jbconf, v->name, v->value))
16322          continue;
16323 
16324       /* Create the interface list */
16325       if (!strcasecmp(v->name, "context")) {
16326          ast_copy_string(default_context, v->value, sizeof(default_context));
16327       } else if (!strcasecmp(v->name, "allowguest")) {
16328          global_allowguest = ast_true(v->value) ? 1 : 0;
16329       } else if (!strcasecmp(v->name, "realm")) {
16330          ast_copy_string(global_realm, v->value, sizeof(global_realm));
16331       } else if (!strcasecmp(v->name, "useragent")) {
16332          ast_copy_string(global_useragent, v->value, sizeof(global_useragent));
16333          if (option_debug)
16334             ast_log(LOG_DEBUG, "Setting SIP channel User-Agent Name to %s\n", global_useragent);
16335       } else if (!strcasecmp(v->name, "allowtransfer")) {
16336          global_allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED;
16337       } else if (!strcasecmp(v->name, "rtcachefriends")) {
16338          ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_RTCACHEFRIENDS);   
16339       } else if (!strcasecmp(v->name, "rtsavesysname")) {
16340          ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_RTSAVE_SYSNAME);   
16341       } else if (!strcasecmp(v->name, "rtupdate")) {
16342          ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_RTUPDATE);   
16343       } else if (!strcasecmp(v->name, "ignoreregexpire")) {
16344          ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_IGNOREREGEXPIRE);  
16345       } else if (!strcasecmp(v->name, "t1min")) {
16346          global_t1min = atoi(v->value);
16347       } else if (!strcasecmp(v->name, "rtautoclear")) {
16348          int i = atoi(v->value);
16349          if (i > 0)
16350             global_rtautoclear = i;
16351          else
16352             i = 0;
16353          ast_set2_flag(&global_flags[1], i || ast_true(v->value), SIP_PAGE2_RTAUTOCLEAR);
16354       } else if (!strcasecmp(v->name, "usereqphone")) {
16355          ast_set2_flag(&global_flags[0], ast_true(v->value), SIP_USEREQPHONE);   
16356       } else if (!strcasecmp(v->name, "relaxdtmf")) {
16357          global_relaxdtmf = ast_true(v->value);
16358       } else if (!strcasecmp(v->name, "checkmwi")) {
16359          if ((sscanf(v->value, "%d", &global_mwitime) != 1) || (global_mwitime < 0)) {
16360             ast_log(LOG_WARNING, "'%s' is not a valid MWI time setting at line %d.  Using default (10).\n", v->value, v->lineno);
16361             global_mwitime = DEFAULT_MWITIME;
16362          }
16363       } else if (!strcasecmp(v->name, "vmexten")) {
16364          ast_copy_string(default_vmexten, v->value, sizeof(default_vmexten));
16365       } else if (!strcasecmp(v->name, "rtptimeout")) {
16366          if ((sscanf(v->value, "%d", &global_rtptimeout) != 1) || (global_rtptimeout < 0)) {
16367             ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d.  Using default.\n", v->value, v->lineno);
16368             global_rtptimeout = 0;
16369          }
16370       } else if (!strcasecmp(v->name, "rtpholdtimeout")) {
16371          if ((sscanf(v->value, "%d", &global_rtpholdtimeout) != 1) || (global_rtpholdtimeout < 0)) {
16372             ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d.  Using default.\n", v->value, v->lineno);
16373             global_rtpholdtimeout = 0;
16374          }
16375       } else if (!strcasecmp(v->name, "rtpkeepalive")) {
16376          if ((sscanf(v->value, "%d", &global_rtpkeepalive) != 1) || (global_rtpkeepalive < 0)) {
16377             ast_log(LOG_WARNING, "'%s' is not a valid RTP keepalive time at line %d.  Using default.\n", v->value, v->lineno);
16378             global_rtpkeepalive = 0;
16379          }
16380       } else if (!strcasecmp(v->name, "compactheaders")) {
16381          compactheaders = ast_true(v->value);
16382       } else if (!strcasecmp(v->name, "notifymimetype")) {
16383          ast_copy_string(default_notifymime, v->value, sizeof(default_notifymime));
16384       } else if (!strncasecmp(v->name, "limitonpeer", 11)) {
16385          global_limitonpeers = ast_true(v->value);
16386       } else if (!strcasecmp(v->name, "directrtpsetup")) {
16387          global_directrtpsetup = ast_true(v->value);
16388       } else if (!strcasecmp(v->name, "notifyringing")) {
16389          global_notifyringing = ast_true(v->value);
16390       } else if (!strcasecmp(v->name, "notifyhold")) {
16391          global_notifyhold = ast_true(v->value);
16392       } else if (!strcasecmp(v->name, "alwaysauthreject")) {
16393          global_alwaysauthreject = ast_true(v->value);
16394       } else if (!strcasecmp(v->name, "mohinterpret") 
16395          || !strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) {
16396          ast_copy_string(default_mohinterpret, v->value, sizeof(default_mohinterpret));
16397       } else if (!strcasecmp(v->name, "mohsuggest")) {
16398          ast_copy_string(default_mohsuggest, v->value, sizeof(default_mohsuggest));
16399       } else if (!strcasecmp(v->name, "language")) {
16400          ast_copy_string(default_language, v->value, sizeof(default_language));
16401       } else if (!strcasecmp(v->name, "regcontext")) {
16402          ast_copy_string(newcontexts, v->value, sizeof(newcontexts));
16403          stringp = newcontexts;
16404          /* Let's remove any contexts that are no longer defined in regcontext */
16405          cleanup_stale_contexts(stringp, oldregcontext);
16406          /* Create contexts if they don't exist already */
16407          while ((context = strsep(&stringp, "&"))) {
16408             if (!ast_context_find(context))
16409                ast_context_create(NULL, context,"SIP");
16410          }
16411          ast_copy_string(global_regcontext, v->value, sizeof(global_regcontext));
16412       } else if (!strcasecmp(v->name, "callerid")) {
16413          ast_copy_string(default_callerid, v->value, sizeof(default_callerid));
16414       } else if (!strcasecmp(v->name, "fromdomain")) {
16415          ast_copy_string(default_fromdomain, v->value, sizeof(default_fromdomain));
16416       } else if (!strcasecmp(v->name, "outboundproxy")) {
16417          if (ast_get_ip_or_srv(&outboundproxyip, v->value, srvlookup ? "_sip._udp" : NULL) < 0)
16418             ast_log(LOG_WARNING, "Unable to locate host '%s'\n", v->value);
16419       } else if (!strcasecmp(v->name, "outboundproxyport")) {
16420          /* Port needs to be after IP */
16421          sscanf(v->value, "%d", &format);
16422          outboundproxyip.sin_port = htons(format);
16423       } else if (!strcasecmp(v->name, "autocreatepeer")) {
16424          autocreatepeer = ast_true(v->value);
16425       } else if (!strcasecmp(v->name, "srvlookup")) {
16426          srvlookup = ast_true(v->value);
16427       } else if (!strcasecmp(v->name, "pedantic")) {
16428          pedanticsipchecking = ast_true(v->value);
16429       } else if (!strcasecmp(v->name, "maxexpirey") || !strcasecmp(v->name, "maxexpiry")) {
16430          max_expiry = atoi(v->value);
16431          if (max_expiry < 1)
16432             max_expiry = DEFAULT_MAX_EXPIRY;
16433       } else if (!strcasecmp(v->name, "minexpirey") || !strcasecmp(v->name, "minexpiry")) {
16434          min_expiry = atoi(v->value);
16435          if (min_expiry < 1)
16436             min_expiry = DEFAULT_MIN_EXPIRY;
16437       } else if (!strcasecmp(v->name, "defaultexpiry") || !strcasecmp(v->name, "defaultexpirey")) {
16438          default_expiry = atoi(v->value);
16439          if (default_expiry < 1)
16440             default_expiry = DEFAULT_DEFAULT_EXPIRY;
16441       } else if (!strcasecmp(v->name, "sipdebug")) {  /* XXX maybe ast_set2_flags ? */
16442          if (ast_true(v->value))
16443             ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONFIG);
16444       } else if (!strcasecmp(v->name, "dumphistory")) {
16445          dumphistory = ast_true(v->value);
16446       } else if (!strcasecmp(v->name, "recordhistory")) {
16447          recordhistory = ast_true(v->value);
16448       } else if (!strcasecmp(v->name, "registertimeout")) {
16449          global_reg_timeout = atoi(v->value);
16450          if (global_reg_timeout < 1)
16451             global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT;
16452       } else if (!strcasecmp(v->name, "registerattempts")) {
16453          global_regattempts_max = atoi(v->value);
16454       } else if (!strcasecmp(v->name, "bindaddr")) {
16455          if (!(hp = ast_gethostbyname(v->value, &ahp))) {
16456             ast_log(LOG_WARNING, "Invalid address: %s\n", v->value);
16457          } else {
16458             memcpy(&bindaddr.sin_addr, hp->h_addr, sizeof(bindaddr.sin_addr));
16459          }
16460       } else if (!strcasecmp(v->name, "localnet")) {
16461          struct ast_ha *na;
16462          if (!(na = ast_append_ha("d", v->value, localaddr)))
16463             ast_log(LOG_WARNING, "Invalid localnet value: %s\n", v->value);
16464          else
16465             localaddr = na;
16466       } else if (!strcasecmp(v->name, "localmask")) {
16467          ast_log(LOG_WARNING, "Use of localmask is no long supported -- use localnet with mask syntax\n");
16468       } else if (!strcasecmp(v->name, "externip")) {
16469          if (!(hp = ast_gethostbyname(v->value, &ahp))) 
16470             ast_log(LOG_WARNING, "Invalid address for externip keyword: %s\n", v->value);
16471          else
16472             memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr));
16473          externexpire = 0;
16474       } else if (!strcasecmp(v->name, "externhost")) {
16475          ast_copy_string(externhost, v->value, sizeof(externhost));
16476          if (!(hp = ast_gethostbyname(externhost, &ahp))) 
16477             ast_log(LOG_WARNING, "Invalid address for externhost keyword: %s\n", externhost);
16478          else
16479             memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr));
16480          externexpire = time(NULL);
16481       } else if (!strcasecmp(v->name, "externrefresh")) {
16482          if (sscanf(v->value, "%d", &externrefresh) != 1) {
16483             ast_log(LOG_WARNING, "Invalid externrefresh value '%s', must be an integer >0 at line %d\n", v->value, v->lineno);
16484             externrefresh = 10;
16485          }
16486       } else if (!strcasecmp(v->name, "allow")) {
16487          ast_parse_allow_disallow(&default_prefs, &global_capability, v->value, 1);
16488       } else if (!strcasecmp(v->name, "disallow")) {
16489          ast_parse_allow_disallow(&default_prefs, &global_capability, v->value, 0);
16490       } else if (!strcasecmp(v->name, "autoframing")) {
16491          global_autoframing = ast_true(v->value);
16492       } else if (!strcasecmp(v->name, "allowexternaldomains")) {
16493          allow_external_domains = ast_true(v->value);
16494       } else if (!strcasecmp(v->name, "autodomain")) {
16495          auto_sip_domains = ast_true(v->value);
16496       } else if (!strcasecmp(v->name, "domain")) {
16497          char *domain = ast_strdupa(v->value);
16498          char *context = strchr(domain, ',');
16499 
16500          if (context)
16501             *context++ = '\0';
16502 
16503          if (option_debug && ast_strlen_zero(context))
16504             ast_log(LOG_DEBUG, "No context specified at line %d for domain '%s'\n", v->lineno, domain);
16505          if (ast_strlen_zero(domain))
16506             ast_log(LOG_WARNING, "Empty domain specified at line %d\n", v->lineno);
16507          else
16508             add_sip_domain(ast_strip(domain), SIP_DOMAIN_CONFIG, context ? ast_strip(context) : "");
16509       } else if (!strcasecmp(v->name, "register")) {
16510          if (sip_register(v->value, v->lineno) == 0)
16511             registry_count++;
16512       } else if (!strcasecmp(v->name, "tos")) {
16513          if (!ast_str2tos(v->value, &temp_tos)) {
16514             global_tos_sip = temp_tos;
16515             global_tos_audio = temp_tos;
16516             global_tos_video = temp_tos;
16517             ast_log(LOG_WARNING, "tos value at line %d is deprecated.  See doc/ip-tos.txt for more information.\n", v->lineno);
16518          } else
16519             ast_log(LOG_WARNING, "Invalid tos value at line %d, See doc/ip-tos.txt for more information.\n", v->lineno);
16520       } else if (!strcasecmp(v->name, "tos_sip")) {
16521          if (ast_str2tos(v->value, &global_tos_sip))
16522             ast_log(LOG_WARNING, "Invalid tos_sip value at line %d, recommended value is 'cs3'. See doc/ip-tos.txt.\n", v->lineno);
16523       } else if (!strcasecmp(v->name, "tos_audio")) {
16524          if (ast_str2tos(v->value, &global_tos_audio))
16525             ast_log(LOG_WARNING, "Invalid tos_audio value at line %d, recommended value is 'ef'. See doc/ip-tos.txt.\n", v->lineno);
16526       } else if (!strcasecmp(v->name, "tos_video")) {
16527          if (ast_str2tos(v->value, &global_tos_video))
16528             ast_log(LOG_WARNING, "Invalid tos_video value at line %d, recommended value is 'af41'. See doc/ip-tos.txt.\n", v->lineno);
16529       } else if (!strcasecmp(v->name, "bindport")) {
16530          if (sscanf(v->value, "%d", &ourport) == 1) {
16531             bindaddr.sin_port = htons(ourport);
16532          } else {
16533             ast_log(LOG_WARNING, "Invalid port number '%s' at line %d of %s\n", v->value, v->lineno, config);
16534          }
16535       } else if (!strcasecmp(v->name, "qualify")) {
16536          if (!strcasecmp(v->value, "no")) {
16537             default_qualify = 0;
16538          } else if (!strcasecmp(v->value, "yes")) {
16539             default_qualify = DEFAULT_MAXMS;
16540          } else if (sscanf(v->value, "%d", &default_qualify) != 1) {
16541             ast_log(LOG_WARNING, "Qualification default should be 'yes', 'no', or a number of milliseconds at line %d of sip.conf\n", v->lineno);
16542             default_qualify = 0;
16543          }
16544       } else if (!strcasecmp(v->name, "callevents")) {
16545          global_callevents = ast_true(v->value);
16546       } else if (!strcasecmp(v->name, "maxcallbitrate")) {
16547          default_maxcallbitrate = atoi(v->value);
16548          if (default_maxcallbitrate < 0)
16549             default_maxcallbitrate = DEFAULT_MAX_CALL_BITRATE;
16550       } else if (!strcasecmp(v->name, "matchexterniplocally")) {
16551          global_matchexterniplocally = ast_true(v->value);
16552       }
16553    }
16554 
16555    if (!allow_external_domains && AST_LIST_EMPTY(&domain_list)) {
16556       ast_log(LOG_WARNING, "To disallow external domains, you need to configure local SIP domains.\n");
16557       allow_external_domains = 1;
16558    }
16559    
16560    /* Build list of authentication to various SIP realms, i.e. service providers */
16561    for (v = ast_variable_browse(cfg, "authentication"); v ; v = v->next) {
16562       /* Format for authentication is auth = username:password@realm */
16563       if (!strcasecmp(v->name, "auth"))
16564          authl = add_realm_authentication(authl, v->value, v->lineno);
16565    }
16566    
16567    ucfg = ast_config_load("users.conf");
16568    if (ucfg) {
16569       struct ast_variable *gen;
16570       int genhassip, genregistersip;
16571       const char *hassip, *registersip;
16572       
16573       genhassip = ast_true(ast_variable_retrieve(ucfg, "general", "hassip"));
16574       genregistersip = ast_true(ast_variable_retrieve(ucfg, "general", "registersip"));
16575       gen = ast_variable_browse(ucfg, "general");
16576       cat = ast_category_browse(ucfg, NULL);
16577       while (cat) {
16578          if (strcasecmp(cat, "general")) {
16579             hassip = ast_variable_retrieve(ucfg, cat, "hassip");
16580             registersip = ast_variable_retrieve(ucfg, cat, "registersip");
16581             if (ast_true(hassip) || (!hassip && genhassip)) {
16582                peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0);
16583                if (peer) {
16584                   ASTOBJ_CONTAINER_LINK(&peerl,peer);
16585                   ASTOBJ_UNREF(peer, sip_destroy_peer);
16586                   peer_count++;
16587                }
16588             }
16589             if (ast_true(registersip) || (!registersip && genregistersip)) {
16590                char tmp[256];
16591                const char *host = ast_variable_retrieve(ucfg, cat, "host");
16592                const char *username = ast_variable_retrieve(ucfg, cat, "username");
16593                const char *secret = ast_variable_retrieve(ucfg, cat, "secret");
16594                const char *contact = ast_variable_retrieve(ucfg, cat, "contact");
16595                if (!host)
16596                   host = ast_variable_retrieve(ucfg, "general", "host");
16597                if (!username)
16598                   username = ast_variable_retrieve(ucfg, "general", "username");
16599                if (!secret)
16600                   secret = ast_variable_retrieve(ucfg, "general", "secret");
16601                if (!contact)
16602                   contact = "s";
16603                if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) {
16604                   if (!ast_strlen_zero(secret))
16605                      snprintf(tmp, sizeof(tmp), "%s:%s@%s/%s", username, secret, host, contact);
16606                   else
16607                      snprintf(tmp, sizeof(tmp), "%s@%s/%s", username, host, contact);
16608                   if (sip_register(tmp, 0) == 0)
16609                      registry_count++;
16610                }
16611             }
16612          }
16613          cat = ast_category_browse(ucfg, cat);
16614       }
16615       ast_config_destroy(ucfg);
16616    }
16617    
16618 
16619    /* Load peers, users and friends */
16620    cat = NULL;
16621    while ( (cat = ast_category_browse(cfg, cat)) ) {
16622       const char *utype;
16623       if (!strcasecmp(cat, "general") || !strcasecmp(cat, "authentication"))
16624          continue;
16625       utype = ast_variable_retrieve(cfg, cat, "type");
16626       if (!utype) {
16627          ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat);
16628          continue;
16629       } else {
16630          int is_user = 0, is_peer = 0;
16631          if (!strcasecmp(utype, "user"))
16632             is_user = 1;
16633          else if (!strcasecmp(utype, "friend"))
16634             is_user = is_peer = 1;
16635          else if (!strcasecmp(utype, "peer"))
16636             is_peer = 1;
16637          else {
16638             ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, "sip.conf");
16639             continue;
16640          }
16641          if (is_user) {
16642             user = build_user(cat, ast_variable_browse(cfg, cat), 0);
16643             if (user) {
16644                ASTOBJ_CONTAINER_LINK(&userl,user);
16645                ASTOBJ_UNREF(user, sip_destroy_user);
16646                user_count++;
16647             }
16648          }
16649          if (is_peer) {
16650             peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0);
16651             if (peer) {
16652                ASTOBJ_CONTAINER_LINK(&peerl,peer);
16653                ASTOBJ_UNREF(peer, sip_destroy_peer);
16654                peer_count++;
16655             }
16656          }
16657       }
16658    }
16659    if (ast_find_ourip(&__ourip, bindaddr)) {
16660       ast_log(LOG_WARNING, "Unable to get own IP address, SIP disabled\n");
16661       return 0;
16662    }
16663    if (!ntohs(bindaddr.sin_port))
16664       bindaddr.sin_port = ntohs(STANDARD_SIP_PORT);
16665    bindaddr.sin_family = AF_INET;
16666    ast_mutex_lock(&netlock);
16667    if ((sipsock > -1) && (memcmp(&old_bindaddr, &bindaddr, sizeof(struct sockaddr_in)))) {
16668       close(sipsock);
16669       sipsock = -1;
16670    }
16671    if (sipsock < 0) {
16672       sipsock = socket(AF_INET, SOCK_DGRAM, 0);
16673       if (sipsock < 0) {
16674          ast_log(LOG_WARNING, "Unable to create SIP socket: %s\n", strerror(errno));
16675          return -1;
16676       } else {
16677          /* Allow SIP clients on the same host to access us: */
16678          const int reuseFlag = 1;
16679 
16680          setsockopt(sipsock, SOL_SOCKET, SO_REUSEADDR,
16681                (const char*)&reuseFlag,
16682                sizeof reuseFlag);
16683 
16684          ast_enable_packet_fragmentation(sipsock);
16685 
16686          if (bind(sipsock, (struct sockaddr *)&bindaddr, sizeof(bindaddr)) < 0) {
16687             ast_log(LOG_WARNING, "Failed to bind to %s:%d: %s\n",
16688             ast_inet_ntoa(bindaddr.sin_addr), ntohs(bindaddr.sin_port),
16689             strerror(errno));
16690             close(sipsock);
16691             sipsock = -1;
16692          } else {
16693             if (option_verbose > 1) { 
16694                ast_verbose(VERBOSE_PREFIX_2 "SIP Listening on %s:%d\n", 
16695                ast_inet_ntoa(bindaddr.sin_addr), ntohs(bindaddr.sin_port));
16696                ast_verbose(VERBOSE_PREFIX_2 "Using SIP TOS: %s\n", ast_tos2str(global_tos_sip));
16697             }
16698             if (setsockopt(sipsock, IPPROTO_IP, IP_TOS, &global_tos_sip, sizeof(global_tos_sip))) 
16699                ast_log(LOG_WARNING, "Unable to set SIP TOS to %s\n", ast_tos2str(global_tos_sip));
16700          }
16701       }
16702    }
16703    ast_mutex_unlock(&netlock);
16704 
16705    /* Add default domains - host name, IP address and IP:port */
16706    /* Only do this if user added any sip domain with "localdomains" */
16707    /* In order to *not* break backwards compatibility */
16708    /*    Some phones address us at IP only, some with additional port number */
16709    if (auto_sip_domains) {
16710       char temp[MAXHOSTNAMELEN];
16711 
16712       /* First our default IP address */
16713       if (bindaddr.sin_addr.s_addr)
16714          add_sip_domain(ast_inet_ntoa(bindaddr.sin_addr), SIP_DOMAIN_AUTO, NULL);
16715       else
16716          ast_log(LOG_NOTICE, "Can't add wildcard IP address to domain list, please add IP address to domain manually.\n");
16717 
16718       /* Our extern IP address, if configured */
16719       if (externip.sin_addr.s_addr)
16720          add_sip_domain(ast_inet_ntoa(externip.sin_addr), SIP_DOMAIN_AUTO, NULL);
16721 
16722       /* Extern host name (NAT traversal support) */
16723       if (!ast_strlen_zero(externhost))
16724          add_sip_domain(externhost, SIP_DOMAIN_AUTO, NULL);
16725       
16726       /* Our host name */
16727       if (!gethostname(temp, sizeof(temp)))
16728          add_sip_domain(temp, SIP_DOMAIN_AUTO, NULL);
16729    }
16730 
16731    /* Release configuration from memory */
16732    ast_config_destroy(cfg);
16733 
16734    /* Load the list of manual NOTIFY types to support */
16735    if (notify_types)
16736       ast_config_destroy(notify_types);
16737    notify_types = ast_config_load(notify_config);
16738 
16739    /* Done, tell the manager */
16740    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);
16741 
16742    return 0;
16743 }

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

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

Referenced by do_proxy_auth(), and do_register_auth().

11114 {
11115    char tmp[512];
11116    char *c;
11117    char oldnonce[256];
11118 
11119    /* table of recognised keywords, and places where they should be copied */
11120    const struct x {
11121       const char *key;
11122       int field_index;
11123    } *i, keys[] = {
11124       { "realm=", ast_string_field_index(p, realm) },
11125       { "nonce=", ast_string_field_index(p, nonce) },
11126       { "opaque=", ast_string_field_index(p, opaque) },
11127       { "qop=", ast_string_field_index(p, qop) },
11128       { "domain=", ast_string_field_index(p, domain) },
11129       { NULL, 0 },
11130    };
11131 
11132    ast_copy_string(tmp, get_header(req, header), sizeof(tmp));
11133    if (ast_strlen_zero(tmp)) 
11134       return -1;
11135    if (strncasecmp(tmp, "Digest ", strlen("Digest "))) {
11136       ast_log(LOG_WARNING, "missing Digest.\n");
11137       return -1;
11138    }
11139    c = tmp + strlen("Digest ");
11140    ast_copy_string(oldnonce, p->nonce, sizeof(oldnonce));
11141    while (c && *(c = ast_skip_blanks(c))) {  /* lookup for keys */
11142       for (i = keys; i->key != NULL; i++) {
11143          char *src, *separator;
11144          if (strncasecmp(c, i->key, strlen(i->key)) != 0)
11145             continue;
11146          /* Found. Skip keyword, take text in quotes or up to the separator. */
11147          c += strlen(i->key);
11148          if (*c == '"') {
11149             src = ++c;
11150             separator = "\"";
11151          } else {
11152             src = c;
11153             separator = ",";
11154          }
11155          strsep(&c, separator); /* clear separator and move ptr */
11156          ast_string_field_index_set(p, i->field_index, src);
11157          break;
11158       }
11159       if (i->key == NULL) /* not found, try ',' */
11160          strsep(&c, ",");
11161    }
11162    /* Reset nonce count */
11163    if (strcmp(p->nonce, oldnonce)) 
11164       p->noncecount = 0;
11165 
11166    /* Save auth data for following registrations */
11167    if (p->registry) {
11168       struct sip_registry *r = p->registry;
11169 
11170       if (strcmp(r->nonce, p->nonce)) {
11171          ast_string_field_set(r, realm, p->realm);
11172          ast_string_field_set(r, nonce, p->nonce);
11173          ast_string_field_set(r, domain, p->domain);
11174          ast_string_field_set(r, opaque, p->opaque);
11175          ast_string_field_set(r, qop, p->qop);
11176          r->noncecount = 0;
11177       }
11178    }
11179    return build_reply_digest(p, sipmethod, digest, digest_len); 
11180 }

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

05634 {
05635    struct sip_request *orig = &p->initreq;
05636    char stripped[80];
05637    char tmp[80];
05638    char newto[256];
05639    const char *c;
05640    const char *ot, *of;
05641    int is_strict = FALSE;     /*!< Strict routing flag */
05642 
05643    memset(req, 0, sizeof(struct sip_request));
05644    
05645    snprintf(p->lastmsg, sizeof(p->lastmsg), "Tx: %s", sip_methods[sipmethod].text);
05646    
05647    if (!seqno) {
05648       p->ocseq++;
05649       seqno = p->ocseq;
05650    }
05651    
05652    if (newbranch) {
05653       p->branch ^= ast_random();
05654       build_via(p);
05655    }
05656 
05657    /* Check for strict or loose router */
05658    if (p->route && !ast_strlen_zero(p->route->hop) && strstr(p->route->hop,";lr") == NULL) {
05659       is_strict = TRUE;
05660       if (sipdebug)
05661          ast_log(LOG_DEBUG, "Strict routing enforced for session %s\n", p->callid);
05662    }
05663 
05664    if (sipmethod == SIP_CANCEL)
05665       c = p->initreq.rlPart2; /* Use original URI */
05666    else if (sipmethod == SIP_ACK) {
05667       /* Use URI from Contact: in 200 OK (if INVITE) 
05668       (we only have the contacturi on INVITEs) */
05669       if (!ast_strlen_zero(p->okcontacturi))
05670          c = is_strict ? p->route->hop : p->okcontacturi;
05671       else
05672          c = p->initreq.rlPart2;
05673    } else if (!ast_strlen_zero(p->okcontacturi)) 
05674       c = is_strict ? p->route->hop : p->okcontacturi; /* Use for BYE or REINVITE */
05675    else if (!ast_strlen_zero(p->uri)) 
05676       c = p->uri;
05677    else {
05678       char *n;
05679       /* We have no URI, use To: or From:  header as URI (depending on direction) */
05680       ast_copy_string(stripped, get_header(orig, (ast_test_flag(&p->flags[0], SIP_OUTGOING)) ? "To" : "From"),
05681             sizeof(stripped));
05682       n = get_in_brackets(stripped);
05683       c = strsep(&n, ";"); /* trim ; and beyond */
05684    }  
05685    init_req(req, sipmethod, c);
05686 
05687    snprintf(tmp, sizeof(tmp), "%d %s", seqno, sip_methods[sipmethod].text);
05688 
05689    add_header(req, "Via", p->via);
05690    if (p->route) {
05691       set_destination(p, p->route->hop);
05692       add_route(req, is_strict ? p->route->next : p->route);
05693    }
05694 
05695    ot = get_header(orig, "To");
05696    of = get_header(orig, "From");
05697 
05698    /* Add tag *unless* this is a CANCEL, in which case we need to send it exactly
05699       as our original request, including tag (or presumably lack thereof) */
05700    if (!strcasestr(ot, "tag=") && sipmethod != SIP_CANCEL) {
05701       /* Add the proper tag if we don't have it already.  If they have specified
05702          their tag, use it.  Otherwise, use our own tag */
05703       if (ast_test_flag(&p->flags[0], SIP_OUTGOING) && !ast_strlen_zero(p->theirtag))
05704          snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->theirtag);
05705       else if (!ast_test_flag(&p->flags[0], SIP_OUTGOING))
05706          snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->tag);
05707       else
05708          snprintf(newto, sizeof(newto), "%s", ot);
05709       ot = newto;
05710    }
05711 
05712    if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
05713       add_header(req, "From", of);
05714       add_header(req, "To", ot);
05715    } else {
05716       add_header(req, "From", ot);
05717       add_header(req, "To", of);
05718    }
05719    /* Do not add Contact for MESSAGE, BYE and Cancel requests */
05720    if (sipmethod != SIP_BYE && sipmethod != SIP_CANCEL && sipmethod != SIP_MESSAGE)
05721       add_header(req, "Contact", p->our_contact);
05722 
05723    copy_header(req, orig, "Call-ID");
05724    add_header(req, "CSeq", tmp);
05725 
05726    if (!ast_strlen_zero(global_useragent))
05727       add_header(req, "User-Agent", global_useragent);
05728    add_header(req, "Max-Forwards", DEFAULT_MAX_FORWARDS);
05729 
05730    if (!ast_strlen_zero(p->rpid))
05731       add_header(req, "Remote-Party-ID", p->rpid);
05732 
05733    return 0;
05734 }

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

05586 {
05587    char newto[256];
05588    const char *ot;
05589 
05590    init_resp(resp, msg);
05591    copy_via_headers(p, resp, req, "Via");
05592    if (msg[0] == '2')
05593       copy_all_header(resp, req, "Record-Route");
05594    copy_header(resp, req, "From");
05595    ot = get_header(req, "To");
05596    if (!strcasestr(ot, "tag=") && strncmp(msg, "100", 3)) {
05597       /* Add the proper tag if we don't have it already.  If they have specified
05598          their tag, use it.  Otherwise, use our own tag */
05599       if (!ast_strlen_zero(p->theirtag) && ast_test_flag(&p->flags[0], SIP_OUTGOING))
05600          snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->theirtag);
05601       else if (p->tag && !ast_test_flag(&p->flags[0], SIP_OUTGOING))
05602          snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->tag);
05603       else
05604          ast_copy_string(newto, ot, sizeof(newto));
05605       ot = newto;
05606    }
05607    add_header(resp, "To", ot);
05608    copy_header(resp, req, "Call-ID");
05609    copy_header(resp, req, "CSeq");
05610    if (!ast_strlen_zero(global_useragent))
05611       add_header(resp, "User-Agent", global_useragent);
05612    add_header(resp, "Allow", ALLOWED_METHODS);
05613    add_header(resp, "Supported", SUPPORTED_EXTENSIONS);
05614    if (msg[0] == '2' && (p->method == SIP_SUBSCRIBE || p->method == SIP_REGISTER)) {
05615       /* For registration responses, we also need expiry and
05616          contact info */
05617       char tmp[256];
05618 
05619       snprintf(tmp, sizeof(tmp), "%d", p->expiry);
05620       add_header(resp, "Expires", tmp);
05621       if (p->expiry) {  /* Only add contact if we have an expiry time */
05622          char contact[BUFSIZ];
05623          snprintf(contact, sizeof(contact), "%s;expires=%d", p->our_contact, p->expiry);
05624          add_header(resp, "Contact", contact);  /* Not when we unregister */
05625       }
05626    } else if (msg[0] != '4' && p->our_contact[0]) {
05627       add_header(resp, "Contact", p->our_contact);
05628    }
05629    return 0;
05630 }

static int restart_monitor ( void   )  [static]

Start the channel monitor thread.

Definition at line 15180 of file chan_sip.c.

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

15181 {
15182    /* If we're supposed to be stopped -- stay stopped */
15183    if (monitor_thread == AST_PTHREADT_STOP)
15184       return 0;
15185    ast_mutex_lock(&monlock);
15186    if (monitor_thread == pthread_self()) {
15187       ast_mutex_unlock(&monlock);
15188       ast_log(LOG_WARNING, "Cannot kill myself\n");
15189       return -1;
15190    }
15191    if (monitor_thread != AST_PTHREADT_NULL) {
15192       /* Wake up the thread */
15193       pthread_kill(monitor_thread, SIGURG);
15194    } else {
15195       /* Start a new monitor */
15196       if (ast_pthread_create_background(&monitor_thread, NULL, do_monitor, NULL) < 0) {
15197          ast_mutex_unlock(&monlock);
15198          ast_log(LOG_ERROR, "Unable to start monitor thread.\n");
15199          return -1;
15200       }
15201    }
15202    ast_mutex_unlock(&monlock);
15203    return 0;
15204 }

static int retrans_pkt ( void *  data  )  [static]

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

Definition at line 1850 of file chan_sip.c.

References __sip_xmit(), append_history, 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, 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_alreadygone(), 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, and sip_pkt::timer_t1.

01851 {
01852    struct sip_pkt *pkt = data, *prev, *cur = NULL;
01853    int reschedule = DEFAULT_RETRANS;
01854 
01855    /* Lock channel PVT */
01856    ast_mutex_lock(&pkt->owner->lock);
01857 
01858    if (pkt->retrans < MAX_RETRANS) {
01859       pkt->retrans++;
01860       if (!pkt->timer_t1) {   /* Re-schedule using timer_a and timer_t1 */
01861          if (sipdebug && option_debug > 3)
01862             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);
01863       } else {
01864          int siptimer_a;
01865 
01866          if (sipdebug && option_debug > 3)
01867             ast_log(LOG_DEBUG, "SIP TIMER: Rescheduling retransmission #%d (%d) %s - %d\n", pkt->retransid, pkt->retrans, sip_methods[pkt->method].text, pkt->method);
01868          if (!pkt->timer_a)
01869             pkt->timer_a = 2 ;
01870          else
01871             pkt->timer_a = 2 * pkt->timer_a;
01872  
01873          /* For non-invites, a maximum of 4 secs */
01874          siptimer_a = pkt->timer_t1 * pkt->timer_a;   /* Double each time */
01875          if (pkt->method != SIP_INVITE && siptimer_a > 4000)
01876             siptimer_a = 4000;
01877       
01878          /* Reschedule re-transmit */
01879          reschedule = siptimer_a;
01880          if (option_debug > 3)
01881             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);
01882       } 
01883 
01884       if (sip_debug_test_pvt(pkt->owner)) {
01885          const struct sockaddr_in *dst = sip_real_dst(pkt->owner);
01886          ast_verbose("Retransmitting #%d (%s) to %s:%d:\n%s\n---\n",
01887             pkt->retrans, sip_nat_mode(pkt->owner),
01888             ast_inet_ntoa(dst->sin_addr),
01889             ntohs(dst->sin_port), pkt->data);
01890       }
01891 
01892       append_history(pkt->owner, "ReTx", "%d %s", reschedule, pkt->data);
01893       __sip_xmit(pkt->owner, pkt->data, pkt->packetlen);
01894       ast_mutex_unlock(&pkt->owner->lock);
01895       return  reschedule;
01896    } 
01897    /* Too many retries */
01898    if (pkt->owner && pkt->method != SIP_OPTIONS) {
01899       if (ast_test_flag(pkt, FLAG_FATAL) || sipdebug) /* Tell us if it's critical or if we're debugging */
01900          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");
01901    } else {
01902       if ((pkt->method == SIP_OPTIONS) && sipdebug)
01903          ast_log(LOG_WARNING, "Cancelling retransmit of OPTIONs (call id %s) \n", pkt->owner->callid);
01904    }
01905    append_history(pkt->owner, "MaxRetries", "%s", (ast_test_flag(pkt, FLAG_FATAL)) ? "(Critical)" : "(Non-critical)");
01906       
01907    pkt->retransid = -1;
01908 
01909    if (ast_test_flag(pkt, FLAG_FATAL)) {
01910       while(pkt->owner->owner && ast_channel_trylock(pkt->owner->owner)) {
01911          ast_mutex_unlock(&pkt->owner->lock);   /* SIP_PVT, not channel */
01912          usleep(1);
01913          ast_mutex_lock(&pkt->owner->lock);
01914       }
01915       if (pkt->owner->owner) {
01916          sip_alreadygone(pkt->owner);
01917          ast_log(LOG_WARNING, "Hanging up call %s - no reply to our critical packet.\n", pkt->owner->callid);
01918          ast_queue_hangup(pkt->owner->owner);
01919          ast_channel_unlock(pkt->owner->owner);
01920       } else {
01921          /* If no channel owner, destroy now */
01922 
01923          /* Let the peerpoke system expire packets when the timer expires for poke_noanswer */
01924          if (pkt->method != SIP_OPTIONS)
01925             ast_set_flag(&pkt->owner->flags[0], SIP_NEEDDESTROY); 
01926       }
01927    }
01928    /* In any case, go ahead and remove the packet */
01929    for (prev = NULL, cur = pkt->owner->packets; cur; prev = cur, cur = cur->next) {
01930       if (cur == pkt)
01931          break;
01932    }
01933    if (cur) {
01934       if (prev)
01935          prev->next = cur->next;
01936       else
01937          pkt->owner->packets = cur->next;
01938       ast_mutex_unlock(&pkt->owner->lock);
01939       free(cur);
01940       pkt = NULL;
01941    } else
01942       ast_log(LOG_WARNING, "Weird, couldn't find packet owner!\n");
01943    if (pkt)
01944       ast_mutex_unlock(&pkt->owner->lock);
01945    return 0;
01946 }

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 2185 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, and cfsip_methods::text.

02186 {
02187    int res;
02188 
02189    add_blank(req);
02190    if (sip_debug_test_pvt(p)) {
02191       if (ast_test_flag(&p->flags[0], SIP_NAT_ROUTE))
02192          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);
02193       else
02194          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);
02195    }
02196    if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) {
02197       struct sip_request tmp;
02198       parse_copy(&tmp, req);
02199       append_history(p, reliable ? "TxReqRel" : "TxReq", "%s / %s - %s", tmp.data, get_header(&tmp, "CSeq"), sip_methods[tmp.method].text);
02200    }
02201    res = (reliable) ?
02202       __sip_reliable_xmit(p, seqno, 0, req->data, req->len, (reliable > 1), req->method) :
02203       __sip_xmit(p, req->data, req->len);
02204    return res;
02205 }

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

02158 {
02159    int res;
02160 
02161    add_blank(req);
02162    if (sip_debug_test_pvt(p)) {
02163       const struct sockaddr_in *dst = sip_real_dst(p);
02164 
02165       ast_verbose("\n<--- %sTransmitting (%s) to %s:%d --->\n%s\n<------------>\n",
02166          reliable ? "Reliably " : "", sip_nat_mode(p),
02167          ast_inet_ntoa(dst->sin_addr),
02168          ntohs(dst->sin_port), req->data);
02169    }
02170    if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) {
02171       struct sip_request tmp;
02172       parse_copy(&tmp, req);
02173       append_history(p, reliable ? "TxRespRel" : "TxResp", "%s / %s - %s", tmp.data, get_header(&tmp, "CSeq"), 
02174          (tmp.method == SIP_RESPONSE || tmp.method == SIP_UNKNOWN) ? tmp.rlPart2 : sip_methods[tmp.method].text);
02175    }
02176    res = (reliable) ?
02177       __sip_reliable_xmit(p, seqno, 1, req->data, req->len, (reliable == XMIT_CRITICAL), req->method) :
02178       __sip_xmit(p, req->data, req->len);
02179    if (res > 0)
02180       return 0;
02181    return res;
02182 }

static int set_address_from_contact ( struct sip_pvt pvt  )  [static]

Change the other partys IP address based on given contact.

Definition at line 7698 of file chan_sip.c.

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

Referenced by handle_response_invite().

07699 {
07700    struct hostent *hp;
07701    struct ast_hostent ahp;
07702    int port;
07703    char *c, *host, *pt;
07704    char *contact;
07705 
07706 
07707    if (ast_test_flag(&pvt->flags[0], SIP_NAT_ROUTE)) {
07708       /* NAT: Don't trust the contact field.  Just use what they came to us
07709          with. */
07710       pvt->sa = pvt->recv;
07711       return 0;
07712    }
07713 
07714 
07715    /* Work on a copy */
07716    contact = ast_strdupa(pvt->fullcontact);
07717 
07718    /* XXX this code is repeated all over */
07719    /* Make sure it's a SIP URL */
07720    if (strncasecmp(contact, "sip:", 4)) {
07721       ast_log(LOG_NOTICE, "'%s' is not a valid SIP contact (missing sip:) trying to use anyway\n", contact);
07722    } else
07723       contact += 4;
07724 
07725    /* Ditch arguments */
07726    /* XXX this code is replicated also shortly below */
07727    contact = strsep(&contact, ";"); /* trim ; and beyond */
07728 
07729    /* Grab host */
07730    host = strchr(contact, '@');
07731    if (!host) {   /* No username part */
07732       host = contact;
07733       c = NULL;
07734    } else {
07735       *host++ = '\0';
07736    }
07737    pt = strchr(host, ':');
07738    if (pt) {
07739       *pt++ = '\0';
07740       port = atoi(pt);
07741    } else
07742       port = STANDARD_SIP_PORT;
07743 
07744    /* XXX This could block for a long time XXX */
07745    /* We should only do this if it's a name, not an IP */
07746    hp = ast_gethostbyname(host, &ahp);
07747    if (!hp)  {
07748       ast_log(LOG_WARNING, "Invalid host name in Contact: (can't resolve in DNS) : '%s'\n", host);
07749       return -1;
07750    }
07751    pvt->sa.sin_family = AF_INET;
07752    memcpy(&pvt->sa.sin_addr, hp->h_addr, sizeof(pvt->sa.sin_addr));
07753    pvt->sa.sin_port = htons(port);
07754 
07755    return 0;
07756 }

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

Set destination from SIP URI.

Definition at line 5494 of file chan_sip.c.

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

Referenced by reqprep().

05495 {
05496    char *h, *maddr, hostname[256];
05497    int port, hn;
05498    struct hostent *hp;
05499    struct ast_hostent ahp;
05500    int debug=sip_debug_test_pvt(p);
05501 
05502    /* Parse uri to h (host) and port - uri is already just the part inside the <> */
05503    /* general form we are expecting is sip[s]:username[:password]@host[:port][;...] */
05504 
05505    if (debug)
05506       ast_verbose("set_destination: Parsing <%s> for address/port to send to\n", uri);
05507 
05508    /* Find and parse hostname */
05509    h = strchr(uri, '@');
05510    if (h)
05511       ++h;
05512    else {
05513       h = uri;
05514       if (strncmp(h, "sip:", 4) == 0)
05515          h += 4;
05516       else if (strncmp(h, "sips:", 5) == 0)
05517          h += 5;
05518    }
05519    hn = strcspn(h, ":;>") + 1;
05520    if (hn > sizeof(hostname)) 
05521       hn = sizeof(hostname);
05522    ast_copy_string(hostname, h, hn);
05523    /* XXX bug here if string has been trimmed to sizeof(hostname) */
05524    h += hn - 1;
05525 
05526    /* Is "port" present? if not default to STANDARD_SIP_PORT */
05527    if (*h == ':') {
05528       /* Parse port */
05529       ++h;
05530       port = strtol(h, &h, 10);
05531    }
05532    else
05533       port = STANDARD_SIP_PORT;
05534 
05535    /* Got the hostname:port - but maybe there's a "maddr=" to override address? */
05536    maddr = strstr(h, "maddr=");
05537    if (maddr) {
05538       maddr += 6;
05539       hn = strspn(maddr, "0123456789.") + 1;
05540       if (hn > sizeof(hostname))
05541          hn = sizeof(hostname);
05542       ast_copy_string(hostname, maddr, hn);
05543    }
05544    
05545    hp = ast_gethostbyname(hostname, &ahp);
05546    if (hp == NULL)  {
05547       ast_log(LOG_WARNING, "Can't find address for host '%s'\n", hostname);
05548       return;
05549    }
05550    p->sa.sin_family = AF_INET;
05551    memcpy(&p->sa.sin_addr, hp->h_addr, sizeof(p->sa.sin_addr));
05552    p->sa.sin_port = htons(port);
05553    if (debug)
05554       ast_verbose("set_destination: set destination to %s, port %d\n", ast_inet_ntoa(p->sa.sin_addr), port);
05555 }

static void set_peer_defaults ( struct sip_peer peer  )  [static]

Set peer defaults before configuring specific configurations.

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

15883 {
15884    if (peer->expire == 0) {
15885       /* Don't reset expire or port time during reload 
15886          if we have an active registration 
15887       */
15888       peer->expire = -1;
15889       peer->pokeexpire = -1;
15890       peer->addr.sin_port = htons(STANDARD_SIP_PORT);
15891    }
15892    ast_copy_flags(&peer->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY);
15893    ast_copy_flags(&peer->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY);
15894    strcpy(peer->context, default_context);
15895    strcpy(peer->subscribecontext, default_subscribecontext);
15896    strcpy(peer->language, default_language);
15897    strcpy(peer->mohinterpret, default_mohinterpret);
15898    strcpy(peer->mohsuggest, default_mohsuggest);
15899    peer->addr.sin_family = AF_INET;
15900    peer->defaddr.sin_family = AF_INET;
15901    peer->capability = global_capability;
15902    peer->maxcallbitrate = default_maxcallbitrate;
15903    peer->rtptimeout = global_rtptimeout;
15904    peer->rtpholdtimeout = global_rtpholdtimeout;
15905    peer->rtpkeepalive = global_rtpkeepalive;
15906    peer->allowtransfer = global_allowtransfer;
15907    peer->autoframing = global_autoframing;
15908    strcpy(peer->vmexten, default_vmexten);
15909    peer->secret[0] = '\0';
15910    peer->md5secret[0] = '\0';
15911    peer->cid_num[0] = '\0';
15912    peer->cid_name[0] = '\0';
15913    peer->fromdomain[0] = '\0';
15914    peer->fromuser[0] = '\0';
15915    peer->regexten[0] = '\0';
15916    peer->mailbox[0] = '\0';
15917    peer->callgroup = 0;
15918    peer->pickupgroup = 0;
15919    peer->maxms = default_qualify;
15920    peer->prefs = default_prefs;
15921 }

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

Add a SIP header to an outbound INVITE.

Definition at line 17075 of file chan_sip.c.

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

Referenced by load_module().

17076 {
17077    int no = 0;
17078    int ok = FALSE;
17079    char varbuf[30];
17080    char *inbuf = (char *) data;
17081    
17082    if (ast_strlen_zero(inbuf)) {
17083       ast_log(LOG_WARNING, "This application requires the argument: Header\n");
17084       return 0;
17085    }
17086    ast_channel_lock(chan);
17087 
17088    /* Check for headers */
17089    while (!ok && no <= 50) {
17090       no++;
17091       snprintf(varbuf, sizeof(varbuf), "_SIPADDHEADER%.2d", no);
17092 
17093       /* Compare without the leading underscore */
17094       if( (pbx_builtin_getvar_helper(chan, (const char *) varbuf + 1) == (const char *) NULL) )
17095          ok = TRUE;
17096    }
17097    if (ok) {
17098       pbx_builtin_setvar_helper (chan, varbuf, inbuf);
17099       if (sipdebug)
17100          ast_log(LOG_DEBUG,"SIP Header added \"%s\" as %s\n", inbuf, varbuf);
17101    } else {
17102       ast_log(LOG_WARNING, "Too many SIP headers added, max 50\n");
17103    }
17104    ast_channel_unlock(chan);
17105    return 0;
17106 }

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

Support routine for find_peer.

Definition at line 2470 of file chan_sip.c.

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

Referenced by find_peer().

02471 {
02472    /* We know name is the first field, so we can cast */
02473    struct sip_peer *p = (struct sip_peer *) name;
02474    return   !(!inaddrcmp(&p->addr, sin) || 
02475                (ast_test_flag(&p->flags[0], SIP_INSECURE_PORT) &&
02476                (p->addr.sin_addr.s_addr == sin->sin_addr.s_addr)));
02477 }

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

04204 {
04205    struct sip_pvt *p;
04206 
04207    if (!(p = ast_calloc(1, sizeof(*p))))
04208       return NULL;
04209 
04210    if (ast_string_field_init(p, 512)) {
04211       free(p);
04212       return NULL;
04213    }
04214 
04215    ast_mutex_init(&p->lock);
04216 
04217    p->method = intended_method;
04218    p->initid = -1;
04219    p->autokillid = -1;
04220    p->subscribed = NONE;
04221    p->stateid = -1;
04222    p->prefs = default_prefs;     /* Set default codecs for this call */
04223 
04224    if (intended_method != SIP_OPTIONS) /* Peerpoke has it's own system */
04225       p->timer_t1 = 500;   /* Default SIP retransmission timer T1 (RFC 3261) */
04226 
04227    if (sin) {
04228       p->sa = *sin;
04229       if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
04230          p->ourip = __ourip;
04231    } else
04232       p->ourip = __ourip;
04233 
04234    /* Copy global flags to this PVT at setup. */
04235    ast_copy_flags(&p->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY);
04236    ast_copy_flags(&p->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY);
04237 
04238    ast_set2_flag(&p->flags[0], !recordhistory, SIP_NO_HISTORY);
04239 
04240    p->branch = ast_random();  
04241    make_our_tag(p->tag, sizeof(p->tag));
04242    p->ocseq = INITIAL_CSEQ;
04243 
04244    if (sip_methods[intended_method].need_rtp) {
04245       p->rtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr.sin_addr);
04246       /* If the global videosupport flag is on, we always create a RTP interface for video */
04247       if (ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT))
04248          p->vrtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr.sin_addr);
04249       if (ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT))
04250          p->udptl = ast_udptl_new_with_bindaddr(sched, io, 0, bindaddr.sin_addr);
04251       if (!p->rtp || (ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) && !p->vrtp)) {
04252          ast_log(LOG_WARNING, "Unable to create RTP audio %s session: %s\n",
04253             ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) ? "and video" : "", strerror(errno));
04254          ast_mutex_destroy(&p->lock);
04255          if (p->chanvars) {
04256             ast_variables_destroy(p->chanvars);
04257             p->chanvars = NULL;
04258          }
04259          free(p);
04260          return NULL;
04261       }
04262       ast_rtp_setdtmf(p->rtp, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833);
04263       ast_rtp_setdtmfcompensate(p->rtp, ast_test_flag(&p->flags[1], SIP_PAGE2_RFC2833_COMPENSATE));
04264       ast_rtp_settos(p->rtp, global_tos_audio);
04265       ast_rtp_set_rtptimeout(p->rtp, global_rtptimeout);
04266       ast_rtp_set_rtpholdtimeout(p->rtp, global_rtpholdtimeout);
04267       ast_rtp_set_rtpkeepalive(p->rtp, global_rtpkeepalive);
04268       if (p->vrtp) {
04269          ast_rtp_settos(p->vrtp, global_tos_video);
04270          ast_rtp_setdtmf(p->vrtp, 0);
04271          ast_rtp_setdtmfcompensate(p->vrtp, 0);
04272          ast_rtp_set_rtptimeout(p->vrtp, global_rtptimeout);
04273          ast_rtp_set_rtpholdtimeout(p->vrtp, global_rtpholdtimeout);
04274          ast_rtp_set_rtpkeepalive(p->vrtp, global_rtpkeepalive);
04275       }
04276       if (p->udptl)
04277          ast_udptl_settos(p->udptl, global_tos_audio);
04278       p->maxcallbitrate = default_maxcallbitrate;
04279    }
04280 
04281    if (useglobal_nat && sin) {
04282       /* Setup NAT structure according to global settings if we have an address */
04283       ast_copy_flags(&p->flags[0], &global_flags[0], SIP_NAT);
04284       p->recv = *sin;
04285       do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE);
04286    }
04287 
04288    if (p->method != SIP_REGISTER)
04289       ast_string_field_set(p, fromdomain, default_fromdomain);
04290    build_via(p);
04291    if (!callid)
04292       build_callid_pvt(p);
04293    else
04294       ast_string_field_set(p, callid, callid);
04295    /* Assign default music on hold class */
04296    ast_string_field_set(p, mohinterpret, default_mohinterpret);
04297    ast_string_field_set(p, mohsuggest, default_mohsuggest);
04298    p->capability = global_capability;
04299    p->allowtransfer = global_allowtransfer;
04300    if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) ||
04301        (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO))
04302       p->noncodeccapability |= AST_RTP_DTMF;
04303    if (p->udptl) {
04304       p->t38.capability = global_t38_capability;
04305       if (ast_udptl_get_error_correction_scheme(p->udptl) == UDPTL_ERROR_CORRECTION_REDUNDANCY)
04306          p->t38.capability |= T38FAX_UDP_EC_REDUNDANCY;
04307       else if (ast_udptl_get_error_correction_scheme(p->udptl) == UDPTL_ERROR_CORRECTION_FEC)
04308          p->t38.capability |= T38FAX_UDP_EC_FEC;
04309       else if (ast_udptl_get_error_correction_scheme(p->udptl) == UDPTL_ERROR_CORRECTION_NONE)
04310          p->t38.capability |= T38FAX_UDP_EC_NONE;
04311       p->t38.capability |= T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF;
04312       p->t38.jointcapability = p->t38.capability;
04313    }
04314    ast_string_field_set(p, context, default_context);
04315 
04316    /* Add to active dialog list */
04317    ast_mutex_lock(&iflock);
04318    p->next = iflist;
04319    iflist = p;
04320    ast_mutex_unlock(&iflock);
04321    if (option_debug)
04322       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");
04323    return p;
04324 }

static void sip_alreadygone ( struct sip_pvt dialog  )  [static]

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

01632 {
01633    if (option_debug > 2)
01634       ast_log(LOG_DEBUG, "Setting SIP_ALREADYGONE on dialog %s\n", dialog->callid);
01635    ast_set_flag(&dialog->flags[0], SIP_ALREADYGONE);
01636 }

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

03454 {
03455    int res = 0;
03456    struct sip_pvt *p = ast->tech_pvt;
03457 
03458    ast_mutex_lock(&p->lock);
03459    if (ast->_state != AST_STATE_UP) {
03460       try_suggested_sip_codec(p);   
03461 
03462       ast_setstate(ast, AST_STATE_UP);
03463       if (option_debug)
03464          ast_log(LOG_DEBUG, "SIP answering channel: %s\n", ast->name);
03465       if (p->t38.state == T38_PEER_DIRECT) {
03466          p->t38.state = T38_ENABLED;
03467          if (option_debug > 1)
03468             ast_log(LOG_DEBUG,"T38State change to %d on channel %s\n", p->t38.state, ast->name);
03469          res = transmit_response_with_t38_sdp(p, "200 OK", &p->initreq, XMIT_CRITICAL);
03470       } else 
03471          res = transmit_response_with_sdp(p, "200 OK", &p->initreq, XMIT_CRITICAL);
03472    }
03473    ast_mutex_unlock(&p->lock);
03474    return res;
03475 }

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

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

02772 {
02773    int res;
02774    struct sip_pvt *p;
02775    struct varshead *headp;
02776    struct ast_var_t *current;
02777    const char *referer = NULL;   /* SIP refererer */  
02778 
02779    p = ast->tech_pvt;
02780    if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) {
02781       ast_log(LOG_WARNING, "sip_call called on %s, neither down nor reserved\n", ast->name);
02782       return -1;
02783    }
02784 
02785    /* Check whether there is vxml_url, distinctive ring variables */
02786    headp=&ast->varshead;
02787    AST_LIST_TRAVERSE(headp,current,entries) {
02788       /* Check whether there is a VXML_URL variable */
02789       if (!p->options->vxml_url && !strcasecmp(ast_var_name(current), "VXML_URL")) {
02790          p->options->vxml_url = ast_var_value(current);
02791       } else if (!p->options->uri_options && !strcasecmp(ast_var_name(current), "SIP_URI_OPTIONS")) {
02792          p->options->uri_options = ast_var_value(current);
02793       } else if (!p->options->distinctive_ring && !strcasecmp(ast_var_name(current), "ALERT_INFO")) {
02794          /* Check whether there is a ALERT_INFO variable */
02795          p->options->distinctive_ring = ast_var_value(current);
02796       } else if (!p->options->addsipheaders && !strncasecmp(ast_var_name(current), "SIPADDHEADER", strlen("SIPADDHEADER"))) {
02797          /* Check whether there is a variable with a name starting with SIPADDHEADER */
02798          p->options->addsipheaders = 1;
02799       } else if (!strcasecmp(ast_var_name(current), "SIPTRANSFER")) {
02800          /* This is a transfered call */
02801          p->options->transfer = 1;
02802       } else if (!strcasecmp(ast_var_name(current), "SIPTRANSFER_REFERER")) {
02803          /* This is the referer */
02804          referer = ast_var_value(current);
02805       } else if (!strcasecmp(ast_var_name(current), "SIPTRANSFER_REPLACES")) {
02806          /* We're replacing a call. */
02807          p->options->replaces = ast_var_value(current);
02808       } else if (!strcasecmp(ast_var_name(current), "T38CALL")) {
02809          p->t38.state = T38_LOCAL_DIRECT;
02810          if (option_debug)
02811             ast_log(LOG_DEBUG,"T38State change to %d on channel %s\n", p->t38.state, ast->name);
02812       }
02813 
02814    }
02815    
02816    res = 0;
02817    ast_set_flag(&p->flags[0], SIP_OUTGOING);
02818 
02819    if (p->options->transfer) {
02820       char buf[BUFSIZ/2];
02821 
02822       if (referer) {
02823          if (sipdebug && option_debug > 2)
02824             ast_log(LOG_DEBUG, "Call for %s transfered by %s\n", p->username, referer);
02825          snprintf(buf, sizeof(buf)-1, "-> %s (via %s)", p->cid_name, referer);
02826       } else 
02827          snprintf(buf, sizeof(buf)-1, "-> %s", p->cid_name);
02828       ast_string_field_set(p, cid_name, buf);
02829    } 
02830    if (option_debug)
02831       ast_log(LOG_DEBUG, "Outgoing Call for %s\n", p->username);
02832 
02833    res = update_call_counter(p, INC_CALL_RINGING);
02834    if ( res != -1 ) {
02835       p->callingpres = ast->cid.cid_pres;
02836       p->jointcapability = ast_translate_available_formats(p->capability, p->prefcodec);
02837       p->jointnoncodeccapability = p->noncodeccapability;
02838 
02839       /* If there are no audio formats left to offer, punt */
02840       if (!(p->jointcapability & AST_FORMAT_AUDIO_MASK)) {
02841          ast_log(LOG_WARNING, "No audio format found to offer. Cancelling call to %s\n", p->username);
02842          res = -1;
02843       } else {
02844          p->t38.jointcapability = p->t38.capability;
02845          if (option_debug > 1)
02846             ast_log(LOG_DEBUG,"Our T38 capability (%d), joint T38 capability (%d)\n", p->t38.capability, p->t38.jointcapability);
02847          transmit_invite(p, SIP_INVITE, 1, 2);
02848          p->invitestate = INV_CALLING;
02849 
02850          /* Initialize auto-congest time */
02851          p->initid = ast_sched_add(sched, p->maxtime ? (p->maxtime * 4) : SIP_TRANS_TIMEOUT, auto_congest, p);
02852       }
02853    }
02854    return res;
02855 }

static void sip_cancel_destroy ( struct sip_pvt p  )  [static]

Cancel destruction of SIP dialog.

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

02046 {
02047    if (p->autokillid > -1) {
02048       ast_sched_del(sched, p->autokillid);
02049       append_history(p, "CancelDestroy", "");
02050       p->autokillid = -1;
02051    }
02052 }

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

See if we pass debug IP filter.

Definition at line 1713 of file chan_sip.c.

References sipdebug.

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

01714 {
01715    if (!sipdebug)
01716       return 0;
01717    if (debugaddr.sin_addr.s_addr) {
01718       if (((ntohs(debugaddr.sin_port) != 0)
01719          && (debugaddr.sin_port != addr->sin_port))
01720          || (debugaddr.sin_addr.s_addr != addr->sin_addr.s_addr))
01721          return 0;
01722    }
01723    return 1;
01724 }

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

Test PVT for debugging output.

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

01740 {
01741    if (!sipdebug)
01742       return 0;
01743    return sip_debug_test_addr(sip_real_dst(p));
01744 }

static void sip_destroy ( struct sip_pvt p  )  [static]

Destroy SIP call structure.

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

03107 {
03108    ast_mutex_lock(&iflock);
03109    if (option_debug > 2)
03110       ast_log(LOG_DEBUG, "Destroying SIP dialog %s\n", p->callid);
03111    __sip_destroy(p, 1);
03112    ast_mutex_unlock(&iflock);
03113 }

static void sip_destroy_peer ( struct sip_peer peer  )  [static]

Destroy peer object from memory.

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

02358 {
02359    if (option_debug > 2)
02360       ast_log(LOG_DEBUG, "Destroying SIP peer %s\n", peer->name);
02361 
02362    /* Delete it, it needs to disappear */
02363    if (peer->call)
02364       sip_destroy(peer->call);
02365 
02366    if (peer->mwipvt)    /* We have an active subscription, delete it */
02367       sip_destroy(peer->mwipvt);
02368 
02369    if (peer->chanvars) {
02370       ast_variables_destroy(peer->chanvars);
02371       peer->chanvars = NULL;
02372    }
02373    if (peer->expire > -1)
02374       ast_sched_del(sched, peer->expire);
02375 
02376    if (peer->pokeexpire > -1)
02377       ast_sched_del(sched, peer->pokeexpire);
02378    register_peer_exten(peer, FALSE);
02379    ast_free_ha(peer->ha);
02380    if (ast_test_flag(&peer->flags[1], SIP_PAGE2_SELFDESTRUCT))
02381       apeerobjs--;
02382    else if (ast_test_flag(&peer->flags[0], SIP_REALTIME))
02383       rpeerobjs--;
02384    else
02385       speerobjs--;
02386    clear_realm_authentication(peer->auth);
02387    peer->auth = NULL;
02388    free(peer);
02389 }

static void sip_destroy_user ( struct sip_user user  )  [static]

Remove user object from in-memory storage.

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

02499 {
02500    if (option_debug > 2)
02501       ast_log(LOG_DEBUG, "Destroying user object from memory: %s\n", user->name);
02502    ast_free_ha(user->ha);
02503    if (user->chanvars) {
02504       ast_variables_destroy(user->chanvars);
02505       user->chanvars = NULL;
02506    }
02507    if (ast_test_flag(&user->flags[0], SIP_REALTIME))
02508       ruserobjs--;
02509    else
02510       suserobjs--;
02511    free(user);
02512 }

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

15321 {
15322    char *host;
15323    char *tmp;
15324 
15325    struct hostent *hp;
15326    struct ast_hostent ahp;
15327    struct sip_peer *p;
15328 
15329    int res = AST_DEVICE_INVALID;
15330 
15331    /* make sure data is not null. Maybe unnecessary, but better be safe */
15332    host = ast_strdupa(data ? data : "");
15333    if ((tmp = strchr(host, '@')))
15334       host = tmp + 1;
15335 
15336    if (option_debug > 2) 
15337       ast_log(LOG_DEBUG, "Checking device state for peer %s\n", host);
15338 
15339    if ((p = find_peer(host, NULL, 1))) {
15340       if (p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) {
15341          /* we have an address for the peer */
15342       
15343          /* Check status in this order
15344             - Hold
15345             - Ringing
15346             - Busy (enforced only by call limit)
15347             - Inuse (we have a call)
15348             - Unreachable (qualify)
15349             If we don't find any of these state, report AST_DEVICE_NOT_INUSE
15350             for registered devices */
15351 
15352          if (p->onHold)
15353             /* First check for hold or ring states */
15354             res = AST_DEVICE_ONHOLD;
15355          else if (p->inRinging) {
15356             if (p->inRinging == p->inUse)
15357                res = AST_DEVICE_RINGING;
15358             else
15359                res = AST_DEVICE_RINGINUSE;
15360          } else if (p->call_limit && (p->inUse == p->call_limit))
15361             /* check call limit */
15362             res = AST_DEVICE_BUSY;
15363          else if (p->call_limit && p->inUse)
15364             /* Not busy, but we do have a call */
15365             res = AST_DEVICE_INUSE;
15366          else if (p->maxms && (p->lastms > p->maxms)) 
15367             /* We don't have a call. Are we reachable at all? Requires qualify= */
15368             res = AST_DEVICE_UNAVAILABLE;
15369          else  /* Default reply if we're registered and have no other data */
15370             res = AST_DEVICE_NOT_INUSE;
15371       } else {
15372          /* there is no address, it's unavailable */
15373          res = AST_DEVICE_UNAVAILABLE;
15374       }
15375       ASTOBJ_UNREF(p,sip_destroy_peer);
15376    } else {
15377       hp = ast_gethostbyname(host, &ahp);
15378       if (hp)
15379          res = AST_DEVICE_UNKNOWN;
15380    }
15381 
15382    return res;
15383 }

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

Turn on SIP debugging (CLI command).

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

10927 {
10928    int oldsipdebug = sipdebug_console;
10929    if (argc != 3) {
10930       if (argc != 5) 
10931          return RESULT_SHOWUSAGE;
10932       else if (strcmp(argv[3], "ip") == 0)
10933          return sip_do_debug_ip(fd, argc, argv);
10934       else if (strcmp(argv[3], "peer") == 0)
10935          return sip_do_debug_peer(fd, argc, argv);
10936       else
10937          return RESULT_SHOWUSAGE;
10938    }
10939    ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE);
10940    memset(&debugaddr, 0, sizeof(debugaddr));
10941    ast_cli(fd, "SIP Debugging %senabled\n", oldsipdebug ? "re-" : "");
10942    return RESULT_SUCCESS;
10943 }

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

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

10946 {
10947    int oldsipdebug = sipdebug_console;
10948    char *newargv[6] = { "sip", "set", "debug", NULL };
10949    if (argc != 2) {
10950       if (argc != 4) 
10951          return RESULT_SHOWUSAGE;
10952       else if (strcmp(argv[2], "ip") == 0) {
10953          newargv[3] = argv[2];
10954          newargv[4] = argv[3];
10955          return sip_do_debug_ip(fd, argc + 1, newargv);
10956       } else if (strcmp(argv[2], "peer") == 0) {
10957          newargv[3] = argv[2];
10958          newargv[4] = argv[3];
10959          return sip_do_debug_peer(fd, argc + 1, newargv);
10960       } else
10961          return RESULT_SHOWUSAGE;
10962    }
10963    ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE);
10964    memset(&debugaddr, 0, sizeof(debugaddr));
10965    ast_cli(fd, "SIP Debugging %senabled\n", oldsipdebug ? "re-" : "");
10966    return RESULT_SUCCESS;
10967 }

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

Enable SIP Debugging in CLI.

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

10873 {
10874    struct hostent *hp;
10875    struct ast_hostent ahp;
10876    int port = 0;
10877    char *p, *arg;
10878 
10879    /* sip set debug ip <ip> */
10880    if (argc != 5)
10881       return RESULT_SHOWUSAGE;
10882    p = arg = argv[4];
10883    strsep(&p, ":");
10884    if (p)
10885       port = atoi(p);
10886    hp = ast_gethostbyname(arg, &ahp);
10887    if (hp == NULL)
10888       return RESULT_SHOWUSAGE;
10889 
10890    debugaddr.sin_family = AF_INET;
10891    memcpy(&debugaddr.sin_addr, hp->h_addr, sizeof(debugaddr.sin_addr));
10892    debugaddr.sin_port = htons(port);
10893    if (port == 0)
10894       ast_cli(fd, "SIP Debugging Enabled for IP: %s\n", ast_inet_ntoa(debugaddr.sin_addr));
10895    else
10896       ast_cli(fd, "SIP Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(debugaddr.sin_addr), port);
10897 
10898    ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE);
10899 
10900    return RESULT_SUCCESS;
10901 }

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

10905 {
10906    struct sip_peer *peer;
10907    if (argc != 5)
10908       return RESULT_SHOWUSAGE;
10909    peer = find_peer(argv[4], NULL, 1);
10910    if (peer) {
10911       if (peer->addr.sin_addr.s_addr) {
10912          debugaddr.sin_family = AF_INET;
10913          debugaddr.sin_addr = peer->addr.sin_addr;
10914          debugaddr.sin_port = peer->addr.sin_port;
10915          ast_cli(fd, "SIP Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(debugaddr.sin_addr), ntohs(debugaddr.sin_port));
10916          ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE);
10917       } else
10918          ast_cli(fd, "Unable to get IP address of peer '%s'\n", argv[4]);
10919       ASTOBJ_UNREF(peer,sip_destroy_peer);
10920    } else
10921       ast_cli(fd, "No such peer '%s'\n", argv[4]);
10922    return RESULT_SUCCESS;
10923 }

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

Enable SIP History logging (CLI).

Definition at line 11045 of file chan_sip.c.

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

11046 {
11047    if (argc != 2) {
11048       return RESULT_SHOWUSAGE;
11049    }
11050    recordhistory = TRUE;
11051    ast_cli(fd, "SIP History Recording Enabled (use 'sip show history')\n");
11052    return RESULT_SUCCESS;
11053 }

static int sip_do_reload ( enum channelreloadreason  reason  )  [static]

Reload module.

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

17217 {
17218    if (option_debug > 3)
17219       ast_log(LOG_DEBUG, "--------------- SIP reload started\n");
17220 
17221    clear_realm_authentication(authl);
17222    clear_sip_domains();
17223    authl = NULL;
17224 
17225    /* First, destroy all outstanding registry calls */
17226    /* This is needed, since otherwise active registry entries will not be destroyed */
17227    ASTOBJ_CONTAINER_TRAVERSE(&regl, 1, do {
17228       ASTOBJ_RDLOCK(iterator);
17229       if (iterator->call) {
17230          if (option_debug > 2)
17231             ast_log(LOG_DEBUG, "Destroying active SIP dialog for registry %s@%s\n", iterator->username, iterator->hostname);
17232          /* This will also remove references to the registry */
17233          sip_destroy(iterator->call);
17234       }
17235       ASTOBJ_UNLOCK(iterator);
17236    
17237    } while(0));
17238 
17239    /* Then, actually destroy users and registry */
17240    ASTOBJ_CONTAINER_DESTROYALL(&userl, sip_destroy_user);
17241    if (option_debug > 3)
17242       ast_log(LOG_DEBUG, "--------------- Done destroying user list\n");
17243    ASTOBJ_CONTAINER_DESTROYALL(&regl, sip_registry_destroy);
17244    if (option_debug > 3)
17245       ast_log(LOG_DEBUG, "--------------- Done destroying registry list\n");
17246    ASTOBJ_CONTAINER_MARKALL(&peerl);
17247    reload_config(reason);
17248 
17249    /* Prune peers who still are supposed to be deleted */
17250    ASTOBJ_CONTAINER_PRUNE_MARKED(&peerl, sip_destroy_peer);
17251    if (option_debug > 3)
17252       ast_log(LOG_DEBUG, "--------------- Done destroying pruned peers\n");
17253 
17254    /* Send qualify (OPTIONS) to all peers */
17255    sip_poke_all_peers();
17256 
17257    /* Register with all services */
17258    sip_send_all_registers();
17259 
17260    if (option_debug > 3)
17261       ast_log(LOG_DEBUG, "--------------- SIP reload done\n");
17262 
17263    return 0;
17264 }

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

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

Definition at line 17020 of file chan_sip.c.

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

Referenced by load_module().

17021 {
17022    struct sip_pvt *p;
17023    char *mode;
17024    if (data)
17025       mode = (char *)data;
17026    else {
17027       ast_log(LOG_WARNING, "This application requires the argument: info, inband, rfc2833\n");
17028       return 0;
17029    }
17030    ast_channel_lock(chan);
17031    if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) {
17032       ast_log(LOG_WARNING, "Call this application only on SIP incoming calls\n");
17033       ast_channel_unlock(chan);
17034       return 0;
17035    }
17036    p = chan->tech_pvt;
17037    if (!p) {
17038       ast_channel_unlock(chan);
17039       return 0;
17040    }
17041    ast_mutex_lock(&p->lock);
17042    if (!strcasecmp(mode,"info")) {
17043       ast_clear_flag(&p->flags[0], SIP_DTMF);
17044       ast_set_flag(&p->flags[0], SIP_DTMF_INFO);
17045       p->jointnoncodeccapability &= ~AST_RTP_DTMF;
17046    } else if (!strcasecmp(mode,"rfc2833")) {
17047       ast_clear_flag(&p->flags[0], SIP_DTMF);
17048       ast_set_flag(&p->flags[0], SIP_DTMF_RFC2833);
17049       p->jointnoncodeccapability |= AST_RTP_DTMF;
17050    } else if (!strcasecmp(mode,"inband")) { 
17051       ast_clear_flag(&p->flags[0], SIP_DTMF);
17052       ast_set_flag(&p->flags[0], SIP_DTMF_INBAND);
17053       p->jointnoncodeccapability &= ~AST_RTP_DTMF;
17054    } else
17055       ast_log(LOG_WARNING, "I don't know about this dtmf mode: %s\n",mode);
17056    if (p->rtp)
17057       ast_rtp_setdtmf(p->rtp, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833);
17058    if (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) {
17059       if (!p->vad) {
17060          p->vad = ast_dsp_new();
17061          ast_dsp_set_features(p->vad, DSP_FEATURE_DTMF_DETECT);
17062       }
17063    } else {
17064       if (p->vad) {
17065          ast_dsp_free(p->vad);
17066          p->vad = NULL;
17067       }
17068    }
17069    ast_mutex_unlock(&p->lock);
17070    ast_channel_unlock(chan);
17071    return 0;
17072 }

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

10743 {
10744    int x = 0;
10745    struct sip_history *hist;
10746    static int errmsg = 0;
10747 
10748    if (!dialog)
10749       return;
10750 
10751    if (!option_debug && !sipdebug) {
10752       if (!errmsg) {
10753          ast_log(LOG_NOTICE, "You must have debugging enabled (SIP or Asterisk) in order to dump SIP history.\n");
10754          errmsg = 1;
10755       }
10756       return;
10757    }
10758 
10759    ast_log(LOG_DEBUG, "\n---------- SIP HISTORY for '%s' \n", dialog->callid);
10760    if (dialog->subscribed)
10761       ast_log(LOG_DEBUG, "  * Subscription\n");
10762    else
10763       ast_log(LOG_DEBUG, "  * SIP Call\n");
10764    if (dialog->history)
10765       AST_LIST_TRAVERSE(dialog->history, hist, list)
10766          ast_log(LOG_DEBUG, "  %-3.3d. %s\n", ++x, hist->event);
10767    if (!x)
10768       ast_log(LOG_DEBUG, "Call '%s' has no history\n", dialog->callid);
10769    ast_log(LOG_DEBUG, "\n---------- END SIP HISTORY for '%s' \n", dialog->callid);
10770 }

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

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

03558 {
03559    int ret = -1;
03560    struct sip_pvt *p;
03561 
03562    if (newchan && ast_test_flag(newchan, AST_FLAG_ZOMBIE) && option_debug)
03563       ast_log(LOG_DEBUG, "New channel is zombie\n");
03564    if (oldchan && ast_test_flag(oldchan, AST_FLAG_ZOMBIE) && option_debug)
03565       ast_log(LOG_DEBUG, "Old channel is zombie\n");
03566 
03567    if (!newchan || !newchan->tech_pvt) {
03568       if (!newchan)
03569          ast_log(LOG_WARNING, "No new channel! Fixup of %s failed.\n", oldchan->name);
03570       else
03571          ast_log(LOG_WARNING, "No SIP tech_pvt! Fixup of %s failed.\n", oldchan->name);
03572       return -1;
03573    }
03574    p = newchan->tech_pvt;
03575 
03576    if (!p) {
03577       ast_log(LOG_WARNING, "No pvt after masquerade. Strange things may happen\n");
03578       return -1;
03579    }
03580 
03581    ast_mutex_lock(&p->lock);
03582    append_history(p, "Masq", "Old channel: %s\n", oldchan->name);
03583    append_history(p, "Masq (cont)", "...new owner: %s\n", newchan->name);
03584    if (p->owner != oldchan)
03585       ast_log(LOG_WARNING, "old channel wasn't %p but was %p\n", oldchan, p->owner);
03586    else {
03587       p->owner = newchan;
03588       ret = 0;
03589    }
03590    if (option_debug > 2)
03591       ast_log(LOG_DEBUG, "SIP Fixup: New owner for dialogue %s: %s (Old parent: %s)\n", p->callid, p->owner->name, oldchan->name);
03592 
03593    ast_mutex_unlock(&p->lock);
03594    return ret;
03595 }

static int sip_get_codec ( struct ast_channel chan  )  [static]

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

Definition at line 17165 of file chan_sip.c.

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

17166 {
17167    struct sip_pvt *p = chan->tech_pvt;
17168    return p->peercapability ? p->peercapability : p->capability;  
17169 }

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

16881 {
16882    struct sip_pvt *p = NULL;
16883    enum ast_rtp_get_result res = AST_RTP_TRY_PARTIAL;
16884 
16885    if (!(p = chan->tech_pvt))
16886       return AST_RTP_GET_FAILED;
16887 
16888    ast_mutex_lock(&p->lock);
16889    if (!(p->rtp)) {
16890       ast_mutex_unlock(&p->lock);
16891       return AST_RTP_GET_FAILED;
16892    }
16893 
16894    *rtp = p->rtp;
16895 
16896    if (ast_rtp_getnat(*rtp) && !ast_test_flag(&p->flags[0], SIP_CAN_REINVITE_NAT))
16897       res = AST_RTP_TRY_PARTIAL;
16898    else if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE))
16899       res = AST_RTP_TRY_NATIVE;
16900    else if (ast_test_flag(&global_jbconf, AST_JB_FORCED))
16901       res = AST_RTP_GET_FAILED;
16902 
16903    ast_mutex_unlock(&p->lock);
16904 
16905    return res;
16906 }

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

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

16746 {
16747    struct sip_pvt *p;
16748    struct ast_udptl *udptl = NULL;
16749    
16750    p = chan->tech_pvt;
16751    if (!p)
16752       return NULL;
16753    
16754    ast_mutex_lock(&p->lock);
16755    if (p->udptl && ast_test_flag(&p->flags[0], SIP_CAN_REINVITE))
16756       udptl = p->udptl;
16757    ast_mutex_unlock(&p->lock);
16758    return udptl;
16759 }

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

16910 {
16911    struct sip_pvt *p = NULL;
16912    enum ast_rtp_get_result res = AST_RTP_TRY_PARTIAL;
16913    
16914    if (!(p = chan->tech_pvt))
16915       return AST_RTP_GET_FAILED;
16916 
16917    ast_mutex_lock(&p->lock);
16918    if (!(p->vrtp)) {
16919       ast_mutex_unlock(&p->lock);
16920       return AST_RTP_GET_FAILED;
16921    }
16922 
16923    *rtp = p->vrtp;
16924 
16925    if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE))
16926       res = AST_RTP_TRY_NATIVE;
16927 
16928    ast_mutex_unlock(&p->lock);
16929 
16930    return res;
16931 }

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

16798 {
16799    struct sip_pvt *p;
16800    int flag = 0;
16801    
16802    p = chan->tech_pvt;
16803    if (!p || !pvt->udptl)
16804       return -1;
16805    
16806    /* Setup everything on the other side like offered/responded from first side */
16807    ast_mutex_lock(&p->lock);
16808 
16809    /*! \todo check if this is not set earlier when setting up the PVT. If not
16810       maybe it should move there. */
16811    p->t38.jointcapability = p->t38.peercapability = pvt->t38.jointcapability;
16812 
16813    ast_udptl_set_far_max_datagram(p->udptl, ast_udptl_get_local_max_datagram(pvt->udptl));
16814    ast_udptl_set_local_max_datagram(p->udptl, ast_udptl_get_local_max_datagram(pvt->udptl));
16815    ast_udptl_set_error_correction_scheme(p->udptl, ast_udptl_get_error_correction_scheme(pvt->udptl));
16816    
16817    if (reinvite) {      /* If we are handling sending re-invite to the other side of the bridge */
16818       /*! \note The SIP_CAN_REINVITE flag is for RTP media redirects,
16819          not really T38 re-invites which are different. In this
16820          case it's used properly, to see if we can reinvite over
16821          NAT 
16822       */
16823       if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE) && ast_test_flag(&pvt->flags[0], SIP_CAN_REINVITE)) {
16824          ast_udptl_get_peer(pvt->udptl, &p->udptlredirip);
16825          flag =1;
16826       } else {
16827          memset(&p->udptlredirip, 0, sizeof(p->udptlredirip));
16828       }
16829       if (!ast_test_flag(&p->flags[0], SIP_GOTREFER)) {
16830          if (!p->pendinginvite) {
16831             if (option_debug > 2) {
16832                if (flag)
16833                   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));
16834                else
16835                   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));
16836             }
16837             transmit_reinvite_with_t38_sdp(p);
16838          } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) {
16839             if (option_debug > 2) {
16840                if (flag)
16841                   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));
16842                else
16843                   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));
16844             }
16845             ast_set_flag(&p->flags[0], SIP_NEEDREINVITE);
16846          }
16847       }
16848       /* Reset lastrtprx timer */
16849       p->lastrtprx = p->lastrtptx = time(NULL);
16850       ast_mutex_unlock(&p->lock);
16851       return 0;
16852    } else { /* If we are handling sending 200 OK to the other side of the bridge */
16853       if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE) && ast_test_flag(&pvt->flags[0], SIP_CAN_REINVITE)) {
16854          ast_udptl_get_peer(pvt->udptl, &p->udptlredirip);
16855          flag = 1;
16856       } else {
16857          memset(&p->udptlredirip, 0, sizeof(p->udptlredirip));
16858       }
16859       if (option_debug > 2) {
16860          if (flag)
16861             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));
16862          else
16863             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));
16864       }
16865       pvt->t38.state = T38_ENABLED;
16866       p->t38.state = T38_ENABLED;
16867       if (option_debug > 1) {
16868          ast_log(LOG_DEBUG, "T38 changed state to %d on channel %s\n", pvt->t38.state, pvt->owner ? pvt->owner->name : "<none>");
16869          ast_log(LOG_DEBUG, "T38 changed state to %d on channel %s\n", p->t38.state, chan ? chan->name : "<none>");
16870       }
16871       transmit_response_with_t38_sdp(p, "200 OK", &p->initreq, XMIT_CRITICAL);
16872       p->lastrtprx = p->lastrtptx = time(NULL);
16873       ast_mutex_unlock(&p->lock);
16874       return 0;
16875    }
16876 }

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

References __sip_pretend_ack(), ast_channel::_state, append_history, 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, LOG_WARNING, 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_PENDINGBYE, sip_scheddestroy(), sipdebug, ast_channel::tech_pvt, transmit_request(), transmit_request_with_auth(), transmit_response_reliable(), TRUE, update_call_counter(), sip_pvt::vad, and XMIT_RELIABLE.

03279 {
03280    struct sip_pvt *p = ast->tech_pvt;
03281    int needcancel = FALSE;
03282    int needdestroy = 0;
03283    struct ast_channel *oldowner = ast;
03284 
03285    if (!p) {
03286       if (option_debug)
03287          ast_log(LOG_DEBUG, "Asked to hangup channel that was not connected\n");
03288       return 0;
03289    }
03290 
03291    if (ast_test_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER)) {
03292       if (ast_test_flag(&p->flags[0], SIP_INC_COUNT)) {
03293          if (option_debug && sipdebug)
03294             ast_log(LOG_DEBUG, "update_call_counter(%s) - decrement call limit counter on hangup\n", p->username);
03295          update_call_counter(p, DEC_CALL_LIMIT);
03296       }
03297       if (option_debug >3)
03298          ast_log(LOG_DEBUG, "SIP Transfer: Not hanging up right now... Rescheduling hangup for %s.\n", p->callid);
03299       if (p->autokillid > -1)
03300          sip_cancel_destroy(p);
03301       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
03302       ast_clear_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Really hang up next time */
03303       ast_clear_flag(&p->flags[0], SIP_NEEDDESTROY);
03304       p->owner->tech_pvt = NULL;
03305       p->owner = NULL;  /* Owner will be gone after we return, so take it away */
03306       return 0;
03307    }
03308    if (option_debug) {
03309       if (ast_test_flag(ast, AST_FLAG_ZOMBIE) && p->refer && option_debug)
03310                ast_log(LOG_DEBUG, "SIP Transfer: Hanging up Zombie channel %s after transfer ... Call-ID: %s\n", ast->name, p->callid);
03311       else  {
03312          if (option_debug)
03313             ast_log(LOG_DEBUG, "Hangup call %s, SIP callid %s)\n", ast->name, p->callid);
03314       }
03315    }
03316    if (option_debug && ast_test_flag(ast, AST_FLAG_ZOMBIE)) 
03317       ast_log(LOG_DEBUG, "Hanging up zombie call. Be scared.\n");
03318 
03319    ast_mutex_lock(&p->lock);
03320    if (ast_test_flag(&p->flags[0], SIP_INC_COUNT)) {
03321       if (option_debug && sipdebug)
03322          ast_log(LOG_DEBUG, "update_call_counter(%s) - decrement call limit counter on hangup\n", p->username);
03323       update_call_counter(p, DEC_CALL_LIMIT);
03324    }
03325 
03326    /* Determine how to disconnect */
03327    if (p->owner != ast) {
03328       ast_log(LOG_WARNING, "Huh?  We aren't the owner? Can't hangup call.\n");
03329       ast_mutex_unlock(&p->lock);
03330       return 0;
03331    }
03332    /* If the call is not UP, we need to send CANCEL instead of BYE */
03333    if (ast->_state == AST_STATE_RING || ast->_state == AST_STATE_RINGING || (p->invitestate < INV_COMPLETED && ast->_state != AST_STATE_UP)) {
03334       needcancel = TRUE;
03335       if (option_debug > 3)
03336          ast_log(LOG_DEBUG, "Hanging up channel in state %s (not UP)\n", ast_state2str(ast->_state));
03337    }
03338 
03339    /* Disconnect */
03340    if (p->vad)
03341       ast_dsp_free(p->vad);
03342 
03343    p->owner = NULL;
03344    ast->tech_pvt = NULL;
03345 
03346    ast_module_unref(ast_module_info->self);
03347 
03348    /* Do not destroy this pvt until we have timeout or
03349       get an answer to the BYE or INVITE/CANCEL 
03350       If we get no answer during retransmit period, drop the call anyway.
03351       (Sorry, mother-in-law, you can't deny a hangup by sending
03352       603 declined to BYE...)
03353    */
03354    if (ast_test_flag(&p->flags[0], SIP_ALREADYGONE))
03355       needdestroy = 1;  /* Set destroy flag at end of this function */
03356    else if (p->invitestate != INV_CALLING)
03357       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
03358 
03359    /* Start the process if it's not already started */
03360    if (!ast_test_flag(&p->flags[0], SIP_ALREADYGONE) && !ast_strlen_zero(p->initreq.data)) {
03361       if (needcancel) { /* Outgoing call, not up */
03362          if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
03363             /* stop retransmitting an INVITE that has not received a response */
03364             __sip_pretend_ack(p);
03365 
03366             /* if we can't send right now, mark it pending */
03367             if (p->invitestate == INV_CALLING) {
03368                /* We can't send anything in CALLING state */
03369                ast_set_flag(&p->flags[0], SIP_PENDINGBYE);
03370                /* Do we need a timer here if we don't hear from them at all? */
03371             } else {
03372                /* Send a new request: CANCEL */
03373                transmit_request(p, SIP_CANCEL, p->ocseq, XMIT_RELIABLE, FALSE);
03374                /* Actually don't destroy us yet, wait for the 487 on our original 
03375                   INVITE, but do set an autodestruct just in case we never get it. */
03376                needdestroy = 0;
03377                sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
03378             }
03379             if ( p->initid != -1 ) {
03380                /* channel still up - reverse dec of inUse counter
03381                   only if the channel is not auto-congested */
03382                update_call_counter(p, INC_CALL_LIMIT);
03383             }
03384          } else { /* Incoming call, not up */
03385             const char *res;
03386             if (ast->hangupcause && (res = hangup_cause2sip(ast->hangupcause)))
03387                transmit_response_reliable(p, res, &p->initreq);
03388             else 
03389                transmit_response_reliable(p, "603 Declined", &p->initreq);
03390          }
03391       } else { /* Call is in UP state, send BYE */
03392          if (!p->pendinginvite) {
03393             char *audioqos = "";
03394             char *videoqos = "";
03395             if (p->rtp)
03396                audioqos = ast_rtp_get_quality(p->rtp, NULL);
03397             if (p->vrtp)
03398                videoqos = ast_rtp_get_quality(p->vrtp, NULL);
03399             /* Send a hangup */
03400             transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, 1);
03401 
03402             /* Get RTCP quality before end of call */
03403             if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) {
03404                if (p->rtp)
03405                   append_history(p, "RTCPaudio", "Quality:%s", audioqos);
03406                if (p->vrtp)
03407                   append_history(p, "RTCPvideo", "Quality:%s", videoqos);
03408             }
03409             if (p->rtp && oldowner)
03410                pbx_builtin_setvar_helper(oldowner, "RTPAUDIOQOS", audioqos);
03411             if (p->vrtp && oldowner)
03412                pbx_builtin_setvar_helper(oldowner, "RTPVIDEOQOS", videoqos);
03413          } else {
03414             /* Note we will need a BYE when this all settles out
03415                but we can't send one while we have "INVITE" outstanding. */
03416             ast_set_flag(&p->flags[0], SIP_PENDINGBYE);  
03417             ast_clear_flag(&p->flags[0], SIP_NEEDREINVITE); 
03418             sip_cancel_destroy(p);
03419          }
03420       }
03421    }
03422    if (needdestroy)
03423       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
03424    ast_mutex_unlock(&p->lock);
03425    return 0;
03426 }

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

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

03667 {
03668    struct sip_pvt *p = ast->tech_pvt;
03669    int res = 0;
03670 
03671    ast_mutex_lock(&p->lock);
03672    switch(condition) {
03673    case AST_CONTROL_RINGING:
03674       if (ast->_state == AST_STATE_RING) {
03675          p->invitestate = INV_EARLY_MEDIA;
03676          if (!ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) ||
03677              (ast_test_flag(&p->flags[0], SIP_PROG_INBAND) == SIP_PROG_INBAND_NEVER)) {            
03678             /* Send 180 ringing if out-of-band seems reasonable */
03679             transmit_response(p, "180 Ringing", &p->initreq);
03680             ast_set_flag(&p->flags[0], SIP_RINGING);
03681             if (ast_test_flag(&p->flags[0], SIP_PROG_INBAND) != SIP_PROG_INBAND_YES)
03682                break;
03683          } else {
03684             /* Well, if it's not reasonable, just send in-band */
03685          }
03686       }
03687       res = -1;
03688       break;
03689    case AST_CONTROL_BUSY:
03690       if (ast->_state != AST_STATE_UP) {
03691          transmit_response(p, "486 Busy Here", &p->initreq);
03692          p->invitestate = INV_COMPLETED;
03693          sip_alreadygone(p);
03694          ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV);
03695          break;
03696       }
03697       res = -1;
03698       break;
03699    case AST_CONTROL_CONGESTION:
03700       if (ast->_state != AST_STATE_UP) {
03701          transmit_response(p, "503 Service Unavailable", &p->initreq);
03702          p->invitestate = INV_COMPLETED;
03703          sip_alreadygone(p);
03704          ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV);
03705          break;
03706       }
03707       res = -1;
03708       break;
03709    case AST_CONTROL_PROCEEDING:
03710       if ((ast->_state != AST_STATE_UP) &&
03711           !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) &&
03712           !ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
03713          transmit_response(p, "100 Trying", &p->initreq);
03714          p->invitestate = INV_PROCEEDING;  
03715          break;
03716       }
03717       res = -1;
03718       break;
03719    case AST_CONTROL_PROGRESS:
03720       if ((ast->_state != AST_STATE_UP) &&
03721           !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) &&
03722           !ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
03723          p->invitestate = INV_EARLY_MEDIA;
03724          transmit_response_with_sdp(p, "183 Session Progress", &p->initreq, XMIT_UNRELIABLE);
03725          ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT);  
03726          break;
03727       }
03728       res = -1;
03729       break;
03730    case AST_CONTROL_HOLD:
03731       ast_moh_start(ast, data, p->mohinterpret);
03732       break;
03733    case AST_CONTROL_UNHOLD:
03734       ast_moh_stop(ast);
03735       break;
03736    case AST_CONTROL_VIDUPDATE:   /* Request a video frame update */
03737       if (p->vrtp && !ast_test_flag(&p->flags[0], SIP_NOVIDEO)) {
03738          transmit_info_with_vidupdate(p);
03739          /* ast_rtcp_send_h261fur(p->vrtp); */
03740       } else
03741          res = -1;
03742       break;
03743    case -1:
03744       res = -1;
03745       break;
03746    default:
03747       ast_log(LOG_WARNING, "Don't know how to indicate condition %d\n", condition);
03748       res = -1;
03749       break;
03750    }
03751    ast_mutex_unlock(&p->lock);
03752    return res;
03753 }

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

Display SIP nat mode.

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

01734 {
01735    return ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE ? "NAT" : "no NAT";
01736 }

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

References accountcode, ast_channel::adsicpe, ast_channel::amaflags, sip_pvt::amaflags, append_history, AST_ADSI_UNAVAILABLE, ast_best_codec(), AST_CAUSE_SWITCH_CONGESTION, ast_channel_alloc(), ast_codec_choose(), ast_dsp_digitmode(), ast_dsp_new(), ast_dsp_set_features(), AST_FORMAT_VIDEO_MASK, ast_getformatname_multiple(), ast_hangup(), ast_jb_configure(), ast_log(), ast_module_ref(), ast_mutex_lock(), ast_mutex_unlock(), ast_pbx_start(), ast_rtcp_fd(), ast_rtp_fd(), AST_STATE_DOWN, AST_STATE_RING, ast_strdup, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_udptl_fd(), sip_pvt::callgroup, ast_channel::callgroup, sip_pvt::callingpres, sip_pvt::capability, sip_pvt::chanvars, ast_channel::cid, ast_callerid::cid_ani, ast_callerid::cid_dnid, ast_callerid::cid_name, ast_callerid::cid_num, ast_callerid::cid_pres, ast_callerid::cid_rdnis, ast_channel::context, DSP_DIGITMODE_DTMF, DSP_DIGITMODE_RELAXDTMF, DSP_FEATURE_DTMF_DETECT, ast_channel::exten, ast_channel::fds, sip_pvt::flags, fmt, global_jbconf, ast_channel::hangupcause, sip_pvt::jointcapability, language, sip_pvt::lock, LOG_DEBUG, LOG_WARNING, ast_variable::name, ast_channel::nativeformats, ast_variable::next, option_debug, sip_pvt::owner, pbx_builtin_setvar_helper(), sip_pvt::pickupgroup, ast_channel::pickupgroup, sip_pvt::prefcodec, sip_pvt::prefs, ast_channel::priority, ast_channel::rawreadformat, ast_channel::rawwriteformat, ast_channel::readformat, ast_channel::rings, sip_pvt::rtp, SIP_DTMF, SIP_DTMF_INBAND, SIP_DTMF_INFO, SIP_NO_HISTORY, sip_tech, sip_tech_info, ast_channel::tech, ast_channel::tech_pvt, sip_pvt::udptl, sip_pvt::vad, ast_variable::value, sip_pvt::vrtp, and ast_channel::writeformat.

Referenced by handle_request_invite(), and sip_request_call().

03763 {
03764    struct ast_channel *tmp;
03765    struct ast_variable *v = NULL;
03766    int fmt;
03767    int what;
03768    int needvideo = 0;
03769    {
03770       const char *my_name;    /* pick a good name */
03771 
03772       if (title)
03773          my_name = title;
03774       else if ( (my_name = strchr(i->fromdomain,':')) )
03775          my_name++;      /* skip ':' */
03776       else
03777          my_name = i->fromdomain;
03778 
03779       ast_mutex_unlock(&i->lock);
03780       /* Don't hold a sip pvt lock while we allocate a channel */
03781       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);
03782 
03783    }
03784    if (!tmp) {
03785       ast_log(LOG_WARNING, "Unable to allocate AST channel structure for SIP channel\n");
03786       return NULL;
03787    }
03788    ast_mutex_lock(&i->lock);
03789 
03790    if (ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_INFO)
03791       tmp->tech = &sip_tech_info;
03792    else
03793       tmp->tech = &sip_tech;
03794 
03795    /* Select our native format based on codec preference until we receive
03796       something from another device to the contrary. */
03797    if (i->jointcapability)    /* The joint capabilities of us and peer */
03798       what = i->jointcapability;
03799    else if (i->capability)    /* Our configured capability for this peer */
03800       what = i->capability;
03801    else
03802       what = global_capability;  /* Global codec support */
03803 
03804    /* Set the native formats for audio  and merge in video */
03805    tmp->nativeformats = ast_codec_choose(&i->prefs, what, 1) | (i->jointcapability & AST_FORMAT_VIDEO_MASK);
03806    if (option_debug > 2) {
03807       char buf[BUFSIZ];
03808       ast_log(LOG_DEBUG, "*** Our native formats are %s \n", ast_getformatname_multiple(buf, BUFSIZ, tmp->nativeformats));
03809       ast_log(LOG_DEBUG, "*** Joint capabilities are %s \n", ast_getformatname_multiple(buf, BUFSIZ, i->jointcapability));
03810       ast_log(LOG_DEBUG, "*** Our capabilities are %s \n", ast_getformatname_multiple(buf, BUFSIZ, i->capability));
03811       ast_log(LOG_DEBUG, "*** AST_CODEC_CHOOSE formats are %s \n", ast_getformatname_multiple(buf, BUFSIZ, ast_codec_choose(&i->prefs, what, 1)));
03812       if (i->prefcodec)
03813          ast_log(LOG_DEBUG, "*** Our preferred formats from the incoming channel are %s \n", ast_getformatname_multiple(buf, BUFSIZ, i->prefcodec));
03814    }
03815 
03816    /* XXX Why are we choosing a codec from the native formats?? */
03817    fmt = ast_best_codec(tmp->nativeformats);
03818 
03819    /* If we have a prefcodec setting, we have an inbound channel that set a 
03820       preferred format for this call. Otherwise, we check the jointcapability
03821       We also check for vrtp. If it's not there, we are not allowed do any video anyway.
03822     */
03823    if (i->vrtp) {
03824       if (i->prefcodec)
03825          needvideo = i->prefcodec & AST_FORMAT_VIDEO_MASK;  /* Outbound call */
03826       else
03827          needvideo = i->jointcapability & AST_FORMAT_VIDEO_MASK;  /* Inbound call */
03828    }
03829 
03830    if (option_debug > 2) {
03831       if (needvideo) 
03832          ast_log(LOG_DEBUG, "This channel can handle video! HOLLYWOOD next!\n");
03833       else
03834          ast_log(LOG_DEBUG, "This channel will not be able to handle video.\n");
03835    }
03836 
03837 
03838 
03839    if (ast_test_flag(&i->flags[0], SIP_DTMF) ==  SIP_DTMF_INBAND) {
03840       i->vad = ast_dsp_new();
03841       ast_dsp_set_features(i->vad, DSP_FEATURE_DTMF_DETECT);
03842       if (global_relaxdtmf)
03843          ast_dsp_digitmode(i->vad, DSP_DIGITMODE_DTMF | DSP_DIGITMODE_RELAXDTMF);
03844    }
03845    if (i->rtp) {
03846       tmp->fds[0] = ast_rtp_fd(i->rtp);
03847       tmp->fds[1] = ast_rtcp_fd(i->rtp);
03848    }
03849    if (needvideo && i->vrtp) {
03850       tmp->fds[2] = ast_rtp_fd(i->vrtp);
03851       tmp->fds[3] = ast_rtcp_fd(i->vrtp);
03852    }
03853    if (i->udptl) {
03854       tmp->fds[5] = ast_udptl_fd(i->udptl);
03855    }
03856    if (state == AST_STATE_RING)
03857       tmp->rings = 1;
03858    tmp->adsicpe = AST_ADSI_UNAVAILABLE;
03859    tmp->writeformat = fmt;
03860    tmp->rawwriteformat = fmt;
03861    tmp->readformat = fmt;
03862    tmp->rawreadformat = fmt;
03863    tmp->tech_pvt = i;
03864 
03865    tmp->callgroup = i->callgroup;
03866    tmp->pickupgroup = i->pickupgroup;
03867    tmp->cid.cid_pres = i->callingpres;
03868    if (!ast_strlen_zero(i->accountcode))
03869       ast_string_field_set(tmp, accountcode, i->accountcode);
03870    if (i->amaflags)
03871       tmp->amaflags = i->amaflags;
03872    if (!ast_strlen_zero(i->language))
03873       ast_string_field_set(tmp, language, i->language);
03874    i->owner = tmp;
03875    ast_module_ref(ast_module_info->self);
03876    ast_copy_string(tmp->context, i->context, sizeof(tmp->context));
03877    ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten));
03878 
03879 
03880    /* Don't use ast_set_callerid() here because it will
03881     * generate an unnecessary NewCallerID event  */
03882    tmp->cid.cid_num = ast_strdup(i->cid_num);
03883    tmp->cid.cid_ani = ast_strdup(i->cid_num);
03884    tmp->cid.cid_name = ast_strdup(i->cid_name);
03885    if (!ast_strlen_zero(i->rdnis))
03886       tmp->cid.cid_rdnis = ast_strdup(i->rdnis);
03887    
03888    if (!ast_strlen_zero(i->exten) && strcmp(i->exten, "s"))
03889       tmp->cid.cid_dnid = ast_strdup(i->exten);
03890 
03891    tmp->priority = 1;
03892    if (!ast_strlen_zero(i->uri))
03893       pbx_builtin_setvar_helper(tmp, "SIPURI", i->uri);
03894    if (!ast_strlen_zero(i->domain))
03895       pbx_builtin_setvar_helper(tmp, "SIPDOMAIN", i->domain);
03896    if (!ast_strlen_zero(i->useragent))
03897       pbx_builtin_setvar_helper(tmp, "SIPUSERAGENT", i->useragent);
03898    if (!ast_strlen_zero(i->callid))
03899       pbx_builtin_setvar_helper(tmp, "SIPCALLID", i->callid);
03900    if (i->rtp)
03901       ast_jb_configure(tmp, &global_jbconf);
03902    if (state != AST_STATE_DOWN && ast_pbx_start(tmp)) {
03903       ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
03904       tmp->hangupcause = AST_CAUSE_SWITCH_CONGESTION;
03905       ast_hangup(tmp);
03906       tmp = NULL;
03907    }
03908    /* Set channel variables for this call from configuration */
03909    for (v = i->chanvars ; v ; v = v->next)
03910       pbx_builtin_setvar_helper(tmp,v->name,v->value);
03911 
03912    if (!ast_test_flag(&i->flags[0], SIP_NO_HISTORY))
03913       append_history(i, "NewChan", "Channel %s - from %s", tmp->name, i->callid);
03914 
03915    return tmp;
03916 }

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

Disable SIP Debugging in CLI.

Definition at line 11026 of file chan_sip.c.

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

11027 {
11028    if (argc != 4)
11029       return RESULT_SHOWUSAGE;
11030    ast_clear_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE);
11031    ast_cli(fd, "SIP Debugging Disabled\n");
11032    return RESULT_SUCCESS;
11033 }

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

Definition at line 11035 of file chan_sip.c.

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

11036 {
11037    if (argc != 3)
11038       return RESULT_SHOWUSAGE;
11039    ast_clear_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE);
11040    ast_cli(fd, "SIP Debugging Disabled\n");
11041    return RESULT_SUCCESS;
11042 }

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

Disable SIP History logging (CLI).

Definition at line 11056 of file chan_sip.c.

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

11057 {
11058    if (argc != 3) {
11059       return RESULT_SHOWUSAGE;
11060    }
11061    recordhistory = FALSE;
11062    ast_cli(fd, "SIP History Recording Disabled\n");
11063    return RESULT_SUCCESS;
11064 }

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

Cli command to send SIP notify to peer.

Definition at line 10970 of file chan_sip.c.

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

10971 {
10972    struct ast_variable *varlist;
10973    int i;
10974 
10975    if (argc < 4)
10976       return RESULT_SHOWUSAGE;
10977 
10978    if (!notify_types) {
10979       ast_cli(fd, "No %s file found, or no types listed there\n", notify_config);
10980       return RESULT_FAILURE;
10981    }
10982 
10983    varlist = ast_variable_browse(notify_types, argv[2]);
10984 
10985    if (!varlist) {
10986       ast_cli(fd, "Unable to find notify type '%s'\n", argv[2]);
10987       return RESULT_FAILURE;
10988    }
10989 
10990    for (i = 3; i < argc; i++) {
10991       struct sip_pvt *p;
10992       struct sip_request req;
10993       struct ast_variable *var;
10994 
10995       if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY))) {
10996          ast_log(LOG_WARNING, "Unable to build sip pvt data for notify (memory/socket error)\n");
10997          return RESULT_FAILURE;
10998       }
10999 
11000       if (create_addr(p, argv[i])) {
11001          /* Maybe they're not registered, etc. */
11002          sip_destroy(p);
11003          ast_cli(fd, "Could not create address for '%s'\n", argv[i]);
11004          continue;
11005       }
11006 
11007       initreqprep(&req, p, SIP_NOTIFY);
11008 
11009       for (var = varlist; var; var = var->next)
11010          add_header(&req, var->name, var->value);
11011 
11012       /* Recalculate our side, and recalculate Call ID */
11013       if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
11014          p->ourip = __ourip;
11015       build_via(p);
11016       build_callid_pvt(p);
11017       ast_cli(fd, "Sending NOTIFY of type '%s' to '%s'\n", argv[2], argv[i]);
11018       transmit_sip_request(p, &req);
11019       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
11020    }
11021 
11022    return RESULT_SUCCESS;
11023 }

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 12652 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, LOG_WARNING, option_debug, ast_channel::priority, ast_channel::readformat, sip_park_thread(), and ast_channel::writeformat.

Referenced by handle_request_refer().

12653 {
12654    struct sip_dual *d;
12655    struct ast_channel *transferee, *transferer;
12656       /* Chan2m: The transferer, chan1m: The transferee */
12657    pthread_t th;
12658 
12659    transferee = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan1->accountcode, chan1->exten, chan1->context, chan1->amaflags, "Parking/%s", chan1->name);
12660    transferer = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->amaflags, "SIPPeer/%s", chan2->name);
12661    if ((!transferer) || (!transferee)) {
12662       if (transferee) {
12663          transferee->hangupcause = AST_CAUSE_SWITCH_CONGESTION;
12664          ast_hangup(transferee);
12665       }
12666       if (transferer) {
12667          transferer->hangupcause = AST_CAUSE_SWITCH_CONGESTION;
12668          ast_hangup(transferer);
12669       }
12670       return -1;
12671    }
12672 
12673    /* Make formats okay */
12674    transferee->readformat = chan1->readformat;
12675    transferee->writeformat = chan1->writeformat;
12676 
12677    /* Prepare for taking over the channel */
12678    ast_channel_masquerade(transferee, chan1);
12679 
12680    /* Setup the extensions and such */
12681    ast_copy_string(transferee->context, chan1->context, sizeof(transferee->context));
12682    ast_copy_string(transferee->exten, chan1->exten, sizeof(transferee->exten));
12683    transferee->priority = chan1->priority;
12684       
12685    /* We make a clone of the peer channel too, so we can play
12686       back the announcement */
12687 
12688    /* Make formats okay */
12689    transferer->readformat = chan2->readformat;
12690    transferer->writeformat = chan2->writeformat;
12691 
12692    /* Prepare for taking over the channel */
12693    ast_channel_masquerade(transferer, chan2);
12694 
12695    /* Setup the extensions and such */
12696    ast_copy_string(transferer->context, chan2->context, sizeof(transferer->context));
12697    ast_copy_string(transferer->exten, chan2->exten, sizeof(transferer->exten));
12698    transferer->priority = chan2->priority;
12699 
12700    ast_channel_lock(transferer);
12701    if (ast_do_masquerade(transferer)) {
12702       ast_log(LOG_WARNING, "Masquerade failed :(\n");
12703       ast_channel_unlock(transferer);
12704       transferer->hangupcause = AST_CAUSE_SWITCH_CONGESTION;
12705       ast_hangup(transferer);
12706       return -1;
12707    }
12708    ast_channel_unlock(transferer);
12709    if (!transferer || !transferee) {
12710       if (!transferer) { 
12711          if (option_debug)
12712             ast_log(LOG_DEBUG, "No transferer channel, giving up parking\n");
12713       }
12714       if (!transferee) {
12715          if (option_debug)
12716             ast_log(LOG_DEBUG, "No transferee channel, giving up parking\n");
12717       }
12718       return -1;
12719    }
12720    if ((d = ast_calloc(1, sizeof(*d)))) {
12721       pthread_attr_t attr;
12722 
12723       pthread_attr_init(&attr);
12724       pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);   
12725 
12726       /* Save original request for followup */
12727       copy_request(&d->req, req);
12728       d->chan1 = transferee;  /* Transferee */
12729       d->chan2 = transferer;  /* Transferer */
12730       d->seqno = seqno;
12731       if (ast_pthread_create_background(&th, &attr, sip_park_thread, d) < 0) {
12732          /* Could not start thread */
12733          free(d); /* We don't need it anymore. If thread is created, d will be free'd
12734                   by sip_park_thread() */
12735          pthread_attr_destroy(&attr);
12736          return 0;
12737       }
12738       pthread_attr_destroy(&attr);
12739    } 
12740    return -1;
12741 }

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

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

Referenced by sip_park().

12586 {
12587    struct ast_channel *transferee, *transferer; /* Chan1: The transferee, Chan2: The transferer */
12588    struct sip_dual *d;
12589    struct sip_request req;
12590    int ext;
12591    int res;
12592 
12593    d = stuff;
12594    transferee = d->chan1;
12595    transferer = d->chan2;
12596    copy_request(&req, &d->req);
12597    free(d);
12598 
12599    if (!transferee || !transferer) {
12600       ast_log(LOG_ERROR, "Missing channels for parking! Transferer %s Transferee %s\n", transferer ? "<available>" : "<missing>", transferee ? "<available>" : "<missing>" );
12601       return NULL;
12602    }
12603    if (option_debug > 3) 
12604       ast_log(LOG_DEBUG, "SIP Park: Transferer channel %s, Transferee %s\n", transferer->name, transferee->name);
12605 
12606    ast_channel_lock(transferee);
12607    if (ast_do_masquerade(transferee)) {
12608       ast_log(LOG_WARNING, "Masquerade failed.\n");
12609       transmit_response(transferer->tech_pvt, "503 Internal error", &req);
12610       ast_channel_unlock(transferee);
12611       return NULL;
12612    } 
12613    ast_channel_unlock(transferee);
12614 
12615    res = ast_park_call(transferee, transferer, 0, &ext);
12616    
12617 
12618 #ifdef WHEN_WE_KNOW_THAT_THE_CLIENT_SUPPORTS_MESSAGE
12619    if (!res) {
12620       transmit_message_with_text(transferer->tech_pvt, "Unable to park call.\n");
12621    } else {
12622       /* Then tell the transferer what happened */
12623       sprintf(buf, "Call parked on extension '%d'", ext);
12624       transmit_message_with_text(transferer->tech_pvt, buf);
12625    }
12626 #endif
12627 
12628    /* Any way back to the current call??? */
12629    /* Transmit response to the REFER request */
12630    transmit_response(transferer->tech_pvt, "202 Accepted", &req);
12631    if (!res)   {
12632       /* Transfer succeeded */
12633       append_history(transferer->tech_pvt, "SIPpark","Parked call on %d", ext);
12634       transmit_notify_with_sipfrag(transferer->tech_pvt, d->seqno, "200 OK", TRUE);
12635       transferer->hangupcause = AST_CAUSE_NORMAL_CLEARING;
12636       ast_hangup(transferer); /* This will cause a BYE */
12637       if (option_debug)
12638          ast_log(LOG_DEBUG, "SIP Call parked on extension '%d'\n", ext);
12639    } else {
12640       transmit_notify_with_sipfrag(transferer->tech_pvt, d->seqno, "503 Service Unavailable", TRUE);
12641       append_history(transferer->tech_pvt, "SIPpark","Parking failed\n");
12642       if (option_debug)
12643          ast_log(LOG_DEBUG, "SIP Call parked failed \n");
12644       /* Do not hangup call */
12645    }
12646    return NULL;
12647 }

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

References ast_device_state_changed(), find_peer(), and sip_peer::onHold.

Referenced by process_sdp(), and update_call_counter().

08204 {
08205    struct sip_peer *peer = find_peer(p->peername, NULL, 1);
08206 
08207    if (!peer)
08208       return;
08209 
08210    /* If they put someone on hold, increment the value... otherwise decrement it */
08211    if (hold)
08212       peer->onHold++;
08213    else
08214       peer->onHold--;
08215 
08216    /* Request device state update */
08217    ast_device_state_changed("SIP/%s", peer->name);
08218 
08219    return;
08220 }

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

17176 {
17177    int ms = 0;
17178    
17179    if (!speerobjs)   /* No peers, just give up */
17180       return;
17181 
17182    ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do {
17183       ASTOBJ_WRLOCK(iterator);
17184       if (iterator->pokeexpire > -1)
17185          ast_sched_del(sched, iterator->pokeexpire);
17186       ms += 100;
17187       iterator->pokeexpire = ast_sched_add(sched, ms, sip_poke_peer_s, iterator);
17188       ASTOBJ_UNLOCK(iterator);
17189    } while (0)
17190    );
17191 }

static int sip_poke_noanswer ( void *  data  )  [static]

React to lack of answer to Qualify poke.

Definition at line 15207 of file chan_sip.c.

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

Referenced by sip_poke_peer().

15208 {
15209    struct sip_peer *peer = data;
15210    
15211    peer->pokeexpire = -1;
15212    if (peer->lastms > -1) {
15213       ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE!  Last qualify: %d\n", peer->name, peer->lastms);
15214       manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, -1);
15215    }
15216    if (peer->call)
15217       sip_destroy(peer->call);
15218    peer->call = NULL;
15219    peer->lastms = -1;
15220    ast_device_state_changed("SIP/%s", peer->name);
15221    /* Try again quickly */
15222    peer->pokeexpire = ast_sched_add(sched, DEFAULT_FREQ_NOTOK, sip_poke_peer_s, peer);
15223    return 0;
15224 }

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 15229 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, and transmit_invite().

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

15230 {
15231    struct sip_pvt *p;
15232 
15233    if (!peer->maxms || !peer->addr.sin_addr.s_addr) {
15234       /* IF we have no IP, or this isn't to be monitored, return
15235         imeediately after clearing things out */
15236       if (peer->pokeexpire > -1)
15237          ast_sched_del(sched, peer->pokeexpire);
15238       peer->lastms = 0;
15239       peer->pokeexpire = -1;
15240       peer->call = NULL;
15241       return 0;
15242    }
15243    if (peer->call) {
15244       if (sipdebug)
15245          ast_log(LOG_NOTICE, "Still have a QUALIFY dialog active, deleting\n");
15246       sip_destroy(peer->call);
15247    }
15248    if (!(p = peer->call = sip_alloc(NULL, NULL, 0, SIP_OPTIONS)))
15249       return -1;
15250    
15251    p->sa = peer->addr;
15252    p->recv = peer->addr;
15253    ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY);
15254    ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY);
15255 
15256    /* Send OPTIONs to peer's fullcontact */
15257    if (!ast_strlen_zero(peer->fullcontact))
15258       ast_string_field_set(p, fullcontact, peer->fullcontact);
15259 
15260    if (!ast_strlen_zero(peer->tohost))
15261       ast_string_field_set(p, tohost, peer->tohost);
15262    else
15263       ast_string_field_set(p, tohost, ast_inet_ntoa(peer->addr.sin_addr));
15264 
15265    /* Recalculate our side, and recalculate Call ID */
15266    if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
15267       p->ourip = __ourip;
15268    build_via(p);
15269    build_callid_pvt(p);
15270 
15271    if (peer->pokeexpire > -1)
15272       ast_sched_del(sched, peer->pokeexpire);
15273    p->relatedpeer = peer;
15274    ast_set_flag(&p->flags[0], SIP_OUTGOING);
15275 #ifdef VOCAL_DATA_HACK
15276    ast_copy_string(p->username, "__VOCAL_DATA_SHOULD_READ_THE_SIP_SPEC__", sizeof(p->username));
15277    transmit_invite(p, SIP_INVITE, 0, 2);
15278 #else
15279    transmit_invite(p, SIP_OPTIONS, 0, 2);
15280 #endif
15281    gettimeofday(&peer->ps, NULL);
15282    peer->pokeexpire = ast_sched_add(sched, DEFAULT_MAXMS * 2, sip_poke_noanswer, peer);
15283 
15284    return 0;
15285 }

static int sip_poke_peer_s ( void *  data  )  [static]

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

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

07608 {
07609    struct sip_peer *peer = data;
07610 
07611    peer->pokeexpire = -1;
07612    sip_poke_peer(peer);
07613    return 0;
07614 }

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

Remove temporary realtime objects from memory (CLI).

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

09764 {
09765    struct sip_peer *peer;
09766    struct sip_user *user;
09767    int pruneuser = FALSE;
09768    int prunepeer = FALSE;
09769    int multi = FALSE;
09770    char *name = NULL;
09771    regex_t regexbuf;
09772 
09773    switch (argc) {
09774    case 4:
09775       if (!strcasecmp(argv[3], "user"))
09776          return RESULT_SHOWUSAGE;
09777       if (!strcasecmp(argv[3], "peer"))
09778          return RESULT_SHOWUSAGE;
09779       if (!strcasecmp(argv[3], "like"))
09780          return RESULT_SHOWUSAGE;
09781       if (!strcasecmp(argv[3], "all")) {
09782          multi = TRUE;
09783          pruneuser = prunepeer = TRUE;
09784       } else {
09785          pruneuser = prunepeer = TRUE;
09786          name = argv[3];
09787       }
09788       break;
09789    case 5:
09790       if (!strcasecmp(argv[4], "like"))
09791          return RESULT_SHOWUSAGE;
09792       if (!strcasecmp(argv[3], "all"))
09793          return RESULT_SHOWUSAGE;
09794       if (!strcasecmp(argv[3], "like")) {
09795          multi = TRUE;
09796          name = argv[4];
09797          pruneuser = prunepeer = TRUE;
09798       } else if (!strcasecmp(argv[3], "user")) {
09799          pruneuser = TRUE;
09800          if (!strcasecmp(argv[4], "all"))
09801             multi = TRUE;
09802          else
09803             name = argv[4];
09804       } else if (!strcasecmp(argv[3], "peer")) {
09805          prunepeer = TRUE;
09806          if (!strcasecmp(argv[4], "all"))
09807             multi = TRUE;
09808          else
09809             name = argv[4];
09810       } else
09811          return RESULT_SHOWUSAGE;
09812       break;
09813    case 6:
09814       if (strcasecmp(argv[4], "like"))
09815          return RESULT_SHOWUSAGE;
09816       if (!strcasecmp(argv[3], "user")) {
09817          pruneuser = TRUE;
09818          name = argv[5];
09819       } else if (!strcasecmp(argv[3], "peer")) {
09820          prunepeer = TRUE;
09821          name = argv[5];
09822       } else
09823          return RESULT_SHOWUSAGE;
09824       break;
09825    default:
09826       return RESULT_SHOWUSAGE;
09827    }
09828 
09829    if (multi && name) {
09830       if (regcomp(&regexbuf, name, REG_EXTENDED | REG_NOSUB))
09831          return RESULT_SHOWUSAGE;
09832    }
09833 
09834    if (multi) {
09835       if (prunepeer) {
09836          int pruned = 0;
09837 
09838          ASTOBJ_CONTAINER_WRLOCK(&peerl);
09839          ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do {
09840             ASTOBJ_RDLOCK(iterator);
09841             if (name && regexec(&regexbuf, iterator->name, 0, NULL, 0)) {
09842                ASTOBJ_UNLOCK(iterator);
09843                continue;
09844             };
09845             if (ast_test_flag(&iterator->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) {
09846                ASTOBJ_MARK(iterator);
09847                pruned++;
09848             }
09849             ASTOBJ_UNLOCK(iterator);
09850          } while (0) );
09851          if (pruned) {
09852             ASTOBJ_CONTAINER_PRUNE_MARKED(&peerl, sip_destroy_peer);
09853             ast_cli(fd, "%d peers pruned.\n", pruned);
09854          } else
09855             ast_cli(fd, "No peers found to prune.\n");
09856          ASTOBJ_CONTAINER_UNLOCK(&peerl);
09857       }
09858       if (pruneuser) {
09859          int pruned = 0;
09860 
09861          ASTOBJ_CONTAINER_WRLOCK(&userl);
09862          ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do {
09863             ASTOBJ_RDLOCK(iterator);
09864             if (name && regexec(&regexbuf, iterator->name, 0, NULL, 0)) {
09865                ASTOBJ_UNLOCK(iterator);
09866                continue;
09867             };
09868             if (ast_test_flag(&iterator->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) {
09869                ASTOBJ_MARK(iterator);
09870                pruned++;
09871             }
09872             ASTOBJ_UNLOCK(iterator);
09873          } while (0) );
09874          if (pruned) {
09875             ASTOBJ_CONTAINER_PRUNE_MARKED(&userl, sip_destroy_user);
09876             ast_cli(fd, "%d users pruned.\n", pruned);
09877          } else
09878             ast_cli(fd, "No users found to prune.\n");
09879          ASTOBJ_CONTAINER_UNLOCK(&userl);
09880       }
09881    } else {
09882       if (prunepeer) {
09883          if ((peer = ASTOBJ_CONTAINER_FIND_UNLINK(&peerl, name))) {
09884             if (!ast_test_flag(&peer->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) {
09885                ast_cli(fd, "Peer '%s' is not a Realtime peer, cannot be pruned.\n", name);
09886                ASTOBJ_CONTAINER_LINK(&peerl, peer);
09887             } else
09888                ast_cli(fd, "Peer '%s' pruned.\n", name);
09889             ASTOBJ_UNREF(peer, sip_destroy_peer);
09890          } else
09891             ast_cli(fd, "Peer '%s' not found.\n", name);
09892       }
09893       if (pruneuser) {
09894          if ((user = ASTOBJ_CONTAINER_FIND_UNLINK(&userl, name))) {
09895             if (!ast_test_flag(&user->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) {
09896                ast_cli(fd, "User '%s' is not a Realtime user, cannot be pruned.\n", name);
09897                ASTOBJ_CONTAINER_LINK(&userl, user);
09898             } else
09899                ast_cli(fd, "User '%s' pruned.\n", name);
09900             ASTOBJ_UNREF(user, sip_destroy_user);
09901          } else
09902             ast_cli(fd, "User '%s' not found.\n", name);
09903       }
09904    }
09905 
09906    return RESULT_SUCCESS;
09907 }

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

Read SIP RTP from channel.

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

04120 {
04121    struct ast_frame *fr;
04122    struct sip_pvt *p;
04123    
04124    if( ast == NULL )
04125        return NULL;
04126    
04127    p = ast->tech_pvt;
04128    int faxdetected = FALSE;
04129 
04130    if( p == NULL )
04131        return NULL;  
04132 
04133    ast_mutex_lock(&p->lock);
04134    fr = sip_rtp_read(ast, p, &faxdetected);
04135    p->lastrtprx = time(NULL);
04136 
04137    /* If we are NOT bridged to another channel, and we have detected fax tone we issue T38 re-invite to a peer */
04138    /* 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 */
04139    if (faxdetected && ast_test_flag(&p->t38.t38support, SIP_PAGE2_T38SUPPORT_UDPTL) && (p->t38.state == T38_DISABLED) && !(ast_bridged_channel(ast))) {
04140       if (!ast_test_flag(&p->flags[0], SIP_GOTREFER)) {
04141          if (!p->pendinginvite) {
04142             if (option_debug > 2)
04143                ast_log(LOG_DEBUG, "Sending reinvite on SIP (%s) for T.38 negotiation.\n",ast->name);
04144             p->t38.state = T38_LOCAL_REINVITE;
04145             transmit_reinvite_with_t38_sdp(p);
04146             if (option_debug > 1)
04147                ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, ast->name);
04148          }
04149       } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) {
04150          if (option_debug > 2)
04151             ast_log(LOG_DEBUG, "Deferring reinvite on SIP (%s) - it will be re-negotiated for T.38\n", ast->name);
04152          ast_set_flag(&p->flags[0], SIP_NEEDREINVITE);
04153       }
04154    }
04155 
04156    ast_mutex_unlock(&p->lock);
04157    return fr;
04158 }

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

The real destination address for a write.

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

01728 {
01729    return ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE ? &p->recv : &p->sa;
01730 }

static int sip_refer_allocate ( struct sip_pvt p  )  [static]

Allocate SIP refer structure.

Definition at line 7418 of file chan_sip.c.

References ast_calloc, and sip_pvt::refer.

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

07419 {
07420    p->refer = ast_calloc(1, sizeof(struct sip_refer)); 
07421    return p->refer ? 1 : 0;
07422 }

static int sip_reg_timeout ( void *  data  )  [static]

Registration timeout, register again.

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

07176 {
07177 
07178    /* if we are here, our registration timed out, so we'll just do it over */
07179    struct sip_registry *r = ASTOBJ_REF((struct sip_registry *) data);
07180    struct sip_pvt *p;
07181    int res;
07182 
07183    /* if we couldn't get a reference to the registry object, punt */
07184    if (!r)
07185       return 0;
07186 
07187    ast_log(LOG_NOTICE, "   -- Registration for '%s@%s' timed out, trying again (Attempt #%d)\n", r->username, r->hostname, r->regattempts); 
07188    if (r->call) {
07189       /* Unlink us, destroy old call.  Locking is not relevant here because all this happens
07190          in the single SIP manager thread. */
07191       p = r->call;
07192       if (p->registry)
07193          ASTOBJ_UNREF(p->registry, sip_registry_destroy);
07194       r->call = NULL;
07195       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
07196       /* Pretend to ACK anything just in case */
07197       __sip_pretend_ack(p); /* XXX we need p locked, not sure we have */
07198    }
07199    /* If we have a limit, stop registration and give up */
07200    if (global_regattempts_max && (r->regattempts > global_regattempts_max)) {
07201       /* Ok, enough is enough. Don't try any more */
07202       /* We could add an external notification here... 
07203          steal it from app_voicemail :-) */
07204       ast_log(LOG_NOTICE, "   -- Giving up forever trying to register '%s@%s'\n", r->username, r->hostname);
07205       r->regstate = REG_STATE_FAILED;
07206    } else {
07207       r->regstate = REG_STATE_UNREGISTERED;
07208       r->timeout = -1;
07209       res=transmit_register(r, SIP_REGISTER, NULL, NULL);
07210    }
07211    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));
07212    ASTOBJ_UNREF(r, sip_registry_destroy);
07213    return 0;
07214 }

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

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

Definition at line 4446 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, LOG_WARNING, regl, secret, sip_registry_destroy(), and username.

04447 {
04448    struct sip_registry *reg;
04449    int portnum = 0;
04450    char username[256] = "";
04451    char *hostname=NULL, *secret=NULL, *authuser=NULL;
04452    char *porta=NULL;
04453    char *contact=NULL;
04454 
04455    if (!value)
04456       return -1;
04457    ast_copy_string(username, value, sizeof(username));
04458    /* First split around the last '@' then parse the two components. */
04459    hostname = strrchr(username, '@'); /* allow @ in the first part */
04460    if (hostname)
04461       *hostname++ = '\0';
04462    if (ast_strlen_zero(username) || ast_strlen_zero(hostname)) {
04463       ast_log(LOG_WARNING, "Format for registration is user[:secret[:authuser]]@host[:port][/contact] at line %d\n", lineno);
04464       return -1;
04465    }
04466    /* split user[:secret[:authuser]] */
04467    secret = strchr(username, ':');
04468    if (secret) {
04469       *secret++ = '\0';
04470       authuser = strchr(secret, ':');
04471       if (authuser)
04472          *authuser++ = '\0';
04473    }
04474    /* split host[:port][/contact] */
04475    contact = strchr(hostname, '/');
04476    if (contact)
04477       *contact++ = '\0';
04478    if (ast_strlen_zero(contact))
04479       contact = "s";
04480    porta = strchr(hostname, ':');
04481    if (porta) {
04482       *porta++ = '\0';
04483       portnum = atoi(porta);
04484       if (portnum == 0) {
04485          ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno);
04486          return -1;
04487       }
04488    }
04489    if (!(reg = ast_calloc(1, sizeof(*reg)))) {
04490       ast_log(LOG_ERROR, "Out of memory. Can't allocate SIP registry entry\n");
04491       return -1;
04492    }
04493 
04494    if (ast_string_field_init(reg, 256)) {
04495       ast_log(LOG_ERROR, "Out of memory. Can't allocate SIP registry strings\n");
04496       free(reg);
04497       return -1;
04498    }
04499 
04500    regobjs++;
04501    ASTOBJ_INIT(reg);
04502    ast_string_field_set(reg, contact, contact);
04503    if (username)
04504       ast_string_field_set(reg, username, username);
04505    if (hostname)
04506       ast_string_field_set(reg, hostname, hostname);
04507    if (authuser)
04508       ast_string_field_set(reg, authuser, authuser);
04509    if (secret)
04510       ast_string_field_set(reg, secret, secret);
04511    reg->expire = -1;
04512    reg->timeout =  -1;
04513    reg->refresh = default_expiry;
04514    reg->portno = portnum;
04515    reg->callid_valid = FALSE;
04516    reg->ocseq = INITIAL_CSEQ;
04517    ASTOBJ_CONTAINER_LINK(&regl, reg);  /* Add the new registry entry to the list */
04518    ASTOBJ_UNREF(reg,sip_registry_destroy);
04519    return 0;
04520 }

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

02860 {
02861    /* Really delete */
02862    if (option_debug > 2)
02863       ast_log(LOG_DEBUG, "Destroying registry entry for %s@%s\n", reg->username, reg->hostname);
02864 
02865    if (reg->call) {
02866       /* Clear registry before destroying to ensure
02867          we don't get reentered trying to grab the registry lock */
02868       reg->call->registry = NULL;
02869       if (option_debug > 2)
02870          ast_log(LOG_DEBUG, "Destroying active SIP dialog for registry %s@%s\n", reg->username, reg->hostname);
02871       sip_destroy(reg->call);
02872    }
02873    if (reg->expire > -1)
02874       ast_sched_del(sched, reg->expire);
02875    if (reg->timeout > -1)
02876       ast_sched_del(sched, reg->timeout);
02877    ast_string_field_free_pools(reg);
02878    regobjs--;
02879    free(reg);
02880    
02881 }

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

Force reload of module from cli.

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

17268 {
17269    ast_mutex_lock(&sip_reload_lock);
17270    if (sip_reloading) 
17271       ast_verbose("Previous SIP reload not yet done\n");
17272    else {
17273       sip_reloading = TRUE;
17274       if (fd)
17275          sip_reloadreason = CHANNEL_CLI_RELOAD;
17276       else
17277          sip_reloadreason = CHANNEL_MODULE_RELOAD;
17278    }
17279    ast_mutex_unlock(&sip_reload_lock);
17280    restart_monitor();
17281 
17282    return 0;
17283 }

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

15388 {
15389    int oldformat;
15390    struct sip_pvt *p;
15391    struct ast_channel *tmpc = NULL;
15392    char *ext, *host;
15393    char tmp[256];
15394    char *dest = data;
15395 
15396    oldformat = format;
15397    if (!(format &= ((AST_FORMAT_MAX_AUDIO << 1) - 1))) {
15398       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));
15399       *cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;   /* Can't find codec to connect to host */
15400       return NULL;
15401    }
15402    if (option_debug)
15403       ast_log(LOG_DEBUG, "Asked to create a SIP channel with formats: %s\n", ast_getformatname_multiple(tmp, sizeof(tmp), oldformat));
15404 
15405    if (!(p = sip_alloc(NULL, NULL, 0, SIP_INVITE))) {
15406       ast_log(LOG_ERROR, "Unable to build sip pvt data for '%s' (Out of memory or socket error)\n", (char *)data);
15407       *cause = AST_CAUSE_SWITCH_CONGESTION;
15408       return NULL;
15409    }
15410 
15411    ast_set_flag(&p->flags[1], SIP_PAGE2_OUTGOING_CALL);
15412 
15413    if (!(p->options = ast_calloc(1, sizeof(*p->options)))) {
15414       sip_destroy(p);
15415       ast_log(LOG_ERROR, "Unable to build option SIP data structure - Out of memory\n");
15416       *cause = AST_CAUSE_SWITCH_CONGESTION;
15417       return NULL;
15418    }
15419 
15420    ast_copy_string(tmp, dest, sizeof(tmp));
15421    host = strchr(tmp, '@');
15422    if (host) {
15423       *host++ = '\0';
15424       ext = tmp;
15425    } else {
15426       ext = strchr(tmp, '/');
15427       if (ext) 
15428          *ext++ = '\0';
15429       host = tmp;
15430    }
15431 
15432    if (create_addr(p, host)) {
15433       *cause = AST_CAUSE_UNREGISTERED;
15434       if (option_debug > 2)
15435          ast_log(LOG_DEBUG, "Cant create SIP call - target device not registred\n");
15436       sip_destroy(p);
15437       return NULL;
15438    }
15439    if (ast_strlen_zero(p->peername) && ext)
15440       ast_string_field_set(p, peername, ext);
15441    /* Recalculate our side, and recalculate Call ID */
15442    if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
15443       p->ourip = __ourip;
15444    build_via(p);
15445    build_callid_pvt(p);
15446    
15447    /* We have an extension to call, don't use the full contact here */
15448    /* This to enable dialing registered peers with extension dialling,
15449       like SIP/peername/extension   
15450       SIP/peername will still use the full contact */
15451    if (ext) {
15452       ast_string_field_set(p, username, ext);
15453       ast_string_field_free(p, fullcontact);
15454    }
15455 #if 0
15456    printf("Setting up to call extension '%s' at '%s'\n", ext ? ext : "<none>", host);
15457 #endif
15458    p->prefcodec = oldformat;           /* Format for this call */
15459    ast_mutex_lock(&p->lock);
15460    tmpc = sip_new(p, AST_STATE_DOWN, host);  /* Place the call */
15461    ast_mutex_unlock(&p->lock);
15462    if (!tmpc)
15463       sip_destroy(p);
15464    ast_update_use_count();
15465    restart_monitor();
15466    return tmpc;
15467 }

static int sip_reregister ( void *  data  )  [static]

Update registration with SIP Proxy.

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

07144 {
07145    /* if we are here, we know that we need to reregister. */
07146    struct sip_registry *r= ASTOBJ_REF((struct sip_registry *) data);
07147 
07148    /* if we couldn't get a reference to the registry object, punt */
07149    if (!r)
07150       return 0;
07151 
07152    if (r->call && !ast_test_flag(&r->call->flags[0], SIP_NO_HISTORY))
07153       append_history(r->call, "RegistryRenew", "Account: %s@%s", r->username, r->hostname);
07154    /* Since registry's are only added/removed by the the monitor thread, this
07155       may be overkill to reference/dereference at all here */
07156    if (sipdebug)
07157       ast_log(LOG_NOTICE, "   -- Re-registration for  %s@%s\n", r->username, r->hostname);
07158 
07159    r->expire = -1;
07160    __sip_do_register(r);
07161    ASTOBJ_UNREF(r, sip_registry_destroy);
07162    return 0;
07163 }

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

04050 {
04051    /* Retrieve audio/etc from channel.  Assumes p->lock is already held. */
04052    struct ast_frame *f;
04053    
04054    if (!p->rtp) {
04055       /* We have no RTP allocated for this channel */
04056       return &ast_null_frame;
04057    }
04058 
04059    switch(ast->fdno) {
04060    case 0:
04061       f = ast_rtp_read(p->rtp);  /* RTP Audio */
04062       break;
04063    case 1:
04064       f = ast_rtcp_read(p->rtp); /* RTCP Control Channel */
04065       break;
04066    case 2:
04067       f = ast_rtp_read(p->vrtp); /* RTP Video */
04068       break;
04069    case 3:
04070       f = ast_rtcp_read(p->vrtp);   /* RTCP Control Channel for video */
04071       break;
04072    case 5:
04073       f = ast_udptl_read(p->udptl); /* UDPTL for T.38 */
04074       break;
04075    default:
04076       f = &ast_null_frame;
04077    }
04078    /* Don't forward RFC2833 if we're not supposed to */
04079    if (f && (f->frametype == AST_FRAME_DTMF) &&
04080        (ast_test_flag(&p->flags[0], SIP_DTMF) != SIP_DTMF_RFC2833))
04081       return &ast_null_frame;
04082 
04083       /* We already hold the channel lock */
04084    if (!p->owner || f->frametype != AST_FRAME_VOICE)
04085       return f;
04086 
04087    if (f->subclass != (p->owner->nativeformats & AST_FORMAT_AUDIO_MASK)) {
04088       if (!(f->subclass & p->jointcapability)) {
04089          if (option_debug) {
04090             ast_log(LOG_DEBUG, "Bogus frame of format '%s' received from '%s'!\n",
04091                ast_getformatname(f->subclass), p->owner->name);
04092          }
04093          return &ast_null_frame;
04094       }
04095       if (option_debug)
04096          ast_log(LOG_DEBUG, "Oooh, format changed to %d\n", f->subclass);
04097       p->owner->nativeformats = (p->owner->nativeformats & AST_FORMAT_VIDEO_MASK) | f->subclass;
04098       ast_set_read_format(p->owner, p->owner->readformat);
04099       ast_set_write_format(p->owner, p->owner->writeformat);
04100    }
04101 
04102    if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) && p->vad) {
04103       f = ast_dsp_process(p->owner, p->vad, f);
04104       if (f && f->frametype == AST_FRAME_DTMF) {
04105          if (ast_test_flag(&p->t38.t38support, SIP_PAGE2_T38SUPPORT_UDPTL) && f->subclass == 'f') {
04106             if (option_debug)
04107                ast_log(LOG_DEBUG, "Fax CNG detected on %s\n", ast->name);
04108             *faxdetect = 1;
04109          } else if (option_debug) {
04110             ast_log(LOG_DEBUG, "* Detected inband DTMF '%c'\n", f->subclass);
04111          }
04112       }
04113    }
04114    
04115    return f;
04116 }

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

Schedule destruction of SIP dialog.

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

02028 {
02029    if (ms < 0) {
02030       if (p->timer_t1 == 0)
02031          p->timer_t1 = 500;   /* Set timer T1 if not set (RFC 3261) */
02032       ms = p->timer_t1 * 64;
02033    }
02034    if (sip_debug_test_pvt(p))
02035       ast_verbose("Scheduling destruction of SIP dialog '%s' in %d ms (Method: %s)\n", p->callid, ms, sip_methods[p->method].text);
02036    if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY))
02037       append_history(p, "SchedDestroy", "%d ms", ms);
02038 
02039    if (p->autokillid > -1)
02040       ast_sched_del(sched, p->autokillid);
02041    p->autokillid = ast_sched_add(sched, ms, __sip_autodestruct, p);
02042 }

static void sip_send_all_registers ( void   )  [static]

Send all known registrations.

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

17195 {
17196    int ms;
17197    int regspacing;
17198    if (!regobjs)
17199       return;
17200    regspacing = default_expiry * 1000/regobjs;
17201    if (regspacing > 100)
17202       regspacing = 100;
17203    ms = regspacing;
17204    ASTOBJ_CONTAINER_TRAVERSE(&regl, 1, do {
17205       ASTOBJ_WRLOCK(iterator);
17206       if (iterator->expire > -1)
17207          ast_sched_del(sched, iterator->expire);
17208       ms += regspacing;
17209       iterator->expire = ast_sched_add(sched, ms, sip_reregister, iterator);
17210       ASTOBJ_UNLOCK(iterator);
17211    } while (0)
17212    );
17213 }

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

References __ourip, ast_app_inboxcount(), ast_set_flag, ast_sip_ouraddrfor(), build_callid_pvt(), build_via(), create_addr_from_peer(), 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().

14958 {
14959    /* Called with peerl lock, but releases it */
14960    struct sip_pvt *p;
14961    int newmsgs, oldmsgs;
14962 
14963    /* Check for messages */
14964    ast_app_inboxcount(peer->mailbox, &newmsgs, &oldmsgs);
14965    
14966    peer->lastmsgcheck = time(NULL);
14967    
14968    /* Return now if it's the same thing we told them last time */
14969    if (((newmsgs > 0x7fff ? 0x7fff0000 : (newmsgs << 16)) | (oldmsgs > 0xffff ? 0xffff : oldmsgs)) == peer->lastmsgssent) {
14970       return 0;
14971    }
14972    
14973    
14974    peer->lastmsgssent = ((newmsgs > 0x7fff ? 0x7fff0000 : (newmsgs << 16)) | (oldmsgs > 0xffff ? 0xffff : oldmsgs));
14975 
14976    if (peer->mwipvt) {
14977       /* Base message on subscription */
14978       p = peer->mwipvt;
14979    } else {
14980       /* Build temporary dialog for this message */
14981       if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY))) 
14982          return -1;
14983       if (create_addr_from_peer(p, peer)) {
14984          /* Maybe they're not registered, etc. */
14985          sip_destroy(p);
14986          return 0;
14987       }
14988       /* Recalculate our side, and recalculate Call ID */
14989       if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
14990          p->ourip = __ourip;
14991       build_via(p);
14992       build_callid_pvt(p);
14993       /* Destroy this session after 32 secs */
14994       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
14995    }
14996    /* Send MWI */
14997    ast_set_flag(&p->flags[0], SIP_OUTGOING);
14998    transmit_notify_with_mwi(p, newmsgs, oldmsgs, peer->vmexten);
14999    return 0;
15000 }

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

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

03598 {
03599    struct sip_pvt *p = ast->tech_pvt;
03600    int res = 0;
03601 
03602    ast_mutex_lock(&p->lock);
03603    switch (ast_test_flag(&p->flags[0], SIP_DTMF)) {
03604    case SIP_DTMF_INBAND:
03605       res = -1; /* Tell Asterisk to generate inband indications */
03606       break;
03607    case SIP_DTMF_RFC2833:
03608       if (p->rtp)
03609          ast_rtp_senddigit_begin(p->rtp, digit);
03610       break;
03611    default:
03612       break;
03613    }
03614    ast_mutex_unlock(&p->lock);
03615 
03616    return res;
03617 }

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

03622 {
03623    struct sip_pvt *p = ast->tech_pvt;
03624    int res = 0;
03625 
03626    ast_mutex_lock(&p->lock);
03627    switch (ast_test_flag(&p->flags[0], SIP_DTMF)) {
03628    case SIP_DTMF_INFO:
03629       transmit_info_with_digit(p, digit, duration);
03630       break;
03631    case SIP_DTMF_RFC2833:
03632       if (p->rtp)
03633          ast_rtp_senddigit_end(p->rtp, digit);
03634       break;
03635    case SIP_DTMF_INBAND:
03636       res = -1; /* Tell Asterisk to stop inband indications */
03637       break;
03638    }
03639    ast_mutex_unlock(&p->lock);
03640 
03641    return res;
03642 }

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

02271 {
02272    struct sip_pvt *p = ast->tech_pvt;
02273    int debug = sip_debug_test_pvt(p);
02274 
02275    if (debug)
02276       ast_verbose("Sending text %s on %s\n", text, ast->name);
02277    if (!p)
02278       return -1;
02279    if (ast_strlen_zero(text))
02280       return 0;
02281    if (debug)
02282       ast_verbose("Really sending text %s on %s\n", text, ast->name);
02283    transmit_message_with_text(p, text);
02284    return 0;   
02285 }

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 16934 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::flags, 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.

16935 {
16936    struct sip_pvt *p;
16937    int changed = 0;
16938 
16939    p = chan->tech_pvt;
16940    if (!p) 
16941       return -1;
16942 
16943    /* Disable early RTP bridge  */
16944    if (chan->_state != AST_STATE_UP && !global_directrtpsetup)    /* We are in early state */
16945       return 0;
16946 
16947    ast_mutex_lock(&p->lock);
16948    if (ast_test_flag(&p->flags[0], SIP_ALREADYGONE)) {
16949       /* If we're destroyed, don't bother */
16950       ast_mutex_unlock(&p->lock);
16951       return 0;
16952    }
16953 
16954    /* if this peer cannot handle reinvites of the media stream to devices
16955       that are known to be behind a NAT, then stop the process now
16956    */
16957    if (nat_active && !ast_test_flag(&p->flags[0], SIP_CAN_REINVITE_NAT)) {
16958       ast_mutex_unlock(&p->lock);
16959       return 0;
16960    }
16961 
16962    if (rtp) {
16963       changed |= ast_rtp_get_peer(rtp, &p->redirip);
16964    } else if (p->redirip.sin_addr.s_addr || ntohs(p->redirip.sin_port) != 0) {
16965       memset(&p->redirip, 0, sizeof(p->redirip));
16966       changed = 1;
16967    }
16968    if (vrtp) {
16969       changed |= ast_rtp_get_peer(vrtp, &p->vredirip);
16970    } else if (p->vredirip.sin_addr.s_addr || ntohs(p->vredirip.sin_port) != 0) {
16971       memset(&p->vredirip, 0, sizeof(p->vredirip));
16972       changed = 1;
16973    }
16974    if (codecs && (p->redircodecs != codecs)) {
16975       p->redircodecs = codecs;
16976       changed = 1;
16977    }
16978    if (changed && !ast_test_flag(&p->flags[0], SIP_GOTREFER)) {
16979       if (chan->_state != AST_STATE_UP) { /* We are in early state */
16980          if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY))
16981             append_history(p, "ExtInv", "Initial invite sent with remote bridge proposal.");
16982          if (option_debug)
16983             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));
16984       } else if (!p->pendinginvite) {     /* We are up, and have no outstanding invite */
16985          if (option_debug > 2) {
16986             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));
16987          }
16988          transmit_reinvite_with_sdp(p);
16989       } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) {
16990          if (option_debug > 2) {
16991             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));
16992          }
16993          /* We have a pending Invite. Send re-invite when we're done with the invite */
16994          ast_set_flag(&p->flags[0], SIP_NEEDREINVITE);   
16995       }
16996    }
16997    /* Reset lastrtprx timer */
16998    p->lastrtprx = p->lastrtptx = time(NULL);
16999    ast_mutex_unlock(&p->lock);
17000    return 0;
17001 }

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

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

16762 {
16763    struct sip_pvt *p;
16764    
16765    p = chan->tech_pvt;
16766    if (!p)
16767       return -1;
16768    ast_mutex_lock(&p->lock);
16769    if (udptl)
16770       ast_udptl_get_peer(udptl, &p->udptlredirip);
16771    else
16772       memset(&p->udptlredirip, 0, sizeof(p->udptlredirip));
16773    if (!ast_test_flag(&p->flags[0], SIP_GOTREFER)) {
16774       if (!p->pendinginvite) {
16775          if (option_debug > 2) {
16776             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);
16777          }
16778          transmit_reinvite_with_t38_sdp(p);
16779       } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) {
16780          if (option_debug > 2) {
16781             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);
16782          }
16783          ast_set_flag(&p->flags[0], SIP_NEEDREINVITE);
16784       }
16785    }
16786    /* Reset lastrtprx timer */
16787    p->lastrtprx = p->lastrtptx = time(NULL);
16788    ast_mutex_unlock(&p->lock);
16789    return 0;
16790 }

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

Show details of one active dialog.

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

10638 {
10639    struct sip_pvt *cur;
10640    size_t len;
10641    int found = 0;
10642 
10643    if (argc != 4)
10644       return RESULT_SHOWUSAGE;
10645    len = strlen(argv[3]);
10646    ast_mutex_lock(&iflock);
10647    for (cur = iflist; cur; cur = cur->next) {
10648       if (!strncasecmp(cur->callid, argv[3], len)) {
10649          char formatbuf[BUFSIZ/2];
10650          ast_cli(fd,"\n");
10651          if (cur->subscribed != NONE)
10652             ast_cli(fd, "  * Subscription (type: %s)\n", subscription_type2str(cur->subscribed));
10653          else
10654             ast_cli(fd, "  * SIP Call\n");
10655          ast_cli(fd, "  Curr. trans. direction:  %s\n", ast_test_flag(&cur->flags[0], SIP_OUTGOING) ? "Outgoing" : "Incoming");
10656          ast_cli(fd, "  Call-ID:                %s\n", cur->callid);
10657          ast_cli(fd, "  Owner channel ID:       %s\n", cur->owner ? cur->owner->name : "<none>");
10658          ast_cli(fd, "  Our Codec Capability:   %d\n", cur->capability);
10659          ast_cli(fd, "  Non-Codec Capability (DTMF):   %d\n", cur->noncodeccapability);
10660          ast_cli(fd, "  Their Codec Capability:   %d\n", cur->peercapability);
10661          ast_cli(fd, "  Joint Codec Capability:   %d\n", cur->jointcapability);
10662          ast_cli(fd, "  Format:                 %s\n", ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->owner ? cur->owner->nativeformats : 0) );
10663          ast_cli(fd, "  MaxCallBR:              %d kbps\n", cur->maxcallbitrate);
10664          ast_cli(fd, "  Theoretical Address:    %s:%d\n", ast_inet_ntoa(cur->sa.sin_addr), ntohs(cur->sa.sin_port));
10665          ast_cli(fd, "  Received Address:       %s:%d\n", ast_inet_ntoa(cur->recv.sin_addr), ntohs(cur->recv.sin_port));
10666          ast_cli(fd, "  SIP Transfer mode:      %s\n", transfermode2str(cur->allowtransfer));
10667          ast_cli(fd, "  NAT Support:            %s\n", nat2str(ast_test_flag(&cur->flags[0], SIP_NAT)));
10668          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)" );
10669          ast_cli(fd, "  Our Tag:                %s\n", cur->tag);
10670          ast_cli(fd, "  Their Tag:              %s\n", cur->theirtag);
10671          ast_cli(fd, "  SIP User agent:         %s\n", cur->useragent);
10672          if (!ast_strlen_zero(cur->username))
10673             ast_cli(fd, "  Username:               %s\n", cur->username);
10674          if (!ast_strlen_zero(cur->peername))
10675             ast_cli(fd, "  Peername:               %s\n", cur->peername);
10676          if (!ast_strlen_zero(cur->uri))
10677             ast_cli(fd, "  Original uri:           %s\n", cur->uri);
10678          if (!ast_strlen_zero(cur->cid_num))
10679             ast_cli(fd, "  Caller-ID:              %s\n", cur->cid_num);
10680          ast_cli(fd, "  Need Destroy:           %d\n", ast_test_flag(&cur->flags[0], SIP_NEEDDESTROY));
10681          ast_cli(fd, "  Last Message:           %s\n", cur->lastmsg);
10682          ast_cli(fd, "  Promiscuous Redir:      %s\n", ast_test_flag(&cur->flags[0], SIP_PROMISCREDIR) ? "Yes" : "No");
10683          ast_cli(fd, "  Route:                  %s\n", cur->route ? cur->route->hop : "N/A");
10684          ast_cli(fd, "  DTMF Mode:              %s\n", dtmfmode2str(ast_test_flag(&cur->flags[0], SIP_DTMF)));
10685          ast_cli(fd, "  SIP Options:            ");
10686          if (cur->sipoptions) {
10687             int x;
10688             for (x=0 ; (x < (sizeof(sip_options) / sizeof(sip_options[0]))); x++) {
10689                if (cur->sipoptions & sip_options[x].id)
10690                   ast_cli(fd, "%s ", sip_options[x].text);
10691             }
10692          } else
10693             ast_cli(fd, "(none)\n");
10694          ast_cli(fd, "\n\n");
10695          found++;
10696       }
10697    }
10698    ast_mutex_unlock(&iflock);
10699    if (!found) 
10700       ast_cli(fd, "No such SIP Call ID starting with '%s'\n", argv[3]);
10701    return RESULT_SUCCESS;
10702 }

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

Show active SIP channels.

Definition at line 10435 of file chan_sip.c.

References __sip_show_channels().

10436 {
10437         return __sip_show_channels(fd, argc, argv, 0);
10438 }

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

CLI command to list local domains.

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

09942 {
09943    struct domain *d;
09944 #define FORMAT "%-40.40s %-20.20s %-16.16s\n"
09945 
09946    if (AST_LIST_EMPTY(&domain_list)) {
09947       ast_cli(fd, "SIP Domain support not enabled.\n\n");
09948       return RESULT_SUCCESS;
09949    } else {
09950       ast_cli(fd, FORMAT, "Our local SIP domains:", "Context", "Set by");
09951       AST_LIST_LOCK(&domain_list);
09952       AST_LIST_TRAVERSE(&domain_list, d, list)
09953          ast_cli(fd, FORMAT, d->domain, S_OR(d->context, "(default)"),
09954             domain_mode_to_text(d->mode));
09955       AST_LIST_UNLOCK(&domain_list);
09956       ast_cli(fd, "\n");
09957       return RESULT_SUCCESS;
09958    }
09959 }

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

Show history details of one dialog.

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

10706 {
10707    struct sip_pvt *cur;
10708    size_t len;
10709    int found = 0;
10710 
10711    if (argc != 4)
10712       return RESULT_SHOWUSAGE;
10713    if (!recordhistory)
10714       ast_cli(fd, "\n***Note: History recording is currently DISABLED.  Use 'sip history' to ENABLE.\n");
10715    len = strlen(argv[3]);
10716    ast_mutex_lock(&iflock);
10717    for (cur = iflist; cur; cur = cur->next) {
10718       if (!strncasecmp(cur->callid, argv[3], len)) {
10719          struct sip_history *hist;
10720          int x = 0;
10721 
10722          ast_cli(fd,"\n");
10723          if (cur->subscribed != NONE)
10724             ast_cli(fd, "  * Subscription\n");
10725          else
10726             ast_cli(fd, "  * SIP Call\n");
10727          if (cur->history)
10728             AST_LIST_TRAVERSE(cur->history, hist, list)
10729                ast_cli(fd, "%d. %s\n", ++x, hist->event);
10730          if (x == 0)
10731             ast_cli(fd, "Call '%s' has no history\n", cur->callid);
10732          found++;
10733       }
10734    }
10735    ast_mutex_unlock(&iflock);
10736    if (!found) 
10737       ast_cli(fd, "No such SIP Call ID starting with '%s'\n", argv[3]);
10738    return RESULT_SUCCESS;
10739 }

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

09367 {
09368 #define FORMAT  "%-25.25s %-15.15s %-15.15s \n"
09369 #define FORMAT2 "%-25.25s %-15.15s %-15.15s \n"
09370    char ilimits[40];
09371    char iused[40];
09372    int showall = FALSE;
09373 
09374    if (argc < 3) 
09375       return RESULT_SHOWUSAGE;
09376 
09377    if (argc == 4 && !strcmp(argv[3],"all")) 
09378          showall = TRUE;
09379    
09380    ast_cli(fd, FORMAT, "* User name", "In use", "Limit");
09381    ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do {
09382       ASTOBJ_RDLOCK(iterator);
09383       if (iterator->call_limit)
09384          snprintf(ilimits, sizeof(ilimits), "%d", iterator->call_limit);
09385       else 
09386          ast_copy_string(ilimits, "N/A", sizeof(ilimits));
09387       snprintf(iused, sizeof(iused), "%d", iterator->inUse);
09388       if (showall || iterator->call_limit)
09389          ast_cli(fd, FORMAT2, iterator->name, iused, ilimits);
09390       ASTOBJ_UNLOCK(iterator);
09391    } while (0) );
09392 
09393    ast_cli(fd, FORMAT, "* Peer name", "In use", "Limit");
09394 
09395    ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do {
09396       ASTOBJ_RDLOCK(iterator);
09397       if (iterator->call_limit)
09398          snprintf(ilimits, sizeof(ilimits), "%d", iterator->call_limit);
09399       else 
09400          ast_copy_string(ilimits, "N/A", sizeof(ilimits));
09401       snprintf(iused, sizeof(iused), "%d/%d", iterator->inUse, iterator->inRinging);
09402       if (showall || iterator->call_limit)
09403          ast_cli(fd, FORMAT2, iterator->name, iused, ilimits);
09404       ASTOBJ_UNLOCK(iterator);
09405    } while (0) );
09406 
09407    return RESULT_SUCCESS;
09408 #undef FORMAT
09409 #undef FORMAT2
09410 }

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

List all allocated SIP Objects (realtime or static).

Definition at line 9687 of file chan_sip.c.

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

09688 {
09689    char tmp[256];
09690    if (argc != 3)
09691       return RESULT_SHOWUSAGE;
09692    ast_cli(fd, "-= User objects: %d static, %d realtime =-\n\n", suserobjs, ruserobjs);
09693    ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), &userl);
09694    ast_cli(fd, "-= Peer objects: %d static, %d realtime, %d autocreate =-\n\n", speerobjs, rpeerobjs, apeerobjs);
09695    ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), &peerl);
09696    ast_cli(fd, "-= Registry objects: %d =-\n\n", regobjs);
09697    ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), &regl);
09698    return RESULT_SUCCESS;
09699 }

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

Show one peer in detail.

Definition at line 9993 of file chan_sip.c.

References _sip_show_peer().

09994 {
09995    return _sip_show_peer(0, fd, NULL, NULL, argc, (const char **) argv);
09996 }

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

CLI Show Peers command.

Definition at line 9543 of file chan_sip.c.

References _sip_show_peers().

09544 {
09545    return _sip_show_peers(fd, NULL, NULL, NULL, argc, (const char **) argv);
09546 }

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

Show SIP Registry (registrations with other SIP proxies.

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

10267 {
10268 #define FORMAT2 "%-30.30s  %-12.12s  %8.8s %-20.20s %-25.25s\n"
10269 #define FORMAT  "%-30.30s  %-12.12s  %8d %-20.20s %-25.25s\n"
10270    char host[80];
10271    char tmpdat[256];
10272    struct tm tm;
10273 
10274 
10275    if (argc != 3)
10276       return RESULT_SHOWUSAGE;
10277    ast_cli(fd, FORMAT2, "Host", "Username", "Refresh", "State", "Reg.Time");
10278    ASTOBJ_CONTAINER_TRAVERSE(&regl, 1, do {
10279       ASTOBJ_RDLOCK(iterator);
10280       snprintf(host, sizeof(host), "%s:%d", iterator->hostname, iterator->portno ? iterator->portno : STANDARD_SIP_PORT);
10281       if (iterator->regtime) {
10282          ast_localtime(&iterator->regtime, &tm, NULL);
10283          strftime(tmpdat, sizeof(tmpdat), "%a, %d %b %Y %T", &tm);
10284       } else {
10285          tmpdat[0] = 0;
10286       }
10287       ast_cli(fd, FORMAT, host, iterator->username, iterator->refresh, regstate2str(iterator->regstate), tmpdat);
10288       ASTOBJ_UNLOCK(iterator);
10289    } while(0));
10290    return RESULT_SUCCESS;
10291 #undef FORMAT
10292 #undef FORMAT2
10293 }

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

List global settings for the SIP channel.

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

10297 {
10298    int realtimepeers;
10299    int realtimeusers;
10300    char codec_buf[BUFSIZ];
10301 
10302    realtimepeers = ast_check_realtime("sippeers");
10303    realtimeusers = ast_check_realtime("sipusers");
10304 
10305    if (argc != 3)
10306       return RESULT_SHOWUSAGE;
10307    ast_cli(fd, "\n\nGlobal Settings:\n");
10308    ast_cli(fd, "----------------\n");
10309    ast_cli(fd, "  SIP Port:               %d\n", ntohs(bindaddr.sin_port));
10310    ast_cli(fd, "  Bindaddress:            %s\n", ast_inet_ntoa(bindaddr.sin_addr));
10311    ast_cli(fd, "  Videosupport:           %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_VIDEOSUPPORT) ? "Yes" : "No");
10312    ast_cli(fd, "  AutoCreatePeer:         %s\n", autocreatepeer ? "Yes" : "No");
10313    ast_cli(fd, "  Allow unknown access:   %s\n", global_allowguest ? "Yes" : "No");
10314    ast_cli(fd, "  Allow subscriptions:    %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWSUBSCRIBE) ? "Yes" : "No");
10315    ast_cli(fd, "  Allow overlap dialing:  %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP) ? "Yes" : "No");
10316    ast_cli(fd, "  Promsic. redir:         %s\n", ast_test_flag(&global_flags[0], SIP_PROMISCREDIR) ? "Yes" : "No");
10317    ast_cli(fd, "  SIP domain support:     %s\n", AST_LIST_EMPTY(&domain_list) ? "No" : "Yes");
10318    ast_cli(fd, "  Call to non-local dom.: %s\n", allow_external_domains ? "Yes" : "No");
10319    ast_cli(fd, "  URI user is phone no:   %s\n", ast_test_flag(&global_flags[0], SIP_USEREQPHONE) ? "Yes" : "No");
10320    ast_cli(fd, "  Our auth realm          %s\n", global_realm);
10321    ast_cli(fd, "  Realm. auth:            %s\n", authl ? "Yes": "No");
10322    ast_cli(fd, "  Always auth rejects:    %s\n", global_alwaysauthreject ? "Yes" : "No");
10323    ast_cli(fd, "  Call limit peers only:  %s\n", global_limitonpeers ? "Yes" : "No");
10324    ast_cli(fd, "  Direct RTP setup:       %s\n", global_directrtpsetup ? "Yes" : "No");
10325    ast_cli(fd, "  User Agent:             %s\n", global_useragent);
10326    ast_cli(fd, "  MWI checking interval:  %d secs\n", global_mwitime);
10327    ast_cli(fd, "  Reg. context:           %s\n", S_OR(global_regcontext, "(not set)"));
10328    ast_cli(fd, "  Caller ID:              %s\n", default_callerid);
10329    ast_cli(fd, "  From: Domain:           %s\n", default_fromdomain);
10330    ast_cli(fd, "  Record SIP history:     %s\n", recordhistory ? "On" : "Off");
10331    ast_cli(fd, "  Call Events:            %s\n", global_callevents ? "On" : "Off");
10332    ast_cli(fd, "  IP ToS SIP:             %s\n", ast_tos2str(global_tos_sip));
10333    ast_cli(fd, "  IP ToS RTP audio:       %s\n", ast_tos2str(global_tos_audio));
10334    ast_cli(fd, "  IP ToS RTP video:       %s\n", ast_tos2str(global_tos_video));
10335    ast_cli(fd, "  T38 fax pt UDPTL:       %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT_UDPTL) ? "Yes" : "No");
10336 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS
10337    ast_cli(fd, "  T38 fax pt RTP:         %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT_RTP) ? "Yes" : "No");
10338    ast_cli(fd, "  T38 fax pt TCP:         %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT_TCP) ? "Yes" : "No");
10339 #endif
10340    ast_cli(fd, "  RFC2833 Compensation:   %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RFC2833_COMPENSATE) ? "Yes" : "No");
10341    ast_cli(fd, "  Jitterbuffer enabled:   %s\n", ast_test_flag(&global_jbconf, AST_JB_ENABLED) ? "Yes" : "No");
10342    ast_cli(fd, "  Jitterbuffer forced:    %s\n", ast_test_flag(&global_jbconf, AST_JB_FORCED) ? "Yes" : "No");
10343    ast_cli(fd, "  Jitterbuffer max size:  %ld\n", global_jbconf.max_size);
10344    ast_cli(fd, "  Jitterbuffer resync:    %ld\n", global_jbconf.resync_threshold);
10345    ast_cli(fd, "  Jitterbuffer impl:      %s\n", global_jbconf.impl);
10346    ast_cli(fd, "  Jitterbuffer log:       %s\n", ast_test_flag(&global_jbconf, AST_JB_LOG) ? "Yes" : "No");
10347    if (!realtimepeers && !realtimeusers)
10348       ast_cli(fd, "  SIP realtime:           Disabled\n" );
10349    else
10350       ast_cli(fd, "  SIP realtime:           Enabled\n" );
10351 
10352    ast_cli(fd, "\nGlobal Signalling Settings:\n");
10353    ast_cli(fd, "---------------------------\n");
10354    ast_cli(fd, "  Codecs:                 ");
10355    ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, global_capability);
10356    ast_cli(fd, "%s\n", codec_buf);
10357    ast_cli(fd, "  Codec Order:            ");
10358    print_codec_to_cli(fd, &default_prefs);
10359    ast_cli(fd, "\n");
10360    ast_cli(fd, "  T1 minimum:             %d\n", global_t1min);
10361    ast_cli(fd, "  Relax DTMF:             %s\n", global_relaxdtmf ? "Yes" : "No");
10362    ast_cli(fd, "  Compact SIP headers:    %s\n", compactheaders ? "Yes" : "No");
10363    ast_cli(fd, "  RTP Keepalive:          %d %s\n", global_rtpkeepalive, global_rtpkeepalive ? "" : "(Disabled)" );
10364    ast_cli(fd, "  RTP Timeout:            %d %s\n", global_rtptimeout, global_rtptimeout ? "" : "(Disabled)" );
10365    ast_cli(fd, "  RTP Hold Timeout:       %d %s\n", global_rtpholdtimeout, global_rtpholdtimeout ? "" : "(Disabled)");
10366    ast_cli(fd, "  MWI NOTIFY mime type:   %s\n", default_notifymime);
10367    ast_cli(fd, "  DNS SRV lookup:         %s\n", srvlookup ? "Yes" : "No");
10368    ast_cli(fd, "  Pedantic SIP support:   %s\n", pedanticsipchecking ? "Yes" : "No");
10369    ast_cli(fd, "  Reg. min duration       %d secs\n", min_expiry);
10370    ast_cli(fd, "  Reg. max duration:      %d secs\n", max_expiry);
10371    ast_cli(fd, "  Reg. default duration:  %d secs\n", default_expiry);
10372    ast_cli(fd, "  Outbound reg. timeout:  %d secs\n", global_reg_timeout);
10373    ast_cli(fd, "  Outbound reg. attempts: %d\n", global_regattempts_max);
10374    ast_cli(fd, "  Notify ringing state:   %s\n", global_notifyringing ? "Yes" : "No");
10375    ast_cli(fd, "  Notify hold state:      %s\n", global_notifyhold ? "Yes" : "No");
10376    ast_cli(fd, "  SIP Transfer mode:      %s\n", transfermode2str(global_allowtransfer));
10377    ast_cli(fd, "  Max Call Bitrate:       %d kbps\r\n", default_maxcallbitrate);
10378    ast_cli(fd, "  Auto-Framing:           %s \r\n", global_autoframing ? "Yes" : "No");
10379    ast_cli(fd, "\nDefault Settings:\n");
10380    ast_cli(fd, "-----------------\n");
10381    ast_cli(fd, "  Context:                %s\n", default_context);
10382    ast_cli(fd, "  Nat:                    %s\n", nat2str(ast_test_flag(&global_flags[0], SIP_NAT)));
10383    ast_cli(fd, "  DTMF:                   %s\n", dtmfmode2str(ast_test_flag(&global_flags[0], SIP_DTMF)));
10384    ast_cli(fd, "  Qualify:                %d\n", default_qualify);
10385    ast_cli(fd, "  Use ClientCode:         %s\n", ast_test_flag(&global_flags[0], SIP_USECLIENTCODE) ? "Yes" : "No");
10386    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" );
10387    ast_cli(fd, "  Language:               %s\n", S_OR(default_language, "(Defaults to English)"));
10388    ast_cli(fd, "  MOH Interpret:          %s\n", default_mohinterpret);
10389    ast_cli(fd, "  MOH Suggest:            %s\n", default_mohsuggest);
10390    ast_cli(fd, "  Voice Mail Extension:   %s\n", default_vmexten);
10391 
10392    
10393    if (realtimepeers || realtimeusers) {
10394       ast_cli(fd, "\nRealtime SIP Settings:\n");
10395       ast_cli(fd, "----------------------\n");
10396       ast_cli(fd, "  Realtime Peers:         %s\n", realtimepeers ? "Yes" : "No");
10397       ast_cli(fd, "  Realtime Users:         %s\n", realtimeusers ? "Yes" : "No");
10398       ast_cli(fd, "  Cache Friends:          %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS) ? "Yes" : "No");
10399       ast_cli(fd, "  Update:                 %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RTUPDATE) ? "Yes" : "No");
10400       ast_cli(fd, "  Ignore Reg. Expire:     %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_IGNOREREGEXPIRE) ? "Yes" : "No");
10401       ast_cli(fd, "  Save sys. name:         %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RTSAVE_SYSNAME) ? "Yes" : "No");
10402       ast_cli(fd, "  Auto Clear:             %d\n", global_rtautoclear);
10403    }
10404    ast_cli(fd, "\n----\n");
10405    return RESULT_SUCCESS;
10406 }

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

Show active SIP subscriptions.

Definition at line 10441 of file chan_sip.c.

References __sip_show_channels().

10442 {
10443         return __sip_show_channels(fd, argc, argv, 1);
10444 }

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

Show one user in detail.

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

10212 {
10213    char cbuf[256];
10214    struct sip_user *user;
10215    struct ast_variable *v;
10216    int load_realtime;
10217 
10218    if (argc < 4)
10219       return RESULT_SHOWUSAGE;
10220 
10221    /* Load from realtime storage? */
10222    load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? TRUE : FALSE;
10223 
10224    user = find_user(argv[3], load_realtime);
10225    if (user) {
10226       ast_cli(fd,"\n\n");
10227       ast_cli(fd, "  * Name       : %s\n", user->name);
10228       ast_cli(fd, "  Secret       : %s\n", ast_strlen_zero(user->secret)?"<Not set>":"<Set>");
10229       ast_cli(fd, "  MD5Secret    : %s\n", ast_strlen_zero(user->md5secret)?"<Not set>":"<Set>");
10230       ast_cli(fd, "  Context      : %s\n", user->context);
10231       ast_cli(fd, "  Language     : %s\n", user->language);
10232       if (!ast_strlen_zero(user->accountcode))
10233          ast_cli(fd, "  Accountcode  : %s\n", user->accountcode);
10234       ast_cli(fd, "  AMA flags    : %s\n", ast_cdr_flags2str(user->amaflags));
10235       ast_cli(fd, "  Transfer mode: %s\n", transfermode2str(user->allowtransfer));
10236       ast_cli(fd, "  MaxCallBR    : %d kbps\n", user->maxcallbitrate);
10237       ast_cli(fd, "  CallingPres  : %s\n", ast_describe_caller_presentation(user->callingpres));
10238       ast_cli(fd, "  Call limit   : %d\n", user->call_limit);
10239       ast_cli(fd, "  Callgroup    : ");
10240       print_group(fd, user->callgroup, 0);
10241       ast_cli(fd, "  Pickupgroup  : ");
10242       print_group(fd, user->pickupgroup, 0);
10243       ast_cli(fd, "  Callerid     : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), user->cid_name, user->cid_num, "<unspecified>"));
10244       ast_cli(fd, "  ACL          : %s\n", (user->ha?"Yes":"No"));
10245       ast_cli(fd, "  Codec Order  : (");
10246       print_codec_to_cli(fd, &user->prefs);
10247       ast_cli(fd, ")\n");
10248 
10249       ast_cli(fd, "  Auto-Framing:  %s \n", user->autoframing ? "Yes" : "No");
10250       if (user->chanvars) {
10251          ast_cli(fd, "  Variables    :\n");
10252          for (v = user->chanvars ; v ; v = v->next)
10253             ast_cli(fd, "                 %s = %s\n", v->name, v->value);
10254       }
10255       ast_cli(fd,"\n");
10256       ASTOBJ_UNREF(user,sip_destroy_user);
10257    } else {
10258       ast_cli(fd,"User %s not found.\n", argv[3]);
10259       ast_cli(fd,"\n");
10260    }
10261 
10262    return RESULT_SUCCESS;
10263 }

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

CLI Command 'SIP Show Users'.

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

09467 {
09468    regex_t regexbuf;
09469    int havepattern = FALSE;
09470 
09471 #define FORMAT  "%-25.25s  %-15.15s  %-15.15s  %-15.15s  %-5.5s%-10.10s\n"
09472 
09473    switch (argc) {
09474    case 5:
09475       if (!strcasecmp(argv[3], "like")) {
09476          if (regcomp(&regexbuf, argv[4], REG_EXTENDED | REG_NOSUB))
09477             return RESULT_SHOWUSAGE;
09478          havepattern = TRUE;
09479       } else
09480          return RESULT_SHOWUSAGE;
09481    case 3:
09482       break;
09483    default:
09484       return RESULT_SHOWUSAGE;
09485    }
09486 
09487    ast_cli(fd, FORMAT, "Username", "Secret", "Accountcode", "Def.Context", "ACL", "NAT");
09488    ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do {
09489       ASTOBJ_RDLOCK(iterator);
09490 
09491       if (havepattern && regexec(&regexbuf, iterator->name, 0, NULL, 0)) {
09492          ASTOBJ_UNLOCK(iterator);
09493          continue;
09494       }
09495 
09496       ast_cli(fd, FORMAT, iterator->name, 
09497          iterator->secret, 
09498          iterator->accountcode,
09499          iterator->context,
09500          iterator->ha ? "Yes" : "No",
09501          nat2str(ast_test_flag(&iterator->flags[0], SIP_NAT)));
09502       ASTOBJ_UNLOCK(iterator);
09503    } while (0)
09504    );
09505 
09506    if (havepattern)
09507       regfree(&regexbuf);
09508 
09509    return RESULT_SUCCESS;
09510 #undef FORMAT
09511 }

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 17114 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_scheddestroy(), strsep(), and transmit_response_reliable().

Referenced by sip_transfer().

17115 {
17116    char *cdest;
17117    char *extension, *host, *port;
17118    char tmp[80];
17119    
17120    cdest = ast_strdupa(dest);
17121    
17122    extension = strsep(&cdest, "@");
17123    host = strsep(&cdest, ":");
17124    port = strsep(&cdest, ":");
17125    if (ast_strlen_zero(extension)) {
17126       ast_log(LOG_ERROR, "Missing mandatory argument: extension\n");
17127       return 0;
17128    }
17129 
17130    /* we'll issue the redirect message here */
17131    if (!host) {
17132       char *localtmp;
17133       ast_copy_string(tmp, get_header(&p->initreq, "To"), sizeof(tmp));
17134       if (ast_strlen_zero(tmp)) {
17135          ast_log(LOG_ERROR, "Cannot retrieve the 'To' header from the original SIP request!\n");
17136          return 0;
17137       }
17138       if ((localtmp = strstr(tmp, "sip:")) && (localtmp = strchr(localtmp, '@'))) {
17139          char lhost[80], lport[80];
17140          memset(lhost, 0, sizeof(lhost));
17141          memset(lport, 0, sizeof(lport));
17142          localtmp++;
17143          /* This is okey because lhost and lport are as big as tmp */
17144          sscanf(localtmp, "%[^<>:; ]:%[^<>:; ]", lhost, lport);
17145          if (ast_strlen_zero(lhost)) {
17146             ast_log(LOG_ERROR, "Can't find the host address\n");
17147             return 0;
17148          }
17149          host = ast_strdupa(lhost);
17150          if (!ast_strlen_zero(lport)) {
17151             port = ast_strdupa(lport);
17152          }
17153       }
17154    }
17155 
17156    ast_string_field_build(p, our_contact, "Transfer <sip:%s@%s%s%s>", extension, host, port ? ":" : "", port ? port : "");
17157    transmit_response_reliable(p, "302 Moved Temporarily", &p->initreq);
17158 
17159    sip_scheddestroy(p, 32000);   /* Make sure we stop send this reply. */
17160 
17161    return 0;
17162 }

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

Transfer SIP call.

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

03646 {
03647    struct sip_pvt *p = ast->tech_pvt;
03648    int res;
03649 
03650    if (dest == NULL) /* functions below do not take a NULL */
03651       dest = "";
03652    ast_mutex_lock(&p->lock);
03653    if (ast->_state == AST_STATE_RING)
03654       res = sip_sipredirect(p, dest);
03655    else
03656       res = transmit_refer(p, dest);
03657    ast_mutex_unlock(&p->lock);
03658    return res;
03659 }

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

Send frame to media channel (rtp).

Definition at line 3478 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, LOG_WARNING, ast_channel::nativeformats, ast_channel::readformat, sip_pvt::rtp, SIP_OUTGOING, SIP_PROGRESS_SENT, ast_frame::subclass, ast_channel::tech_pvt, transmit_response_with_sdp(), sip_pvt::udptl, sip_pvt::vrtp, ast_channel::writeformat, and XMIT_UNRELIABLE.

03479 {
03480    struct sip_pvt *p = ast->tech_pvt;
03481    int res = 0;
03482 
03483    switch (frame->frametype) {
03484    case AST_FRAME_VOICE:
03485       if (!(frame->subclass & ast->nativeformats)) {
03486          char s1[512], s2[512], s3[512];
03487          ast_log(LOG_WARNING, "Asked to transmit frame type %d, while native formats is %s(%d) read/write = %s(%d)/%s(%d)\n",
03488             frame->subclass, 
03489             ast_getformatname_multiple(s1, sizeof(s1) - 1, ast->nativeformats & AST_FORMAT_AUDIO_MASK),
03490             ast->nativeformats & AST_FORMAT_AUDIO_MASK,
03491             ast_getformatname_multiple(s2, sizeof(s2) - 1, ast->readformat),
03492             ast->readformat,
03493             ast_getformatname_multiple(s3, sizeof(s3) - 1, ast->writeformat),
03494             ast->writeformat);
03495          ast_frame_dump(ast->name, frame, "<<");
03496          ast_backtrace();
03497          return 0;
03498       }
03499       if (p) {
03500          ast_mutex_lock(&p->lock);
03501          if (p->rtp) {
03502             /* If channel is not up, activate early media session */
03503             if ((ast->_state != AST_STATE_UP) &&
03504                 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) &&
03505                 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
03506                transmit_response_with_sdp(p, "183 Session Progress", &p->initreq, XMIT_UNRELIABLE);
03507                ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT);  
03508             }
03509             p->lastrtptx = time(NULL);
03510             res = ast_rtp_write(p->rtp, frame);
03511          }
03512          ast_mutex_unlock(&p->lock);
03513       }
03514       break;
03515    case AST_FRAME_VIDEO:
03516       if (p) {
03517          ast_mutex_lock(&p->lock);
03518          if (p->vrtp) {
03519             /* Activate video early media */
03520             if ((ast->_state != AST_STATE_UP) &&
03521                 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) &&
03522                 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
03523                transmit_response_with_sdp(p, "183 Session Progress", &p->initreq, XMIT_UNRELIABLE);
03524                ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT);  
03525             }
03526             p->lastrtptx = time(NULL);
03527             res = ast_rtp_write(p->vrtp, frame);
03528          }
03529          ast_mutex_unlock(&p->lock);
03530       }
03531       break;
03532    case AST_FRAME_IMAGE:
03533       return 0;
03534       break;
03535    case AST_FRAME_MODEM:
03536       if (p) {
03537          ast_mutex_lock(&p->lock);
03538          /* UDPTL requires two-way communication, so early media is not needed here.
03539             we simply forget the frames if we get modem frames before the bridge is up.
03540             Fax will re-transmit.
03541          */
03542          if (p->udptl && ast->_state == AST_STATE_UP) 
03543             res = ast_udptl_write(p->udptl, frame);
03544          ast_mutex_unlock(&p->lock);
03545       }
03546       break;
03547    default: 
03548       ast_log(LOG_WARNING, "Can't send %d type frames with SIP write\n", frame->frametype);
03549       return 0;
03550    }
03551 
03552    return res;
03553 }

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

14857 {
14858    struct sip_request req;
14859    struct sockaddr_in sin = { 0, };
14860    struct sip_pvt *p;
14861    int res;
14862    socklen_t len = sizeof(sin);
14863    int nounlock;
14864    int recount = 0;
14865    int lockretry;
14866 
14867    memset(&req, 0, sizeof(req));
14868    res = recvfrom(sipsock, req.data, sizeof(req.data) - 1, 0, (struct sockaddr *)&sin, &len);
14869    if (res < 0) {
14870 #if !defined(__FreeBSD__)
14871       if (errno == EAGAIN)
14872          ast_log(LOG_NOTICE, "SIP: Received packet with bad UDP checksum\n");
14873       else 
14874 #endif
14875       if (errno != ECONNREFUSED)
14876          ast_log(LOG_WARNING, "Recv error: %s\n", strerror(errno));
14877       return 1;
14878    }
14879    if (option_debug && res == sizeof(req.data)) {
14880       ast_log(LOG_DEBUG, "Received packet exceeds buffer. Data is possibly lost\n");
14881       req.data[sizeof(req.data) - 1] = '\0';
14882    } else
14883       req.data[res] = '\0';
14884    req.len = res;
14885    if(sip_debug_test_addr(&sin)) /* Set the debug flag early on packet level */
14886       ast_set_flag(&req, SIP_PKT_DEBUG);
14887    if (pedanticsipchecking)
14888       req.len = lws2sws(req.data, req.len);  /* Fix multiline headers */
14889    if (ast_test_flag(&req, SIP_PKT_DEBUG))
14890       ast_verbose("\n<--- SIP read from %s:%d --->\n%s\n<------------->\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port), req.data);
14891 
14892    parse_request(&req);
14893    req.method = find_sip_method(req.rlPart1);
14894 
14895    if (ast_test_flag(&req, SIP_PKT_DEBUG))
14896       ast_verbose("--- (%d headers %d lines)%s ---\n", req.headers, req.lines, (req.headers + req.lines == 0) ? " Nat keepalive" : "");
14897 
14898    if (req.headers < 2) /* Must have at least two headers */
14899       return 1;
14900 
14901    /* Process request, with netlock held, and with usual deadlock avoidance */
14902    for (lockretry = 100; lockretry > 0; lockretry--) {
14903       ast_mutex_lock(&netlock);
14904 
14905       /* Find the active SIP dialog or create a new one */
14906       p = find_call(&req, &sin, req.method); /* returns p locked */
14907       if (p == NULL) {
14908          if (option_debug)
14909             ast_log(LOG_DEBUG, "Invalid SIP message - rejected , no callid, len %d\n", req.len);
14910          ast_mutex_unlock(&netlock);
14911          return 1;
14912       }
14913       /* Go ahead and lock the owner if it has one -- we may need it */
14914       /* becaues this is deadlock-prone, we need to try and unlock if failed */
14915       if (!p->owner || !ast_channel_trylock(p->owner))
14916          break;   /* locking succeeded */
14917       if (option_debug)
14918          ast_log(LOG_DEBUG, "Failed to grab owner channel lock, trying again. (SIP call %s)\n", p->callid);
14919       ast_mutex_unlock(&p->lock);
14920       ast_mutex_unlock(&netlock);
14921       /* Sleep for a very short amount of time */
14922       usleep(1);
14923    }
14924    p->recv = sin;
14925 
14926    if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) /* This is a request or response, note what it was for */
14927       append_history(p, "Rx", "%s / %s / %s", req.data, get_header(&req, "CSeq"), req.rlPart2);
14928 
14929    if (!lockretry) {
14930       if (p->owner)
14931          ast_log(LOG_ERROR, "We could NOT get the channel lock for %s! \n", S_OR(p->owner->name, "- no channel name ??? - "));
14932       ast_log(LOG_ERROR, "SIP transaction failed: %s \n", p->callid);
14933       if (req.method != SIP_ACK)
14934          transmit_response(p, "503 Server error", &req); /* We must respond according to RFC 3261 sec 12.2 */
14935       /* XXX We could add retry-after to make sure they come back */
14936       append_history(p, "LockFail", "Owner lock failed, transaction failed.");
14937       return 1;
14938    }
14939    nounlock = 0;
14940    if (handle_request(p, &req, &sin, &recount, &nounlock) == -1) {
14941       /* Request failed */
14942       if (option_debug)
14943          ast_log(LOG_DEBUG, "SIP message could not be handled, bad request: %-70.70s\n", p->callid[0] ? p->callid : "<no callid>");
14944    }
14945       
14946    if (p->owner && !nounlock)
14947       ast_channel_unlock(p->owner);
14948    ast_mutex_unlock(&p->lock);
14949    ast_mutex_unlock(&netlock);
14950    if (recount)
14951       ast_update_use_count();
14952 
14953    return 1;
14954 }

static void stop_media_flows ( struct sip_pvt p  )  [static]

Immediately stop RTP, VRTP and UDPTL as applicable.

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

12193 {
12194    /* Immediately stop RTP, VRTP and UDPTL as applicable */
12195    if (p->rtp)
12196       ast_rtp_stop(p->rtp);
12197    if (p->vrtp)
12198       ast_rtp_stop(p->vrtp);
12199    if (p->udptl)
12200       ast_udptl_stop(p->udptl);
12201 }

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

Show subscription type in string format.

Definition at line 10409 of file chan_sip.c.

References subscription_types, and type.

Referenced by sip_show_channel().

10410 {
10411    int i;
10412 
10413    for (i = 1; (i < (sizeof(subscription_types) / sizeof(subscription_types[0]))); i++) {
10414       if (subscription_types[i].type == subtype) {
10415          return subscription_types[i].text;
10416       }
10417    }
10418    return subscription_types[0].text;
10419 }

static int t38_get_rate ( int  t38cap  )  [static]

Get Max T.38 Transmission rate from T38 capabilities.

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

05982 {
05983    int maxrate = (t38cap & (T38FAX_RATE_14400 | T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400));
05984    
05985    if (maxrate & T38FAX_RATE_14400) {
05986       if (option_debug > 1)
05987          ast_log(LOG_DEBUG, "T38MaxFaxRate 14400 found\n");
05988       return 14400;
05989    } else if (maxrate & T38FAX_RATE_12000) {
05990       if (option_debug > 1)
05991          ast_log(LOG_DEBUG, "T38MaxFaxRate 12000 found\n");
05992       return 12000;
05993    } else if (maxrate & T38FAX_RATE_9600) {
05994       if (option_debug > 1)
05995          ast_log(LOG_DEBUG, "T38MaxFaxRate 9600 found\n");
05996       return 9600;
05997    } else if (maxrate & T38FAX_RATE_7200) {
05998       if (option_debug > 1)
05999          ast_log(LOG_DEBUG, "T38MaxFaxRate 7200 found\n");
06000       return 7200;
06001    } else if (maxrate & T38FAX_RATE_4800) {
06002       if (option_debug > 1)
06003          ast_log(LOG_DEBUG, "T38MaxFaxRate 4800 found\n");
06004       return 4800;
06005    } else if (maxrate & T38FAX_RATE_2400) {
06006       if (option_debug > 1)
06007          ast_log(LOG_DEBUG, "T38MaxFaxRate 2400 found\n");
06008       return 2400;
06009    } else {
06010       if (option_debug > 1)
06011          ast_log(LOG_DEBUG, "Strange, T38MaxFaxRate NOT found in peers T38 SDP.\n");
06012       return 0;
06013    }
06014 }

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

Create temporary peer (used in autocreatepeer mode).

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

15925 {
15926    struct sip_peer *peer;
15927 
15928    if (!(peer = ast_calloc(1, sizeof(*peer))))
15929       return NULL;
15930 
15931    apeerobjs++;
15932    ASTOBJ_INIT(peer);
15933    set_peer_defaults(peer);
15934 
15935    ast_copy_string(peer->name, name, sizeof(peer->name));
15936 
15937    ast_set_flag(&peer->flags[1], SIP_PAGE2_SELFDESTRUCT);
15938    ast_set_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC);
15939    peer->prefs = default_prefs;
15940    reg_source_db(peer);
15941 
15942    return peer;
15943 }

static void temp_pvt_cleanup ( void *   )  [static]

Definition at line 5760 of file chan_sip.c.

References ast_string_field_free_pools, and free.

05761 {
05762    struct sip_pvt *p = data;
05763 
05764    ast_string_field_free_pools(p);
05765 
05766    free(data);
05767 }

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

Convert transfer mode to text string.

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

09414 {
09415    if (mode == TRANSFER_OPENFORALL)
09416       return "open";
09417    else if (mode == TRANSFER_CLOSED)
09418       return "closed";
09419    return "strict";
09420 }

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

08256 {
08257    ast_string_field_build(p, randdata, "%08lx", ast_random()); /* Create nonce for challenge */
08258    transmit_response_with_auth(p, "401 Unauthorized", req, p->randdata, reliable, "WWW-Authenticate", 0);
08259 }

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

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

Referenced by sip_senddigit_end().

07501 {
07502    struct sip_request req;
07503 
07504    reqprep(&req, p, SIP_INFO, 0, 1);
07505    add_digit(&req, digit, duration);
07506    return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
07507 }

static int transmit_info_with_vidupdate ( struct sip_pvt p  )  [static]

Send SIP INFO with video update request.

Definition at line 7510 of file chan_sip.c.

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

Referenced by sip_indicate().

07511 {
07512    struct sip_request req;
07513 
07514    reqprep(&req, p, SIP_INFO, 0, 1);
07515    add_vidupdate(&req);
07516    return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
07517 }

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

References add_header(), add_header_contentLength(), add_sdp(), add_t38_sdp(), sip_invite_param::addsipheaders, ALLOWED_METHODS, append_date(), AST_LIST_TRAVERSE, ast_log(), ast_random(), ast_strdupa, ast_strlen_zero(), ast_udptl_offered_from_local(), ast_var_name(), ast_var_value(), sip_invite_param::auth, sip_invite_param::authheader, sip_pvt::branch, build_via(), sip_request::headers, initialize_initreq(), sip_pvt::initreq, initreqprep(), sip_pvt::lastinvite, LOG_DEBUG, LOG_WARNING, sip_request::method, sip_pvt::ocseq, option_debug, sip_pvt::options, sip_pvt::owner, sip_pvt::refer, sip_refer::refer_to, sip_refer::referred_by, sip_refer::referred_by_name, sip_invite_param::replaces, reqprep(), sip_pvt::rtp, send_request(), SIP_REFER, sipdebug, t38properties::state, SUPPORTED_EXTENSIONS, sip_pvt::t38, T38_LOCAL_DIRECT, sip_pvt::udptl, ast_channel::varshead, XMIT_CRITICAL, and XMIT_RELIABLE.

Referenced by do_proxy_auth(), sip_call(), and sip_poke_peer().

06782 {
06783    struct sip_request req;
06784    
06785    req.method = sipmethod;
06786    if (init) {    /* Seems like init always is 2 */
06787       /* Bump branch even on initial requests */
06788       p->branch ^= ast_random();
06789       build_via(p);
06790       if (init > 1)
06791          initreqprep(&req, p, sipmethod);
06792       else
06793          reqprep(&req, p, sipmethod, 0, 1);
06794    } else
06795       reqprep(&req, p, sipmethod, 0, 1);
06796       
06797    if (p->options && p->options->auth)
06798       add_header(&req, p->options->authheader, p->options->auth);
06799    append_date(&req);
06800    if (sipmethod == SIP_REFER) { /* Call transfer */
06801       if (p->refer) {
06802          char buf[BUFSIZ];
06803          if (!ast_strlen_zero(p->refer->refer_to))
06804             add_header(&req, "Refer-To", p->refer->refer_to);
06805          if (!ast_strlen_zero(p->refer->referred_by)) {
06806             sprintf(buf, "%s <%s>", p->refer->referred_by_name, p->refer->referred_by);
06807             add_header(&req, "Referred-By", buf);
06808          }
06809       }
06810    }
06811    /* This new INVITE is part of an attended transfer. Make sure that the
06812    other end knows and replace the current call with this new call */
06813    if (p->options && p->options->replaces && !ast_strlen_zero(p->options->replaces)) {
06814       add_header(&req, "Replaces", p->options->replaces);
06815       add_header(&req, "Require", "replaces");
06816    }
06817 
06818    add_header(&req, "Allow", ALLOWED_METHODS);
06819    add_header(&req, "Supported", SUPPORTED_EXTENSIONS);
06820    if (p->options && p->options->addsipheaders && p->owner) {
06821       struct ast_channel *ast = p->owner; /* The owner channel */
06822       struct varshead *headp = &ast->varshead;
06823 
06824          if (!headp)
06825             ast_log(LOG_WARNING,"No Headp for the channel...ooops!\n");
06826          else {
06827             const struct ast_var_t *current;
06828             AST_LIST_TRAVERSE(headp, current, entries) {  
06829                /* SIPADDHEADER: Add SIP header to outgoing call */
06830                if (!strncasecmp(ast_var_name(current), "SIPADDHEADER", strlen("SIPADDHEADER"))) {
06831                   char *content, *end;
06832                   const char *header = ast_var_value(current);
06833                   char *headdup = ast_strdupa(header);
06834 
06835                   /* Strip of the starting " (if it's there) */
06836                   if (*headdup == '"')
06837                      headdup++;
06838                   if ((content = strchr(headdup, ':'))) {
06839                      *content++ = '\0';
06840                      content = ast_skip_blanks(content); /* Skip white space */
06841                      /* Strip the ending " (if it's there) */
06842                      end = content + strlen(content) -1; 
06843                      if (*end == '"')
06844                         *end = '\0';
06845                   
06846                      add_header(&req, headdup, content);
06847                      if (sipdebug)
06848                         ast_log(LOG_DEBUG, "Adding SIP Header \"%s\" with content :%s: \n", headdup, content);
06849                   }
06850                }
06851             }
06852          }
06853    }
06854    if (sdp) {
06855       if (p->udptl && p->t38.state == T38_LOCAL_DIRECT) {
06856          ast_udptl_offered_from_local(p->udptl, 1);
06857          if (option_debug)
06858             ast_log(LOG_DEBUG, "T38 is in state %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>");
06859          add_t38_sdp(&req, p);
06860       } else if (p->rtp) 
06861          add_sdp(&req, p);
06862    } else {
06863       add_header_contentLength(&req, 0);
06864    }
06865 
06866    if (!p->initreq.headers)
06867       initialize_initreq(p, &req);
06868    p->lastinvite = p->ocseq;
06869    return send_request(p, &req, init ? XMIT_CRITICAL : XMIT_RELIABLE, p->ocseq);
06870 }

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

Transmit text with SIP MESSAGE method.

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

07409 {
07410    struct sip_request req;
07411 
07412    reqprep(&req, p, SIP_MESSAGE, 0, 1);
07413    add_text(&req, text);
07414    return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
07415 }

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

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

Referenced by sip_send_mwi_to_peer().

07049 {
07050    struct sip_request req;
07051    char tmp[500];
07052    char *t = tmp;
07053    size_t maxbytes = sizeof(tmp);
07054 
07055    initreqprep(&req, p, SIP_NOTIFY);
07056    add_header(&req, "Event", "message-summary");
07057    add_header(&req, "Content-Type", default_notifymime);
07058 
07059    ast_build_string(&t, &maxbytes, "Messages-Waiting: %s\r\n", newmsgs ? "yes" : "no");
07060    ast_build_string(&t, &maxbytes, "Message-Account: sip:%s@%s\r\n",
07061       S_OR(vmexten, default_vmexten), S_OR(p->fromdomain, ast_inet_ntoa(p->ourip)));
07062    /* Cisco has a bug in the SIP stack where it can't accept the
07063       (0/0) notification. This can temporarily be disabled in
07064       sip.conf with the "buggymwi" option */
07065    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)"));
07066 
07067    if (p->subscribed) {
07068       if (p->expiry)
07069          add_header(&req, "Subscription-State", "active");
07070       else  /* Expired */
07071          add_header(&req, "Subscription-State", "terminated;reason=timeout");
07072    }
07073 
07074    if (t > tmp + sizeof(tmp))
07075       ast_log(LOG_WARNING, "Buffer overflow detected!!  (Please file a bug report)\n");
07076 
07077    add_header_contentLength(&req, strlen(tmp));
07078    add_line(&req, tmp);
07079 
07080    if (!p->initreq.headers) 
07081       initialize_initreq(p, &req);
07082    return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
07083 }

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

07095 {
07096    struct sip_request req;
07097    char tmp[BUFSIZ/2];
07098 
07099    reqprep(&req, p, SIP_NOTIFY, 0, 1);
07100    snprintf(tmp, sizeof(tmp), "refer;id=%d", cseq);
07101    add_header(&req, "Event", tmp);
07102    add_header(&req, "Subscription-state", terminate ? "terminated;reason=noresource" : "active");
07103    add_header(&req, "Content-Type", "message/sipfrag;version=2.0");
07104    add_header(&req, "Allow", ALLOWED_METHODS);
07105    add_header(&req, "Supported", SUPPORTED_EXTENSIONS);
07106 
07107    snprintf(tmp, sizeof(tmp), "SIP/2.0 %s\r\n", message);
07108    add_header_contentLength(&req, strlen(tmp));
07109    add_line(&req, tmp);
07110 
07111    if (!p->initreq.headers)
07112       initialize_initreq(p, &req);
07113 
07114    return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
07115 }

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

07430 {
07431    struct sip_request req = { 
07432       .headers = 0,  
07433    };
07434    char from[256];
07435    const char *of;
07436    char *c;
07437    char referto[256];
07438    char *ttag, *ftag;
07439    char *theirtag = ast_strdupa(p->theirtag);
07440 
07441    if (option_debug || sipdebug)
07442       ast_log(LOG_DEBUG, "SIP transfer of %s to %s\n", p->callid, dest);
07443 
07444    /* Are we transfering an inbound or outbound call ? */
07445    if (ast_test_flag(&p->flags[0], SIP_OUTGOING))  {
07446       of = get_header(&p->initreq, "To");
07447       ttag = theirtag;
07448       ftag = p->tag;
07449    } else {
07450       of = get_header(&p->initreq, "From");
07451       ftag = theirtag;
07452       ttag = p->tag;
07453    }
07454 
07455    ast_copy_string(from, of, sizeof(from));
07456    of = get_in_brackets(from);
07457    ast_string_field_set(p, from, of);
07458    if (strncmp(of, "sip:", 4))
07459       ast_log(LOG_NOTICE, "From address missing 'sip:', using it anyway\n");
07460    else
07461       of += 4;
07462    /* Get just the username part */
07463    if ((c = strchr(dest, '@')))
07464       c = NULL;
07465    else if ((c = strchr(of, '@')))
07466       *c++ = '\0';
07467    if (c) 
07468       snprintf(referto, sizeof(referto), "<sip:%s@%s>", dest, c);
07469    else
07470       snprintf(referto, sizeof(referto), "<sip:%s>", dest);
07471 
07472    /* save in case we get 407 challenge */
07473    sip_refer_allocate(p);
07474    ast_copy_string(p->refer->refer_to, referto, sizeof(p->refer->refer_to));
07475    ast_copy_string(p->refer->referred_by, p->our_contact, sizeof(p->refer->referred_by));
07476    p->refer->status = REFER_SENT;   /* Set refer status */
07477 
07478    reqprep(&req, p, SIP_REFER, 0, 1);
07479    add_header(&req, "Max-Forwards", DEFAULT_MAX_FORWARDS);
07480 
07481    add_header(&req, "Refer-To", referto);
07482    add_header(&req, "Allow", ALLOWED_METHODS);
07483    add_header(&req, "Supported", SUPPORTED_EXTENSIONS);
07484    if (!ast_strlen_zero(p->our_contact))
07485       add_header(&req, "Referred-By", p->our_contact);
07486 
07487    return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
07488    /* We should propably wait for a NOTIFY here until we ack the transfer */
07489    /* Maybe fork a new thread and wait for a STATUS of REFER_200OK on the refer status before returning to app_transfer */
07490 
07491    /*! \todo In theory, we should hang around and wait for a reply, before
07492    returning to the dial plan here. Don't know really how that would
07493    affect the transfer() app or the pbx, but, well, to make this
07494    useful we should have a STATUS code on transfer().
07495    */
07496 }

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

References __ourip, add_header(), add_header_contentLength(), append_history, ast_log(), ast_random(), ast_sched_add(), ast_sched_del(), ast_set_flag, ast_sip_ouraddrfor(), ast_string_field_free, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_verbose(), ASTOBJ_REF, bindaddr, sip_pvt::branch, build_callid_registry(), build_contact(), build_reply_digest(), build_via(), sip_registry::call, sip_registry::callid_valid, create_addr(), DEFAULT_MAX_FORWARDS, exten, sip_pvt::flags, sip_request::headers, init_req(), initialize_initreq(), sip_pvt::initreq, sip_request::lines, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, make_our_tag(), sip_pvt::noncecount, sip_registry::noncecount, sip_pvt::ocseq, sip_registry::ocseq, option_debug, sip_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().

07218 {
07219    struct sip_request req;
07220    char from[256];
07221    char to[256];
07222    char tmp[80];
07223    char addr[80];
07224    struct sip_pvt *p;
07225 
07226    /* exit if we are already in process with this registrar ?*/
07227    if ( r == NULL || ((auth==NULL) && (r->regstate==REG_STATE_REGSENT || r->regstate==REG_STATE_AUTHSENT))) {
07228       ast_log(LOG_NOTICE, "Strange, trying to register %s@%s when registration already pending\n", r->username, r->hostname);
07229       return 0;
07230    }
07231 
07232    if (r->call) { /* We have a registration */
07233       if (!auth) {
07234          ast_log(LOG_WARNING, "Already have a REGISTER going on to %s@%s?? \n", r->username, r->hostname);
07235          return 0;
07236       } else {
07237          p = r->call;
07238          make_our_tag(p->tag, sizeof(p->tag));  /* create a new local tag for every register attempt */
07239          ast_string_field_free(p, theirtag); /* forget their old tag, so we don't match tags when getting response */
07240       }
07241    } else {
07242       /* Build callid for registration if we haven't registered before */
07243       if (!r->callid_valid) {
07244          build_callid_registry(r, __ourip, default_fromdomain);
07245          r->callid_valid = TRUE;
07246       }
07247       /* Allocate SIP packet for registration */
07248       if (!(p = sip_alloc( r->callid, NULL, 0, SIP_REGISTER))) {
07249          ast_log(LOG_WARNING, "Unable to allocate registration transaction (memory or socket error)\n");
07250          return 0;
07251       }
07252       if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY))
07253          append_history(p, "RegistryInit", "Account: %s@%s", r->username, r->hostname);
07254       /* Find address to hostname */
07255       if (create_addr(p, r->hostname)) {
07256          /* we have what we hope is a temporary network error,
07257           * probably DNS.  We need to reschedule a registration try */
07258          sip_destroy(p);
07259          if (r->timeout > -1) {
07260             ast_sched_del(sched, r->timeout);
07261             r->timeout = ast_sched_add(sched, global_reg_timeout*1000, sip_reg_timeout, r);
07262             ast_log(LOG_WARNING, "Still have a registration timeout for %s@%s (create_addr() error), %d\n", r->username, r->hostname, r->timeout);
07263          } else {
07264             r->timeout = ast_sched_add(sched, global_reg_timeout*1000, sip_reg_timeout, r);
07265             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);
07266          }
07267          r->regattempts++;
07268          return 0;
07269       }
07270       /* Copy back Call-ID in case create_addr changed it */
07271       ast_string_field_set(r, callid, p->callid);
07272       if (r->portno)
07273          p->sa.sin_port = htons(r->portno);
07274       else  /* Set registry port to the port set from the peer definition/srv or default */
07275          r->portno = ntohs(p->sa.sin_port);
07276       ast_set_flag(&p->flags[0], SIP_OUTGOING); /* Registration is outgoing call */
07277       r->call=p;        /* Save pointer to SIP packet */
07278       p->registry = ASTOBJ_REF(r);  /* Add pointer to registry in packet */
07279       if (!ast_strlen_zero(r->secret)) /* Secret (password) */
07280          ast_string_field_set(p, peersecret, r->secret);
07281       if (!ast_strlen_zero(r->md5secret))
07282          ast_string_field_set(p, peermd5secret, r->md5secret);
07283       /* User name in this realm  
07284       - if authuser is set, use that, otherwise use username */
07285       if (!ast_strlen_zero(r->authuser)) {   
07286          ast_string_field_set(p, peername, r->authuser);
07287          ast_string_field_set(p, authname, r->authuser);
07288       } else if (!ast_strlen_zero(r->username)) {
07289          ast_string_field_set(p, peername, r->username);
07290          ast_string_field_set(p, authname, r->username);
07291          ast_string_field_set(p, fromuser, r->username);
07292       }
07293       if (!ast_strlen_zero(r->username))
07294          ast_string_field_set(p, username, r->username);
07295       /* Save extension in packet */
07296       ast_string_field_set(p, exten, r->contact);
07297 
07298       /*
07299         check which address we should use in our contact header 
07300         based on whether the remote host is on the external or
07301         internal network so we can register through nat
07302        */
07303       if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
07304          p->ourip = bindaddr.sin_addr;
07305       build_contact(p);
07306    }
07307 
07308    /* set up a timeout */
07309    if (auth == NULL)  {
07310       if (r->timeout > -1) {
07311          ast_log(LOG_WARNING, "Still have a registration timeout, #%d - deleting it\n", r->timeout);
07312          ast_sched_del(sched, r->timeout);
07313       }
07314       r->timeout = ast_sched_add(sched, global_reg_timeout * 1000, sip_reg_timeout, r);
07315       if (option_debug)
07316          ast_log(LOG_DEBUG, "Scheduled a registration timeout for %s id  #%d \n", r->hostname, r->timeout);
07317    }
07318 
07319    if (strchr(r->username, '@')) {
07320       snprintf(from, sizeof(from), "<sip:%s>;tag=%s", r->username, p->tag);
07321       if (!ast_strlen_zero(p->theirtag))
07322          snprintf(to, sizeof(to), "<sip:%s>;tag=%s", r->username, p->theirtag);
07323       else
07324          snprintf(to, sizeof(to), "<sip:%s>", r->username);
07325    } else {
07326       snprintf(from, sizeof(from), "<sip:%s@%s>;tag=%s", r->username, p->tohost, p->tag);
07327       if (!ast_strlen_zero(p->theirtag))
07328          snprintf(to, sizeof(to), "<sip:%s@%s>;tag=%s", r->username, p->tohost, p->theirtag);
07329       else
07330          snprintf(to, sizeof(to), "<sip:%s@%s>", r->username, p->tohost);
07331    }
07332    
07333    /* Fromdomain is what we are registering to, regardless of actual
07334       host name from SRV */
07335    if (!ast_strlen_zero(p->fromdomain)) {
07336       if (r->portno && r->portno != STANDARD_SIP_PORT)
07337          snprintf(addr, sizeof(addr), "sip:%s:%d", p->fromdomain, r->portno);
07338       else
07339          snprintf(addr, sizeof(addr), "sip:%s", p->fromdomain);
07340    } else {
07341       if (r->portno && r->portno != STANDARD_SIP_PORT)
07342          snprintf(addr, sizeof(addr), "sip:%s:%d", r->hostname, r->portno);
07343       else
07344          snprintf(addr, sizeof(addr), "sip:%s", r->hostname);
07345    }
07346    ast_string_field_set(p, uri, addr);
07347 
07348    p->branch ^= ast_random();
07349 
07350    init_req(&req, sipmethod, addr);
07351 
07352    /* Add to CSEQ */
07353    snprintf(tmp, sizeof(tmp), "%u %s", ++r->ocseq, sip_methods[sipmethod].text);
07354    p->ocseq = r->ocseq;
07355 
07356    build_via(p);
07357    add_header(&req, "Via", p->via);
07358    add_header(&req, "From", from);
07359    add_header(&req, "To", to);
07360    add_header(&req, "Call-ID", p->callid);
07361    add_header(&req, "CSeq", tmp);
07362    if (!ast_strlen_zero(global_useragent))
07363       add_header(&req, "User-Agent", global_useragent);
07364    add_header(&req, "Max-Forwards", DEFAULT_MAX_FORWARDS);
07365 
07366    
07367    if (auth)   /* Add auth header */
07368       add_header(&req, authheader, auth);
07369    else if (!ast_strlen_zero(r->nonce)) {
07370       char digest[1024];
07371 
07372       /* We have auth data to reuse, build a digest header! */
07373       if (sipdebug)
07374          ast_log(LOG_DEBUG, "   >>> Re-using Auth data for %s@%s\n", r->username, r->hostname);
07375       ast_string_field_set(p, realm, r->realm);
07376       ast_string_field_set(p, nonce, r->nonce);
07377       ast_string_field_set(p, domain, r->domain);
07378       ast_string_field_set(p, opaque, r->opaque);
07379       ast_string_field_set(p, qop, r->qop);
07380       r->noncecount++;
07381       p->noncecount = r->noncecount;
07382 
07383       memset(digest,0,sizeof(digest));
07384       if(!build_reply_digest(p, sipmethod, digest, sizeof(digest)))
07385          add_header(&req, "Authorization", digest);
07386       else
07387          ast_log(LOG_NOTICE, "No authorization available for authentication of registration to %s@%s\n", r->username, r->hostname);
07388    
07389    }
07390 
07391    snprintf(tmp, sizeof(tmp), "%d", default_expiry);
07392    add_header(&req, "Expires", tmp);
07393    add_header(&req, "Contact", p->our_contact);
07394    add_header(&req, "Event", "registration");
07395    add_header_contentLength(&req, 0);
07396 
07397    initialize_initreq(p, &req);
07398    if (sip_debug_test_pvt(p))
07399       ast_verbose("REGISTER %d headers, %d lines\n", p->initreq.headers, p->initreq.lines);
07400    r->regstate = auth ? REG_STATE_AUTHSENT : REG_STATE_REGSENT;
07401    r->regattempts++; /* Another attempt */
07402    if (option_debug > 3)
07403       ast_verbose("REGISTER attempt %d to %s@%s\n", r->regattempts, r->username, r->hostname);
07404    return send_request(p, &req, XMIT_CRITICAL, p->ocseq);
07405 }

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

06502 {
06503    struct sip_request req;
06504 
06505    reqprep(&req, p, ast_test_flag(&p->flags[0], SIP_REINVITE_UPDATE) ?  SIP_UPDATE : SIP_INVITE, 0, 1);
06506    
06507    add_header(&req, "Allow", ALLOWED_METHODS);
06508    add_header(&req, "Supported", SUPPORTED_EXTENSIONS);
06509    if (sipdebug)
06510       add_header(&req, "X-asterisk-Info", "SIP re-invite (External RTP bridge)");
06511    if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY))
06512       append_history(p, "ReInv", "Re-invite sent");
06513    add_sdp(&req, p);
06514    /* Use this as the basis */
06515    initialize_initreq(p, &req);
06516    p->lastinvite = p->ocseq;
06517    ast_set_flag(&p->flags[0], SIP_OUTGOING);    /* Change direction of this dialog */
06518    return send_request(p, &req, XMIT_CRITICAL, p->ocseq);
06519 }

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

06526 {
06527    struct sip_request req;
06528 
06529    reqprep(&req, p, ast_test_flag(&p->flags[0], SIP_REINVITE_UPDATE) ?  SIP_UPDATE : SIP_INVITE, 0, 1);
06530    
06531    add_header(&req, "Allow", ALLOWED_METHODS);
06532    add_header(&req, "Supported", SUPPORTED_EXTENSIONS);
06533    if (sipdebug)
06534       add_header(&req, "X-asterisk-info", "SIP re-invite (T38 switchover)");
06535    ast_udptl_offered_from_local(p->udptl, 1);
06536    add_t38_sdp(&req, p);
06537    /* Use this as the basis */
06538    initialize_initreq(p, &req);
06539    ast_set_flag(&p->flags[0], SIP_OUTGOING);    /* Change direction of this dialog */
06540    p->lastinvite = p->ocseq;
06541    return send_request(p, &req, XMIT_CRITICAL, p->ocseq);
06542 }

static int transmit_request ( struct sip_pvt p,
int  sipmethod,
int  inc,
enum xmittype  reliable,
int  newbranch 
) [static]

Transmit generic SIP request.

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

07521 {
07522    struct sip_request resp;
07523 
07524    if (sipmethod == SIP_ACK)
07525       p->invitestate = INV_CONFIRMED;
07526 
07527    reqprep(&resp, p, sipmethod, seqno, newbranch);
07528    add_header_contentLength(&resp, 0);
07529    return send_request(p, &resp, reliable, seqno ? seqno : p->ocseq);
07530 }

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

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

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

07534 {
07535    struct sip_request resp;
07536 
07537    reqprep(&resp, p, sipmethod, seqno, newbranch);
07538    if (!ast_strlen_zero(p->realm)) {
07539       char digest[1024];
07540 
07541       memset(digest, 0, sizeof(digest));
07542       if(!build_reply_digest(p, sipmethod, digest, sizeof(digest))) {
07543          if (p->options && p->options->auth_type == PROXY_AUTH)
07544             add_header(&resp, "Proxy-Authorization", digest);
07545          else if (p->options && p->options->auth_type == WWW_AUTH)
07546             add_header(&resp, "Authorization", digest);
07547          else  /* Default, to be backwards compatible (maybe being too careful, but leaving it for now) */
07548             add_header(&resp, "Proxy-Authorization", digest);
07549       } else
07550          ast_log(LOG_WARNING, "No authentication available for call %s\n", p->callid);
07551    }
07552    /* If we are hanging up and know a cause for that, send it in clear text to make
07553       debugging easier. */
07554    if (sipmethod == SIP_BYE && p->owner && p->owner->hangupcause) {
07555       char buf[10];
07556 
07557       add_header(&resp, "X-Asterisk-HangupCause", ast_cause2str(p->owner->hangupcause));
07558       snprintf(buf, sizeof(buf), "%d", p->owner->hangupcause);
07559       add_header(&resp, "X-Asterisk-HangupCauseCode", buf);
07560    }
07561 
07562    add_header_contentLength(&resp, 0);
07563    return send_request(p, &resp, reliable, seqno ? seqno : p->ocseq);   
07564 }

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

Transmit response, no retransmits.

Definition at line 5820 of file chan_sip.c.

References __transmit_response(), and XMIT_UNRELIABLE.

05821 {
05822    return __transmit_response(p, msg, req, XMIT_UNRELIABLE);
05823 }

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

05840 {
05841    return __transmit_response(p, msg, req, XMIT_CRITICAL);
05842 }

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

05771 {
05772    struct sip_pvt *p = NULL;
05773 
05774    if (!(p = ast_threadstorage_get(&ts_temp_pvt, sizeof(*p)))) {
05775       ast_log(LOG_NOTICE, "Failed to get temporary pvt\n");
05776       return -1;
05777    }
05778 
05779    /* if the structure was just allocated, initialize it */
05780    if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) {
05781       ast_set_flag(&p->flags[0], SIP_NO_HISTORY);
05782       if (ast_string_field_init(p, 512))
05783          return -1;
05784    }
05785 
05786    /* Initialize the bare minimum */
05787    p->method = intended_method;
05788 
05789    if (sin) {
05790       p->sa = *sin;
05791       if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
05792          p->ourip = __ourip;
05793    } else
05794       p->ourip = __ourip;
05795 
05796    p->branch = ast_random();
05797    make_our_tag(p->tag, sizeof(p->tag));
05798    p->ocseq = INITIAL_CSEQ;
05799 
05800    if (useglobal_nat && sin) {
05801       ast_copy_flags(&p->flags[0], &global_flags[0], SIP_NAT);
05802       p->recv = *sin;
05803       do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE);
05804    }
05805 
05806    ast_string_field_set(p, fromdomain, default_fromdomain);
05807    build_via(p);
05808    ast_string_field_set(p, callid, callid);
05809 
05810    /* Use this temporary pvt structure to send the message */
05811    __transmit_response(p, msg, req, XMIT_UNRELIABLE);
05812 
05813    /* Free the string fields, but not the pool space */
05814    ast_string_field_free_all(p);
05815 
05816    return 0;
05817 }

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

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

Referenced by handle_request(), and handle_request_options().

05868 {
05869    struct sip_request resp;
05870    respprep(&resp, p, msg, req);
05871    add_header(&resp, "Accept", "application/sdp");
05872    add_header_contentLength(&resp, 0);
05873    return send_response(p, &resp, reliable, 0);
05874 }

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

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

Referenced by check_auth(), and transmit_fake_auth_response().

05878 {
05879    struct sip_request resp;
05880    char tmp[512];
05881    int seqno = 0;
05882 
05883    if (reliable && (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1)) {
05884       ast_log(LOG_WARNING, "Unable to determine sequence number from '%s'\n", get_header(req, "CSeq"));
05885       return -1;
05886    }
05887    /* Stale means that they sent us correct authentication, but 
05888       based it on an old challenge (nonce) */
05889    snprintf(tmp, sizeof(tmp), "Digest algorithm=MD5, realm=\"%s\", nonce=\"%s\"%s", global_realm, randdata, stale ? ", stale=true" : "");
05890    respprep(&resp, p, msg, req);
05891    add_header(&resp, header, tmp);
05892    add_header_contentLength(&resp, 0);
05893    append_history(p, "AuthChal", "Auth challenge sent for %s - nc %d", p->username, p->noncecount);
05894    return send_response(p, &resp, reliable, seqno);
05895 }

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

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

Referenced by register_verify().

05858 {
05859    struct sip_request resp;
05860    respprep(&resp, p, msg, req);
05861    append_date(&resp);
05862    add_header_contentLength(&resp, 0);
05863    return send_response(p, &resp, XMIT_UNRELIABLE, 0);
05864 }

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.

Definition at line 6430 of file chan_sip.c.

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

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

06431 {
06432    struct sip_request resp;
06433    int seqno;
06434    if (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1) {
06435       ast_log(LOG_WARNING, "Unable to get seqno from '%s'\n", get_header(req, "CSeq"));
06436       return -1;
06437    }
06438    respprep(&resp, p, msg, req);
06439    if (p->rtp) {
06440       if (!p->autoframing && !ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
06441          if (option_debug)
06442             ast_log(LOG_DEBUG, "Setting framing from config on incoming call\n");
06443          ast_rtp_codec_setpref(p->rtp, &p->prefs);
06444       }
06445       try_suggested_sip_codec(p);   
06446       add_sdp(&resp, p);
06447    } else 
06448       ast_log(LOG_ERROR, "Can't add SDP to response, since we have no RTP session allocated. Call-ID %s\n", p->callid);
06449    if (reliable && !p->pendinginvite)
06450       p->pendinginvite = seqno;     /* Buggy clients sends ACK on RINGING too */
06451    return send_response(p, &resp, reliable, seqno);
06452 }

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

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

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

06393 {
06394    struct sip_request resp;
06395    int seqno;
06396    
06397    if (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1) {
06398       ast_log(LOG_WARNING, "Unable to get seqno from '%s'\n", get_header(req, "CSeq"));
06399       return -1;
06400    }
06401    respprep(&resp, p, msg, req);
06402    if (p->udptl) {
06403       ast_udptl_offered_from_local(p->udptl, 0);
06404       add_t38_sdp(&resp, p);
06405    } else 
06406       ast_log(LOG_ERROR, "Can't add SDP to response, since we have no UDPTL session allocated. Call-ID %s\n", p->callid);
06407    if (retrans && !p->pendinginvite)
06408       p->pendinginvite = seqno;     /* Buggy clients sends ACK on RINGING too */
06409    return send_response(p, &resp, retrans, seqno);
06410 }

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

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

Referenced by handle_request_invite().

05827 {
05828    struct sip_request resp;
05829    respprep(&resp, p, msg, req);
05830    append_date(&resp);
05831    add_header(&resp, "Unsupported", unsupported);
05832    add_header_contentLength(&resp, 0);
05833    return send_response(p, &resp, XMIT_UNRELIABLE, 0);
05834 }

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

07087 {
07088    if (!p->initreq.headers)   /* Initialize first request before sending */
07089       initialize_initreq(p, req);
07090    return send_request(p, req, XMIT_UNRELIABLE, p->ocseq);
07091 }

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

06874 {
06875    char tmp[4000], from[256], to[256];
06876    char *t = tmp, *c, *mfrom, *mto;
06877    size_t maxbytes = sizeof(tmp);
06878    struct sip_request req;
06879    char hint[AST_MAX_EXTENSION];
06880    char *statestring = "terminated";
06881    const struct cfsubscription_types *subscriptiontype;
06882    enum state { NOTIFY_OPEN, NOTIFY_INUSE, NOTIFY_CLOSED } local_state = NOTIFY_OPEN;
06883    char *pidfstate = "--";
06884    char *pidfnote= "Ready";
06885 
06886    memset(from, 0, sizeof(from));
06887    memset(to, 0, sizeof(to));
06888    memset(tmp, 0, sizeof(tmp));
06889 
06890    switch (state) {
06891    case (AST_EXTENSION_RINGING | AST_EXTENSION_INUSE):
06892       statestring = (global_notifyringing) ? "early" : "confirmed";
06893       local_state = NOTIFY_INUSE;
06894       pidfstate = "busy";
06895       pidfnote = "Ringing";
06896       break;
06897    case AST_EXTENSION_RINGING:
06898       statestring = "early";
06899       local_state = NOTIFY_INUSE;
06900       pidfstate = "busy";
06901       pidfnote = "Ringing";
06902       break;
06903    case AST_EXTENSION_INUSE:
06904       statestring = "confirmed";
06905       local_state = NOTIFY_INUSE;
06906       pidfstate = "busy";
06907       pidfnote = "On the phone";
06908       break;
06909    case AST_EXTENSION_BUSY:
06910       statestring = "confirmed";
06911       local_state = NOTIFY_CLOSED;
06912       pidfstate = "busy";
06913       pidfnote = "On the phone";
06914       break;
06915    case AST_EXTENSION_UNAVAILABLE:
06916       statestring = "terminated";
06917       local_state = NOTIFY_CLOSED;
06918       pidfstate = "away";
06919       pidfnote = "Unavailable";
06920       break;
06921    case AST_EXTENSION_ONHOLD:
06922       statestring = "confirmed";
06923       local_state = NOTIFY_INUSE;
06924       pidfstate = "busy";
06925       pidfnote = "On Hold";
06926       break;
06927    case AST_EXTENSION_NOT_INUSE:
06928    default:
06929       /* Default setting */
06930       break;
06931    }
06932 
06933    subscriptiontype = find_subscription_type(p->subscribed);
06934    
06935    /* Check which device/devices we are watching  and if they are registered */
06936    if (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, p->context, p->exten)) {
06937       /* If they are not registered, we will override notification and show no availability */
06938       if (ast_device_state(hint) == AST_DEVICE_UNAVAILABLE) {
06939          local_state = NOTIFY_CLOSED;
06940          pidfstate = "away";
06941          pidfnote = "Not online";
06942       }
06943    }
06944 
06945    ast_copy_string(from, get_header(&p->initreq, "From"), sizeof(from));
06946    c = get_in_brackets(from);
06947    if (strncmp(c, "sip:", 4)) {
06948       ast_log(LOG_WARNING, "Huh?  Not a SIP header (%s)?\n", c);
06949       return -1;
06950    }
06951    mfrom = strsep(&c, ";");   /* trim ; and beyond */
06952 
06953    ast_copy_string(to, get_header(&p->initreq, "To"), sizeof(to));
06954    c = get_in_brackets(to);
06955    if (strncmp(c, "sip:", 4)) {
06956       ast_log(LOG_WARNING, "Huh?  Not a SIP header (%s)?\n", c);
06957       return -1;
06958    }
06959    mto = strsep(&c, ";");  /* trim ; and beyond */
06960 
06961    reqprep(&req, p, SIP_NOTIFY, 0, 1);
06962 
06963    
06964    add_header(&req, "Event", subscriptiontype->event);
06965    add_header(&req, "Content-Type", subscriptiontype->mediatype);
06966    switch(state) {
06967    case AST_EXTENSION_DEACTIVATED:
06968       if (timeout)
06969          add_header(&req, "Subscription-State", "terminated;reason=timeout");
06970       else {
06971          add_header(&req, "Subscription-State", "terminated;reason=probation");
06972          add_header(&req, "Retry-After", "60");
06973       }
06974       break;
06975    case AST_EXTENSION_REMOVED:
06976       add_header(&req, "Subscription-State", "terminated;reason=noresource");
06977       break;
06978    default:
06979       if (p->expiry)
06980          add_header(&req, "Subscription-State", "active");
06981       else  /* Expired */
06982          add_header(&req, "Subscription-State", "terminated;reason=timeout");
06983    }
06984    switch (p->subscribed) {
06985    case XPIDF_XML:
06986    case CPIM_PIDF_XML:
06987       ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\"?>\n");
06988       ast_build_string(&t, &maxbytes, "<!DOCTYPE presence PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n");
06989       ast_build_string(&t, &maxbytes, "<presence>\n");
06990       ast_build_string(&t, &maxbytes, "<presentity uri=\"%s;method=SUBSCRIBE\" />\n", mfrom);
06991       ast_build_string(&t, &maxbytes, "<atom id=\"%s\">\n", p->exten);
06992       ast_build_string(&t, &maxbytes, "<address uri=\"%s;user=ip\" priority=\"0.800000\">\n", mto);
06993       ast_build_string(&t, &maxbytes, "<status status=\"%s\" />\n", (local_state ==  NOTIFY_OPEN) ? "open" : (local_state == NOTIFY_INUSE) ? "inuse" : "closed");
06994       ast_build_string(&t, &maxbytes, "<msnsubstatus substatus=\"%s\" />\n", (local_state == NOTIFY_OPEN) ? "online" : (local_state == NOTIFY_INUSE) ? "onthephone" : "offline");
06995       ast_build_string(&t, &maxbytes, "</address>\n</atom>\n</presence>\n");
06996       break;
06997    case PIDF_XML: /* Eyebeam supports this format */
06998       ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n");
06999       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);
07000       ast_build_string(&t, &maxbytes, "<pp:person><status>\n");
07001       if (pidfstate[0] != '-')
07002          ast_build_string(&t, &maxbytes, "<ep:activities><ep:%s/></ep:activities>\n", pidfstate);
07003       ast_build_string(&t, &maxbytes, "</status></pp:person>\n");
07004       ast_build_string(&t, &maxbytes, "<note>%s</note>\n", pidfnote); /* Note */
07005       ast_build_string(&t, &maxbytes, "<tuple id=\"%s\">\n", p->exten); /* Tuple start */
07006       ast_build_string(&t, &maxbytes, "<contact priority=\"1\">%s</contact>\n", mto);
07007       if (pidfstate[0] == 'b') /* Busy? Still open ... */
07008          ast_build_string(&t, &maxbytes, "<status><basic>open</basic></status>\n");
07009       else
07010          ast_build_string(&t, &maxbytes, "<status><basic>%s</basic></status>\n", (local_state != NOTIFY_CLOSED) ? "open" : "closed");
07011       ast_build_string(&t, &maxbytes, "</tuple>\n</presence>\n");
07012       break;
07013    case DIALOG_INFO_XML: /* SNOM subscribes in this format */
07014       ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\"?>\n");
07015       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);
07016       if ((state & AST_EXTENSION_RINGING) && global_notifyringing)
07017          ast_build_string(&t, &maxbytes, "<dialog id=\"%s\" direction=\"recipient\">\n", p->exten);
07018       else
07019          ast_build_string(&t, &maxbytes, "<dialog id=\"%s\">\n", p->exten);
07020       ast_build_string(&t, &maxbytes, "<state>%s</state>\n", statestring);
07021       if (state == AST_EXTENSION_ONHOLD) {
07022          ast_build_string(&t, &maxbytes, "<local>\n<target uri=\"%s\">\n"
07023                                          "<param pname=\"+sip.rendering\" pvalue=\"no\">\n"
07024                                          "</target>\n</local>\n", mto);
07025       }
07026       ast_build_string(&t, &maxbytes, "</dialog>\n</dialog-info>\n");
07027       break;
07028    case NONE:
07029    default:
07030       break;
07031    }
07032 
07033    if (t > tmp + sizeof(tmp))
07034       ast_log(LOG_WARNING, "Buffer overflow detected!!  (Please file a bug report)\n");
07035 
07036    add_header_contentLength(&req, strlen(tmp));
07037    add_line(&req, tmp);
07038 
07039    return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
07040 }

static void try_suggested_sip_codec ( struct sip_pvt p  )  [static]

Try setting codec suggested by the SIP_CODEC channel variable.

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

03430 {
03431    int fmt;
03432    const char *codec;
03433 
03434    codec = pbx_builtin_getvar_helper(p->owner, "SIP_CODEC");
03435    if (!codec) 
03436       return;
03437 
03438    fmt = ast_getformatbyname(codec);
03439    if (fmt) {
03440       ast_log(LOG_NOTICE, "Changing codec to '%s' for this call because of ${SIP_CODEC} variable\n", codec);
03441       if (p->jointcapability & fmt) {
03442          p->jointcapability &= fmt;
03443          p->capability &= fmt;
03444       } else
03445          ast_log(LOG_NOTICE, "Ignoring ${SIP_CODEC} variable because it is not shared by both ends.\n");
03446    } else
03447       ast_log(LOG_NOTICE, "Ignoring ${SIP_CODEC} variable because of unrecognized/not configured codec (check allow/disallow in sip.conf): %s\n", codec);
03448    return;  
03449 }

static int unload_module ( void   )  [static]

PBX unload module API.

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

17466 {
17467    struct sip_pvt *p, *pl;
17468    
17469    /* First, take us out of the channel type list */
17470    ast_channel_unregister(&sip_tech);
17471 
17472    /* Unregister dial plan functions */
17473    ast_custom_function_unregister(&sipchaninfo_function);
17474    ast_custom_function_unregister(&sippeer_function);
17475    ast_custom_function_unregister(&sip_header_function);
17476    ast_custom_function_unregister(&checksipdomain_function);
17477 
17478    /* Unregister dial plan applications */
17479    ast_unregister_application(app_dtmfmode);
17480    ast_unregister_application(app_sipaddheader);
17481 
17482    /* Unregister CLI commands */
17483    ast_cli_unregister_multiple(cli_sip, sizeof(cli_sip) / sizeof(struct ast_cli_entry));
17484 
17485    /* Disconnect from the RTP subsystem */
17486    ast_rtp_proto_unregister(&sip_rtp);
17487 
17488    /* Disconnect from UDPTL */
17489    ast_udptl_proto_unregister(&sip_udptl);
17490 
17491    /* Unregister AMI actions */
17492    ast_manager_unregister("SIPpeers");
17493    ast_manager_unregister("SIPshowpeer");
17494 
17495    ast_mutex_lock(&iflock);
17496    /* Hangup all interfaces if they have an owner */
17497    for (p = iflist; p ; p = p->next) {
17498       if (p->owner)
17499          ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD);
17500    }
17501    ast_mutex_unlock(&iflock);
17502 
17503    ast_mutex_lock(&monlock);
17504    if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP)) {
17505       pthread_cancel(monitor_thread);
17506       pthread_kill(monitor_thread, SIGURG);
17507       pthread_join(monitor_thread, NULL);
17508    }
17509    monitor_thread = AST_PTHREADT_STOP;
17510    ast_mutex_unlock(&monlock);
17511 
17512    ast_mutex_lock(&iflock);
17513    /* Destroy all the interfaces and free their memory */
17514    p = iflist;
17515    while (p) {
17516       pl = p;
17517       p = p->next;
17518       __sip_destroy(pl, TRUE);
17519    }
17520    iflist = NULL;
17521    ast_mutex_unlock(&iflock);
17522 
17523    /* Free memory for local network address mask */
17524    ast_free_ha(localaddr);
17525 
17526    ASTOBJ_CONTAINER_DESTROYALL(&userl, sip_destroy_user);
17527    ASTOBJ_CONTAINER_DESTROY(&userl);
17528    ASTOBJ_CONTAINER_DESTROYALL(&peerl, sip_destroy_peer);
17529    ASTOBJ_CONTAINER_DESTROY(&peerl);
17530    ASTOBJ_CONTAINER_DESTROYALL(&regl, sip_registry_destroy);
17531    ASTOBJ_CONTAINER_DESTROY(&regl);
17532 
17533    clear_realm_authentication(authl);
17534    clear_sip_domains();
17535    close(sipsock);
17536    sched_context_destroy(sched);
17537       
17538    return 0;
17539 }

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

References ast_clear_flag, ast_device_state_changed(), ast_log(), ast_set_flag, ast_strlen_zero(), ast_test_flag, ASTOBJ_UNREF, sip_peer::call_limit, sip_user::call_limit, DEC_CALL_LIMIT, DEC_CALL_RINGING, FALSE, find_peer(), find_user(), sip_pvt::flags, INC_CALL_LIMIT, INC_CALL_RINGING, sip_peer::inRinging, sip_peer::inUse, sip_user::inUse, inuse, LOG_DEBUG, LOG_ERROR, LOG_WARNING, name, option_debug, SIP_CALL_LIMIT, sip_destroy_peer(), sip_destroy_user(), SIP_INC_COUNT, SIP_PAGE2_CALL_ONHOLD, SIP_PAGE2_INC_RINGING, SIP_PAGE2_OUTGOING_CALL, sip_peer_hold(), and sipdebug.

Referenced by __sip_destroy(), handle_request_invite(), handle_response_invite(), sip_call(), and sip_hangup().

02996 {
02997    char name[256];
02998    int *inuse = NULL, *call_limit = NULL, *inringing = NULL;
02999    int outgoing = ast_test_flag(&fup->flags[1], SIP_PAGE2_OUTGOING_CALL);
03000    struct sip_user *u = NULL;
03001    struct sip_peer *p = NULL;
03002 
03003    if (option_debug > 2)
03004       ast_log(LOG_DEBUG, "Updating call counter for %s call\n", outgoing ? "outgoing" : "incoming");
03005    /* Test if we need to check call limits, in order to avoid 
03006       realtime lookups if we do not need it */
03007    if (!ast_test_flag(&fup->flags[0], SIP_CALL_LIMIT))
03008       return 0;
03009 
03010    ast_copy_string(name, fup->username, sizeof(name));
03011 
03012    /* Check the list of users only for incoming calls */
03013    if (global_limitonpeers == FALSE && !outgoing && (u = find_user(name, 1)))  {
03014       inuse = &u->inUse;
03015       call_limit = &u->call_limit;
03016       inringing = NULL;
03017    } else if ( (p = find_peer(ast_strlen_zero(fup->peername) ? name : fup->peername, NULL, 1) ) ) { /* Try to find peer */
03018       inuse = &p->inUse;
03019       call_limit = &p->call_limit;
03020       inringing = &p->inRinging;
03021       ast_copy_string(name, fup->peername, sizeof(name));
03022    } 
03023    if (!p && !u) {
03024       if (option_debug > 1)
03025          ast_log(LOG_DEBUG, "%s is not a local device, no call limit\n", name);
03026       return 0;
03027    }
03028 
03029    switch(event) {
03030    /* incoming and outgoing affects the inUse counter */
03031    case DEC_CALL_LIMIT:
03032       if ( *inuse > 0 ) {
03033          if (ast_test_flag(&fup->flags[0], SIP_INC_COUNT)) {
03034             (*inuse)--;
03035             ast_clear_flag(&fup->flags[0], SIP_INC_COUNT);
03036          }
03037       } else {
03038          *inuse = 0;
03039       }
03040       if (inringing) {
03041          if (ast_test_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING)) {
03042             if (*inringing > 0)
03043                (*inringing)--;
03044             else
03045                ast_log(LOG_WARNING, "Inringing for peer '%s' < 0?\n", fup->peername);
03046             ast_clear_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING);
03047          }
03048       }
03049       if (ast_test_flag(&fup->flags[1], SIP_PAGE2_CALL_ONHOLD) && global_notifyhold)
03050          sip_peer_hold(fup, 0);
03051       if (option_debug > 1 || sipdebug) {
03052          ast_log(LOG_DEBUG, "Call %s %s '%s' removed from call limit %d\n", outgoing ? "to" : "from", u ? "user":"peer", name, *call_limit);
03053       }
03054       break;
03055 
03056    case INC_CALL_RINGING:
03057    case INC_CALL_LIMIT:
03058       if (*call_limit > 0 ) {
03059          if (*inuse >= *call_limit) {
03060             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);
03061             if (u)
03062                ASTOBJ_UNREF(u, sip_destroy_user);
03063             else
03064                ASTOBJ_UNREF(p, sip_destroy_peer);
03065             return -1; 
03066          }
03067       }
03068       if (inringing && (event == INC_CALL_RINGING)) {
03069          if (!ast_test_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING)) {
03070             (*inringing)++;
03071             ast_set_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING);
03072          }
03073       }
03074       /* Continue */
03075       (*inuse)++;
03076       ast_set_flag(&fup->flags[0], SIP_INC_COUNT);
03077       if (option_debug > 1 || sipdebug) {
03078          ast_log(LOG_DEBUG, "Call %s %s '%s' is %d out of %d\n", outgoing ? "to" : "from", u ? "user":"peer", name, *inuse, *call_limit);
03079       }
03080       break;
03081 
03082    case DEC_CALL_RINGING:
03083       if (inringing) {
03084          if (ast_test_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING)) {
03085             if (*inringing > 0)
03086                (*inringing)--;
03087             else
03088                ast_log(LOG_WARNING, "Inringing for peer '%s' < 0?\n", p->name);
03089             ast_clear_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING);
03090          }
03091       }
03092       break;
03093 
03094    default:
03095       ast_log(LOG_ERROR, "update_call_counter(%s, %d) called with no event!\n", name, event);
03096    }
03097    if (p) {
03098       ast_device_state_changed("SIP/%s", p->name);
03099       ASTOBJ_UNREF(p, sip_destroy_peer);
03100    } else /* u must be set */
03101       ASTOBJ_UNREF(u, sip_destroy_user);
03102    return 0;
03103 }

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

Update peer data in database (if used).

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

02393 {
02394    int rtcachefriends = ast_test_flag(&p->flags[1], SIP_PAGE2_RTCACHEFRIENDS);
02395    if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTUPDATE) &&
02396        (ast_test_flag(&p->flags[0], SIP_REALTIME) || rtcachefriends)) {
02397       realtime_update_peer(p->name, &p->addr, p->username, rtcachefriends ? p->fullcontact : NULL, expiry);
02398    }
02399 }


Variable Documentation

struct in_addr __ourip [static]

Definition at line 1188 of file chan_sip.c.

int allow_external_domains [static]

Accept calls to external SIP domains?

Definition at line 554 of file chan_sip.c.

int apeerobjs = 0 [static]

Autocreated peer objects

Definition at line 570 of file chan_sip.c.

char* app_dtmfmode = "SIPDtmfMode" [static]

Definition at line 17005 of file chan_sip.c.

char* app_sipaddheader = "SIPAddHeader" [static]

Definition at line 17007 of file chan_sip.c.

struct sip_auth* authl = NULL [static]

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

struct sockaddr_in bindaddr = { 0, } [static]

The address we bind to

Definition at line 1182 of file chan_sip.c.

struct ast_custom_function checksipdomain_function [static]

Definition at line 11427 of file chan_sip.c.

Referenced by load_module(), and unload_module().

struct ast_cli_entry cli_sip[] [static]

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

int compactheaders [static]

send compact sip headers

Definition at line 548 of file chan_sip.c.

const char config[] = "sip.conf" [static]

Definition at line 222 of file chan_sip.c.

char debug_usage[] [static]

Definition at line 11311 of file chan_sip.c.

struct sockaddr_in debugaddr [static]

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

char default_context[AST_MAX_CONTEXT] [static]

Definition at line 511 of file chan_sip.c.

int default_expiry = DEFAULT_DEFAULT_EXPIRY [static]

Definition at line 185 of file chan_sip.c.

char default_fromdomain[AST_MAX_EXTENSION] [static]

Definition at line 515 of file chan_sip.c.

struct ast_jb_conf default_jbconf [static]

Global jitterbuffer configuration - by default, jb is disabled.

Definition at line 213 of file chan_sip.c.

char default_language[MAX_LANGUAGE] [static]

Definition at line 513 of file chan_sip.c.

int default_maxcallbitrate [static]

Maximum bitrate for call

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

char default_notifymime[AST_MAX_EXTENSION] [static]

Definition at line 516 of file chan_sip.c.

struct ast_codec_pref default_prefs [static]

Default codec prefs

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

char default_subscribecontext[AST_MAX_CONTEXT] [static]

Definition at line 512 of file chan_sip.c.

char default_vmexten[AST_MAX_EXTENSION] [static]

Definition at line 518 of file chan_sip.c.

char* descrip_dtmfmode = "SIPDtmfMode(inband|info|rfc2833): Changes the dtmfmode for a SIP call\n" [static]

Definition at line 17004 of file chan_sip.c.

char* descrip_sipaddheader [static]

Definition at line 17010 of file chan_sip.c.

int dumphistory [static]

Dump history to verbose before destroying SIP dialog

Definition at line 550 of file chan_sip.c.

int expiry = DEFAULT_EXPIRY [static]

Definition at line 186 of file chan_sip.c.

time_t externexpire = 0 [static]

Expiration counter for re-resolving external host name in dynamic DNS

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

int externrefresh = 10 [static]

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

enum transfermodes global_allowtransfer [static]

SIP Refer restriction scheme

Definition at line 558 of file chan_sip.c.

int global_alwaysauthreject [static]

Send 401 Unauthorized for all failing requests

Definition at line 531 of file chan_sip.c.

int global_autoframing [static]

Turn autoframing on or off.

Definition at line 557 of file chan_sip.c.

int global_callevents [static]

Whether we send manager events or not

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

int global_directrtpsetup [static]

Enable support for Direct RTP setup (no re-invites)

Definition at line 526 of file chan_sip.c.

struct ast_flags global_flags[2] = {{0}} [static]

global SIP_ flags

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

int global_limitonpeers [static]

Match call limit on peers only

Definition at line 527 of file chan_sip.c.

int global_matchexterniplocally [static]

Match externip/externhost setting against localnet setting

Definition at line 560 of file chan_sip.c.

int global_mwitime [static]

Time between MWI checks for peers

Definition at line 544 of file chan_sip.c.

int global_notifyhold [static]

Send notifications on hold

Definition at line 530 of file chan_sip.c.

int global_notifyringing [static]

Send notifications on ringing

Definition at line 529 of file chan_sip.c.

char global_realm[MAXHOSTNAMELEN] [static]

Default realm

Definition at line 551 of file chan_sip.c.

int global_reg_timeout [static]

Definition at line 539 of file chan_sip.c.

int global_regattempts_max [static]

Registration attempts before giving up

Definition at line 540 of file chan_sip.c.

char global_regcontext[AST_MAX_CONTEXT] [static]

Context for auto-extensions

Definition at line 552 of file chan_sip.c.

int global_relaxdtmf [static]

Relax DTMF

Definition at line 535 of file chan_sip.c.

int global_rtautoclear [static]

Definition at line 528 of file chan_sip.c.

int global_rtpholdtimeout [static]

Definition at line 537 of file chan_sip.c.

int global_rtpkeepalive [static]

Send RTP keepalives

Definition at line 538 of file chan_sip.c.

int global_rtptimeout [static]

Time out call if no RTP

Definition at line 536 of file chan_sip.c.

int global_t1min [static]

T1 roundtrip time minimum

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

unsigned int global_tos_sip [static]

IP type of service for SIP packets

Definition at line 545 of file chan_sip.c.

unsigned int global_tos_video [static]

IP type of service for video RTP packets

Definition at line 547 of file chan_sip.c.

char global_useragent[AST_MAX_EXTENSION] [static]

Useragent for the SIP channel

Definition at line 553 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 11328 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 594 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 1187 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 9962 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 9513 of file chan_sip.c.

int max_expiry = DEFAULT_MAX_EXPIRY [static]

Maximum accepted registration time

Definition at line 184 of file chan_sip.c.

int min_expiry = DEFAULT_MIN_EXPIRY [static]

Minimum accepted registration time

Definition at line 183 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 588 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 11320 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 11324 of file chan_sip.c.

const char notify_config[] = "sip_notify.conf" [static]

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

int ourport [static]

Definition at line 1190 of file chan_sip.c.

struct sockaddr_in outboundproxyip [static]

Definition at line 1189 of file chan_sip.c.

Referenced by reload_config().

int pedanticsipchecking [static]

Extra checking ? Default off

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

int recordhistory [static]

Record SIP history. Off by default

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

int rpeerobjs = 0 [static]

Realtime peers

Definition at line 569 of file chan_sip.c.

int ruserobjs = 0 [static]

Realtime users

Definition at line 567 of file chan_sip.c.

struct sched_context* sched [static]

The scheduling context

Definition at line 593 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 11284 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 11280 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 11255 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 11288 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 11275 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 11341 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 11297 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 11292 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 11307 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 11345 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 11337 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 11270 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 11265 of file chan_sip.c.

struct ast_custom_function sip_header_function [static]

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

int sip_reloading = FALSE [static]

Flag for avoiding multiple reloads at the same time

Definition at line 590 of file chan_sip.c.

enum channelreloadreason sip_reloadreason [static]

Reason for last reload/load of configuration

Definition at line 591 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 1588 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 1531 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 1557 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 1597 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 11582 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 11502 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 1181 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 595 of file chan_sip.c.

int speerobjs = 0 [static]

Statis peers

Definition at line 568 of file chan_sip.c.

int srvlookup [static]

SRV Lookup on or off. Default is off, RFC behavior is on

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

char* synopsis_dtmfmode = "Change the dtmfmode for a SIP call" [static]

Definition at line 17003 of file chan_sip.c.

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

Definition at line 17008 of file chan_sip.c.

struct ast_user_list userl [static]

The user list: Users and friends.


Generated on Mon Apr 30 07:40:02 2007 for Asterisk - the Open Source PBX by  doxygen 1.5.1